assuremind 1.5.3 → 1.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -1,22 +1,22 @@
1
- "use strict";var Ut=Object.create;var Y=Object.defineProperty;var kt=Object.getOwnPropertyDescriptor;var Gt=Object.getOwnPropertyNames;var Mt=Object.getPrototypeOf,Bt=Object.prototype.hasOwnProperty;var Wt=(e,t)=>{for(var n in t)Y(e,n,{get:t[n],enumerable:!0})},Ve=(e,t,n,r)=>{if(t&&typeof t=="object"||typeof t=="function")for(let i of Gt(t))!Bt.call(e,i)&&i!==n&&Y(e,i,{get:()=>t[i],enumerable:!(r=kt(t,i))||r.enumerable});return e};var h=(e,t,n)=>(n=e!=null?Ut(Mt(e)):{},Ve(t||!e||!e.__esModule?Y(n,"default",{value:e,enumerable:!0}):n,e)),Jt=e=>Ve(Y({},"__esModule",{value:!0}),e);var Jn={};Wt(Jn,{AssuremindError:()=>v,ConfigError:()=>C,ExecutionError:()=>Z,HealingError:()=>Q,ProviderError:()=>X,StorageError:()=>g,ValidationError:()=>u,acceptHealingEvent:()=>Ct,appendPendingEvent:()=>jt,callFaker:()=>zt,clearEnvCache:()=>Dt,configExists:()=>ut,createCase:()=>et,createChildLogger:()=>b,createSuite:()=>Ke,defineConfig:()=>Wn,deleteCase:()=>nt,deleteGlobalVariable:()=>ct,deleteResult:()=>bt,deleteSuite:()=>qe,formatError:()=>Ue,generateCacheKey:()=>$t,getAvailableGenerators:()=>Ft,getCasePath:()=>it,getHealingStats:()=>_t,isAssuremindError:()=>ze,listCasePaths:()=>Se,listCases:()=>rt,listHealingReportIds:()=>Nt,listResultIds:()=>_e,listResults:()=>xt,listSuiteDirs:()=>ne,listSuites:()=>Xe,listSuitesWithCounts:()=>Ze,listVariableFiles:()=>lt,logger:()=>he,normalizeUrl:()=>$e,pruneResolvedEvents:()=>Pt,readCase:()=>ae,readConfig:()=>le,readEnvVariables:()=>ve,readGlobalVariables:()=>we,readHealingReport:()=>It,readPendingEvents:()=>V,readResult:()=>Pe,readSuite:()=>G,readVariables:()=>H,redactSecrets:()=>Be,rejectHealingEvent:()=>Tt,resolveVariables:()=>ot,sanitizeGeneratedCode:()=>Me,screenshotsDir:()=>St,setGlobalVariable:()=>st,sha256:()=>Oe,toSlug:()=>N,tracesDir:()=>Et,tryGetEnv:()=>Ht,updateCase:()=>tt,updateConfig:()=>pt,updateSuite:()=>Ye,validateConfig:()=>dt,validateEnv:()=>Le,videosDir:()=>yt,writeCase:()=>oe,writeConfig:()=>Ie,writeHealingReport:()=>Rt,writeResult:()=>ht,writeSuite:()=>te,writeVariables:()=>se});module.exports=Jt(Jn);var c=require("zod"),Kt=c.z.enum(["off","on","only-on-failure"]),Yt=c.z.enum(["off","on","on-first-retry","retain-on-failure"]),qt=c.z.enum(["off","on","on-first-retry","retain-on-failure"]),De=c.z.enum(["chromium","firefox","webkit"]),Xt=c.z.enum(["commit","domcontentloaded","load","networkidle"]),He=c.z.enum(["dev","stage","test","prod"]),Zt=c.z.object({dev:c.z.string().url().or(c.z.literal("")).default(""),stage:c.z.string().url().or(c.z.literal("")).default(""),test:c.z.string().url().or(c.z.literal("")).default(""),prod:c.z.string().url().or(c.z.literal("")).default("")}),Qt=c.z.object({enabled:c.z.boolean(),maxLevel:c.z.number().int().min(1).max(5),dailyBudget:c.z.number().positive(),autoPR:c.z.boolean(),healAssertionLocators:c.z.boolean().default(!1)}),en=c.z.object({allure:c.z.boolean(),html:c.z.boolean(),json:c.z.boolean()}),tn=c.z.object({width:c.z.number().int().positive(),height:c.z.number().int().positive()}),nn=c.z.object({name:c.z.string().min(1),environment:He,baseUrl:c.z.string().url(),browsers:c.z.array(De).min(1),headless:c.z.boolean().optional()}),z=c.z.object({baseUrl:c.z.string().url(),environment:He.default("stage"),environmentUrls:Zt.default({dev:"",stage:"",test:"",prod:""}),browsers:c.z.array(De).min(1),headless:c.z.boolean(),viewport:tn.default({width:1280,height:720}),timeout:c.z.number().int().positive(),retries:c.z.number().int().min(0),parallel:c.z.number().int().positive(),pageLoad:Xt.default("domcontentloaded"),screenshot:Kt,video:Yt,trace:qt,healing:Qt,reporting:en,studioPort:c.z.number().int().min(1024).max(65535),profiles:c.z.array(nn).default([]),activeProfile:c.z.string().optional(),device:c.z.string().optional(),rag:c.z.object({enabled:c.z.boolean(),codeCorpus:c.z.object({enabled:c.z.boolean(),maxEntries:c.z.number().int().positive(),similarityThreshold:c.z.number().min(0).max(1),directUseThreshold:c.z.number().min(0).max(1)}),healingCorpus:c.z.object({enabled:c.z.boolean(),maxEntries:c.z.number().int().positive(),similarityThreshold:c.z.number().min(0).max(1)}),errorCatalog:c.z.object({enabled:c.z.boolean(),maxEntries:c.z.number().int().positive()}),embedder:c.z.literal("tfidf")}).default({enabled:!0,codeCorpus:{enabled:!0,maxEntries:500,similarityThreshold:.65,directUseThreshold:.9},healingCorpus:{enabled:!0,maxEntries:300,similarityThreshold:.6},errorCatalog:{enabled:!0,maxEntries:200},embedder:"tfidf"}),mcp:c.z.object({enabled:c.z.boolean(),headless:c.z.boolean(),actThenScript:c.z.boolean(),proactiveHealing:c.z.boolean(),actionTimeout:c.z.number().int().positive(),idleTimeout:c.z.number().int().positive()}).default({enabled:!0,headless:!0,actThenScript:!1,proactiveHealing:!1,actionTimeout:15e3,idleTimeout:3e4}),ci:c.z.object({writeToRepo:c.z.boolean()}).default({writeToRepo:!1})}),q={baseUrl:"http://localhost:3000",environment:"stage",environmentUrls:{dev:"",stage:"http://localhost:3000",test:"",prod:""},browsers:["chromium"],headless:!0,viewport:{width:1280,height:720},timeout:3e4,retries:1,parallel:1,pageLoad:"domcontentloaded",screenshot:"only-on-failure",video:"off",trace:"on-first-retry",healing:{enabled:!0,maxLevel:5,dailyBudget:5,autoPR:!1,healAssertionLocators:!1},reporting:{allure:!0,html:!0,json:!0},studioPort:4400,profiles:[],rag:{enabled:!0,codeCorpus:{enabled:!0,maxEntries:500,similarityThreshold:.65,directUseThreshold:.9},healingCorpus:{enabled:!0,maxEntries:300,similarityThreshold:.6},errorCatalog:{enabled:!0,maxEntries:200},embedder:"tfidf"},mcp:{enabled:!0,headless:!0,actThenScript:!1,proactiveHealing:!1,actionTimeout:15e3,idleTimeout:3e4},ci:{writeToRepo:!1}};var S=h(require("path")),I=h(require("fs-extra")),Je=require("uuid");var l=require("zod"),U=l.z.object({id:l.z.string().min(1),order:l.z.number().int().positive(),instruction:l.z.string().min(1),generatedCode:l.z.string(),strategy:l.z.enum(["template","cache","rag","batch","fast","primary","recorder"]),stepType:l.z.enum(["ui","api","mock"]).default("ui"),lastHealed:l.z.string().nullable(),timeout:l.z.number().int().positive().optional(),retries:l.z.number().int().min(0).optional(),mockUrl:l.z.string().optional(),mockResponse:l.z.string().optional(),mockStatus:l.z.number().int().optional(),runAudit:l.z.boolean().optional(),soft:l.z.boolean().optional(),visualCheck:l.z.boolean().optional()}),rn=l.z.object({type:l.z.enum(["inline","json-file","csv-file"]),path:l.z.string().optional(),data:l.z.array(l.z.record(l.z.string())).optional()}).optional(),Fe=l.z.object({id:l.z.string(),instruction:l.z.string(),generatedCode:l.z.string().default(""),order:l.z.number().int().default(0)}),an=l.z.object({before:l.z.array(Fe).default([]),after:l.z.array(Fe).default([])}).default({before:[],after:[]}),de=l.z.object({id:l.z.string().min(1),name:l.z.string().min(1),description:l.z.string(),tags:l.z.array(l.z.string()),priority:l.z.enum(["critical","high","medium","low"]),timeout:l.z.number().int().positive().optional(),dataSource:rn,steps:l.z.array(U),caseHooks:an,lighthouseCategories:l.z.array(l.z.enum(["performance","accessibility","seo"])).default(["performance","accessibility","seo"]),createdAt:l.z.string().datetime(),updatedAt:l.z.string().datetime()}),ge=l.z.object({id:l.z.string().min(1),name:l.z.string().min(1),description:l.z.string(),tags:l.z.array(l.z.string()),type:l.z.enum(["ui","api","audit","performance"]).default("ui"),timeout:l.z.number().int().positive().optional(),createdAt:l.z.string().datetime(),updatedAt:l.z.string().datetime()}),Xn=l.z.enum(["before_all","before_each","after_each","after_all"]),Zn=l.z.object({before_all:l.z.array(U).default([]),before_each:l.z.array(U).default([]),after_each:l.z.array(U).default([]),after_all:l.z.array(U).default([])});var v=class extends Error{code;constructor(t,n){super(t),this.name="AssuremindError",this.code=n,Object.setPrototypeOf(this,new.target.prototype)}},X=class extends v{provider;constructor(t,n,r="PROVIDER_ERROR"){super(t,r),this.name="ProviderError",this.provider=n}},Z=class extends v{stepId;constructor(t,n,r="EXECUTION_ERROR"){super(t,r),this.name="ExecutionError",this.stepId=n}},C=class extends v{constructor(t,n="CONFIG_ERROR"){super(t,n),this.name="ConfigError"}},u=class extends v{field;constructor(t,n,r="VALIDATION_ERROR"){super(t,r),this.name="ValidationError",this.field=n}},Q=class extends v{level;constructor(t,n,r="HEALING_ERROR"){super(t,r),this.name="HealingError",this.level=n}},g=class extends v{path;constructor(t,n,r="STORAGE_ERROR"){super(t,r),this.name="StorageError",this.path=n}};function ze(e){return e instanceof v}function Ue(e){return e instanceof v?`[${e.code}] ${e.message}`:e instanceof Error?e.message:String(e)}var fe=h(require("pino")),on=h(require("fs-extra"));var sn=process.env.NODE_ENV!=="production",ke=sn?{target:"pino-pretty",options:{colorize:!0,translateTime:"HH:MM:ss",ignore:"pid,hostname",messageFormat:"[assuremind] {msg}"}}:void 0,he=(0,fe.default)({level:process.env.LOG_LEVEL??"info",base:{name:"assuremind"}},ke?fe.default.transport(ke):void 0);function b(e){return he.child({component:e})}function cn(e){let t=/^```(?:typescript|javascript|ts|js)?\n?([\s\S]*?)```\s*$/m,n=e.match(t);return n?.[1]!==void 0?n[1].trim():e.trim()}var ln=[/\brequire\s*\(/,/\bimport\s*\(/,/\bprocess\b/,/\bchild_process\b/,/\bexec\s*\(/,/\bspawn\s*\(/,/\beval\s*\(/,/\bFunction\s*\(/,/\b__dirname\b/,/\b__filename\b/,/\bglobal\b/,/\bwindow\.location\.href\s*=/,/\bdocument\.cookie\b/,/\blocalStorage\b/,/\bsessionStorage\b/,/\bIndexedDB\b/,/\bXMLHttpRequest\b/,/\bfetch\s*\(/,/\bWebSocket\s*\(/];function mn(e){for(let t of ln)if(t.test(e))throw new u(`Generated code contains forbidden pattern: ${t.source}. This may be a prompt injection attempt. Please regenerate the step.`,"generatedCode","UNSAFE_CODE")}var pn=/\s+(?:field|input|box|textbox|text\s?box|drop-?\s?down|dropdown|combo\s?box|combobox|menu|selector|element|checkbox|radio\s?button|radio)$/i;function Ge(e){let t=e.replace(pn,"").trim();return t.length>0?t:e}function un(e){let t=e;return t=t.replace(/(getBy(?:Label|Placeholder)\(\s*)(['"`])([\s\S]*?)\2/g,(n,r,i,a)=>`${r}${i}${Ge(a)}${i}`),t=t.replace(/(name:\s*)(['"`])([\s\S]*?)\2/g,(n,r,i,a)=>`${r}${i}${Ge(a)}${i}`),t}function dn(e){return e.replace(/\blocator\((['"`])([\s\S]*?)\1\)/g,(t,n,r)=>{if(!r.includes(" >> "))return t;let i=r.split(" >> ").map(a=>a.trim()).filter(Boolean);return i.length<2?t:i.map(a=>`locator(${n}${a}${n})`).join(".")})}function gn(e){let t=e;return t=dn(t),t=t.replace(/\.or\((?:[^()]*|\([^()]*\))*\)(?:\.(?:first|last)\(\))?/g,""),t=t.replace(/\.(?:first|last)\(\)(?=\.\w)/g,""),t=un(t),t}function Me(e){let t=cn(e);if(!t)throw new u("AI returned an empty code response. Please try regenerating.","generatedCode","EMPTY_CODE");let n=gn(t);return mn(n),n}function N(e){return e.toLowerCase().trim().replace(/[^a-z0-9]+/g,"-").replace(/^-+|-+$/g,"")}function Be(e,t){let n=e;for(let r of t)r.length>0&&(n=n.replaceAll(r,"[REDACTED]"));return n}var xe=h(require("path")),R=h(require("fs-extra"));async function x(e,t){let n=xe.default.dirname(e);await R.default.ensureDir(n);let r=`${e}.${process.pid}.tmp`;try{await R.default.writeJson(r,t,{spaces:2}),await R.default.rename(r,e)}catch(i){throw await R.default.remove(r).catch(()=>{}),new g(`Failed to write file "${e}": ${i instanceof Error?i.message:String(i)}`,e,"WRITE_FAILED")}}async function E(e){try{return await R.default.readJson(e)}catch(t){throw new g(`Failed to read JSON file "${e}": ${t instanceof Error?t.message:String(t)}`,e,"READ_FAILED")}}async function We(e,t){let n=xe.default.dirname(e);await R.default.ensureDir(n);let r=`${e}.${process.pid}.tmp`;try{await R.default.writeFile(r,t,"utf8"),await R.default.rename(r,e)}catch(i){throw await R.default.remove(r).catch(()=>{}),new g(`Failed to write file "${e}": ${i instanceof Error?i.message:String(i)}`,e,"WRITE_FAILED")}}var k=b("suite-store"),ee="suite.json";async function G(e){let t=S.default.join(e,ee);if(!await I.default.pathExists(t))throw new g(`Suite file not found at "${t}". Ensure the suite directory exists and contains a suite.json file.`,t,"SUITE_NOT_FOUND");let n=await E(t),r=ge.safeParse(n);if(!r.success){let a=r.error.issues.map(p=>` \u2022 ${p.path.join(".")}: ${p.message}`).join(`
2
- `);throw new u(`Invalid suite.json at "${t}":
3
- ${a}`,"suite","INVALID_SUITE")}if(!n.type){let a=S.default.basename(S.default.dirname(e));a==="api"?r.data.type="api":a==="audit"||a==="performance"?r.data.type="audit":r.data.type="ui"}return r.data}async function te(e,t){await I.default.ensureDir(e);let n=S.default.join(e,ee),r=ge.safeParse(t);if(!r.success){let i=r.error.issues.map(a=>` \u2022 ${a.path.join(".")}: ${a.message}`).join(`
4
- `);throw new u(`Cannot write invalid suite to "${n}":
5
- ${i}`,"suite","INVALID_SUITE")}await x(n,r.data),k.debug({suiteId:t.id,path:n},"Suite written")}async function Ke(e,t){let n=new Date().toISOString(),r=t.type??"ui",i={...t,type:r,id:(0,Je.v4)(),createdAt:n,updatedAt:n},a=S.default.join(e,r),p=S.default.join(a,N(i.name));if(await I.default.pathExists(S.default.join(p,ee)))throw new g(`Suite directory already exists at "${p}". Choose a different name or delete the existing suite first.`,p,"SUITE_ALREADY_EXISTS");return await te(p,i),k.info({suiteId:i.id,path:p},"Suite created"),{suiteDir:p,suiteId:i.id}}async function Ye(e,t){let n=await G(e),r={...n,...t,id:n.id,createdAt:n.createdAt,updatedAt:new Date().toISOString()};return await te(e,r),r}async function qe(e){if(!await I.default.pathExists(e))throw new g(`Suite directory not found at "${e}".`,e,"SUITE_NOT_FOUND");await I.default.remove(e),k.info({path:e},"Suite deleted")}async function ne(e){let t=[],n=[S.default.join(e,"ui"),S.default.join(e,"api"),S.default.join(e,"audit"),S.default.join(e,"performance"),e];for(let r of n){if(!await I.default.pathExists(r))continue;let i=await I.default.readdir(r,{withFileTypes:!0});for(let a of i){if(!a.isDirectory()||r===e&&(a.name==="ui"||a.name==="api"||a.name==="audit"||a.name==="performance"))continue;let p=S.default.join(r,a.name,ee);await I.default.pathExists(p)&&t.push(S.default.join(r,a.name))}}return t}async function Xe(e){let t=await ne(e),n=[];for(let r of t)try{n.push(await G(r))}catch(i){k.warn({path:r,err:i},"Failed to read suite \u2014 skipping")}return n}async function Ze(e){let t=await ne(e),n=[];for(let r of t)try{let i=await G(r),p=(await I.default.readdir(r,{withFileTypes:!0})).filter(y=>y.isFile()&&y.name.endsWith(".test.json")).length;n.push({...i,caseCount:p})}catch(i){k.warn({path:r,err:i},"Failed to read suite \u2014 skipping")}return n}var re=h(require("path")),D=h(require("fs-extra")),Qe=require("uuid");var ie=b("case-store"),be=".test.json";async function ae(e){if(!await D.default.pathExists(e))throw new g(`Test case file not found at "${e}".`,e,"CASE_NOT_FOUND");let t=await E(e),n=de.safeParse(t);if(!n.success){let r=n.error.issues.map(i=>` \u2022 ${i.path.join(".")}: ${i.message}`).join(`
6
- `);throw new u(`Invalid test case file at "${e}":
7
- ${r}`,"case","INVALID_CASE")}return n.data}async function oe(e,t){let n=de.safeParse(t);if(!n.success){let r=n.error.issues.map(i=>` \u2022 ${i.path.join(".")}: ${i.message}`).join(`
8
- `);throw new u(`Cannot write invalid test case to "${e}":
9
- ${r}`,"case","INVALID_CASE")}await x(e,n.data),ie.debug({caseId:t.id,path:e},"Test case written")}async function et(e,t){let n=new Date().toISOString(),r={...t,id:(0,Qe.v4)(),createdAt:n,updatedAt:n},i=re.default.join(e,`${N(r.name)}${be}`);return await oe(i,r),ie.info({caseId:r.id,path:i},"Test case created"),i}async function tt(e,t){let n=await ae(e),r={...n,...t,id:n.id,createdAt:n.createdAt,updatedAt:new Date().toISOString()};return await oe(e,r),r}async function nt(e){if(!await D.default.pathExists(e))throw new g(`Test case file not found at "${e}".`,e,"CASE_NOT_FOUND");await D.default.remove(e),ie.info({path:e},"Test case deleted")}async function Se(e){return await D.default.pathExists(e)?(await D.default.readdir(e,{withFileTypes:!0})).filter(n=>n.isFile()&&n.name.endsWith(be)).map(n=>re.default.join(e,n.name)):[]}async function rt(e){let t=await Se(e),n=[];for(let r of t)try{n.push(await ae(r))}catch(i){ie.warn({path:r,err:i},"Failed to read test case \u2014 skipping")}return n.sort((r,i)=>r.name.localeCompare(i.name))}function it(e,t){return re.default.join(e,`${N(t)}${be}`)}var P=h(require("path")),M=h(require("fs-extra"));var T=require("zod"),fn=T.z.object({value:T.z.string(),secret:T.z.literal(!0)}),hn=T.z.union([T.z.string(),fn]),ye=T.z.record(T.z.string(),hn);function xn(e){return typeof e=="object"&&e.secret===!0}function at(e){return xn(e)?e.value:e}var bn=b("variable-store"),B="variables",Ee="global.json";function Sn(e){return`${e}.env.json`}async function H(e){if(!await M.default.pathExists(e))return{};let t=await E(e),n=ye.safeParse(t);if(!n.success){let r=n.error.issues.map(i=>` \u2022 ${i.path.join(".")}: ${i.message}`).join(`
10
- `);throw new u(`Invalid variables file at "${e}":
11
- ${r}`,"variables","INVALID_VARIABLES")}return n.data}async function se(e,t){let n=ye.safeParse(t);if(!n.success){let r=n.error.issues.map(i=>` \u2022 ${i.path.join(".")}: ${i.message}`).join(`
12
- `);throw new u(`Cannot write invalid variables to "${e}":
13
- ${r}`,"variables","INVALID_VARIABLES")}await x(e,n.data),bn.debug({path:e},"Variables written")}async function we(e){let t=P.default.join(e,B,Ee);return H(t)}async function ve(e,t){let n=P.default.join(e,B,Sn(t));return H(n)}async function ot(e,t){let n=await we(e),r=t?await ve(e,t):{},i={...n,...r},a={};for(let[p,y]of Object.entries(i))a[p]=at(y);return a}async function st(e,t,n){let r=P.default.join(e,B,Ee);await M.default.ensureDir(P.default.dirname(r));let i=await H(r);i[t]=n,await se(r,i)}async function ct(e,t){let n=P.default.join(e,B,Ee),r=await H(n);if(!(t in r))throw new g(`Variable "${t}" not found in global variables.`,n,"VARIABLE_NOT_FOUND");delete r[t],await se(n,r)}async function lt(e){let t=P.default.join(e,B);return await M.default.pathExists(t)?(await M.default.readdir(t,{withFileTypes:!0})).filter(r=>r.isFile()&&r.name.endsWith(".json")).map(r=>P.default.join(t,r.name)):[]}var F=h(require("path")),ce=h(require("fs-extra"));var Ae=b("config-store"),Re="autotest.config.json",mt="autotest.config.ts";async function le(e){let t=F.default.join(e,Re);if(!await ce.default.pathExists(t))return Ae.debug({rootDir:e},"No autotest.config.json found \u2014 using defaults"),q;let n=await E(t),r=z.safeParse(n);if(!r.success){let i=r.error.issues.map(a=>` \u2022 ${a.path.join(".")}: ${a.message}`).join(`
14
- `);throw new u(`Invalid autotest.config.json at "${t}":
15
- ${i}
1
+ "use strict";var Gt=Object.create;var Y=Object.defineProperty;var Mt=Object.getOwnPropertyDescriptor;var Bt=Object.getOwnPropertyNames;var Wt=Object.getPrototypeOf,Jt=Object.prototype.hasOwnProperty;var Kt=(e,t)=>{for(var n in t)Y(e,n,{get:t[n],enumerable:!0})},De=(e,t,n,r)=>{if(t&&typeof t=="object"||typeof t=="function")for(let i of Bt(t))!Jt.call(e,i)&&i!==n&&Y(e,i,{get:()=>t[i],enumerable:!(r=Mt(t,i))||r.enumerable});return e};var h=(e,t,n)=>(n=e!=null?Gt(Wt(e)):{},De(t||!e||!e.__esModule?Y(n,"default",{value:e,enumerable:!0}):n,e)),Yt=e=>De(Y({},"__esModule",{value:!0}),e);var Yn={};Kt(Yn,{AssuremindError:()=>v,ConfigError:()=>T,ExecutionError:()=>Z,HealingError:()=>Q,ProviderError:()=>X,StorageError:()=>g,ValidationError:()=>p,acceptHealingEvent:()=>Ct,appendPendingEvent:()=>Pt,callFaker:()=>kt,clearEnvCache:()=>Ft,configExists:()=>gt,createCase:()=>nt,createChildLogger:()=>b,createSuite:()=>qe,defineConfig:()=>Kn,deleteCase:()=>it,deleteGlobalVariable:()=>mt,deleteResult:()=>yt,deleteSuite:()=>Ze,formatError:()=>Ge,generateCacheKey:()=>Lt,getAvailableGenerators:()=>Ut,getCasePath:()=>ot,getHealingStats:()=>Nt,isAssuremindError:()=>ke,listCasePaths:()=>ye,listCases:()=>at,listHealingReportIds:()=>$t,listResultIds:()=>Oe,listResults:()=>St,listSuiteDirs:()=>ne,listSuites:()=>Qe,listSuitesWithCounts:()=>et,listVariableFiles:()=>ut,logger:()=>xe,normalizeUrl:()=>Ve,pruneResolvedEvents:()=>Ot,readCase:()=>ae,readConfig:()=>le,readEnvVariables:()=>Ae,readGlobalVariables:()=>ve,readHealingReport:()=>Tt,readPendingEvents:()=>L,readResult:()=>_e,readSuite:()=>G,readVariables:()=>H,redactSecrets:()=>Je,rejectHealingEvent:()=>_t,resolveVariables:()=>ct,sanitizeGeneratedCode:()=>We,screenshotsDir:()=>Et,setGlobalVariable:()=>lt,sha256:()=>$e,toSlug:()=>O,tracesDir:()=>vt,tryGetEnv:()=>zt,updateCase:()=>rt,updateConfig:()=>dt,updateSuite:()=>Xe,validateConfig:()=>ft,validateEnv:()=>Le,videosDir:()=>wt,writeCase:()=>oe,writeConfig:()=>je,writeHealingReport:()=>jt,writeResult:()=>bt,writeSuite:()=>te,writeVariables:()=>se});module.exports=Yt(Yn);var c=require("zod"),qt=c.z.enum(["off","on","only-on-failure"]),Xt=c.z.enum(["off","on","on-first-retry","retain-on-failure"]),Zt=c.z.enum(["off","on","on-first-retry","retain-on-failure"]),He=c.z.enum(["chromium","firefox","webkit"]),Qt=c.z.enum(["commit","domcontentloaded","load","networkidle"]),Fe=c.z.string().min(1),ze=["DEV","TEST","STAGE","INT","PROD"],en=c.z.record(c.z.string(),c.z.string()).default({}),tn=c.z.object({enabled:c.z.boolean(),maxLevel:c.z.number().int().min(1).max(5),dailyBudget:c.z.number().positive(),autoPR:c.z.boolean(),healAssertionLocators:c.z.boolean().default(!1)}),nn=c.z.object({allure:c.z.boolean(),html:c.z.boolean(),json:c.z.boolean()}),rn=c.z.object({width:c.z.number().int().positive(),height:c.z.number().int().positive()}),an=c.z.object({name:c.z.string().min(1),environment:Fe,baseUrl:c.z.string().url(),browsers:c.z.array(He).min(1),headless:c.z.boolean().optional()}),z=c.z.object({baseUrl:c.z.string().url(),environment:Fe.default("DEV"),environments:c.z.array(c.z.string().min(1)).default([...ze]),environmentUrls:en.default({DEV:"",TEST:"",STAGE:"",INT:"",PROD:""}),browsers:c.z.array(He).min(1),headless:c.z.boolean(),viewport:rn.default({width:1280,height:720}),timeout:c.z.number().int().positive(),retries:c.z.number().int().min(0),parallel:c.z.number().int().positive(),pageLoad:Qt.default("domcontentloaded"),screenshot:qt,video:Xt,trace:Zt,healing:tn,reporting:nn,studioPort:c.z.number().int().min(1024).max(65535),profiles:c.z.array(an).default([]),activeProfile:c.z.string().optional(),device:c.z.string().optional(),rag:c.z.object({enabled:c.z.boolean(),codeCorpus:c.z.object({enabled:c.z.boolean(),maxEntries:c.z.number().int().positive(),similarityThreshold:c.z.number().min(0).max(1),directUseThreshold:c.z.number().min(0).max(1)}),healingCorpus:c.z.object({enabled:c.z.boolean(),maxEntries:c.z.number().int().positive(),similarityThreshold:c.z.number().min(0).max(1)}),errorCatalog:c.z.object({enabled:c.z.boolean(),maxEntries:c.z.number().int().positive()}),embedder:c.z.literal("tfidf")}).default({enabled:!0,codeCorpus:{enabled:!0,maxEntries:500,similarityThreshold:.65,directUseThreshold:.9},healingCorpus:{enabled:!0,maxEntries:300,similarityThreshold:.6},errorCatalog:{enabled:!0,maxEntries:200},embedder:"tfidf"}),mcp:c.z.object({enabled:c.z.boolean(),headless:c.z.boolean(),actThenScript:c.z.boolean(),proactiveHealing:c.z.boolean(),actionTimeout:c.z.number().int().positive(),idleTimeout:c.z.number().int().positive()}).default({enabled:!0,headless:!0,actThenScript:!1,proactiveHealing:!1,actionTimeout:15e3,idleTimeout:3e4}),ci:c.z.object({writeToRepo:c.z.boolean()}).default({writeToRepo:!1})}),q={baseUrl:"http://localhost:3000",environment:"DEV",environments:[...ze],environmentUrls:{DEV:"http://localhost:3000",TEST:"",STAGE:"",INT:"",PROD:""},browsers:["chromium"],headless:!0,viewport:{width:1280,height:720},timeout:3e4,retries:1,parallel:1,pageLoad:"domcontentloaded",screenshot:"only-on-failure",video:"off",trace:"on-first-retry",healing:{enabled:!0,maxLevel:5,dailyBudget:5,autoPR:!1,healAssertionLocators:!1},reporting:{allure:!0,html:!0,json:!0},studioPort:4400,profiles:[],rag:{enabled:!0,codeCorpus:{enabled:!0,maxEntries:500,similarityThreshold:.65,directUseThreshold:.9},healingCorpus:{enabled:!0,maxEntries:300,similarityThreshold:.6},errorCatalog:{enabled:!0,maxEntries:200},embedder:"tfidf"},mcp:{enabled:!0,headless:!0,actThenScript:!1,proactiveHealing:!1,actionTimeout:15e3,idleTimeout:3e4},ci:{writeToRepo:!1}};var S=h(require("path")),I=h(require("fs-extra")),Ye=require("uuid");var l=require("zod"),U=l.z.object({id:l.z.string().min(1),order:l.z.number().int().positive(),instruction:l.z.string().min(1),generatedCode:l.z.string(),strategy:l.z.enum(["template","cache","rag","batch","fast","primary","recorder"]),stepType:l.z.enum(["ui","api","mock"]).default("ui"),lastHealed:l.z.string().nullable(),timeout:l.z.number().int().positive().optional(),retries:l.z.number().int().min(0).optional(),mockUrl:l.z.string().optional(),mockResponse:l.z.string().optional(),mockStatus:l.z.number().int().optional(),runAudit:l.z.boolean().optional(),soft:l.z.boolean().optional(),visualCheck:l.z.boolean().optional()}),on=l.z.object({type:l.z.enum(["inline","json-file","csv-file"]),path:l.z.string().optional(),data:l.z.array(l.z.record(l.z.string())).optional()}).optional(),Ue=l.z.object({id:l.z.string(),instruction:l.z.string(),generatedCode:l.z.string().default(""),order:l.z.number().int().default(0)}),sn=l.z.object({before:l.z.array(Ue).default([]),after:l.z.array(Ue).default([])}).default({before:[],after:[]}),ge=l.z.object({id:l.z.string().min(1),name:l.z.string().min(1),description:l.z.string(),tags:l.z.array(l.z.string()),priority:l.z.enum(["critical","high","medium","low"]),timeout:l.z.number().int().positive().optional(),dataSource:on,steps:l.z.array(U),caseHooks:sn,lighthouseCategories:l.z.array(l.z.enum(["performance","accessibility","seo"])).default(["performance","accessibility","seo"]),createdAt:l.z.string().datetime(),updatedAt:l.z.string().datetime()}),fe=l.z.object({id:l.z.string().min(1),name:l.z.string().min(1),description:l.z.string(),tags:l.z.array(l.z.string()),type:l.z.enum(["ui","api","audit","performance"]).default("ui"),timeout:l.z.number().int().positive().optional(),createdAt:l.z.string().datetime(),updatedAt:l.z.string().datetime()}),Qn=l.z.enum(["before_all","before_each","after_each","after_all"]),er=l.z.object({before_all:l.z.array(U).default([]),before_each:l.z.array(U).default([]),after_each:l.z.array(U).default([]),after_all:l.z.array(U).default([])});var v=class extends Error{code;constructor(t,n){super(t),this.name="AssuremindError",this.code=n,Object.setPrototypeOf(this,new.target.prototype)}},X=class extends v{provider;constructor(t,n,r="PROVIDER_ERROR"){super(t,r),this.name="ProviderError",this.provider=n}},Z=class extends v{stepId;constructor(t,n,r="EXECUTION_ERROR"){super(t,r),this.name="ExecutionError",this.stepId=n}},T=class extends v{constructor(t,n="CONFIG_ERROR"){super(t,n),this.name="ConfigError"}},p=class extends v{field;constructor(t,n,r="VALIDATION_ERROR"){super(t,r),this.name="ValidationError",this.field=n}},Q=class extends v{level;constructor(t,n,r="HEALING_ERROR"){super(t,r),this.name="HealingError",this.level=n}},g=class extends v{path;constructor(t,n,r="STORAGE_ERROR"){super(t,r),this.name="StorageError",this.path=n}};function ke(e){return e instanceof v}function Ge(e){return e instanceof v?`[${e.code}] ${e.message}`:e instanceof Error?e.message:String(e)}var he=h(require("pino")),cn=h(require("fs-extra"));var ln=process.env.NODE_ENV!=="production",Me=ln?{target:"pino-pretty",options:{colorize:!0,translateTime:"HH:MM:ss",ignore:"pid,hostname",messageFormat:"[assuremind] {msg}"}}:void 0,xe=(0,he.default)({level:process.env.LOG_LEVEL??"info",base:{name:"assuremind"}},Me?he.default.transport(Me):void 0);function b(e){return xe.child({component:e})}function mn(e){let t=/^```(?:typescript|javascript|ts|js)?\n?([\s\S]*?)```\s*$/m,n=e.match(t);return n?.[1]!==void 0?n[1].trim():e.trim()}var un=[/\brequire\s*\(/,/\bimport\s*\(/,/\bprocess\b/,/\bchild_process\b/,/\bexec\s*\(/,/\bspawn\s*\(/,/\beval\s*\(/,/\bFunction\s*\(/,/\b__dirname\b/,/\b__filename\b/,/\bglobal\b/,/\bwindow\.location\.href\s*=/,/\bdocument\.cookie\b/,/\blocalStorage\b/,/\bsessionStorage\b/,/\bIndexedDB\b/,/\bXMLHttpRequest\b/,/\bfetch\s*\(/,/\bWebSocket\s*\(/];function pn(e){for(let t of un)if(t.test(e))throw new p(`Generated code contains forbidden pattern: ${t.source}. This may be a prompt injection attempt. Please regenerate the step.`,"generatedCode","UNSAFE_CODE")}var dn=/\s+(?:field|input|box|textbox|text\s?box|drop-?\s?down|dropdown|combo\s?box|combobox|menu|selector|element|checkbox|radio\s?button|radio)$/i;function Be(e){let t=e.replace(dn,"").trim();return t.length>0?t:e}function gn(e){let t=e;return t=t.replace(/(getBy(?:Label|Placeholder)\(\s*)(['"`])([\s\S]*?)\2/g,(n,r,i,a)=>`${r}${i}${Be(a)}${i}`),t=t.replace(/(name:\s*)(['"`])([\s\S]*?)\2/g,(n,r,i,a)=>`${r}${i}${Be(a)}${i}`),t}function fn(e){return e.replace(/\blocator\((['"`])([\s\S]*?)\1\)/g,(t,n,r)=>{if(!r.includes(" >> "))return t;let i=r.split(" >> ").map(a=>a.trim()).filter(Boolean);return i.length<2?t:i.map(a=>`locator(${n}${a}${n})`).join(".")})}function hn(e){let t=e;return t=fn(t),t=t.replace(/\.or\((?:[^()]*|\([^()]*\))*\)(?:\.(?:first|last)\(\))?/g,""),t=t.replace(/\.(?:first|last)\(\)(?=\.\w)/g,""),t=gn(t),t}function We(e){let t=mn(e);if(!t)throw new p("AI returned an empty code response. Please try regenerating.","generatedCode","EMPTY_CODE");let n=hn(t);return pn(n),n}function O(e){return e.toLowerCase().trim().replace(/[^a-z0-9]+/g,"-").replace(/^-+|-+$/g,"")}function Je(e,t){let n=e;for(let r of t)r.length>0&&(n=n.replaceAll(r,"[REDACTED]"));return n}var be=h(require("path")),R=h(require("fs-extra"));async function x(e,t){let n=be.default.dirname(e);await R.default.ensureDir(n);let r=`${e}.${process.pid}.tmp`;try{await R.default.writeJson(r,t,{spaces:2}),await R.default.rename(r,e)}catch(i){throw await R.default.remove(r).catch(()=>{}),new g(`Failed to write file "${e}": ${i instanceof Error?i.message:String(i)}`,e,"WRITE_FAILED")}}async function E(e){try{return await R.default.readJson(e)}catch(t){throw new g(`Failed to read JSON file "${e}": ${t instanceof Error?t.message:String(t)}`,e,"READ_FAILED")}}async function Ke(e,t){let n=be.default.dirname(e);await R.default.ensureDir(n);let r=`${e}.${process.pid}.tmp`;try{await R.default.writeFile(r,t,"utf8"),await R.default.rename(r,e)}catch(i){throw await R.default.remove(r).catch(()=>{}),new g(`Failed to write file "${e}": ${i instanceof Error?i.message:String(i)}`,e,"WRITE_FAILED")}}var k=b("suite-store"),ee="suite.json";async function G(e){let t=S.default.join(e,ee);if(!await I.default.pathExists(t))throw new g(`Suite file not found at "${t}". Ensure the suite directory exists and contains a suite.json file.`,t,"SUITE_NOT_FOUND");let n=await E(t),r=fe.safeParse(n);if(!r.success){let a=r.error.issues.map(m=>` \u2022 ${m.path.join(".")}: ${m.message}`).join(`
2
+ `);throw new p(`Invalid suite.json at "${t}":
3
+ ${a}`,"suite","INVALID_SUITE")}if(!n.type){let a=S.default.basename(S.default.dirname(e));a==="api"?r.data.type="api":a==="audit"||a==="performance"?r.data.type="audit":r.data.type="ui"}return r.data}async function te(e,t){await I.default.ensureDir(e);let n=S.default.join(e,ee),r=fe.safeParse(t);if(!r.success){let i=r.error.issues.map(a=>` \u2022 ${a.path.join(".")}: ${a.message}`).join(`
4
+ `);throw new p(`Cannot write invalid suite to "${n}":
5
+ ${i}`,"suite","INVALID_SUITE")}await x(n,r.data),k.debug({suiteId:t.id,path:n},"Suite written")}async function qe(e,t){let n=new Date().toISOString(),r=t.type??"ui",i={...t,type:r,id:(0,Ye.v4)(),createdAt:n,updatedAt:n},a=S.default.join(e,r),m=S.default.join(a,O(i.name));if(await I.default.pathExists(S.default.join(m,ee)))throw new g(`Suite directory already exists at "${m}". Choose a different name or delete the existing suite first.`,m,"SUITE_ALREADY_EXISTS");return await te(m,i),k.info({suiteId:i.id,path:m},"Suite created"),{suiteDir:m,suiteId:i.id}}async function Xe(e,t){let n=await G(e),r={...n,...t,id:n.id,createdAt:n.createdAt,updatedAt:new Date().toISOString()};return await te(e,r),r}async function Ze(e){if(!await I.default.pathExists(e))throw new g(`Suite directory not found at "${e}".`,e,"SUITE_NOT_FOUND");await I.default.remove(e),k.info({path:e},"Suite deleted")}async function ne(e){let t=[],n=[S.default.join(e,"ui"),S.default.join(e,"api"),S.default.join(e,"audit"),S.default.join(e,"performance"),e];for(let r of n){if(!await I.default.pathExists(r))continue;let i=await I.default.readdir(r,{withFileTypes:!0});for(let a of i){if(!a.isDirectory()||r===e&&(a.name==="ui"||a.name==="api"||a.name==="audit"||a.name==="performance"))continue;let m=S.default.join(r,a.name,ee);await I.default.pathExists(m)&&t.push(S.default.join(r,a.name))}}return t}async function Qe(e){let t=await ne(e),n=[];for(let r of t)try{n.push(await G(r))}catch(i){k.warn({path:r,err:i},"Failed to read suite \u2014 skipping")}return n}async function et(e){let t=await ne(e),n=[];for(let r of t)try{let i=await G(r),m=(await I.default.readdir(r,{withFileTypes:!0})).filter(y=>y.isFile()&&y.name.endsWith(".test.json")).length;n.push({...i,caseCount:m})}catch(i){k.warn({path:r,err:i},"Failed to read suite \u2014 skipping")}return n}var re=h(require("path")),D=h(require("fs-extra")),tt=require("uuid");var ie=b("case-store"),Se=".test.json";async function ae(e){if(!await D.default.pathExists(e))throw new g(`Test case file not found at "${e}".`,e,"CASE_NOT_FOUND");let t=await E(e),n=ge.safeParse(t);if(!n.success){let r=n.error.issues.map(i=>` \u2022 ${i.path.join(".")}: ${i.message}`).join(`
6
+ `);throw new p(`Invalid test case file at "${e}":
7
+ ${r}`,"case","INVALID_CASE")}return n.data}async function oe(e,t){let n=ge.safeParse(t);if(!n.success){let r=n.error.issues.map(i=>` \u2022 ${i.path.join(".")}: ${i.message}`).join(`
8
+ `);throw new p(`Cannot write invalid test case to "${e}":
9
+ ${r}`,"case","INVALID_CASE")}await x(e,n.data),ie.debug({caseId:t.id,path:e},"Test case written")}async function nt(e,t){let n=new Date().toISOString(),r={...t,id:(0,tt.v4)(),createdAt:n,updatedAt:n},i=re.default.join(e,`${O(r.name)}${Se}`);return await oe(i,r),ie.info({caseId:r.id,path:i},"Test case created"),i}async function rt(e,t){let n=await ae(e),r={...n,...t,id:n.id,createdAt:n.createdAt,updatedAt:new Date().toISOString()};return await oe(e,r),r}async function it(e){if(!await D.default.pathExists(e))throw new g(`Test case file not found at "${e}".`,e,"CASE_NOT_FOUND");await D.default.remove(e),ie.info({path:e},"Test case deleted")}async function ye(e){return await D.default.pathExists(e)?(await D.default.readdir(e,{withFileTypes:!0})).filter(n=>n.isFile()&&n.name.endsWith(Se)).map(n=>re.default.join(e,n.name)):[]}async function at(e){let t=await ye(e),n=[];for(let r of t)try{n.push(await ae(r))}catch(i){ie.warn({path:r,err:i},"Failed to read test case \u2014 skipping")}return n.sort((r,i)=>r.name.localeCompare(i.name))}function ot(e,t){return re.default.join(e,`${O(t)}${Se}`)}var C=h(require("path")),M=h(require("fs-extra"));var P=require("zod"),xn=P.z.object({value:P.z.string(),secret:P.z.literal(!0)}),bn=P.z.union([P.z.string(),xn]),Ee=P.z.record(P.z.string(),bn);function Sn(e){return typeof e=="object"&&e.secret===!0}function st(e){return Sn(e)?e.value:e}var yn=b("variable-store"),B="variables",we="global.json";function En(e){return`${e}.env.json`}async function H(e){if(!await M.default.pathExists(e))return{};let t=await E(e),n=Ee.safeParse(t);if(!n.success){let r=n.error.issues.map(i=>` \u2022 ${i.path.join(".")}: ${i.message}`).join(`
10
+ `);throw new p(`Invalid variables file at "${e}":
11
+ ${r}`,"variables","INVALID_VARIABLES")}return n.data}async function se(e,t){let n=Ee.safeParse(t);if(!n.success){let r=n.error.issues.map(i=>` \u2022 ${i.path.join(".")}: ${i.message}`).join(`
12
+ `);throw new p(`Cannot write invalid variables to "${e}":
13
+ ${r}`,"variables","INVALID_VARIABLES")}await x(e,n.data),yn.debug({path:e},"Variables written")}async function ve(e){let t=C.default.join(e,B,we);return H(t)}async function Ae(e,t){let n=C.default.join(e,B,En(t));return H(n)}async function ct(e,t){let n=await ve(e),r=t?await Ae(e,t):{},i={...n,...r},a={};for(let[m,y]of Object.entries(i)){let de=process.env[m];a[m]=de!==void 0&&de!==""?de:st(y)}return a}async function lt(e,t,n){let r=C.default.join(e,B,we);await M.default.ensureDir(C.default.dirname(r));let i=await H(r);i[t]=n,await se(r,i)}async function mt(e,t){let n=C.default.join(e,B,we),r=await H(n);if(!(t in r))throw new g(`Variable "${t}" not found in global variables.`,n,"VARIABLE_NOT_FOUND");delete r[t],await se(n,r)}async function ut(e){let t=C.default.join(e,B);return await M.default.pathExists(t)?(await M.default.readdir(t,{withFileTypes:!0})).filter(r=>r.isFile()&&r.name.endsWith(".json")).map(r=>C.default.join(t,r.name)):[]}var F=h(require("path")),ce=h(require("fs-extra"));var Re=b("config-store"),Ie="autotest.config.json",pt="autotest.config.ts";async function le(e){let t=F.default.join(e,Ie);if(!await ce.default.pathExists(t))return Re.debug({rootDir:e},"No autotest.config.json found \u2014 using defaults"),q;let n=await E(t),r=z.safeParse(n);if(!r.success){let a=r.error.issues.map(m=>` \u2022 ${m.path.join(".")}: ${m.message}`).join(`
14
+ `);throw new p(`Invalid autotest.config.json at "${t}":
15
+ ${a}
16
16
 
17
- How to fix: Run "npx assuremind init" to reset to defaults, or manually correct the file using autotest.config.ts as reference.`,"config","INVALID_CONFIG")}return r.data}async function Ie(e,t){let n=z.safeParse(t);if(!n.success){let a=n.error.issues.map(p=>` \u2022 ${p.path.join(".")}: ${p.message}`).join(`
18
- `);throw new u(`Cannot write invalid config:
19
- ${a}`,"config","INVALID_CONFIG")}let r=F.default.join(e,Re);await x(r,n.data);let i=F.default.join(e,mt);await We(i,yn(n.data)),Ae.info({rootDir:e},"Config saved")}async function pt(e,t){let n=await le(e),r={...n,...t,healing:{...n.healing,...t.healing??{}},reporting:{...n.reporting,...t.reporting??{}},environmentUrls:{...n.environmentUrls,...t.environmentUrls??{}}};return await Ie(e,r),r}async function ut(e){let t=F.default.join(e,Re),n=F.default.join(e,mt);return await ce.default.pathExists(t)||await ce.default.pathExists(n)}async function dt(e){let t=await le(e);if(!t.baseUrl)throw new C('baseUrl is required in autotest.config.ts. Set it to your application URL, e.g. "http://localhost:3000".',"CONFIG_BASE_URL_MISSING");Ae.debug({config:t},"Config validated successfully")}function yn(e){return`import { defineConfig } from 'assuremind';
17
+ How to fix: Run "npx assuremind init" to reset to defaults, or manually correct the file using autotest.config.ts as reference.`,"config","INVALID_CONFIG")}let i=r.data;if(n&&typeof n=="object"&&"environments"in n)i.environment&&!i.environments.includes(i.environment)&&(i.environments=[...i.environments,i.environment]);else{let a=new Set;for(let m of Object.keys(i.environmentUrls??{}))a.add(m);i.environment&&a.add(i.environment),a.size>0&&(i.environments=[...a])}return i}async function je(e,t){let n=z.safeParse(t);if(!n.success){let a=n.error.issues.map(m=>` \u2022 ${m.path.join(".")}: ${m.message}`).join(`
18
+ `);throw new p(`Cannot write invalid config:
19
+ ${a}`,"config","INVALID_CONFIG")}let r=F.default.join(e,Ie);await x(r,n.data);let i=F.default.join(e,pt);await Ke(i,wn(n.data)),Re.info({rootDir:e},"Config saved")}async function dt(e,t){let n=await le(e),r={...n,...t,healing:{...n.healing,...t.healing??{}},reporting:{...n.reporting,...t.reporting??{}},environmentUrls:{...n.environmentUrls,...t.environmentUrls??{}}};return await je(e,r),r}async function gt(e){let t=F.default.join(e,Ie),n=F.default.join(e,pt);return await ce.default.pathExists(t)||await ce.default.pathExists(n)}async function ft(e){let t=await le(e);if(!t.baseUrl)throw new T('baseUrl is required in autotest.config.ts. Set it to your application URL, e.g. "http://localhost:3000".',"CONFIG_BASE_URL_MISSING");Re.debug({config:t},"Config validated successfully")}function wn(e){return`import { defineConfig } from 'assuremind';
20
20
 
21
21
  export default defineConfig({
22
22
  baseUrl: '${e.baseUrl}',
@@ -41,22 +41,22 @@ export default defineConfig({
41
41
  },
42
42
  studioPort: ${e.studioPort},
43
43
  });
44
- `}var j=h(require("path")),O=h(require("fs-extra"));var s=require("zod"),me=s.z.enum(["pending","running","passed","failed","skipped"]),En=s.z.object({method:s.z.string(),url:s.z.string(),headers:s.z.record(s.z.string()).optional(),body:s.z.string().optional()}).optional(),wn=s.z.object({status:s.z.number(),statusText:s.z.string(),headers:s.z.record(s.z.string()).optional(),body:s.z.string().optional(),duration:s.z.number()}).optional(),A=s.z.number().nullish().transform(e=>e??void 0),gt=s.z.object({id:s.z.string(),title:s.z.string(),passed:s.z.boolean(),partial:s.z.boolean().optional(),na:s.z.boolean().optional()}),vn=s.z.object({url:s.z.string(),stepIndex:s.z.number().int(),stepInstruction:s.z.string(),score:A,a11yScore:A,seoScore:A,fcp:A,lcp:A,cls:A,ttfb:A,tbt:A,si:A,tti:A,inp:A,a11yAudits:s.z.array(gt).optional(),seoAudits:s.z.array(gt).optional(),lighthouseError:s.z.string().optional()}),An=s.z.object({stepId:s.z.string(),instruction:s.z.string(),status:me,code:s.z.string(),error:s.z.string().optional(),duration:s.z.number(),screenshotPath:s.z.string().optional(),healed:s.z.boolean().optional(),healedCode:s.z.string().optional(),stepType:s.z.enum(["ui","api","mock"]).optional(),apiRequest:En,apiResponse:wn,navigatedToUrl:s.z.string().optional(),auditUrl:s.z.string().optional()}),Rn=s.z.object({caseId:s.z.string(),caseName:s.z.string(),status:me,steps:s.z.array(An),duration:s.z.number(),browser:s.z.string(),device:s.z.string().optional(),startedAt:s.z.string().datetime(),finishedAt:s.z.string().datetime(),videoPath:s.z.string().optional(),tracePath:s.z.string().optional(),downloadPaths:s.z.array(s.z.string()).default([]),dataRowIndex:s.z.number().int().optional(),dataRow:s.z.record(s.z.string()).optional(),pageLoads:s.z.array(vn).default([])}),In=s.z.object({suiteId:s.z.string(),suiteName:s.z.string(),suiteType:s.z.enum(["ui","api","audit","performance"]).optional(),status:me,cases:s.z.array(Rn),duration:s.z.number(),browser:s.z.string(),startedAt:s.z.string().datetime(),finishedAt:s.z.string().datetime()}),je=s.z.object({runId:s.z.string(),status:me,environment:s.z.string().optional(),suites:s.z.array(In),duration:s.z.number(),startedAt:s.z.string().datetime(),finishedAt:s.z.string().datetime(),totalTests:s.z.number().int(),passed:s.z.number().int(),failed:s.z.number().int(),skipped:s.z.number().int(),logFilePath:s.z.string().optional()});var Ce=b("result-store"),$="results",ft="runs";function Te(e,t){return j.default.join(e,ft,`${t}.json`)}async function ht(e,t){let n=je.safeParse(t);if(!n.success){let i=n.error.issues.map(a=>` \u2022 ${a.path.join(".")}: ${a.message}`).join(`
45
- `);throw new u(`Cannot write invalid run result:
46
- ${i}`,"result","INVALID_RESULT")}let r=Te(j.default.join(e,$),t.runId);await x(r,n.data),Ce.info({runId:t.runId,status:t.status},"Run result saved")}async function Pe(e,t){let n=Te(j.default.join(e,$),t);if(!await O.default.pathExists(n))throw new g(`Run result not found for runId "${t}".`,n,"RESULT_NOT_FOUND");let r=await E(n),i=je.safeParse(r);if(!i.success){let a=i.error.issues.map(p=>` \u2022 ${p.path.join(".")}: ${p.message}`).join(`
47
- `);throw new u(`Invalid run result at "${n}":
48
- ${a}`,"result","INVALID_RESULT")}return i.data}async function _e(e){let t=j.default.join(e,$,ft);if(!await O.default.pathExists(t))return[];let r=(await O.default.readdir(t,{withFileTypes:!0})).filter(a=>a.isFile()&&a.name.endsWith(".json")).map(a=>a.name.replace(".json",""));return(await Promise.all(r.map(async a=>{let p=await O.default.stat(j.default.join(t,`${a}.json`));return{id:a,mtime:p.mtimeMs}}))).sort((a,p)=>p.mtime-a.mtime).map(a=>a.id)}async function xt(e,t=20){let n=await _e(e),r=[];for(let i of n.slice(0,t))try{let a=await Pe(e,i);r.push({runId:a.runId,status:a.status,environment:a.environment,startedAt:a.startedAt,finishedAt:a.finishedAt,totalTests:a.totalTests,passed:a.passed,failed:a.failed,skipped:a.skipped,duration:a.duration,suiteIds:a.suites.map(p=>p.suiteId)})}catch(a){Ce.warn({runId:i,err:a},"Failed to read run result \u2014 skipping")}return r}async function bt(e,t){let n=Te(j.default.join(e,$),t);if(!await O.default.pathExists(n))throw new g(`Run result not found for runId "${t}".`,n,"RESULT_NOT_FOUND");await O.default.remove(n),Ce.info({runId:t},"Run result deleted")}function St(e){return j.default.join(e,$,"screenshots")}function yt(e){return j.default.join(e,$,"videos")}function Et(e){return j.default.join(e,$,"traces")}var w=h(require("path")),L=h(require("fs-extra"));var d=require("zod"),jn=d.z.enum(["pending","accepted","rejected"]),Cn=d.z.enum(["retry","regenerate","multi-selector","visual","decompose","manual"]),pe=d.z.object({id:d.z.string(),runId:d.z.string(),suiteId:d.z.string(),caseId:d.z.string(),stepId:d.z.string(),stepInstruction:d.z.string(),failedCode:d.z.string(),healedCode:d.z.string(),error:d.z.string(),strategy:Cn,level:d.z.number().int().min(1).max(6),status:jn,pageUrl:d.z.string(),timestamp:d.z.string().datetime(),acceptedAt:d.z.string().datetime().optional(),rejectedAt:d.z.string().datetime().optional()}),Ne=d.z.object({runId:d.z.string(),generatedAt:d.z.string().datetime(),totalHeals:d.z.number().int(),accepted:d.z.number().int(),rejected:d.z.number().int(),pending:d.z.number().int(),events:d.z.array(pe)});var W=b("healing-store"),_=w.default.join("results","healing"),Tn="pending.json",ue="healing-report-";function At(e,t){return w.default.join(e,`${ue}${t}.json`)}function J(e){return w.default.join(e,Tn)}async function Rt(e,t){let n=Ne.safeParse(t);if(!n.success){let a=n.error.issues.map(p=>` \u2022 ${p.path.join(".")}: ${p.message}`).join(`
49
- `);throw new u(`Cannot write invalid healing report:
50
- ${a}`,"healingReport","INVALID_HEALING_REPORT")}let r=w.default.join(e,_),i=At(r,t.runId);await x(i,n.data),W.info({runId:t.runId,totalHeals:t.totalHeals},"Healing report saved")}async function It(e,t){let n=w.default.join(e,_),r=At(n,t);if(!await L.default.pathExists(r))throw new g(`Healing report not found for runId "${t}".`,r,"HEALING_REPORT_NOT_FOUND");let i=await E(r),a=Ne.safeParse(i);if(!a.success){let p=a.error.issues.map(y=>` \u2022 ${y.path.join(".")}: ${y.message}`).join(`
51
- `);throw new u(`Invalid healing report at "${r}":
52
- ${p}`,"healingReport","INVALID_HEALING_REPORT")}return a.data}async function V(e){let t=w.default.join(e,_),n=J(t);if(!await L.default.pathExists(n))return[];let r=await E(n),i=pe.array().safeParse(r);return i.success?i.data:(W.warn({path:n},"Pending healing file is malformed \u2014 resetting"),[])}var wt=50,vt=["pending","rejected","accepted"];function Pn(e){if(e.length<=wt)return e;let t=[...e].sort((i,a)=>{let p=vt.indexOf(i.status),y=vt.indexOf(a.status);return p!==y?p-y:i.timestamp<a.timestamp?-1:1}),n=e.length-wt,r=new Set(t.slice(0,n).map(i=>i.id));return W.info({excess:n,deleted:r.size},"Auto-pruning healing events to enforce cap"),e.filter(i=>!r.has(i.id))}async function jt(e,t){let n=pe.safeParse(t);if(!n.success)throw new u(`Invalid healing event: ${n.error.message}`,"healingEvent","INVALID_HEALING_EVENT");let r=w.default.join(e,_);await L.default.ensureDir(r);let i=await V(e);i.push(n.data),await x(J(r),Pn(i))}async function Ct(e,t){let n=await V(e),r=n.findIndex(a=>a.id===t);if(r===-1)throw new g(`Healing event "${t}" not found in pending list.`,t,"HEALING_EVENT_NOT_FOUND");n[r]={...n[r],status:"accepted",acceptedAt:new Date().toISOString()};let i=w.default.join(e,_);return await x(J(i),n),W.info({eventId:t},"Healing event accepted"),n[r]}async function Tt(e,t){let n=await V(e),r=n.findIndex(a=>a.id===t);if(r===-1)throw new g(`Healing event "${t}" not found in pending list.`,t,"HEALING_EVENT_NOT_FOUND");n[r]={...n[r],status:"rejected",rejectedAt:new Date().toISOString()};let i=w.default.join(e,_);return await x(J(i),n),W.info({eventId:t},"Healing event rejected"),n[r]}async function Pt(e,t=30){let n=await V(e),r=Date.now()-t*24*60*60*1e3,i=n.length,a=n.filter(p=>{if(p.status==="pending")return!0;let y=p.acceptedAt??p.rejectedAt;return y?new Date(y).getTime()>r:!0});if(a.length<i){let p=w.default.join(e,_);await x(J(p),a)}return i-a.length}async function _t(e){let t=await V(e),n=t.filter(a=>a.status==="pending").length,r=t.filter(a=>a.status==="accepted").length,i=t.filter(a=>a.status==="rejected").length;return{pending:n,accepted:r,rejected:i,total:t.length}}async function Nt(e){let t=w.default.join(e,_);if(!await L.default.pathExists(t))return[];let r=(await L.default.readdir(t,{withFileTypes:!0})).filter(a=>a.isFile()&&a.name.startsWith(ue)&&a.name.endsWith(".json")).map(a=>a.name.slice(ue.length,-5));return(await Promise.all(r.map(async a=>{let p=await L.default.stat(w.default.join(t,`${ue}${a}.json`));return{id:a,mtime:p.mtimeMs}}))).sort((a,p)=>p.mtime-a.mtime).map(a=>a.id)}var Ot=require("crypto");function Oe(e){return(0,Ot.createHash)("sha256").update(e,"utf8").digest("hex")}function $e(e){try{return new URL(e).pathname.split("/").map(r=>/^\d+$/.test(r)||/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i.test(r)||/^[a-z0-9-]{8,}$/i.test(r)&&/-/.test(r)?"*":r).join("/")}catch{return e}}function $t(e,t){let n=e.toLowerCase().replace(/\s+/g," ").trim(),r=$e(t);return Oe(`${n}|${r}`).slice(0,16)}var Vt=require("dotenv"),m=require("zod");(0,Vt.config)();var Lt=["anthropic","openai","google","azure-openai","bedrock","deepseek","groq","together","qwen","perplexity","ollama","custom"],_n=m.z.object({NODE_ENV:m.z.enum(["development","production","test"]).default("development"),LOG_LEVEL:m.z.enum(["trace","debug","info","warn","error","fatal"]).default("info"),AI_PROVIDER:m.z.enum(Lt),AI_TIERED_ENABLED:m.z.string().transform(e=>e==="true").default("false"),AI_TIERED_FAST_PROVIDER:m.z.enum(Lt).optional(),AI_TIERED_FAST_MODEL:m.z.string().optional(),AI_TIMEOUT:m.z.coerce.number().int().positive().default(30),AI_MAX_RETRIES:m.z.coerce.number().int().min(0).max(10).default(2)}),Nn=m.z.object({ANTHROPIC_API_KEY:m.z.string().min(1),ANTHROPIC_MODEL:m.z.string().default("claude-sonnet-4-20250514")}),On=m.z.object({OPENAI_API_KEY:m.z.string().min(1),OPENAI_MODEL:m.z.string().default("gpt-4o")}),$n=m.z.object({GOOGLE_API_KEY:m.z.string().min(1),GOOGLE_MODEL:m.z.string().default("gemini-2.5-pro")}),Ln=m.z.object({AZURE_OPENAI_API_KEY:m.z.string().min(1),AZURE_OPENAI_ENDPOINT:m.z.string().url(),AZURE_OPENAI_DEPLOYMENT:m.z.string().min(1),AZURE_OPENAI_API_VERSION:m.z.string().default("2024-10-21")}),Vn=m.z.object({AWS_ACCESS_KEY_ID:m.z.string().min(1),AWS_SECRET_ACCESS_KEY:m.z.string().min(1),AWS_SESSION_TOKEN:m.z.string().optional(),AWS_REGION:m.z.string().default("us-east-1"),BEDROCK_MODEL:m.z.string().default("anthropic.claude-sonnet-4-20250514-v1:0")}),Dn=m.z.object({DEEPSEEK_API_KEY:m.z.string().min(1),DEEPSEEK_MODEL:m.z.string().default("deepseek-chat")}),Hn=m.z.object({GROQ_API_KEY:m.z.string().min(1),GROQ_MODEL:m.z.string().default("llama-3.3-70b-versatile")}),Fn=m.z.object({TOGETHER_API_KEY:m.z.string().min(1),TOGETHER_MODEL:m.z.string().default("meta-llama/Llama-3.3-70B-Instruct-Turbo")}),zn=m.z.object({QWEN_API_KEY:m.z.string().min(1),QWEN_BASE_URL:m.z.string().url().default("https://dashscope-intl.aliyuncs.com/compatible-mode/v1"),QWEN_MODEL:m.z.string().default("qwen-max")}),Un=m.z.object({PERPLEXITY_API_KEY:m.z.string().min(1),PERPLEXITY_MODEL:m.z.string().default("sonar-pro")}),kn=m.z.object({OLLAMA_BASE_URL:m.z.string().url().default("http://localhost:11434"),OLLAMA_MODEL:m.z.string().default("llama3.3")}),Gn=m.z.object({CUSTOM_API_KEY:m.z.string().min(1),CUSTOM_BASE_URL:m.z.string().url(),CUSTOM_MODEL:m.z.string().min(1)}),Mn={anthropic:Nn,openai:On,google:$n,"azure-openai":Ln,bedrock:Vn,deepseek:Dn,groq:Hn,together:Fn,qwen:zn,perplexity:Un,ollama:kn,custom:Gn},K=null;function Le(){if(K!==null)return K;let e=_n.safeParse(process.env);if(!e.success){let a=e.error.issues.map(p=>` \u2022 ${p.path.join(".")}: ${p.message}`).join(`
53
- `);throw new C(`Missing or invalid environment variables:
44
+ `}var j=h(require("path")),N=h(require("fs-extra"));var s=require("zod"),me=s.z.enum(["pending","running","passed","failed","skipped"]),vn=s.z.object({method:s.z.string(),url:s.z.string(),headers:s.z.record(s.z.string()).optional(),body:s.z.string().optional()}).optional(),An=s.z.object({status:s.z.number(),statusText:s.z.string(),headers:s.z.record(s.z.string()).optional(),body:s.z.string().optional(),duration:s.z.number()}).optional(),A=s.z.number().nullish().transform(e=>e??void 0),ht=s.z.object({id:s.z.string(),title:s.z.string(),passed:s.z.boolean(),partial:s.z.boolean().optional(),na:s.z.boolean().optional()}),Rn=s.z.object({url:s.z.string(),stepIndex:s.z.number().int(),stepInstruction:s.z.string(),score:A,a11yScore:A,seoScore:A,fcp:A,lcp:A,cls:A,ttfb:A,tbt:A,si:A,tti:A,inp:A,a11yAudits:s.z.array(ht).optional(),seoAudits:s.z.array(ht).optional(),lighthouseError:s.z.string().optional()}),In=s.z.object({stepId:s.z.string(),instruction:s.z.string(),status:me,code:s.z.string(),error:s.z.string().optional(),duration:s.z.number(),screenshotPath:s.z.string().optional(),healed:s.z.boolean().optional(),healedCode:s.z.string().optional(),stepType:s.z.enum(["ui","api","mock"]).optional(),apiRequest:vn,apiResponse:An,navigatedToUrl:s.z.string().optional(),auditUrl:s.z.string().optional()}),jn=s.z.object({caseId:s.z.string(),caseName:s.z.string(),status:me,steps:s.z.array(In),duration:s.z.number(),browser:s.z.string(),device:s.z.string().optional(),startedAt:s.z.string().datetime(),finishedAt:s.z.string().datetime(),videoPath:s.z.string().optional(),tracePath:s.z.string().optional(),downloadPaths:s.z.array(s.z.string()).default([]),dataRowIndex:s.z.number().int().optional(),dataRow:s.z.record(s.z.string()).optional(),pageLoads:s.z.array(Rn).default([])}),Tn=s.z.object({suiteId:s.z.string(),suiteName:s.z.string(),suiteType:s.z.enum(["ui","api","audit","performance"]).optional(),status:me,cases:s.z.array(jn),duration:s.z.number(),browser:s.z.string(),startedAt:s.z.string().datetime(),finishedAt:s.z.string().datetime()}),Te=s.z.object({runId:s.z.string(),status:me,environment:s.z.string().optional(),suites:s.z.array(Tn),duration:s.z.number(),startedAt:s.z.string().datetime(),finishedAt:s.z.string().datetime(),totalTests:s.z.number().int(),passed:s.z.number().int(),failed:s.z.number().int(),skipped:s.z.number().int(),logFilePath:s.z.string().optional()});var Pe=b("result-store"),$="results",xt="runs";function Ce(e,t){return j.default.join(e,xt,`${t}.json`)}async function bt(e,t){let n=Te.safeParse(t);if(!n.success){let i=n.error.issues.map(a=>` \u2022 ${a.path.join(".")}: ${a.message}`).join(`
45
+ `);throw new p(`Cannot write invalid run result:
46
+ ${i}`,"result","INVALID_RESULT")}let r=Ce(j.default.join(e,$),t.runId);await x(r,n.data),Pe.info({runId:t.runId,status:t.status},"Run result saved")}async function _e(e,t){let n=Ce(j.default.join(e,$),t);if(!await N.default.pathExists(n))throw new g(`Run result not found for runId "${t}".`,n,"RESULT_NOT_FOUND");let r=await E(n),i=Te.safeParse(r);if(!i.success){let a=i.error.issues.map(m=>` \u2022 ${m.path.join(".")}: ${m.message}`).join(`
47
+ `);throw new p(`Invalid run result at "${n}":
48
+ ${a}`,"result","INVALID_RESULT")}return i.data}async function Oe(e){let t=j.default.join(e,$,xt);if(!await N.default.pathExists(t))return[];let r=(await N.default.readdir(t,{withFileTypes:!0})).filter(a=>a.isFile()&&a.name.endsWith(".json")).map(a=>a.name.replace(".json",""));return(await Promise.all(r.map(async a=>{let m=await N.default.stat(j.default.join(t,`${a}.json`));return{id:a,mtime:m.mtimeMs}}))).sort((a,m)=>m.mtime-a.mtime).map(a=>a.id)}async function St(e,t=20){let n=await Oe(e),r=[];for(let i of n.slice(0,t))try{let a=await _e(e,i);r.push({runId:a.runId,status:a.status,environment:a.environment,startedAt:a.startedAt,finishedAt:a.finishedAt,totalTests:a.totalTests,passed:a.passed,failed:a.failed,skipped:a.skipped,duration:a.duration,suiteIds:a.suites.map(m=>m.suiteId)})}catch(a){Pe.warn({runId:i,err:a},"Failed to read run result \u2014 skipping")}return r}async function yt(e,t){let n=Ce(j.default.join(e,$),t);if(!await N.default.pathExists(n))throw new g(`Run result not found for runId "${t}".`,n,"RESULT_NOT_FOUND");await N.default.remove(n),Pe.info({runId:t},"Run result deleted")}function Et(e){return j.default.join(e,$,"screenshots")}function wt(e){return j.default.join(e,$,"videos")}function vt(e){return j.default.join(e,$,"traces")}var w=h(require("path")),V=h(require("fs-extra"));var d=require("zod"),Pn=d.z.enum(["pending","accepted","rejected"]),Cn=d.z.enum(["retry","regenerate","multi-selector","visual","decompose","manual"]),ue=d.z.object({id:d.z.string(),runId:d.z.string(),suiteId:d.z.string(),caseId:d.z.string(),stepId:d.z.string(),stepInstruction:d.z.string(),failedCode:d.z.string(),healedCode:d.z.string(),error:d.z.string(),strategy:Cn,level:d.z.number().int().min(1).max(6),status:Pn,pageUrl:d.z.string(),timestamp:d.z.string().datetime(),acceptedAt:d.z.string().datetime().optional(),rejectedAt:d.z.string().datetime().optional()}),Ne=d.z.object({runId:d.z.string(),generatedAt:d.z.string().datetime(),totalHeals:d.z.number().int(),accepted:d.z.number().int(),rejected:d.z.number().int(),pending:d.z.number().int(),events:d.z.array(ue)});var W=b("healing-store"),_=w.default.join("results","healing"),_n="pending.json",pe="healing-report-";function It(e,t){return w.default.join(e,`${pe}${t}.json`)}function J(e){return w.default.join(e,_n)}async function jt(e,t){let n=Ne.safeParse(t);if(!n.success){let a=n.error.issues.map(m=>` \u2022 ${m.path.join(".")}: ${m.message}`).join(`
49
+ `);throw new p(`Cannot write invalid healing report:
50
+ ${a}`,"healingReport","INVALID_HEALING_REPORT")}let r=w.default.join(e,_),i=It(r,t.runId);await x(i,n.data),W.info({runId:t.runId,totalHeals:t.totalHeals},"Healing report saved")}async function Tt(e,t){let n=w.default.join(e,_),r=It(n,t);if(!await V.default.pathExists(r))throw new g(`Healing report not found for runId "${t}".`,r,"HEALING_REPORT_NOT_FOUND");let i=await E(r),a=Ne.safeParse(i);if(!a.success){let m=a.error.issues.map(y=>` \u2022 ${y.path.join(".")}: ${y.message}`).join(`
51
+ `);throw new p(`Invalid healing report at "${r}":
52
+ ${m}`,"healingReport","INVALID_HEALING_REPORT")}return a.data}async function L(e){let t=w.default.join(e,_),n=J(t);if(!await V.default.pathExists(n))return[];let r=await E(n),i=ue.array().safeParse(r);return i.success?i.data:(W.warn({path:n},"Pending healing file is malformed \u2014 resetting"),[])}var At=50,Rt=["pending","rejected","accepted"];function On(e){if(e.length<=At)return e;let t=[...e].sort((i,a)=>{let m=Rt.indexOf(i.status),y=Rt.indexOf(a.status);return m!==y?m-y:i.timestamp<a.timestamp?-1:1}),n=e.length-At,r=new Set(t.slice(0,n).map(i=>i.id));return W.info({excess:n,deleted:r.size},"Auto-pruning healing events to enforce cap"),e.filter(i=>!r.has(i.id))}async function Pt(e,t){let n=ue.safeParse(t);if(!n.success)throw new p(`Invalid healing event: ${n.error.message}`,"healingEvent","INVALID_HEALING_EVENT");let r=w.default.join(e,_);await V.default.ensureDir(r);let i=await L(e);i.push(n.data),await x(J(r),On(i))}async function Ct(e,t){let n=await L(e),r=n.findIndex(a=>a.id===t);if(r===-1)throw new g(`Healing event "${t}" not found in pending list.`,t,"HEALING_EVENT_NOT_FOUND");n[r]={...n[r],status:"accepted",acceptedAt:new Date().toISOString()};let i=w.default.join(e,_);return await x(J(i),n),W.info({eventId:t},"Healing event accepted"),n[r]}async function _t(e,t){let n=await L(e),r=n.findIndex(a=>a.id===t);if(r===-1)throw new g(`Healing event "${t}" not found in pending list.`,t,"HEALING_EVENT_NOT_FOUND");n[r]={...n[r],status:"rejected",rejectedAt:new Date().toISOString()};let i=w.default.join(e,_);return await x(J(i),n),W.info({eventId:t},"Healing event rejected"),n[r]}async function Ot(e,t=30){let n=await L(e),r=Date.now()-t*24*60*60*1e3,i=n.length,a=n.filter(m=>{if(m.status==="pending")return!0;let y=m.acceptedAt??m.rejectedAt;return y?new Date(y).getTime()>r:!0});if(a.length<i){let m=w.default.join(e,_);await x(J(m),a)}return i-a.length}async function Nt(e){let t=await L(e),n=t.filter(a=>a.status==="pending").length,r=t.filter(a=>a.status==="accepted").length,i=t.filter(a=>a.status==="rejected").length;return{pending:n,accepted:r,rejected:i,total:t.length}}async function $t(e){let t=w.default.join(e,_);if(!await V.default.pathExists(t))return[];let r=(await V.default.readdir(t,{withFileTypes:!0})).filter(a=>a.isFile()&&a.name.startsWith(pe)&&a.name.endsWith(".json")).map(a=>a.name.slice(pe.length,-5));return(await Promise.all(r.map(async a=>{let m=await V.default.stat(w.default.join(t,`${pe}${a}.json`));return{id:a,mtime:m.mtimeMs}}))).sort((a,m)=>m.mtime-a.mtime).map(a=>a.id)}var Vt=require("crypto");function $e(e){return(0,Vt.createHash)("sha256").update(e,"utf8").digest("hex")}function Ve(e){try{return new URL(e).pathname.split("/").map(r=>/^\d+$/.test(r)||/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i.test(r)||/^[a-z0-9-]{8,}$/i.test(r)&&/-/.test(r)?"*":r).join("/")}catch{return e}}function Lt(e,t){let n=e.toLowerCase().replace(/\s+/g," ").trim(),r=Ve(t);return $e(`${n}|${r}`).slice(0,16)}var Ht=require("dotenv"),u=require("zod");(0,Ht.config)();var Dt=["anthropic","openai","google","azure-openai","bedrock","deepseek","groq","together","qwen","perplexity","ollama","custom"],Nn=u.z.object({NODE_ENV:u.z.enum(["development","production","test"]).default("development"),LOG_LEVEL:u.z.enum(["trace","debug","info","warn","error","fatal"]).default("info"),AI_PROVIDER:u.z.enum(Dt),AI_TIERED_ENABLED:u.z.string().transform(e=>e==="true").default("false"),AI_TIERED_FAST_PROVIDER:u.z.enum(Dt).optional(),AI_TIERED_FAST_MODEL:u.z.string().optional(),AI_TIMEOUT:u.z.coerce.number().int().positive().default(30),AI_MAX_RETRIES:u.z.coerce.number().int().min(0).max(10).default(2)}),$n=u.z.object({ANTHROPIC_API_KEY:u.z.string().min(1),ANTHROPIC_MODEL:u.z.string().default("claude-sonnet-4-20250514")}),Vn=u.z.object({OPENAI_API_KEY:u.z.string().min(1),OPENAI_MODEL:u.z.string().default("gpt-4o")}),Ln=u.z.object({GOOGLE_API_KEY:u.z.string().min(1),GOOGLE_MODEL:u.z.string().default("gemini-2.5-pro")}),Dn=u.z.object({AZURE_OPENAI_API_KEY:u.z.string().min(1),AZURE_OPENAI_ENDPOINT:u.z.string().url(),AZURE_OPENAI_DEPLOYMENT:u.z.string().min(1),AZURE_OPENAI_API_VERSION:u.z.string().default("2024-10-21")}),Hn=u.z.object({AWS_ACCESS_KEY_ID:u.z.string().min(1),AWS_SECRET_ACCESS_KEY:u.z.string().min(1),AWS_SESSION_TOKEN:u.z.string().optional(),AWS_REGION:u.z.string().default("us-east-1"),BEDROCK_MODEL:u.z.string().default("anthropic.claude-sonnet-4-20250514-v1:0")}),Fn=u.z.object({DEEPSEEK_API_KEY:u.z.string().min(1),DEEPSEEK_MODEL:u.z.string().default("deepseek-chat")}),zn=u.z.object({GROQ_API_KEY:u.z.string().min(1),GROQ_MODEL:u.z.string().default("llama-3.3-70b-versatile")}),Un=u.z.object({TOGETHER_API_KEY:u.z.string().min(1),TOGETHER_MODEL:u.z.string().default("meta-llama/Llama-3.3-70B-Instruct-Turbo")}),kn=u.z.object({QWEN_API_KEY:u.z.string().min(1),QWEN_BASE_URL:u.z.string().url().default("https://dashscope-intl.aliyuncs.com/compatible-mode/v1"),QWEN_MODEL:u.z.string().default("qwen-max")}),Gn=u.z.object({PERPLEXITY_API_KEY:u.z.string().min(1),PERPLEXITY_MODEL:u.z.string().default("sonar-pro")}),Mn=u.z.object({OLLAMA_BASE_URL:u.z.string().url().default("http://localhost:11434"),OLLAMA_MODEL:u.z.string().default("llama3.3")}),Bn=u.z.object({CUSTOM_API_KEY:u.z.string().min(1),CUSTOM_BASE_URL:u.z.string().url(),CUSTOM_MODEL:u.z.string().min(1)}),Wn={anthropic:$n,openai:Vn,google:Ln,"azure-openai":Dn,bedrock:Hn,deepseek:Fn,groq:zn,together:Un,qwen:kn,perplexity:Gn,ollama:Mn,custom:Bn},K=null;function Le(){if(K!==null)return K;let e=Nn.safeParse(process.env);if(!e.success){let a=e.error.issues.map(m=>` \u2022 ${m.path.join(".")}: ${m.message}`).join(`
53
+ `);throw new T(`Missing or invalid environment variables:
54
54
  ${a}
55
55
 
56
- How to fix: Copy .env.example to .env and fill in your AI provider credentials.`,"ENV_VALIDATION_FAILED")}let t=e.data.AI_PROVIDER,r=Mn[t].safeParse(process.env);if(!r.success){let a=r.error.issues.map(p=>` \u2022 ${p.path.join(".")}: ${p.message}`).join(`
57
- `);throw new C(`Provider "${t}" is missing required environment variables:
56
+ How to fix: Copy .env.example to .env and fill in your AI provider credentials.`,"ENV_VALIDATION_FAILED")}let t=e.data.AI_PROVIDER,r=Wn[t].safeParse(process.env);if(!r.success){let a=r.error.issues.map(m=>` \u2022 ${m.path.join(".")}: ${m.message}`).join(`
57
+ `);throw new T(`Provider "${t}" is missing required environment variables:
58
58
  ${a}
59
59
 
60
- How to fix: Check .env.example for the ${t} section and add the required keys to .env.`,"PROVIDER_ENV_MISSING")}return K={...e.data,...r.data},K}function Dt(){K=null}function Ht(){try{return Le()}catch{return null}}var o=require("@faker-js/faker");function Ft(){return[{category:"person",methods:[{name:"fullName",example:o.faker.person.fullName()},{name:"firstName",example:o.faker.person.firstName()},{name:"lastName",example:o.faker.person.lastName()},{name:"middleName",example:o.faker.person.middleName()},{name:"sex",example:o.faker.person.sex()},{name:"prefix",example:o.faker.person.prefix()},{name:"suffix",example:o.faker.person.suffix()},{name:"jobTitle",example:o.faker.person.jobTitle()},{name:"jobArea",example:o.faker.person.jobArea()},{name:"jobType",example:o.faker.person.jobType()},{name:"bio",example:o.faker.person.bio()}]},{category:"internet",methods:[{name:"email",example:o.faker.internet.email()},{name:"userName",example:o.faker.internet.username()},{name:"password",example:o.faker.internet.password()},{name:"url",example:o.faker.internet.url()},{name:"domainName",example:o.faker.internet.domainName()},{name:"domainWord",example:o.faker.internet.domainWord()},{name:"ip",example:o.faker.internet.ip()},{name:"ipv6",example:o.faker.internet.ipv6()},{name:"mac",example:o.faker.internet.mac()},{name:"userAgent",example:o.faker.internet.userAgent()},{name:"emoji",example:o.faker.internet.emoji()}]},{category:"phone",methods:[{name:"number",example:o.faker.phone.number()},{name:"imei",example:o.faker.phone.imei()}]},{category:"location",methods:[{name:"streetAddress",example:o.faker.location.streetAddress()},{name:"street",example:o.faker.location.street()},{name:"city",example:o.faker.location.city()},{name:"state",example:o.faker.location.state()},{name:"zipCode",example:o.faker.location.zipCode()},{name:"country",example:o.faker.location.country()},{name:"countryCode",example:o.faker.location.countryCode()},{name:"county",example:o.faker.location.county()},{name:"latitude",example:String(o.faker.location.latitude())},{name:"longitude",example:String(o.faker.location.longitude())},{name:"timeZone",example:o.faker.location.timeZone()},{name:"buildingNumber",example:o.faker.location.buildingNumber()}]},{category:"company",methods:[{name:"name",example:o.faker.company.name()},{name:"catchPhrase",example:o.faker.company.catchPhrase()},{name:"buzzPhrase",example:o.faker.company.buzzPhrase()},{name:"buzzNoun",example:o.faker.company.buzzNoun()},{name:"buzzVerb",example:o.faker.company.buzzVerb()},{name:"buzzAdjective",example:o.faker.company.buzzAdjective()}]},{category:"finance",methods:[{name:"accountNumber",example:o.faker.finance.accountNumber()},{name:"accountName",example:o.faker.finance.accountName()},{name:"creditCardNumber",example:o.faker.finance.creditCardNumber()},{name:"creditCardCVV",example:o.faker.finance.creditCardCVV()},{name:"currencyCode",example:o.faker.finance.currencyCode()},{name:"currencyName",example:o.faker.finance.currencyName()},{name:"amount",example:o.faker.finance.amount()},{name:"iban",example:o.faker.finance.iban()},{name:"bic",example:o.faker.finance.bic()},{name:"bitcoinAddress",example:o.faker.finance.bitcoinAddress()},{name:"transactionType",example:o.faker.finance.transactionType()}]},{category:"date",methods:[{name:"past",example:o.faker.date.past().toISOString()},{name:"future",example:o.faker.date.future().toISOString()},{name:"recent",example:o.faker.date.recent().toISOString()},{name:"soon",example:o.faker.date.soon().toISOString()},{name:"birthdate",example:o.faker.date.birthdate().toISOString()},{name:"month",example:o.faker.date.month()},{name:"weekday",example:o.faker.date.weekday()}]},{category:"lorem",methods:[{name:"word",example:o.faker.lorem.word()},{name:"words",example:o.faker.lorem.words()},{name:"sentence",example:o.faker.lorem.sentence()},{name:"sentences",example:o.faker.lorem.sentences()},{name:"paragraph",example:o.faker.lorem.paragraph()},{name:"slug",example:o.faker.lorem.slug()},{name:"lines",example:o.faker.lorem.lines(1)}]},{category:"string",methods:[{name:"uuid",example:o.faker.string.uuid()},{name:"alphanumeric",example:o.faker.string.alphanumeric(10)},{name:"numeric",example:o.faker.string.numeric(6)},{name:"alpha",example:o.faker.string.alpha(8)},{name:"nanoid",example:o.faker.string.nanoid()},{name:"hexadecimal",example:o.faker.string.hexadecimal({length:8})},{name:"sample",example:o.faker.string.sample(12)}]},{category:"number",methods:[{name:"int",example:String(o.faker.number.int({max:9999}))},{name:"float",example:String(o.faker.number.float({max:100,fractionDigits:2}))}]},{category:"datatype",methods:[{name:"boolean",example:String(o.faker.datatype.boolean())}]},{category:"image",methods:[{name:"avatar",example:o.faker.image.avatar()},{name:"url",example:o.faker.image.url()}]},{category:"color",methods:[{name:"human",example:o.faker.color.human()},{name:"rgb",example:o.faker.color.rgb()},{name:"hex",example:o.faker.color.rgb({format:"hex"})}]},{category:"commerce",methods:[{name:"productName",example:o.faker.commerce.productName()},{name:"price",example:o.faker.commerce.price()},{name:"department",example:o.faker.commerce.department()},{name:"productDescription",example:o.faker.commerce.productDescription().slice(0,60)+"..."},{name:"isbn",example:o.faker.commerce.isbn()}]},{category:"vehicle",methods:[{name:"vehicle",example:o.faker.vehicle.vehicle()},{name:"manufacturer",example:o.faker.vehicle.manufacturer()},{name:"model",example:o.faker.vehicle.model()},{name:"vin",example:o.faker.vehicle.vin()},{name:"vrm",example:o.faker.vehicle.vrm()}]},{category:"system",methods:[{name:"fileName",example:o.faker.system.fileName()},{name:"mimeType",example:o.faker.system.mimeType()},{name:"fileExt",example:o.faker.system.fileExt()},{name:"filePath",example:o.faker.system.filePath()},{name:"semver",example:o.faker.system.semver()}]}]}var Bn={"internet.userName":"username"};function zt(e,t){let n=o.faker[e],r=Bn[`${e}.${t}`]??t;if(!n||typeof n[r]!="function")return`[unknown: ${e}.${t}]`;let i=n[r]();return i instanceof Date?i.toISOString():String(i)}function Wn(e){let t={...q,...e},n=z.safeParse(t);if(!n.success){let r=n.error.issues.map(i=>` \u2022 ${i.path.join(".")}: ${i.message}`).join(`
60
+ How to fix: Check .env.example for the ${t} section and add the required keys to .env.`,"PROVIDER_ENV_MISSING")}return K={...e.data,...r.data},K}function Ft(){K=null}function zt(){try{return Le()}catch{return null}}var o=require("@faker-js/faker");function Ut(){return[{category:"person",methods:[{name:"fullName",example:o.faker.person.fullName()},{name:"firstName",example:o.faker.person.firstName()},{name:"lastName",example:o.faker.person.lastName()},{name:"middleName",example:o.faker.person.middleName()},{name:"sex",example:o.faker.person.sex()},{name:"prefix",example:o.faker.person.prefix()},{name:"suffix",example:o.faker.person.suffix()},{name:"jobTitle",example:o.faker.person.jobTitle()},{name:"jobArea",example:o.faker.person.jobArea()},{name:"jobType",example:o.faker.person.jobType()},{name:"bio",example:o.faker.person.bio()}]},{category:"internet",methods:[{name:"email",example:o.faker.internet.email()},{name:"userName",example:o.faker.internet.username()},{name:"password",example:o.faker.internet.password()},{name:"url",example:o.faker.internet.url()},{name:"domainName",example:o.faker.internet.domainName()},{name:"domainWord",example:o.faker.internet.domainWord()},{name:"ip",example:o.faker.internet.ip()},{name:"ipv6",example:o.faker.internet.ipv6()},{name:"mac",example:o.faker.internet.mac()},{name:"userAgent",example:o.faker.internet.userAgent()},{name:"emoji",example:o.faker.internet.emoji()}]},{category:"phone",methods:[{name:"number",example:o.faker.phone.number()},{name:"imei",example:o.faker.phone.imei()}]},{category:"location",methods:[{name:"streetAddress",example:o.faker.location.streetAddress()},{name:"street",example:o.faker.location.street()},{name:"city",example:o.faker.location.city()},{name:"state",example:o.faker.location.state()},{name:"zipCode",example:o.faker.location.zipCode()},{name:"country",example:o.faker.location.country()},{name:"countryCode",example:o.faker.location.countryCode()},{name:"county",example:o.faker.location.county()},{name:"latitude",example:String(o.faker.location.latitude())},{name:"longitude",example:String(o.faker.location.longitude())},{name:"timeZone",example:o.faker.location.timeZone()},{name:"buildingNumber",example:o.faker.location.buildingNumber()}]},{category:"company",methods:[{name:"name",example:o.faker.company.name()},{name:"catchPhrase",example:o.faker.company.catchPhrase()},{name:"buzzPhrase",example:o.faker.company.buzzPhrase()},{name:"buzzNoun",example:o.faker.company.buzzNoun()},{name:"buzzVerb",example:o.faker.company.buzzVerb()},{name:"buzzAdjective",example:o.faker.company.buzzAdjective()}]},{category:"finance",methods:[{name:"accountNumber",example:o.faker.finance.accountNumber()},{name:"accountName",example:o.faker.finance.accountName()},{name:"creditCardNumber",example:o.faker.finance.creditCardNumber()},{name:"creditCardCVV",example:o.faker.finance.creditCardCVV()},{name:"currencyCode",example:o.faker.finance.currencyCode()},{name:"currencyName",example:o.faker.finance.currencyName()},{name:"amount",example:o.faker.finance.amount()},{name:"iban",example:o.faker.finance.iban()},{name:"bic",example:o.faker.finance.bic()},{name:"bitcoinAddress",example:o.faker.finance.bitcoinAddress()},{name:"transactionType",example:o.faker.finance.transactionType()}]},{category:"date",methods:[{name:"past",example:o.faker.date.past().toISOString()},{name:"future",example:o.faker.date.future().toISOString()},{name:"recent",example:o.faker.date.recent().toISOString()},{name:"soon",example:o.faker.date.soon().toISOString()},{name:"birthdate",example:o.faker.date.birthdate().toISOString()},{name:"month",example:o.faker.date.month()},{name:"weekday",example:o.faker.date.weekday()}]},{category:"lorem",methods:[{name:"word",example:o.faker.lorem.word()},{name:"words",example:o.faker.lorem.words()},{name:"sentence",example:o.faker.lorem.sentence()},{name:"sentences",example:o.faker.lorem.sentences()},{name:"paragraph",example:o.faker.lorem.paragraph()},{name:"slug",example:o.faker.lorem.slug()},{name:"lines",example:o.faker.lorem.lines(1)}]},{category:"string",methods:[{name:"uuid",example:o.faker.string.uuid()},{name:"alphanumeric",example:o.faker.string.alphanumeric(10)},{name:"numeric",example:o.faker.string.numeric(6)},{name:"alpha",example:o.faker.string.alpha(8)},{name:"nanoid",example:o.faker.string.nanoid()},{name:"hexadecimal",example:o.faker.string.hexadecimal({length:8})},{name:"sample",example:o.faker.string.sample(12)}]},{category:"number",methods:[{name:"int",example:String(o.faker.number.int({max:9999}))},{name:"float",example:String(o.faker.number.float({max:100,fractionDigits:2}))}]},{category:"datatype",methods:[{name:"boolean",example:String(o.faker.datatype.boolean())}]},{category:"image",methods:[{name:"avatar",example:o.faker.image.avatar()},{name:"url",example:o.faker.image.url()}]},{category:"color",methods:[{name:"human",example:o.faker.color.human()},{name:"rgb",example:o.faker.color.rgb()},{name:"hex",example:o.faker.color.rgb({format:"hex"})}]},{category:"commerce",methods:[{name:"productName",example:o.faker.commerce.productName()},{name:"price",example:o.faker.commerce.price()},{name:"department",example:o.faker.commerce.department()},{name:"productDescription",example:o.faker.commerce.productDescription().slice(0,60)+"..."},{name:"isbn",example:o.faker.commerce.isbn()}]},{category:"vehicle",methods:[{name:"vehicle",example:o.faker.vehicle.vehicle()},{name:"manufacturer",example:o.faker.vehicle.manufacturer()},{name:"model",example:o.faker.vehicle.model()},{name:"vin",example:o.faker.vehicle.vin()},{name:"vrm",example:o.faker.vehicle.vrm()}]},{category:"system",methods:[{name:"fileName",example:o.faker.system.fileName()},{name:"mimeType",example:o.faker.system.mimeType()},{name:"fileExt",example:o.faker.system.fileExt()},{name:"filePath",example:o.faker.system.filePath()},{name:"semver",example:o.faker.system.semver()}]}]}var Jn={"internet.userName":"username"};function kt(e,t){let n=o.faker[e],r=Jn[`${e}.${t}`]??t;if(!n||typeof n[r]!="function")return`[unknown: ${e}.${t}]`;let i=n[r]();return i instanceof Date?i.toISOString():String(i)}function Kn(e){let t={...q,...e},n=z.safeParse(t);if(!n.success){let r=n.error.issues.map(i=>` \u2022 ${i.path.join(".")}: ${i.message}`).join(`
61
61
  `);throw new Error(`Invalid assuremind config:
62
62
  ${r}`)}return n.data}0&&(module.exports={AssuremindError,ConfigError,ExecutionError,HealingError,ProviderError,StorageError,ValidationError,acceptHealingEvent,appendPendingEvent,callFaker,clearEnvCache,configExists,createCase,createChildLogger,createSuite,defineConfig,deleteCase,deleteGlobalVariable,deleteResult,deleteSuite,formatError,generateCacheKey,getAvailableGenerators,getCasePath,getHealingStats,isAssuremindError,listCasePaths,listCases,listHealingReportIds,listResultIds,listResults,listSuiteDirs,listSuites,listSuitesWithCounts,listVariableFiles,logger,normalizeUrl,pruneResolvedEvents,readCase,readConfig,readEnvVariables,readGlobalVariables,readHealingReport,readPendingEvents,readResult,readSuite,readVariables,redactSecrets,rejectHealingEvent,resolveVariables,sanitizeGeneratedCode,screenshotsDir,setGlobalVariable,sha256,toSlug,tracesDir,tryGetEnv,updateCase,updateConfig,updateSuite,validateConfig,validateEnv,videosDir,writeCase,writeConfig,writeHealingReport,writeResult,writeSuite,writeVariables});
package/dist/index.mjs CHANGED
@@ -1,22 +1,22 @@
1
- import{z as c}from"zod";var Ye=c.enum(["off","on","only-on-failure"]),qe=c.enum(["off","on","on-first-retry","retain-on-failure"]),Xe=c.enum(["off","on","on-first-retry","retain-on-failure"]),ve=c.enum(["chromium","firefox","webkit"]),Ze=c.enum(["commit","domcontentloaded","load","networkidle"]),Ae=c.enum(["dev","stage","test","prod"]),Qe=c.object({dev:c.string().url().or(c.literal("")).default(""),stage:c.string().url().or(c.literal("")).default(""),test:c.string().url().or(c.literal("")).default(""),prod:c.string().url().or(c.literal("")).default("")}),et=c.object({enabled:c.boolean(),maxLevel:c.number().int().min(1).max(5),dailyBudget:c.number().positive(),autoPR:c.boolean(),healAssertionLocators:c.boolean().default(!1)}),tt=c.object({allure:c.boolean(),html:c.boolean(),json:c.boolean()}),nt=c.object({width:c.number().int().positive(),height:c.number().int().positive()}),rt=c.object({name:c.string().min(1),environment:Ae,baseUrl:c.string().url(),browsers:c.array(ve).min(1),headless:c.boolean().optional()}),D=c.object({baseUrl:c.string().url(),environment:Ae.default("stage"),environmentUrls:Qe.default({dev:"",stage:"",test:"",prod:""}),browsers:c.array(ve).min(1),headless:c.boolean(),viewport:nt.default({width:1280,height:720}),timeout:c.number().int().positive(),retries:c.number().int().min(0),parallel:c.number().int().positive(),pageLoad:Ze.default("domcontentloaded"),screenshot:Ye,video:qe,trace:Xe,healing:et,reporting:tt,studioPort:c.number().int().min(1024).max(65535),profiles:c.array(rt).default([]),activeProfile:c.string().optional(),device:c.string().optional(),rag:c.object({enabled:c.boolean(),codeCorpus:c.object({enabled:c.boolean(),maxEntries:c.number().int().positive(),similarityThreshold:c.number().min(0).max(1),directUseThreshold:c.number().min(0).max(1)}),healingCorpus:c.object({enabled:c.boolean(),maxEntries:c.number().int().positive(),similarityThreshold:c.number().min(0).max(1)}),errorCatalog:c.object({enabled:c.boolean(),maxEntries:c.number().int().positive()}),embedder:c.literal("tfidf")}).default({enabled:!0,codeCorpus:{enabled:!0,maxEntries:500,similarityThreshold:.65,directUseThreshold:.9},healingCorpus:{enabled:!0,maxEntries:300,similarityThreshold:.6},errorCatalog:{enabled:!0,maxEntries:200},embedder:"tfidf"}),mcp:c.object({enabled:c.boolean(),headless:c.boolean(),actThenScript:c.boolean(),proactiveHealing:c.boolean(),actionTimeout:c.number().int().positive(),idleTimeout:c.number().int().positive()}).default({enabled:!0,headless:!0,actThenScript:!1,proactiveHealing:!1,actionTimeout:15e3,idleTimeout:3e4}),ci:c.object({writeToRepo:c.boolean()}).default({writeToRepo:!1})}),J={baseUrl:"http://localhost:3000",environment:"stage",environmentUrls:{dev:"",stage:"http://localhost:3000",test:"",prod:""},browsers:["chromium"],headless:!0,viewport:{width:1280,height:720},timeout:3e4,retries:1,parallel:1,pageLoad:"domcontentloaded",screenshot:"only-on-failure",video:"off",trace:"on-first-retry",healing:{enabled:!0,maxLevel:5,dailyBudget:5,autoPR:!1,healAssertionLocators:!1},reporting:{allure:!0,html:!0,json:!0},studioPort:4400,profiles:[],rag:{enabled:!0,codeCorpus:{enabled:!0,maxEntries:500,similarityThreshold:.65,directUseThreshold:.9},healingCorpus:{enabled:!0,maxEntries:300,similarityThreshold:.6},errorCatalog:{enabled:!0,maxEntries:200},embedder:"tfidf"},mcp:{enabled:!0,headless:!0,actThenScript:!1,proactiveHealing:!1,actionTimeout:15e3,idleTimeout:3e4},ci:{writeToRepo:!1}};import E from"path";import I from"fs-extra";import{v4 as bt}from"uuid";import{z as l}from"zod";var H=l.object({id:l.string().min(1),order:l.number().int().positive(),instruction:l.string().min(1),generatedCode:l.string(),strategy:l.enum(["template","cache","rag","batch","fast","primary","recorder"]),stepType:l.enum(["ui","api","mock"]).default("ui"),lastHealed:l.string().nullable(),timeout:l.number().int().positive().optional(),retries:l.number().int().min(0).optional(),mockUrl:l.string().optional(),mockResponse:l.string().optional(),mockStatus:l.number().int().optional(),runAudit:l.boolean().optional(),soft:l.boolean().optional(),visualCheck:l.boolean().optional()}),it=l.object({type:l.enum(["inline","json-file","csv-file"]),path:l.string().optional(),data:l.array(l.record(l.string())).optional()}).optional(),Re=l.object({id:l.string(),instruction:l.string(),generatedCode:l.string().default(""),order:l.number().int().default(0)}),at=l.object({before:l.array(Re).default([]),after:l.array(Re).default([])}).default({before:[],after:[]}),te=l.object({id:l.string().min(1),name:l.string().min(1),description:l.string(),tags:l.array(l.string()),priority:l.enum(["critical","high","medium","low"]),timeout:l.number().int().positive().optional(),dataSource:it,steps:l.array(H),caseHooks:at,lighthouseCategories:l.array(l.enum(["performance","accessibility","seo"])).default(["performance","accessibility","seo"]),createdAt:l.string().datetime(),updatedAt:l.string().datetime()}),ne=l.object({id:l.string().min(1),name:l.string().min(1),description:l.string(),tags:l.array(l.string()),type:l.enum(["ui","api","audit","performance"]).default("ui"),timeout:l.number().int().positive().optional(),createdAt:l.string().datetime(),updatedAt:l.string().datetime()}),zn=l.enum(["before_all","before_each","after_each","after_all"]),Un=l.object({before_all:l.array(H).default([]),before_each:l.array(H).default([]),after_each:l.array(H).default([]),after_all:l.array(H).default([])});var v=class extends Error{code;constructor(t,n){super(t),this.name="AssuremindError",this.code=n,Object.setPrototypeOf(this,new.target.prototype)}},re=class extends v{provider;constructor(t,n,r="PROVIDER_ERROR"){super(t,r),this.name="ProviderError",this.provider=n}},ie=class extends v{stepId;constructor(t,n,r="EXECUTION_ERROR"){super(t,r),this.name="ExecutionError",this.stepId=n}},C=class extends v{constructor(t,n="CONFIG_ERROR"){super(t,n),this.name="ConfigError"}},u=class extends v{field;constructor(t,n,r="VALIDATION_ERROR"){super(t,r),this.name="ValidationError",this.field=n}},ae=class extends v{level;constructor(t,n,r="HEALING_ERROR"){super(t,r),this.name="HealingError",this.level=n}},g=class extends v{path;constructor(t,n,r="STORAGE_ERROR"){super(t,r),this.name="StorageError",this.path=n}};function ot(e){return e instanceof v}function st(e){return e instanceof v?`[${e.code}] ${e.message}`:e instanceof Error?e.message:String(e)}import Ie from"pino";import Kn from"fs-extra";var ct=process.env.NODE_ENV!=="production",je=ct?{target:"pino-pretty",options:{colorize:!0,translateTime:"HH:MM:ss",ignore:"pid,hostname",messageFormat:"[assuremind] {msg}"}}:void 0,Ce=Ie({level:process.env.LOG_LEVEL??"info",base:{name:"assuremind"}},je?Ie.transport(je):void 0);function S(e){return Ce.child({component:e})}function lt(e){let t=/^```(?:typescript|javascript|ts|js)?\n?([\s\S]*?)```\s*$/m,n=e.match(t);return n?.[1]!==void 0?n[1].trim():e.trim()}var mt=[/\brequire\s*\(/,/\bimport\s*\(/,/\bprocess\b/,/\bchild_process\b/,/\bexec\s*\(/,/\bspawn\s*\(/,/\beval\s*\(/,/\bFunction\s*\(/,/\b__dirname\b/,/\b__filename\b/,/\bglobal\b/,/\bwindow\.location\.href\s*=/,/\bdocument\.cookie\b/,/\blocalStorage\b/,/\bsessionStorage\b/,/\bIndexedDB\b/,/\bXMLHttpRequest\b/,/\bfetch\s*\(/,/\bWebSocket\s*\(/];function pt(e){for(let t of mt)if(t.test(e))throw new u(`Generated code contains forbidden pattern: ${t.source}. This may be a prompt injection attempt. Please regenerate the step.`,"generatedCode","UNSAFE_CODE")}var ut=/\s+(?:field|input|box|textbox|text\s?box|drop-?\s?down|dropdown|combo\s?box|combobox|menu|selector|element|checkbox|radio\s?button|radio)$/i;function Te(e){let t=e.replace(ut,"").trim();return t.length>0?t:e}function dt(e){let t=e;return t=t.replace(/(getBy(?:Label|Placeholder)\(\s*)(['"`])([\s\S]*?)\2/g,(n,r,i,a)=>`${r}${i}${Te(a)}${i}`),t=t.replace(/(name:\s*)(['"`])([\s\S]*?)\2/g,(n,r,i,a)=>`${r}${i}${Te(a)}${i}`),t}function gt(e){return e.replace(/\blocator\((['"`])([\s\S]*?)\1\)/g,(t,n,r)=>{if(!r.includes(" >> "))return t;let i=r.split(" >> ").map(a=>a.trim()).filter(Boolean);return i.length<2?t:i.map(a=>`locator(${n}${a}${n})`).join(".")})}function ft(e){let t=e;return t=gt(t),t=t.replace(/\.or\((?:[^()]*|\([^()]*\))*\)(?:\.(?:first|last)\(\))?/g,""),t=t.replace(/\.(?:first|last)\(\)(?=\.\w)/g,""),t=dt(t),t}function ht(e){let t=lt(e);if(!t)throw new u("AI returned an empty code response. Please try regenerating.","generatedCode","EMPTY_CODE");let n=ft(t);return pt(n),n}function O(e){return e.toLowerCase().trim().replace(/[^a-z0-9]+/g,"-").replace(/^-+|-+$/g,"")}function xt(e,t){let n=e;for(let r of t)r.length>0&&(n=n.replaceAll(r,"[REDACTED]"));return n}import Pe from"path";import R from"fs-extra";async function x(e,t){let n=Pe.dirname(e);await R.ensureDir(n);let r=`${e}.${process.pid}.tmp`;try{await R.writeJson(r,t,{spaces:2}),await R.rename(r,e)}catch(i){throw await R.remove(r).catch(()=>{}),new g(`Failed to write file "${e}": ${i instanceof Error?i.message:String(i)}`,e,"WRITE_FAILED")}}async function y(e){try{return await R.readJson(e)}catch(t){throw new g(`Failed to read JSON file "${e}": ${t instanceof Error?t.message:String(t)}`,e,"READ_FAILED")}}async function _e(e,t){let n=Pe.dirname(e);await R.ensureDir(n);let r=`${e}.${process.pid}.tmp`;try{await R.writeFile(r,t,"utf8"),await R.rename(r,e)}catch(i){throw await R.remove(r).catch(()=>{}),new g(`Failed to write file "${e}": ${i instanceof Error?i.message:String(i)}`,e,"WRITE_FAILED")}}var F=S("suite-store"),K="suite.json";async function Y(e){let t=E.join(e,K);if(!await I.pathExists(t))throw new g(`Suite file not found at "${t}". Ensure the suite directory exists and contains a suite.json file.`,t,"SUITE_NOT_FOUND");let n=await y(t),r=ne.safeParse(n);if(!r.success){let a=r.error.issues.map(p=>` \u2022 ${p.path.join(".")}: ${p.message}`).join(`
2
- `);throw new u(`Invalid suite.json at "${t}":
3
- ${a}`,"suite","INVALID_SUITE")}if(!n.type){let a=E.basename(E.dirname(e));a==="api"?r.data.type="api":a==="audit"||a==="performance"?r.data.type="audit":r.data.type="ui"}return r.data}async function oe(e,t){await I.ensureDir(e);let n=E.join(e,K),r=ne.safeParse(t);if(!r.success){let i=r.error.issues.map(a=>` \u2022 ${a.path.join(".")}: ${a.message}`).join(`
4
- `);throw new u(`Cannot write invalid suite to "${n}":
5
- ${i}`,"suite","INVALID_SUITE")}await x(n,r.data),F.debug({suiteId:t.id,path:n},"Suite written")}async function St(e,t){let n=new Date().toISOString(),r=t.type??"ui",i={...t,type:r,id:bt(),createdAt:n,updatedAt:n},a=E.join(e,r),p=E.join(a,O(i.name));if(await I.pathExists(E.join(p,K)))throw new g(`Suite directory already exists at "${p}". Choose a different name or delete the existing suite first.`,p,"SUITE_ALREADY_EXISTS");return await oe(p,i),F.info({suiteId:i.id,path:p},"Suite created"),{suiteDir:p,suiteId:i.id}}async function yt(e,t){let n=await Y(e),r={...n,...t,id:n.id,createdAt:n.createdAt,updatedAt:new Date().toISOString()};return await oe(e,r),r}async function Et(e){if(!await I.pathExists(e))throw new g(`Suite directory not found at "${e}".`,e,"SUITE_NOT_FOUND");await I.remove(e),F.info({path:e},"Suite deleted")}async function se(e){let t=[],n=[E.join(e,"ui"),E.join(e,"api"),E.join(e,"audit"),E.join(e,"performance"),e];for(let r of n){if(!await I.pathExists(r))continue;let i=await I.readdir(r,{withFileTypes:!0});for(let a of i){if(!a.isDirectory()||r===e&&(a.name==="ui"||a.name==="api"||a.name==="audit"||a.name==="performance"))continue;let p=E.join(r,a.name,K);await I.pathExists(p)&&t.push(E.join(r,a.name))}}return t}async function wt(e){let t=await se(e),n=[];for(let r of t)try{n.push(await Y(r))}catch(i){F.warn({path:r,err:i},"Failed to read suite \u2014 skipping")}return n}async function vt(e){let t=await se(e),n=[];for(let r of t)try{let i=await Y(r),p=(await I.readdir(r,{withFileTypes:!0})).filter(b=>b.isFile()&&b.name.endsWith(".test.json")).length;n.push({...i,caseCount:p})}catch(i){F.warn({path:r,err:i},"Failed to read suite \u2014 skipping")}return n}import ce from"path";import z from"fs-extra";import{v4 as At}from"uuid";var q=S("case-store"),le=".test.json";async function me(e){if(!await z.pathExists(e))throw new g(`Test case file not found at "${e}".`,e,"CASE_NOT_FOUND");let t=await y(e),n=te.safeParse(t);if(!n.success){let r=n.error.issues.map(i=>` \u2022 ${i.path.join(".")}: ${i.message}`).join(`
6
- `);throw new u(`Invalid test case file at "${e}":
7
- ${r}`,"case","INVALID_CASE")}return n.data}async function pe(e,t){let n=te.safeParse(t);if(!n.success){let r=n.error.issues.map(i=>` \u2022 ${i.path.join(".")}: ${i.message}`).join(`
8
- `);throw new u(`Cannot write invalid test case to "${e}":
9
- ${r}`,"case","INVALID_CASE")}await x(e,n.data),q.debug({caseId:t.id,path:e},"Test case written")}async function Rt(e,t){let n=new Date().toISOString(),r={...t,id:At(),createdAt:n,updatedAt:n},i=ce.join(e,`${O(r.name)}${le}`);return await pe(i,r),q.info({caseId:r.id,path:i},"Test case created"),i}async function It(e,t){let n=await me(e),r={...n,...t,id:n.id,createdAt:n.createdAt,updatedAt:new Date().toISOString()};return await pe(e,r),r}async function jt(e){if(!await z.pathExists(e))throw new g(`Test case file not found at "${e}".`,e,"CASE_NOT_FOUND");await z.remove(e),q.info({path:e},"Test case deleted")}async function Ne(e){return await z.pathExists(e)?(await z.readdir(e,{withFileTypes:!0})).filter(n=>n.isFile()&&n.name.endsWith(le)).map(n=>ce.join(e,n.name)):[]}async function Ct(e){let t=await Ne(e),n=[];for(let r of t)try{n.push(await me(r))}catch(i){q.warn({path:r,err:i},"Failed to read test case \u2014 skipping")}return n.sort((r,i)=>r.name.localeCompare(i.name))}function Tt(e,t){return ce.join(e,`${O(t)}${le}`)}import _ from"path";import X from"fs-extra";import{z as P}from"zod";var Pt=P.object({value:P.string(),secret:P.literal(!0)}),_t=P.union([P.string(),Pt]),ue=P.record(P.string(),_t);function Nt(e){return typeof e=="object"&&e.secret===!0}function Oe(e){return Nt(e)?e.value:e}var Ot=S("variable-store"),U="variables",de="global.json";function $t(e){return`${e}.env.json`}async function k(e){if(!await X.pathExists(e))return{};let t=await y(e),n=ue.safeParse(t);if(!n.success){let r=n.error.issues.map(i=>` \u2022 ${i.path.join(".")}: ${i.message}`).join(`
10
- `);throw new u(`Invalid variables file at "${e}":
11
- ${r}`,"variables","INVALID_VARIABLES")}return n.data}async function ge(e,t){let n=ue.safeParse(t);if(!n.success){let r=n.error.issues.map(i=>` \u2022 ${i.path.join(".")}: ${i.message}`).join(`
12
- `);throw new u(`Cannot write invalid variables to "${e}":
13
- ${r}`,"variables","INVALID_VARIABLES")}await x(e,n.data),Ot.debug({path:e},"Variables written")}async function $e(e){let t=_.join(e,U,de);return k(t)}async function Le(e,t){let n=_.join(e,U,$t(t));return k(n)}async function Lt(e,t){let n=await $e(e),r=t?await Le(e,t):{},i={...n,...r},a={};for(let[p,b]of Object.entries(i))a[p]=Oe(b);return a}async function Vt(e,t,n){let r=_.join(e,U,de);await X.ensureDir(_.dirname(r));let i=await k(r);i[t]=n,await ge(r,i)}async function Dt(e,t){let n=_.join(e,U,de),r=await k(n);if(!(t in r))throw new g(`Variable "${t}" not found in global variables.`,n,"VARIABLE_NOT_FOUND");delete r[t],await ge(n,r)}async function Ht(e){let t=_.join(e,U);return await X.pathExists(t)?(await X.readdir(t,{withFileTypes:!0})).filter(r=>r.isFile()&&r.name.endsWith(".json")).map(r=>_.join(t,r.name)):[]}import G from"path";import fe from"fs-extra";var he=S("config-store"),xe="autotest.config.json",Ve="autotest.config.ts";async function be(e){let t=G.join(e,xe);if(!await fe.pathExists(t))return he.debug({rootDir:e},"No autotest.config.json found \u2014 using defaults"),J;let n=await y(t),r=D.safeParse(n);if(!r.success){let i=r.error.issues.map(a=>` \u2022 ${a.path.join(".")}: ${a.message}`).join(`
14
- `);throw new u(`Invalid autotest.config.json at "${t}":
15
- ${i}
1
+ import{z as c}from"zod";var Xe=c.enum(["off","on","only-on-failure"]),Ze=c.enum(["off","on","on-first-retry","retain-on-failure"]),Qe=c.enum(["off","on","on-first-retry","retain-on-failure"]),Ae=c.enum(["chromium","firefox","webkit"]),et=c.enum(["commit","domcontentloaded","load","networkidle"]),Re=c.string().min(1),Ie=["DEV","TEST","STAGE","INT","PROD"],tt=c.record(c.string(),c.string()).default({}),nt=c.object({enabled:c.boolean(),maxLevel:c.number().int().min(1).max(5),dailyBudget:c.number().positive(),autoPR:c.boolean(),healAssertionLocators:c.boolean().default(!1)}),rt=c.object({allure:c.boolean(),html:c.boolean(),json:c.boolean()}),it=c.object({width:c.number().int().positive(),height:c.number().int().positive()}),at=c.object({name:c.string().min(1),environment:Re,baseUrl:c.string().url(),browsers:c.array(Ae).min(1),headless:c.boolean().optional()}),D=c.object({baseUrl:c.string().url(),environment:Re.default("DEV"),environments:c.array(c.string().min(1)).default([...Ie]),environmentUrls:tt.default({DEV:"",TEST:"",STAGE:"",INT:"",PROD:""}),browsers:c.array(Ae).min(1),headless:c.boolean(),viewport:it.default({width:1280,height:720}),timeout:c.number().int().positive(),retries:c.number().int().min(0),parallel:c.number().int().positive(),pageLoad:et.default("domcontentloaded"),screenshot:Xe,video:Ze,trace:Qe,healing:nt,reporting:rt,studioPort:c.number().int().min(1024).max(65535),profiles:c.array(at).default([]),activeProfile:c.string().optional(),device:c.string().optional(),rag:c.object({enabled:c.boolean(),codeCorpus:c.object({enabled:c.boolean(),maxEntries:c.number().int().positive(),similarityThreshold:c.number().min(0).max(1),directUseThreshold:c.number().min(0).max(1)}),healingCorpus:c.object({enabled:c.boolean(),maxEntries:c.number().int().positive(),similarityThreshold:c.number().min(0).max(1)}),errorCatalog:c.object({enabled:c.boolean(),maxEntries:c.number().int().positive()}),embedder:c.literal("tfidf")}).default({enabled:!0,codeCorpus:{enabled:!0,maxEntries:500,similarityThreshold:.65,directUseThreshold:.9},healingCorpus:{enabled:!0,maxEntries:300,similarityThreshold:.6},errorCatalog:{enabled:!0,maxEntries:200},embedder:"tfidf"}),mcp:c.object({enabled:c.boolean(),headless:c.boolean(),actThenScript:c.boolean(),proactiveHealing:c.boolean(),actionTimeout:c.number().int().positive(),idleTimeout:c.number().int().positive()}).default({enabled:!0,headless:!0,actThenScript:!1,proactiveHealing:!1,actionTimeout:15e3,idleTimeout:3e4}),ci:c.object({writeToRepo:c.boolean()}).default({writeToRepo:!1})}),J={baseUrl:"http://localhost:3000",environment:"DEV",environments:[...Ie],environmentUrls:{DEV:"http://localhost:3000",TEST:"",STAGE:"",INT:"",PROD:""},browsers:["chromium"],headless:!0,viewport:{width:1280,height:720},timeout:3e4,retries:1,parallel:1,pageLoad:"domcontentloaded",screenshot:"only-on-failure",video:"off",trace:"on-first-retry",healing:{enabled:!0,maxLevel:5,dailyBudget:5,autoPR:!1,healAssertionLocators:!1},reporting:{allure:!0,html:!0,json:!0},studioPort:4400,profiles:[],rag:{enabled:!0,codeCorpus:{enabled:!0,maxEntries:500,similarityThreshold:.65,directUseThreshold:.9},healingCorpus:{enabled:!0,maxEntries:300,similarityThreshold:.6},errorCatalog:{enabled:!0,maxEntries:200},embedder:"tfidf"},mcp:{enabled:!0,headless:!0,actThenScript:!1,proactiveHealing:!1,actionTimeout:15e3,idleTimeout:3e4},ci:{writeToRepo:!1}};import E from"path";import I from"fs-extra";import{v4 as yt}from"uuid";import{z as l}from"zod";var H=l.object({id:l.string().min(1),order:l.number().int().positive(),instruction:l.string().min(1),generatedCode:l.string(),strategy:l.enum(["template","cache","rag","batch","fast","primary","recorder"]),stepType:l.enum(["ui","api","mock"]).default("ui"),lastHealed:l.string().nullable(),timeout:l.number().int().positive().optional(),retries:l.number().int().min(0).optional(),mockUrl:l.string().optional(),mockResponse:l.string().optional(),mockStatus:l.number().int().optional(),runAudit:l.boolean().optional(),soft:l.boolean().optional(),visualCheck:l.boolean().optional()}),ot=l.object({type:l.enum(["inline","json-file","csv-file"]),path:l.string().optional(),data:l.array(l.record(l.string())).optional()}).optional(),je=l.object({id:l.string(),instruction:l.string(),generatedCode:l.string().default(""),order:l.number().int().default(0)}),st=l.object({before:l.array(je).default([]),after:l.array(je).default([])}).default({before:[],after:[]}),ne=l.object({id:l.string().min(1),name:l.string().min(1),description:l.string(),tags:l.array(l.string()),priority:l.enum(["critical","high","medium","low"]),timeout:l.number().int().positive().optional(),dataSource:ot,steps:l.array(H),caseHooks:st,lighthouseCategories:l.array(l.enum(["performance","accessibility","seo"])).default(["performance","accessibility","seo"]),createdAt:l.string().datetime(),updatedAt:l.string().datetime()}),re=l.object({id:l.string().min(1),name:l.string().min(1),description:l.string(),tags:l.array(l.string()),type:l.enum(["ui","api","audit","performance"]).default("ui"),timeout:l.number().int().positive().optional(),createdAt:l.string().datetime(),updatedAt:l.string().datetime()}),kn=l.enum(["before_all","before_each","after_each","after_all"]),Gn=l.object({before_all:l.array(H).default([]),before_each:l.array(H).default([]),after_each:l.array(H).default([]),after_all:l.array(H).default([])});var v=class extends Error{code;constructor(t,n){super(t),this.name="AssuremindError",this.code=n,Object.setPrototypeOf(this,new.target.prototype)}},ie=class extends v{provider;constructor(t,n,r="PROVIDER_ERROR"){super(t,r),this.name="ProviderError",this.provider=n}},ae=class extends v{stepId;constructor(t,n,r="EXECUTION_ERROR"){super(t,r),this.name="ExecutionError",this.stepId=n}},T=class extends v{constructor(t,n="CONFIG_ERROR"){super(t,n),this.name="ConfigError"}},p=class extends v{field;constructor(t,n,r="VALIDATION_ERROR"){super(t,r),this.name="ValidationError",this.field=n}},oe=class extends v{level;constructor(t,n,r="HEALING_ERROR"){super(t,r),this.name="HealingError",this.level=n}},g=class extends v{path;constructor(t,n,r="STORAGE_ERROR"){super(t,r),this.name="StorageError",this.path=n}};function ct(e){return e instanceof v}function lt(e){return e instanceof v?`[${e.code}] ${e.message}`:e instanceof Error?e.message:String(e)}import Te from"pino";import qn from"fs-extra";var mt=process.env.NODE_ENV!=="production",Pe=mt?{target:"pino-pretty",options:{colorize:!0,translateTime:"HH:MM:ss",ignore:"pid,hostname",messageFormat:"[assuremind] {msg}"}}:void 0,Ce=Te({level:process.env.LOG_LEVEL??"info",base:{name:"assuremind"}},Pe?Te.transport(Pe):void 0);function S(e){return Ce.child({component:e})}function ut(e){let t=/^```(?:typescript|javascript|ts|js)?\n?([\s\S]*?)```\s*$/m,n=e.match(t);return n?.[1]!==void 0?n[1].trim():e.trim()}var pt=[/\brequire\s*\(/,/\bimport\s*\(/,/\bprocess\b/,/\bchild_process\b/,/\bexec\s*\(/,/\bspawn\s*\(/,/\beval\s*\(/,/\bFunction\s*\(/,/\b__dirname\b/,/\b__filename\b/,/\bglobal\b/,/\bwindow\.location\.href\s*=/,/\bdocument\.cookie\b/,/\blocalStorage\b/,/\bsessionStorage\b/,/\bIndexedDB\b/,/\bXMLHttpRequest\b/,/\bfetch\s*\(/,/\bWebSocket\s*\(/];function dt(e){for(let t of pt)if(t.test(e))throw new p(`Generated code contains forbidden pattern: ${t.source}. This may be a prompt injection attempt. Please regenerate the step.`,"generatedCode","UNSAFE_CODE")}var gt=/\s+(?:field|input|box|textbox|text\s?box|drop-?\s?down|dropdown|combo\s?box|combobox|menu|selector|element|checkbox|radio\s?button|radio)$/i;function _e(e){let t=e.replace(gt,"").trim();return t.length>0?t:e}function ft(e){let t=e;return t=t.replace(/(getBy(?:Label|Placeholder)\(\s*)(['"`])([\s\S]*?)\2/g,(n,r,i,a)=>`${r}${i}${_e(a)}${i}`),t=t.replace(/(name:\s*)(['"`])([\s\S]*?)\2/g,(n,r,i,a)=>`${r}${i}${_e(a)}${i}`),t}function ht(e){return e.replace(/\blocator\((['"`])([\s\S]*?)\1\)/g,(t,n,r)=>{if(!r.includes(" >> "))return t;let i=r.split(" >> ").map(a=>a.trim()).filter(Boolean);return i.length<2?t:i.map(a=>`locator(${n}${a}${n})`).join(".")})}function xt(e){let t=e;return t=ht(t),t=t.replace(/\.or\((?:[^()]*|\([^()]*\))*\)(?:\.(?:first|last)\(\))?/g,""),t=t.replace(/\.(?:first|last)\(\)(?=\.\w)/g,""),t=ft(t),t}function bt(e){let t=ut(e);if(!t)throw new p("AI returned an empty code response. Please try regenerating.","generatedCode","EMPTY_CODE");let n=xt(t);return dt(n),n}function N(e){return e.toLowerCase().trim().replace(/[^a-z0-9]+/g,"-").replace(/^-+|-+$/g,"")}function St(e,t){let n=e;for(let r of t)r.length>0&&(n=n.replaceAll(r,"[REDACTED]"));return n}import Oe from"path";import R from"fs-extra";async function x(e,t){let n=Oe.dirname(e);await R.ensureDir(n);let r=`${e}.${process.pid}.tmp`;try{await R.writeJson(r,t,{spaces:2}),await R.rename(r,e)}catch(i){throw await R.remove(r).catch(()=>{}),new g(`Failed to write file "${e}": ${i instanceof Error?i.message:String(i)}`,e,"WRITE_FAILED")}}async function y(e){try{return await R.readJson(e)}catch(t){throw new g(`Failed to read JSON file "${e}": ${t instanceof Error?t.message:String(t)}`,e,"READ_FAILED")}}async function Ne(e,t){let n=Oe.dirname(e);await R.ensureDir(n);let r=`${e}.${process.pid}.tmp`;try{await R.writeFile(r,t,"utf8"),await R.rename(r,e)}catch(i){throw await R.remove(r).catch(()=>{}),new g(`Failed to write file "${e}": ${i instanceof Error?i.message:String(i)}`,e,"WRITE_FAILED")}}var F=S("suite-store"),K="suite.json";async function Y(e){let t=E.join(e,K);if(!await I.pathExists(t))throw new g(`Suite file not found at "${t}". Ensure the suite directory exists and contains a suite.json file.`,t,"SUITE_NOT_FOUND");let n=await y(t),r=re.safeParse(n);if(!r.success){let a=r.error.issues.map(m=>` \u2022 ${m.path.join(".")}: ${m.message}`).join(`
2
+ `);throw new p(`Invalid suite.json at "${t}":
3
+ ${a}`,"suite","INVALID_SUITE")}if(!n.type){let a=E.basename(E.dirname(e));a==="api"?r.data.type="api":a==="audit"||a==="performance"?r.data.type="audit":r.data.type="ui"}return r.data}async function se(e,t){await I.ensureDir(e);let n=E.join(e,K),r=re.safeParse(t);if(!r.success){let i=r.error.issues.map(a=>` \u2022 ${a.path.join(".")}: ${a.message}`).join(`
4
+ `);throw new p(`Cannot write invalid suite to "${n}":
5
+ ${i}`,"suite","INVALID_SUITE")}await x(n,r.data),F.debug({suiteId:t.id,path:n},"Suite written")}async function Et(e,t){let n=new Date().toISOString(),r=t.type??"ui",i={...t,type:r,id:yt(),createdAt:n,updatedAt:n},a=E.join(e,r),m=E.join(a,N(i.name));if(await I.pathExists(E.join(m,K)))throw new g(`Suite directory already exists at "${m}". Choose a different name or delete the existing suite first.`,m,"SUITE_ALREADY_EXISTS");return await se(m,i),F.info({suiteId:i.id,path:m},"Suite created"),{suiteDir:m,suiteId:i.id}}async function wt(e,t){let n=await Y(e),r={...n,...t,id:n.id,createdAt:n.createdAt,updatedAt:new Date().toISOString()};return await se(e,r),r}async function vt(e){if(!await I.pathExists(e))throw new g(`Suite directory not found at "${e}".`,e,"SUITE_NOT_FOUND");await I.remove(e),F.info({path:e},"Suite deleted")}async function ce(e){let t=[],n=[E.join(e,"ui"),E.join(e,"api"),E.join(e,"audit"),E.join(e,"performance"),e];for(let r of n){if(!await I.pathExists(r))continue;let i=await I.readdir(r,{withFileTypes:!0});for(let a of i){if(!a.isDirectory()||r===e&&(a.name==="ui"||a.name==="api"||a.name==="audit"||a.name==="performance"))continue;let m=E.join(r,a.name,K);await I.pathExists(m)&&t.push(E.join(r,a.name))}}return t}async function At(e){let t=await ce(e),n=[];for(let r of t)try{n.push(await Y(r))}catch(i){F.warn({path:r,err:i},"Failed to read suite \u2014 skipping")}return n}async function Rt(e){let t=await ce(e),n=[];for(let r of t)try{let i=await Y(r),m=(await I.readdir(r,{withFileTypes:!0})).filter(b=>b.isFile()&&b.name.endsWith(".test.json")).length;n.push({...i,caseCount:m})}catch(i){F.warn({path:r,err:i},"Failed to read suite \u2014 skipping")}return n}import le from"path";import z from"fs-extra";import{v4 as It}from"uuid";var q=S("case-store"),me=".test.json";async function ue(e){if(!await z.pathExists(e))throw new g(`Test case file not found at "${e}".`,e,"CASE_NOT_FOUND");let t=await y(e),n=ne.safeParse(t);if(!n.success){let r=n.error.issues.map(i=>` \u2022 ${i.path.join(".")}: ${i.message}`).join(`
6
+ `);throw new p(`Invalid test case file at "${e}":
7
+ ${r}`,"case","INVALID_CASE")}return n.data}async function pe(e,t){let n=ne.safeParse(t);if(!n.success){let r=n.error.issues.map(i=>` \u2022 ${i.path.join(".")}: ${i.message}`).join(`
8
+ `);throw new p(`Cannot write invalid test case to "${e}":
9
+ ${r}`,"case","INVALID_CASE")}await x(e,n.data),q.debug({caseId:t.id,path:e},"Test case written")}async function jt(e,t){let n=new Date().toISOString(),r={...t,id:It(),createdAt:n,updatedAt:n},i=le.join(e,`${N(r.name)}${me}`);return await pe(i,r),q.info({caseId:r.id,path:i},"Test case created"),i}async function Tt(e,t){let n=await ue(e),r={...n,...t,id:n.id,createdAt:n.createdAt,updatedAt:new Date().toISOString()};return await pe(e,r),r}async function Pt(e){if(!await z.pathExists(e))throw new g(`Test case file not found at "${e}".`,e,"CASE_NOT_FOUND");await z.remove(e),q.info({path:e},"Test case deleted")}async function $e(e){return await z.pathExists(e)?(await z.readdir(e,{withFileTypes:!0})).filter(n=>n.isFile()&&n.name.endsWith(me)).map(n=>le.join(e,n.name)):[]}async function Ct(e){let t=await $e(e),n=[];for(let r of t)try{n.push(await ue(r))}catch(i){q.warn({path:r,err:i},"Failed to read test case \u2014 skipping")}return n.sort((r,i)=>r.name.localeCompare(i.name))}function _t(e,t){return le.join(e,`${N(t)}${me}`)}import _ from"path";import X from"fs-extra";import{z as C}from"zod";var Ot=C.object({value:C.string(),secret:C.literal(!0)}),Nt=C.union([C.string(),Ot]),de=C.record(C.string(),Nt);function $t(e){return typeof e=="object"&&e.secret===!0}function Ve(e){return $t(e)?e.value:e}var Vt=S("variable-store"),U="variables",ge="global.json";function Lt(e){return`${e}.env.json`}async function k(e){if(!await X.pathExists(e))return{};let t=await y(e),n=de.safeParse(t);if(!n.success){let r=n.error.issues.map(i=>` \u2022 ${i.path.join(".")}: ${i.message}`).join(`
10
+ `);throw new p(`Invalid variables file at "${e}":
11
+ ${r}`,"variables","INVALID_VARIABLES")}return n.data}async function fe(e,t){let n=de.safeParse(t);if(!n.success){let r=n.error.issues.map(i=>` \u2022 ${i.path.join(".")}: ${i.message}`).join(`
12
+ `);throw new p(`Cannot write invalid variables to "${e}":
13
+ ${r}`,"variables","INVALID_VARIABLES")}await x(e,n.data),Vt.debug({path:e},"Variables written")}async function Le(e){let t=_.join(e,U,ge);return k(t)}async function De(e,t){let n=_.join(e,U,Lt(t));return k(n)}async function Dt(e,t){let n=await Le(e),r=t?await De(e,t):{},i={...n,...r},a={};for(let[m,b]of Object.entries(i)){let te=process.env[m];a[m]=te!==void 0&&te!==""?te:Ve(b)}return a}async function Ht(e,t,n){let r=_.join(e,U,ge);await X.ensureDir(_.dirname(r));let i=await k(r);i[t]=n,await fe(r,i)}async function Ft(e,t){let n=_.join(e,U,ge),r=await k(n);if(!(t in r))throw new g(`Variable "${t}" not found in global variables.`,n,"VARIABLE_NOT_FOUND");delete r[t],await fe(n,r)}async function zt(e){let t=_.join(e,U);return await X.pathExists(t)?(await X.readdir(t,{withFileTypes:!0})).filter(r=>r.isFile()&&r.name.endsWith(".json")).map(r=>_.join(t,r.name)):[]}import G from"path";import he from"fs-extra";var xe=S("config-store"),be="autotest.config.json",He="autotest.config.ts";async function Se(e){let t=G.join(e,be);if(!await he.pathExists(t))return xe.debug({rootDir:e},"No autotest.config.json found \u2014 using defaults"),J;let n=await y(t),r=D.safeParse(n);if(!r.success){let a=r.error.issues.map(m=>` \u2022 ${m.path.join(".")}: ${m.message}`).join(`
14
+ `);throw new p(`Invalid autotest.config.json at "${t}":
15
+ ${a}
16
16
 
17
- How to fix: Run "npx assuremind init" to reset to defaults, or manually correct the file using autotest.config.ts as reference.`,"config","INVALID_CONFIG")}return r.data}async function De(e,t){let n=D.safeParse(t);if(!n.success){let a=n.error.issues.map(p=>` \u2022 ${p.path.join(".")}: ${p.message}`).join(`
18
- `);throw new u(`Cannot write invalid config:
19
- ${a}`,"config","INVALID_CONFIG")}let r=G.join(e,xe);await x(r,n.data);let i=G.join(e,Ve);await _e(i,kt(n.data)),he.info({rootDir:e},"Config saved")}async function Ft(e,t){let n=await be(e),r={...n,...t,healing:{...n.healing,...t.healing??{}},reporting:{...n.reporting,...t.reporting??{}},environmentUrls:{...n.environmentUrls,...t.environmentUrls??{}}};return await De(e,r),r}async function zt(e){let t=G.join(e,xe),n=G.join(e,Ve);return await fe.pathExists(t)||await fe.pathExists(n)}async function Ut(e){let t=await be(e);if(!t.baseUrl)throw new C('baseUrl is required in autotest.config.ts. Set it to your application URL, e.g. "http://localhost:3000".',"CONFIG_BASE_URL_MISSING");he.debug({config:t},"Config validated successfully")}function kt(e){return`import { defineConfig } from 'assuremind';
17
+ How to fix: Run "npx assuremind init" to reset to defaults, or manually correct the file using autotest.config.ts as reference.`,"config","INVALID_CONFIG")}let i=r.data;if(n&&typeof n=="object"&&"environments"in n)i.environment&&!i.environments.includes(i.environment)&&(i.environments=[...i.environments,i.environment]);else{let a=new Set;for(let m of Object.keys(i.environmentUrls??{}))a.add(m);i.environment&&a.add(i.environment),a.size>0&&(i.environments=[...a])}return i}async function Fe(e,t){let n=D.safeParse(t);if(!n.success){let a=n.error.issues.map(m=>` \u2022 ${m.path.join(".")}: ${m.message}`).join(`
18
+ `);throw new p(`Cannot write invalid config:
19
+ ${a}`,"config","INVALID_CONFIG")}let r=G.join(e,be);await x(r,n.data);let i=G.join(e,He);await Ne(i,Mt(n.data)),xe.info({rootDir:e},"Config saved")}async function Ut(e,t){let n=await Se(e),r={...n,...t,healing:{...n.healing,...t.healing??{}},reporting:{...n.reporting,...t.reporting??{}},environmentUrls:{...n.environmentUrls,...t.environmentUrls??{}}};return await Fe(e,r),r}async function kt(e){let t=G.join(e,be),n=G.join(e,He);return await he.pathExists(t)||await he.pathExists(n)}async function Gt(e){let t=await Se(e);if(!t.baseUrl)throw new T('baseUrl is required in autotest.config.ts. Set it to your application URL, e.g. "http://localhost:3000".',"CONFIG_BASE_URL_MISSING");xe.debug({config:t},"Config validated successfully")}function Mt(e){return`import { defineConfig } from 'assuremind';
20
20
 
21
21
  export default defineConfig({
22
22
  baseUrl: '${e.baseUrl}',
@@ -41,22 +41,22 @@ export default defineConfig({
41
41
  },
42
42
  studioPort: ${e.studioPort},
43
43
  });
44
- `}import j from"path";import $ from"fs-extra";import{z as s}from"zod";var Z=s.enum(["pending","running","passed","failed","skipped"]),Gt=s.object({method:s.string(),url:s.string(),headers:s.record(s.string()).optional(),body:s.string().optional()}).optional(),Mt=s.object({status:s.number(),statusText:s.string(),headers:s.record(s.string()).optional(),body:s.string().optional(),duration:s.number()}).optional(),A=s.number().nullish().transform(e=>e??void 0),He=s.object({id:s.string(),title:s.string(),passed:s.boolean(),partial:s.boolean().optional(),na:s.boolean().optional()}),Bt=s.object({url:s.string(),stepIndex:s.number().int(),stepInstruction:s.string(),score:A,a11yScore:A,seoScore:A,fcp:A,lcp:A,cls:A,ttfb:A,tbt:A,si:A,tti:A,inp:A,a11yAudits:s.array(He).optional(),seoAudits:s.array(He).optional(),lighthouseError:s.string().optional()}),Wt=s.object({stepId:s.string(),instruction:s.string(),status:Z,code:s.string(),error:s.string().optional(),duration:s.number(),screenshotPath:s.string().optional(),healed:s.boolean().optional(),healedCode:s.string().optional(),stepType:s.enum(["ui","api","mock"]).optional(),apiRequest:Gt,apiResponse:Mt,navigatedToUrl:s.string().optional(),auditUrl:s.string().optional()}),Jt=s.object({caseId:s.string(),caseName:s.string(),status:Z,steps:s.array(Wt),duration:s.number(),browser:s.string(),device:s.string().optional(),startedAt:s.string().datetime(),finishedAt:s.string().datetime(),videoPath:s.string().optional(),tracePath:s.string().optional(),downloadPaths:s.array(s.string()).default([]),dataRowIndex:s.number().int().optional(),dataRow:s.record(s.string()).optional(),pageLoads:s.array(Bt).default([])}),Kt=s.object({suiteId:s.string(),suiteName:s.string(),suiteType:s.enum(["ui","api","audit","performance"]).optional(),status:Z,cases:s.array(Jt),duration:s.number(),browser:s.string(),startedAt:s.string().datetime(),finishedAt:s.string().datetime()}),Se=s.object({runId:s.string(),status:Z,environment:s.string().optional(),suites:s.array(Kt),duration:s.number(),startedAt:s.string().datetime(),finishedAt:s.string().datetime(),totalTests:s.number().int(),passed:s.number().int(),failed:s.number().int(),skipped:s.number().int(),logFilePath:s.string().optional()});var ye=S("result-store"),N="results",Fe="runs";function Ee(e,t){return j.join(e,Fe,`${t}.json`)}async function Yt(e,t){let n=Se.safeParse(t);if(!n.success){let i=n.error.issues.map(a=>` \u2022 ${a.path.join(".")}: ${a.message}`).join(`
45
- `);throw new u(`Cannot write invalid run result:
46
- ${i}`,"result","INVALID_RESULT")}let r=Ee(j.join(e,N),t.runId);await x(r,n.data),ye.info({runId:t.runId,status:t.status},"Run result saved")}async function ze(e,t){let n=Ee(j.join(e,N),t);if(!await $.pathExists(n))throw new g(`Run result not found for runId "${t}".`,n,"RESULT_NOT_FOUND");let r=await y(n),i=Se.safeParse(r);if(!i.success){let a=i.error.issues.map(p=>` \u2022 ${p.path.join(".")}: ${p.message}`).join(`
47
- `);throw new u(`Invalid run result at "${n}":
48
- ${a}`,"result","INVALID_RESULT")}return i.data}async function Ue(e){let t=j.join(e,N,Fe);if(!await $.pathExists(t))return[];let r=(await $.readdir(t,{withFileTypes:!0})).filter(a=>a.isFile()&&a.name.endsWith(".json")).map(a=>a.name.replace(".json",""));return(await Promise.all(r.map(async a=>{let p=await $.stat(j.join(t,`${a}.json`));return{id:a,mtime:p.mtimeMs}}))).sort((a,p)=>p.mtime-a.mtime).map(a=>a.id)}async function qt(e,t=20){let n=await Ue(e),r=[];for(let i of n.slice(0,t))try{let a=await ze(e,i);r.push({runId:a.runId,status:a.status,environment:a.environment,startedAt:a.startedAt,finishedAt:a.finishedAt,totalTests:a.totalTests,passed:a.passed,failed:a.failed,skipped:a.skipped,duration:a.duration,suiteIds:a.suites.map(p=>p.suiteId)})}catch(a){ye.warn({runId:i,err:a},"Failed to read run result \u2014 skipping")}return r}async function Xt(e,t){let n=Ee(j.join(e,N),t);if(!await $.pathExists(n))throw new g(`Run result not found for runId "${t}".`,n,"RESULT_NOT_FOUND");await $.remove(n),ye.info({runId:t},"Run result deleted")}function Zt(e){return j.join(e,N,"screenshots")}function Qt(e){return j.join(e,N,"videos")}function en(e){return j.join(e,N,"traces")}import w from"path";import L from"fs-extra";import{z as d}from"zod";var tn=d.enum(["pending","accepted","rejected"]),nn=d.enum(["retry","regenerate","multi-selector","visual","decompose","manual"]),Q=d.object({id:d.string(),runId:d.string(),suiteId:d.string(),caseId:d.string(),stepId:d.string(),stepInstruction:d.string(),failedCode:d.string(),healedCode:d.string(),error:d.string(),strategy:nn,level:d.number().int().min(1).max(6),status:tn,pageUrl:d.string(),timestamp:d.string().datetime(),acceptedAt:d.string().datetime().optional(),rejectedAt:d.string().datetime().optional()}),we=d.object({runId:d.string(),generatedAt:d.string().datetime(),totalHeals:d.number().int(),accepted:d.number().int(),rejected:d.number().int(),pending:d.number().int(),events:d.array(Q)});var M=S("healing-store"),T=w.join("results","healing"),rn="pending.json",ee="healing-report-";function Me(e,t){return w.join(e,`${ee}${t}.json`)}function B(e){return w.join(e,rn)}async function an(e,t){let n=we.safeParse(t);if(!n.success){let a=n.error.issues.map(p=>` \u2022 ${p.path.join(".")}: ${p.message}`).join(`
49
- `);throw new u(`Cannot write invalid healing report:
50
- ${a}`,"healingReport","INVALID_HEALING_REPORT")}let r=w.join(e,T),i=Me(r,t.runId);await x(i,n.data),M.info({runId:t.runId,totalHeals:t.totalHeals},"Healing report saved")}async function on(e,t){let n=w.join(e,T),r=Me(n,t);if(!await L.pathExists(r))throw new g(`Healing report not found for runId "${t}".`,r,"HEALING_REPORT_NOT_FOUND");let i=await y(r),a=we.safeParse(i);if(!a.success){let p=a.error.issues.map(b=>` \u2022 ${b.path.join(".")}: ${b.message}`).join(`
51
- `);throw new u(`Invalid healing report at "${r}":
52
- ${p}`,"healingReport","INVALID_HEALING_REPORT")}return a.data}async function V(e){let t=w.join(e,T),n=B(t);if(!await L.pathExists(n))return[];let r=await y(n),i=Q.array().safeParse(r);return i.success?i.data:(M.warn({path:n},"Pending healing file is malformed \u2014 resetting"),[])}var ke=50,Ge=["pending","rejected","accepted"];function sn(e){if(e.length<=ke)return e;let t=[...e].sort((i,a)=>{let p=Ge.indexOf(i.status),b=Ge.indexOf(a.status);return p!==b?p-b:i.timestamp<a.timestamp?-1:1}),n=e.length-ke,r=new Set(t.slice(0,n).map(i=>i.id));return M.info({excess:n,deleted:r.size},"Auto-pruning healing events to enforce cap"),e.filter(i=>!r.has(i.id))}async function cn(e,t){let n=Q.safeParse(t);if(!n.success)throw new u(`Invalid healing event: ${n.error.message}`,"healingEvent","INVALID_HEALING_EVENT");let r=w.join(e,T);await L.ensureDir(r);let i=await V(e);i.push(n.data),await x(B(r),sn(i))}async function ln(e,t){let n=await V(e),r=n.findIndex(a=>a.id===t);if(r===-1)throw new g(`Healing event "${t}" not found in pending list.`,t,"HEALING_EVENT_NOT_FOUND");n[r]={...n[r],status:"accepted",acceptedAt:new Date().toISOString()};let i=w.join(e,T);return await x(B(i),n),M.info({eventId:t},"Healing event accepted"),n[r]}async function mn(e,t){let n=await V(e),r=n.findIndex(a=>a.id===t);if(r===-1)throw new g(`Healing event "${t}" not found in pending list.`,t,"HEALING_EVENT_NOT_FOUND");n[r]={...n[r],status:"rejected",rejectedAt:new Date().toISOString()};let i=w.join(e,T);return await x(B(i),n),M.info({eventId:t},"Healing event rejected"),n[r]}async function pn(e,t=30){let n=await V(e),r=Date.now()-t*24*60*60*1e3,i=n.length,a=n.filter(p=>{if(p.status==="pending")return!0;let b=p.acceptedAt??p.rejectedAt;return b?new Date(b).getTime()>r:!0});if(a.length<i){let p=w.join(e,T);await x(B(p),a)}return i-a.length}async function un(e){let t=await V(e),n=t.filter(a=>a.status==="pending").length,r=t.filter(a=>a.status==="accepted").length,i=t.filter(a=>a.status==="rejected").length;return{pending:n,accepted:r,rejected:i,total:t.length}}async function dn(e){let t=w.join(e,T);if(!await L.pathExists(t))return[];let r=(await L.readdir(t,{withFileTypes:!0})).filter(a=>a.isFile()&&a.name.startsWith(ee)&&a.name.endsWith(".json")).map(a=>a.name.slice(ee.length,-5));return(await Promise.all(r.map(async a=>{let p=await L.stat(w.join(t,`${ee}${a}.json`));return{id:a,mtime:p.mtimeMs}}))).sort((a,p)=>p.mtime-a.mtime).map(a=>a.id)}import{createHash as gn}from"crypto";function Be(e){return gn("sha256").update(e,"utf8").digest("hex")}function We(e){try{return new URL(e).pathname.split("/").map(r=>/^\d+$/.test(r)||/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i.test(r)||/^[a-z0-9-]{8,}$/i.test(r)&&/-/.test(r)?"*":r).join("/")}catch{return e}}function fn(e,t){let n=e.toLowerCase().replace(/\s+/g," ").trim(),r=We(t);return Be(`${n}|${r}`).slice(0,16)}import{config as hn}from"dotenv";import{z as m}from"zod";hn();var Je=["anthropic","openai","google","azure-openai","bedrock","deepseek","groq","together","qwen","perplexity","ollama","custom"],xn=m.object({NODE_ENV:m.enum(["development","production","test"]).default("development"),LOG_LEVEL:m.enum(["trace","debug","info","warn","error","fatal"]).default("info"),AI_PROVIDER:m.enum(Je),AI_TIERED_ENABLED:m.string().transform(e=>e==="true").default("false"),AI_TIERED_FAST_PROVIDER:m.enum(Je).optional(),AI_TIERED_FAST_MODEL:m.string().optional(),AI_TIMEOUT:m.coerce.number().int().positive().default(30),AI_MAX_RETRIES:m.coerce.number().int().min(0).max(10).default(2)}),bn=m.object({ANTHROPIC_API_KEY:m.string().min(1),ANTHROPIC_MODEL:m.string().default("claude-sonnet-4-20250514")}),Sn=m.object({OPENAI_API_KEY:m.string().min(1),OPENAI_MODEL:m.string().default("gpt-4o")}),yn=m.object({GOOGLE_API_KEY:m.string().min(1),GOOGLE_MODEL:m.string().default("gemini-2.5-pro")}),En=m.object({AZURE_OPENAI_API_KEY:m.string().min(1),AZURE_OPENAI_ENDPOINT:m.string().url(),AZURE_OPENAI_DEPLOYMENT:m.string().min(1),AZURE_OPENAI_API_VERSION:m.string().default("2024-10-21")}),wn=m.object({AWS_ACCESS_KEY_ID:m.string().min(1),AWS_SECRET_ACCESS_KEY:m.string().min(1),AWS_SESSION_TOKEN:m.string().optional(),AWS_REGION:m.string().default("us-east-1"),BEDROCK_MODEL:m.string().default("anthropic.claude-sonnet-4-20250514-v1:0")}),vn=m.object({DEEPSEEK_API_KEY:m.string().min(1),DEEPSEEK_MODEL:m.string().default("deepseek-chat")}),An=m.object({GROQ_API_KEY:m.string().min(1),GROQ_MODEL:m.string().default("llama-3.3-70b-versatile")}),Rn=m.object({TOGETHER_API_KEY:m.string().min(1),TOGETHER_MODEL:m.string().default("meta-llama/Llama-3.3-70B-Instruct-Turbo")}),In=m.object({QWEN_API_KEY:m.string().min(1),QWEN_BASE_URL:m.string().url().default("https://dashscope-intl.aliyuncs.com/compatible-mode/v1"),QWEN_MODEL:m.string().default("qwen-max")}),jn=m.object({PERPLEXITY_API_KEY:m.string().min(1),PERPLEXITY_MODEL:m.string().default("sonar-pro")}),Cn=m.object({OLLAMA_BASE_URL:m.string().url().default("http://localhost:11434"),OLLAMA_MODEL:m.string().default("llama3.3")}),Tn=m.object({CUSTOM_API_KEY:m.string().min(1),CUSTOM_BASE_URL:m.string().url(),CUSTOM_MODEL:m.string().min(1)}),Pn={anthropic:bn,openai:Sn,google:yn,"azure-openai":En,bedrock:wn,deepseek:vn,groq:An,together:Rn,qwen:In,perplexity:jn,ollama:Cn,custom:Tn},W=null;function Ke(){if(W!==null)return W;let e=xn.safeParse(process.env);if(!e.success){let a=e.error.issues.map(p=>` \u2022 ${p.path.join(".")}: ${p.message}`).join(`
53
- `);throw new C(`Missing or invalid environment variables:
44
+ `}import j from"path";import $ from"fs-extra";import{z as s}from"zod";var Z=s.enum(["pending","running","passed","failed","skipped"]),Bt=s.object({method:s.string(),url:s.string(),headers:s.record(s.string()).optional(),body:s.string().optional()}).optional(),Wt=s.object({status:s.number(),statusText:s.string(),headers:s.record(s.string()).optional(),body:s.string().optional(),duration:s.number()}).optional(),A=s.number().nullish().transform(e=>e??void 0),ze=s.object({id:s.string(),title:s.string(),passed:s.boolean(),partial:s.boolean().optional(),na:s.boolean().optional()}),Jt=s.object({url:s.string(),stepIndex:s.number().int(),stepInstruction:s.string(),score:A,a11yScore:A,seoScore:A,fcp:A,lcp:A,cls:A,ttfb:A,tbt:A,si:A,tti:A,inp:A,a11yAudits:s.array(ze).optional(),seoAudits:s.array(ze).optional(),lighthouseError:s.string().optional()}),Kt=s.object({stepId:s.string(),instruction:s.string(),status:Z,code:s.string(),error:s.string().optional(),duration:s.number(),screenshotPath:s.string().optional(),healed:s.boolean().optional(),healedCode:s.string().optional(),stepType:s.enum(["ui","api","mock"]).optional(),apiRequest:Bt,apiResponse:Wt,navigatedToUrl:s.string().optional(),auditUrl:s.string().optional()}),Yt=s.object({caseId:s.string(),caseName:s.string(),status:Z,steps:s.array(Kt),duration:s.number(),browser:s.string(),device:s.string().optional(),startedAt:s.string().datetime(),finishedAt:s.string().datetime(),videoPath:s.string().optional(),tracePath:s.string().optional(),downloadPaths:s.array(s.string()).default([]),dataRowIndex:s.number().int().optional(),dataRow:s.record(s.string()).optional(),pageLoads:s.array(Jt).default([])}),qt=s.object({suiteId:s.string(),suiteName:s.string(),suiteType:s.enum(["ui","api","audit","performance"]).optional(),status:Z,cases:s.array(Yt),duration:s.number(),browser:s.string(),startedAt:s.string().datetime(),finishedAt:s.string().datetime()}),ye=s.object({runId:s.string(),status:Z,environment:s.string().optional(),suites:s.array(qt),duration:s.number(),startedAt:s.string().datetime(),finishedAt:s.string().datetime(),totalTests:s.number().int(),passed:s.number().int(),failed:s.number().int(),skipped:s.number().int(),logFilePath:s.string().optional()});var Ee=S("result-store"),O="results",Ue="runs";function we(e,t){return j.join(e,Ue,`${t}.json`)}async function Xt(e,t){let n=ye.safeParse(t);if(!n.success){let i=n.error.issues.map(a=>` \u2022 ${a.path.join(".")}: ${a.message}`).join(`
45
+ `);throw new p(`Cannot write invalid run result:
46
+ ${i}`,"result","INVALID_RESULT")}let r=we(j.join(e,O),t.runId);await x(r,n.data),Ee.info({runId:t.runId,status:t.status},"Run result saved")}async function ke(e,t){let n=we(j.join(e,O),t);if(!await $.pathExists(n))throw new g(`Run result not found for runId "${t}".`,n,"RESULT_NOT_FOUND");let r=await y(n),i=ye.safeParse(r);if(!i.success){let a=i.error.issues.map(m=>` \u2022 ${m.path.join(".")}: ${m.message}`).join(`
47
+ `);throw new p(`Invalid run result at "${n}":
48
+ ${a}`,"result","INVALID_RESULT")}return i.data}async function Ge(e){let t=j.join(e,O,Ue);if(!await $.pathExists(t))return[];let r=(await $.readdir(t,{withFileTypes:!0})).filter(a=>a.isFile()&&a.name.endsWith(".json")).map(a=>a.name.replace(".json",""));return(await Promise.all(r.map(async a=>{let m=await $.stat(j.join(t,`${a}.json`));return{id:a,mtime:m.mtimeMs}}))).sort((a,m)=>m.mtime-a.mtime).map(a=>a.id)}async function Zt(e,t=20){let n=await Ge(e),r=[];for(let i of n.slice(0,t))try{let a=await ke(e,i);r.push({runId:a.runId,status:a.status,environment:a.environment,startedAt:a.startedAt,finishedAt:a.finishedAt,totalTests:a.totalTests,passed:a.passed,failed:a.failed,skipped:a.skipped,duration:a.duration,suiteIds:a.suites.map(m=>m.suiteId)})}catch(a){Ee.warn({runId:i,err:a},"Failed to read run result \u2014 skipping")}return r}async function Qt(e,t){let n=we(j.join(e,O),t);if(!await $.pathExists(n))throw new g(`Run result not found for runId "${t}".`,n,"RESULT_NOT_FOUND");await $.remove(n),Ee.info({runId:t},"Run result deleted")}function en(e){return j.join(e,O,"screenshots")}function tn(e){return j.join(e,O,"videos")}function nn(e){return j.join(e,O,"traces")}import w from"path";import V from"fs-extra";import{z as d}from"zod";var rn=d.enum(["pending","accepted","rejected"]),an=d.enum(["retry","regenerate","multi-selector","visual","decompose","manual"]),Q=d.object({id:d.string(),runId:d.string(),suiteId:d.string(),caseId:d.string(),stepId:d.string(),stepInstruction:d.string(),failedCode:d.string(),healedCode:d.string(),error:d.string(),strategy:an,level:d.number().int().min(1).max(6),status:rn,pageUrl:d.string(),timestamp:d.string().datetime(),acceptedAt:d.string().datetime().optional(),rejectedAt:d.string().datetime().optional()}),ve=d.object({runId:d.string(),generatedAt:d.string().datetime(),totalHeals:d.number().int(),accepted:d.number().int(),rejected:d.number().int(),pending:d.number().int(),events:d.array(Q)});var M=S("healing-store"),P=w.join("results","healing"),on="pending.json",ee="healing-report-";function We(e,t){return w.join(e,`${ee}${t}.json`)}function B(e){return w.join(e,on)}async function sn(e,t){let n=ve.safeParse(t);if(!n.success){let a=n.error.issues.map(m=>` \u2022 ${m.path.join(".")}: ${m.message}`).join(`
49
+ `);throw new p(`Cannot write invalid healing report:
50
+ ${a}`,"healingReport","INVALID_HEALING_REPORT")}let r=w.join(e,P),i=We(r,t.runId);await x(i,n.data),M.info({runId:t.runId,totalHeals:t.totalHeals},"Healing report saved")}async function cn(e,t){let n=w.join(e,P),r=We(n,t);if(!await V.pathExists(r))throw new g(`Healing report not found for runId "${t}".`,r,"HEALING_REPORT_NOT_FOUND");let i=await y(r),a=ve.safeParse(i);if(!a.success){let m=a.error.issues.map(b=>` \u2022 ${b.path.join(".")}: ${b.message}`).join(`
51
+ `);throw new p(`Invalid healing report at "${r}":
52
+ ${m}`,"healingReport","INVALID_HEALING_REPORT")}return a.data}async function L(e){let t=w.join(e,P),n=B(t);if(!await V.pathExists(n))return[];let r=await y(n),i=Q.array().safeParse(r);return i.success?i.data:(M.warn({path:n},"Pending healing file is malformed \u2014 resetting"),[])}var Me=50,Be=["pending","rejected","accepted"];function ln(e){if(e.length<=Me)return e;let t=[...e].sort((i,a)=>{let m=Be.indexOf(i.status),b=Be.indexOf(a.status);return m!==b?m-b:i.timestamp<a.timestamp?-1:1}),n=e.length-Me,r=new Set(t.slice(0,n).map(i=>i.id));return M.info({excess:n,deleted:r.size},"Auto-pruning healing events to enforce cap"),e.filter(i=>!r.has(i.id))}async function mn(e,t){let n=Q.safeParse(t);if(!n.success)throw new p(`Invalid healing event: ${n.error.message}`,"healingEvent","INVALID_HEALING_EVENT");let r=w.join(e,P);await V.ensureDir(r);let i=await L(e);i.push(n.data),await x(B(r),ln(i))}async function un(e,t){let n=await L(e),r=n.findIndex(a=>a.id===t);if(r===-1)throw new g(`Healing event "${t}" not found in pending list.`,t,"HEALING_EVENT_NOT_FOUND");n[r]={...n[r],status:"accepted",acceptedAt:new Date().toISOString()};let i=w.join(e,P);return await x(B(i),n),M.info({eventId:t},"Healing event accepted"),n[r]}async function pn(e,t){let n=await L(e),r=n.findIndex(a=>a.id===t);if(r===-1)throw new g(`Healing event "${t}" not found in pending list.`,t,"HEALING_EVENT_NOT_FOUND");n[r]={...n[r],status:"rejected",rejectedAt:new Date().toISOString()};let i=w.join(e,P);return await x(B(i),n),M.info({eventId:t},"Healing event rejected"),n[r]}async function dn(e,t=30){let n=await L(e),r=Date.now()-t*24*60*60*1e3,i=n.length,a=n.filter(m=>{if(m.status==="pending")return!0;let b=m.acceptedAt??m.rejectedAt;return b?new Date(b).getTime()>r:!0});if(a.length<i){let m=w.join(e,P);await x(B(m),a)}return i-a.length}async function gn(e){let t=await L(e),n=t.filter(a=>a.status==="pending").length,r=t.filter(a=>a.status==="accepted").length,i=t.filter(a=>a.status==="rejected").length;return{pending:n,accepted:r,rejected:i,total:t.length}}async function fn(e){let t=w.join(e,P);if(!await V.pathExists(t))return[];let r=(await V.readdir(t,{withFileTypes:!0})).filter(a=>a.isFile()&&a.name.startsWith(ee)&&a.name.endsWith(".json")).map(a=>a.name.slice(ee.length,-5));return(await Promise.all(r.map(async a=>{let m=await V.stat(w.join(t,`${ee}${a}.json`));return{id:a,mtime:m.mtimeMs}}))).sort((a,m)=>m.mtime-a.mtime).map(a=>a.id)}import{createHash as hn}from"crypto";function Je(e){return hn("sha256").update(e,"utf8").digest("hex")}function Ke(e){try{return new URL(e).pathname.split("/").map(r=>/^\d+$/.test(r)||/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i.test(r)||/^[a-z0-9-]{8,}$/i.test(r)&&/-/.test(r)?"*":r).join("/")}catch{return e}}function xn(e,t){let n=e.toLowerCase().replace(/\s+/g," ").trim(),r=Ke(t);return Je(`${n}|${r}`).slice(0,16)}import{config as bn}from"dotenv";import{z as u}from"zod";bn();var Ye=["anthropic","openai","google","azure-openai","bedrock","deepseek","groq","together","qwen","perplexity","ollama","custom"],Sn=u.object({NODE_ENV:u.enum(["development","production","test"]).default("development"),LOG_LEVEL:u.enum(["trace","debug","info","warn","error","fatal"]).default("info"),AI_PROVIDER:u.enum(Ye),AI_TIERED_ENABLED:u.string().transform(e=>e==="true").default("false"),AI_TIERED_FAST_PROVIDER:u.enum(Ye).optional(),AI_TIERED_FAST_MODEL:u.string().optional(),AI_TIMEOUT:u.coerce.number().int().positive().default(30),AI_MAX_RETRIES:u.coerce.number().int().min(0).max(10).default(2)}),yn=u.object({ANTHROPIC_API_KEY:u.string().min(1),ANTHROPIC_MODEL:u.string().default("claude-sonnet-4-20250514")}),En=u.object({OPENAI_API_KEY:u.string().min(1),OPENAI_MODEL:u.string().default("gpt-4o")}),wn=u.object({GOOGLE_API_KEY:u.string().min(1),GOOGLE_MODEL:u.string().default("gemini-2.5-pro")}),vn=u.object({AZURE_OPENAI_API_KEY:u.string().min(1),AZURE_OPENAI_ENDPOINT:u.string().url(),AZURE_OPENAI_DEPLOYMENT:u.string().min(1),AZURE_OPENAI_API_VERSION:u.string().default("2024-10-21")}),An=u.object({AWS_ACCESS_KEY_ID:u.string().min(1),AWS_SECRET_ACCESS_KEY:u.string().min(1),AWS_SESSION_TOKEN:u.string().optional(),AWS_REGION:u.string().default("us-east-1"),BEDROCK_MODEL:u.string().default("anthropic.claude-sonnet-4-20250514-v1:0")}),Rn=u.object({DEEPSEEK_API_KEY:u.string().min(1),DEEPSEEK_MODEL:u.string().default("deepseek-chat")}),In=u.object({GROQ_API_KEY:u.string().min(1),GROQ_MODEL:u.string().default("llama-3.3-70b-versatile")}),jn=u.object({TOGETHER_API_KEY:u.string().min(1),TOGETHER_MODEL:u.string().default("meta-llama/Llama-3.3-70B-Instruct-Turbo")}),Tn=u.object({QWEN_API_KEY:u.string().min(1),QWEN_BASE_URL:u.string().url().default("https://dashscope-intl.aliyuncs.com/compatible-mode/v1"),QWEN_MODEL:u.string().default("qwen-max")}),Pn=u.object({PERPLEXITY_API_KEY:u.string().min(1),PERPLEXITY_MODEL:u.string().default("sonar-pro")}),Cn=u.object({OLLAMA_BASE_URL:u.string().url().default("http://localhost:11434"),OLLAMA_MODEL:u.string().default("llama3.3")}),_n=u.object({CUSTOM_API_KEY:u.string().min(1),CUSTOM_BASE_URL:u.string().url(),CUSTOM_MODEL:u.string().min(1)}),On={anthropic:yn,openai:En,google:wn,"azure-openai":vn,bedrock:An,deepseek:Rn,groq:In,together:jn,qwen:Tn,perplexity:Pn,ollama:Cn,custom:_n},W=null;function qe(){if(W!==null)return W;let e=Sn.safeParse(process.env);if(!e.success){let a=e.error.issues.map(m=>` \u2022 ${m.path.join(".")}: ${m.message}`).join(`
53
+ `);throw new T(`Missing or invalid environment variables:
54
54
  ${a}
55
55
 
56
- How to fix: Copy .env.example to .env and fill in your AI provider credentials.`,"ENV_VALIDATION_FAILED")}let t=e.data.AI_PROVIDER,r=Pn[t].safeParse(process.env);if(!r.success){let a=r.error.issues.map(p=>` \u2022 ${p.path.join(".")}: ${p.message}`).join(`
57
- `);throw new C(`Provider "${t}" is missing required environment variables:
56
+ How to fix: Copy .env.example to .env and fill in your AI provider credentials.`,"ENV_VALIDATION_FAILED")}let t=e.data.AI_PROVIDER,r=On[t].safeParse(process.env);if(!r.success){let a=r.error.issues.map(m=>` \u2022 ${m.path.join(".")}: ${m.message}`).join(`
57
+ `);throw new T(`Provider "${t}" is missing required environment variables:
58
58
  ${a}
59
59
 
60
- How to fix: Check .env.example for the ${t} section and add the required keys to .env.`,"PROVIDER_ENV_MISSING")}return W={...e.data,...r.data},W}function _n(){W=null}function Nn(){try{return Ke()}catch{return null}}import{faker as o}from"@faker-js/faker";function On(){return[{category:"person",methods:[{name:"fullName",example:o.person.fullName()},{name:"firstName",example:o.person.firstName()},{name:"lastName",example:o.person.lastName()},{name:"middleName",example:o.person.middleName()},{name:"sex",example:o.person.sex()},{name:"prefix",example:o.person.prefix()},{name:"suffix",example:o.person.suffix()},{name:"jobTitle",example:o.person.jobTitle()},{name:"jobArea",example:o.person.jobArea()},{name:"jobType",example:o.person.jobType()},{name:"bio",example:o.person.bio()}]},{category:"internet",methods:[{name:"email",example:o.internet.email()},{name:"userName",example:o.internet.username()},{name:"password",example:o.internet.password()},{name:"url",example:o.internet.url()},{name:"domainName",example:o.internet.domainName()},{name:"domainWord",example:o.internet.domainWord()},{name:"ip",example:o.internet.ip()},{name:"ipv6",example:o.internet.ipv6()},{name:"mac",example:o.internet.mac()},{name:"userAgent",example:o.internet.userAgent()},{name:"emoji",example:o.internet.emoji()}]},{category:"phone",methods:[{name:"number",example:o.phone.number()},{name:"imei",example:o.phone.imei()}]},{category:"location",methods:[{name:"streetAddress",example:o.location.streetAddress()},{name:"street",example:o.location.street()},{name:"city",example:o.location.city()},{name:"state",example:o.location.state()},{name:"zipCode",example:o.location.zipCode()},{name:"country",example:o.location.country()},{name:"countryCode",example:o.location.countryCode()},{name:"county",example:o.location.county()},{name:"latitude",example:String(o.location.latitude())},{name:"longitude",example:String(o.location.longitude())},{name:"timeZone",example:o.location.timeZone()},{name:"buildingNumber",example:o.location.buildingNumber()}]},{category:"company",methods:[{name:"name",example:o.company.name()},{name:"catchPhrase",example:o.company.catchPhrase()},{name:"buzzPhrase",example:o.company.buzzPhrase()},{name:"buzzNoun",example:o.company.buzzNoun()},{name:"buzzVerb",example:o.company.buzzVerb()},{name:"buzzAdjective",example:o.company.buzzAdjective()}]},{category:"finance",methods:[{name:"accountNumber",example:o.finance.accountNumber()},{name:"accountName",example:o.finance.accountName()},{name:"creditCardNumber",example:o.finance.creditCardNumber()},{name:"creditCardCVV",example:o.finance.creditCardCVV()},{name:"currencyCode",example:o.finance.currencyCode()},{name:"currencyName",example:o.finance.currencyName()},{name:"amount",example:o.finance.amount()},{name:"iban",example:o.finance.iban()},{name:"bic",example:o.finance.bic()},{name:"bitcoinAddress",example:o.finance.bitcoinAddress()},{name:"transactionType",example:o.finance.transactionType()}]},{category:"date",methods:[{name:"past",example:o.date.past().toISOString()},{name:"future",example:o.date.future().toISOString()},{name:"recent",example:o.date.recent().toISOString()},{name:"soon",example:o.date.soon().toISOString()},{name:"birthdate",example:o.date.birthdate().toISOString()},{name:"month",example:o.date.month()},{name:"weekday",example:o.date.weekday()}]},{category:"lorem",methods:[{name:"word",example:o.lorem.word()},{name:"words",example:o.lorem.words()},{name:"sentence",example:o.lorem.sentence()},{name:"sentences",example:o.lorem.sentences()},{name:"paragraph",example:o.lorem.paragraph()},{name:"slug",example:o.lorem.slug()},{name:"lines",example:o.lorem.lines(1)}]},{category:"string",methods:[{name:"uuid",example:o.string.uuid()},{name:"alphanumeric",example:o.string.alphanumeric(10)},{name:"numeric",example:o.string.numeric(6)},{name:"alpha",example:o.string.alpha(8)},{name:"nanoid",example:o.string.nanoid()},{name:"hexadecimal",example:o.string.hexadecimal({length:8})},{name:"sample",example:o.string.sample(12)}]},{category:"number",methods:[{name:"int",example:String(o.number.int({max:9999}))},{name:"float",example:String(o.number.float({max:100,fractionDigits:2}))}]},{category:"datatype",methods:[{name:"boolean",example:String(o.datatype.boolean())}]},{category:"image",methods:[{name:"avatar",example:o.image.avatar()},{name:"url",example:o.image.url()}]},{category:"color",methods:[{name:"human",example:o.color.human()},{name:"rgb",example:o.color.rgb()},{name:"hex",example:o.color.rgb({format:"hex"})}]},{category:"commerce",methods:[{name:"productName",example:o.commerce.productName()},{name:"price",example:o.commerce.price()},{name:"department",example:o.commerce.department()},{name:"productDescription",example:o.commerce.productDescription().slice(0,60)+"..."},{name:"isbn",example:o.commerce.isbn()}]},{category:"vehicle",methods:[{name:"vehicle",example:o.vehicle.vehicle()},{name:"manufacturer",example:o.vehicle.manufacturer()},{name:"model",example:o.vehicle.model()},{name:"vin",example:o.vehicle.vin()},{name:"vrm",example:o.vehicle.vrm()}]},{category:"system",methods:[{name:"fileName",example:o.system.fileName()},{name:"mimeType",example:o.system.mimeType()},{name:"fileExt",example:o.system.fileExt()},{name:"filePath",example:o.system.filePath()},{name:"semver",example:o.system.semver()}]}]}var $n={"internet.userName":"username"};function Ln(e,t){let n=o[e],r=$n[`${e}.${t}`]??t;if(!n||typeof n[r]!="function")return`[unknown: ${e}.${t}]`;let i=n[r]();return i instanceof Date?i.toISOString():String(i)}function zi(e){let t={...J,...e},n=D.safeParse(t);if(!n.success){let r=n.error.issues.map(i=>` \u2022 ${i.path.join(".")}: ${i.message}`).join(`
60
+ How to fix: Check .env.example for the ${t} section and add the required keys to .env.`,"PROVIDER_ENV_MISSING")}return W={...e.data,...r.data},W}function Nn(){W=null}function $n(){try{return qe()}catch{return null}}import{faker as o}from"@faker-js/faker";function Vn(){return[{category:"person",methods:[{name:"fullName",example:o.person.fullName()},{name:"firstName",example:o.person.firstName()},{name:"lastName",example:o.person.lastName()},{name:"middleName",example:o.person.middleName()},{name:"sex",example:o.person.sex()},{name:"prefix",example:o.person.prefix()},{name:"suffix",example:o.person.suffix()},{name:"jobTitle",example:o.person.jobTitle()},{name:"jobArea",example:o.person.jobArea()},{name:"jobType",example:o.person.jobType()},{name:"bio",example:o.person.bio()}]},{category:"internet",methods:[{name:"email",example:o.internet.email()},{name:"userName",example:o.internet.username()},{name:"password",example:o.internet.password()},{name:"url",example:o.internet.url()},{name:"domainName",example:o.internet.domainName()},{name:"domainWord",example:o.internet.domainWord()},{name:"ip",example:o.internet.ip()},{name:"ipv6",example:o.internet.ipv6()},{name:"mac",example:o.internet.mac()},{name:"userAgent",example:o.internet.userAgent()},{name:"emoji",example:o.internet.emoji()}]},{category:"phone",methods:[{name:"number",example:o.phone.number()},{name:"imei",example:o.phone.imei()}]},{category:"location",methods:[{name:"streetAddress",example:o.location.streetAddress()},{name:"street",example:o.location.street()},{name:"city",example:o.location.city()},{name:"state",example:o.location.state()},{name:"zipCode",example:o.location.zipCode()},{name:"country",example:o.location.country()},{name:"countryCode",example:o.location.countryCode()},{name:"county",example:o.location.county()},{name:"latitude",example:String(o.location.latitude())},{name:"longitude",example:String(o.location.longitude())},{name:"timeZone",example:o.location.timeZone()},{name:"buildingNumber",example:o.location.buildingNumber()}]},{category:"company",methods:[{name:"name",example:o.company.name()},{name:"catchPhrase",example:o.company.catchPhrase()},{name:"buzzPhrase",example:o.company.buzzPhrase()},{name:"buzzNoun",example:o.company.buzzNoun()},{name:"buzzVerb",example:o.company.buzzVerb()},{name:"buzzAdjective",example:o.company.buzzAdjective()}]},{category:"finance",methods:[{name:"accountNumber",example:o.finance.accountNumber()},{name:"accountName",example:o.finance.accountName()},{name:"creditCardNumber",example:o.finance.creditCardNumber()},{name:"creditCardCVV",example:o.finance.creditCardCVV()},{name:"currencyCode",example:o.finance.currencyCode()},{name:"currencyName",example:o.finance.currencyName()},{name:"amount",example:o.finance.amount()},{name:"iban",example:o.finance.iban()},{name:"bic",example:o.finance.bic()},{name:"bitcoinAddress",example:o.finance.bitcoinAddress()},{name:"transactionType",example:o.finance.transactionType()}]},{category:"date",methods:[{name:"past",example:o.date.past().toISOString()},{name:"future",example:o.date.future().toISOString()},{name:"recent",example:o.date.recent().toISOString()},{name:"soon",example:o.date.soon().toISOString()},{name:"birthdate",example:o.date.birthdate().toISOString()},{name:"month",example:o.date.month()},{name:"weekday",example:o.date.weekday()}]},{category:"lorem",methods:[{name:"word",example:o.lorem.word()},{name:"words",example:o.lorem.words()},{name:"sentence",example:o.lorem.sentence()},{name:"sentences",example:o.lorem.sentences()},{name:"paragraph",example:o.lorem.paragraph()},{name:"slug",example:o.lorem.slug()},{name:"lines",example:o.lorem.lines(1)}]},{category:"string",methods:[{name:"uuid",example:o.string.uuid()},{name:"alphanumeric",example:o.string.alphanumeric(10)},{name:"numeric",example:o.string.numeric(6)},{name:"alpha",example:o.string.alpha(8)},{name:"nanoid",example:o.string.nanoid()},{name:"hexadecimal",example:o.string.hexadecimal({length:8})},{name:"sample",example:o.string.sample(12)}]},{category:"number",methods:[{name:"int",example:String(o.number.int({max:9999}))},{name:"float",example:String(o.number.float({max:100,fractionDigits:2}))}]},{category:"datatype",methods:[{name:"boolean",example:String(o.datatype.boolean())}]},{category:"image",methods:[{name:"avatar",example:o.image.avatar()},{name:"url",example:o.image.url()}]},{category:"color",methods:[{name:"human",example:o.color.human()},{name:"rgb",example:o.color.rgb()},{name:"hex",example:o.color.rgb({format:"hex"})}]},{category:"commerce",methods:[{name:"productName",example:o.commerce.productName()},{name:"price",example:o.commerce.price()},{name:"department",example:o.commerce.department()},{name:"productDescription",example:o.commerce.productDescription().slice(0,60)+"..."},{name:"isbn",example:o.commerce.isbn()}]},{category:"vehicle",methods:[{name:"vehicle",example:o.vehicle.vehicle()},{name:"manufacturer",example:o.vehicle.manufacturer()},{name:"model",example:o.vehicle.model()},{name:"vin",example:o.vehicle.vin()},{name:"vrm",example:o.vehicle.vrm()}]},{category:"system",methods:[{name:"fileName",example:o.system.fileName()},{name:"mimeType",example:o.system.mimeType()},{name:"fileExt",example:o.system.fileExt()},{name:"filePath",example:o.system.filePath()},{name:"semver",example:o.system.semver()}]}]}var Ln={"internet.userName":"username"};function Dn(e,t){let n=o[e],r=Ln[`${e}.${t}`]??t;if(!n||typeof n[r]!="function")return`[unknown: ${e}.${t}]`;let i=n[r]();return i instanceof Date?i.toISOString():String(i)}function ki(e){let t={...J,...e},n=D.safeParse(t);if(!n.success){let r=n.error.issues.map(i=>` \u2022 ${i.path.join(".")}: ${i.message}`).join(`
61
61
  `);throw new Error(`Invalid assuremind config:
62
- ${r}`)}return n.data}export{v as AssuremindError,C as ConfigError,ie as ExecutionError,ae as HealingError,re as ProviderError,g as StorageError,u as ValidationError,ln as acceptHealingEvent,cn as appendPendingEvent,Ln as callFaker,_n as clearEnvCache,zt as configExists,Rt as createCase,S as createChildLogger,St as createSuite,zi as defineConfig,jt as deleteCase,Dt as deleteGlobalVariable,Xt as deleteResult,Et as deleteSuite,st as formatError,fn as generateCacheKey,On as getAvailableGenerators,Tt as getCasePath,un as getHealingStats,ot as isAssuremindError,Ne as listCasePaths,Ct as listCases,dn as listHealingReportIds,Ue as listResultIds,qt as listResults,se as listSuiteDirs,wt as listSuites,vt as listSuitesWithCounts,Ht as listVariableFiles,Ce as logger,We as normalizeUrl,pn as pruneResolvedEvents,me as readCase,be as readConfig,Le as readEnvVariables,$e as readGlobalVariables,on as readHealingReport,V as readPendingEvents,ze as readResult,Y as readSuite,k as readVariables,xt as redactSecrets,mn as rejectHealingEvent,Lt as resolveVariables,ht as sanitizeGeneratedCode,Zt as screenshotsDir,Vt as setGlobalVariable,Be as sha256,O as toSlug,en as tracesDir,Nn as tryGetEnv,It as updateCase,Ft as updateConfig,yt as updateSuite,Ut as validateConfig,Ke as validateEnv,Qt as videosDir,pe as writeCase,De as writeConfig,an as writeHealingReport,Yt as writeResult,oe as writeSuite,ge as writeVariables};
62
+ ${r}`)}return n.data}export{v as AssuremindError,T as ConfigError,ae as ExecutionError,oe as HealingError,ie as ProviderError,g as StorageError,p as ValidationError,un as acceptHealingEvent,mn as appendPendingEvent,Dn as callFaker,Nn as clearEnvCache,kt as configExists,jt as createCase,S as createChildLogger,Et as createSuite,ki as defineConfig,Pt as deleteCase,Ft as deleteGlobalVariable,Qt as deleteResult,vt as deleteSuite,lt as formatError,xn as generateCacheKey,Vn as getAvailableGenerators,_t as getCasePath,gn as getHealingStats,ct as isAssuremindError,$e as listCasePaths,Ct as listCases,fn as listHealingReportIds,Ge as listResultIds,Zt as listResults,ce as listSuiteDirs,At as listSuites,Rt as listSuitesWithCounts,zt as listVariableFiles,Ce as logger,Ke as normalizeUrl,dn as pruneResolvedEvents,ue as readCase,Se as readConfig,De as readEnvVariables,Le as readGlobalVariables,cn as readHealingReport,L as readPendingEvents,ke as readResult,Y as readSuite,k as readVariables,St as redactSecrets,pn as rejectHealingEvent,Dt as resolveVariables,bt as sanitizeGeneratedCode,en as screenshotsDir,Ht as setGlobalVariable,Je as sha256,N as toSlug,nn as tracesDir,$n as tryGetEnv,Tt as updateCase,Ut as updateConfig,wt as updateSuite,Gt as validateConfig,qe as validateEnv,tn as videosDir,pe as writeCase,Fe as writeConfig,sn as writeHealingReport,Xt as writeResult,se as writeSuite,fe as writeVariables};