assuremind 1.5.3 → 1.6.1

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 Bt=Object.create;var X=Object.defineProperty;var Wt=Object.getOwnPropertyDescriptor;var Jt=Object.getOwnPropertyNames;var Kt=Object.getPrototypeOf,Yt=Object.prototype.hasOwnProperty;var Xt=(e,t)=>{for(var n in t)X(e,n,{get:t[n],enumerable:!0})},De=(e,t,n,r)=>{if(t&&typeof t=="object"||typeof t=="function")for(let i of Jt(t))!Yt.call(e,i)&&i!==n&&X(e,i,{get:()=>t[i],enumerable:!(r=Wt(t,i))||r.enumerable});return e};var h=(e,t,n)=>(n=e!=null?Bt(Kt(e)):{},De(t||!e||!e.__esModule?X(n,"default",{value:e,enumerable:!0}):n,e)),qt=e=>De(X({},"__esModule",{value:!0}),e);var qn={};Xt(qn,{AssuremindError:()=>v,ConfigError:()=>T,ExecutionError:()=>Q,HealingError:()=>ee,ProviderError:()=>Z,StorageError:()=>g,ValidationError:()=>p,acceptHealingEvent:()=>Ot,appendPendingEvent:()=>_t,callFaker:()=>Mt,clearEnvCache:()=>Ut,configExists:()=>ft,createCase:()=>nt,createChildLogger:()=>b,createSuite:()=>Xe,defineConfig:()=>Xn,deleteCase:()=>it,deleteGlobalVariable:()=>ut,deleteResult:()=>wt,deleteSuite:()=>Ze,formatError:()=>Ge,generateCacheKey:()=>Ht,getAvailableGenerators:()=>Gt,getCasePath:()=>ot,getHealingStats:()=>Vt,isAssuremindError:()=>ke,listCasePaths:()=>ve,listCases:()=>at,listHealingReportIds:()=>Lt,listResultIds:()=>de,listResults:()=>Et,listSuiteDirs:()=>re,listSuites:()=>Qe,listSuitesWithCounts:()=>et,listVariableFiles:()=>pt,logger:()=>ye,normalizeUrl:()=>Ve,pruneResolvedEvents:()=>$t,readCase:()=>oe,readConfig:()=>me,readEnvVariables:()=>je,readGlobalVariables:()=>Ie,readHealingReport:()=>Ct,readPendingEvents:()=>L,readResult:()=>Oe,readSuite:()=>G,readVariables:()=>H,redactSecrets:()=>Je,rejectHealingEvent:()=>Nt,resolveVariables:()=>lt,sanitizeGeneratedCode:()=>We,screenshotsDir:()=>vt,setGlobalVariable:()=>mt,sha256:()=>$e,toSlug:()=>$,tracesDir:()=>Rt,tryGetEnv:()=>kt,updateCase:()=>rt,updateConfig:()=>gt,updateSuite:()=>qe,validateConfig:()=>ht,validateEnv:()=>Le,videosDir:()=>At,writeCase:()=>se,writeConfig:()=>Ce,writeHealingReport:()=>Pt,writeResult:()=>yt,writeSuite:()=>ne,writeVariables:()=>ce});module.exports=qt(qn);var c=require("zod"),Zt=c.z.enum(["off","on","only-on-failure"]),Qt=c.z.enum(["off","on","on-first-retry","retain-on-failure"]),en=c.z.enum(["off","on","on-first-retry","retain-on-failure"]),He=c.z.enum(["chromium","firefox","webkit"]),tn=c.z.enum(["commit","domcontentloaded","load","networkidle"]),Fe=c.z.string().min(1),ze=["DEV","TEST","STAGE","INT","PROD"],nn=c.z.record(c.z.string(),c.z.string()).default({}),rn=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)}),an=c.z.object({allure:c.z.boolean(),html:c.z.boolean(),json:c.z.boolean()}),on=c.z.object({width:c.z.number().int().positive(),height:c.z.number().int().positive()}),sn=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:nn.default({DEV:"",TEST:"",STAGE:"",INT:"",PROD:""}),browsers:c.z.array(He).min(1),headless:c.z.boolean(),viewport:on.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:tn.default("domcontentloaded"),screenshot:Zt,video:Qt,trace:en,healing:rn,reporting:an,studioPort:c.z.number().int().min(1024).max(65535),profiles:c.z.array(sn).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")),j=h(require("fs-extra")),Ye=require("uuid");var m=require("zod"),U=m.z.object({id:m.z.string().min(1),order:m.z.number().int().positive(),instruction:m.z.string().min(1),generatedCode:m.z.string(),strategy:m.z.enum(["template","cache","rag","batch","fast","primary","recorder"]),stepType:m.z.enum(["ui","api","mock"]).default("ui"),lastHealed:m.z.string().nullable(),timeout:m.z.number().int().positive().optional(),retries:m.z.number().int().min(0).optional(),mockUrl:m.z.string().optional(),mockResponse:m.z.string().optional(),mockStatus:m.z.number().int().optional(),runAudit:m.z.boolean().optional(),soft:m.z.boolean().optional(),visualCheck:m.z.boolean().optional()}),cn=m.z.object({type:m.z.enum(["inline","json-file","csv-file"]),path:m.z.string().optional(),data:m.z.array(m.z.record(m.z.string())).optional()}).optional(),Ue=m.z.object({id:m.z.string(),instruction:m.z.string(),generatedCode:m.z.string().default(""),order:m.z.number().int().default(0)}),ln=m.z.object({before:m.z.array(Ue).default([]),after:m.z.array(Ue).default([])}).default({before:[],after:[]}),xe=m.z.object({id:m.z.string().min(1),name:m.z.string().min(1),description:m.z.string(),tags:m.z.array(m.z.string()),priority:m.z.enum(["critical","high","medium","low"]),timeout:m.z.number().int().positive().optional(),dataSource:cn,steps:m.z.array(U),caseHooks:ln,lighthouseCategories:m.z.array(m.z.enum(["performance","accessibility","seo"])).default(["performance","accessibility","seo"]),createdAt:m.z.string().datetime(),updatedAt:m.z.string().datetime()}),be=m.z.object({id:m.z.string().min(1),name:m.z.string().min(1),description:m.z.string(),tags:m.z.array(m.z.string()),type:m.z.enum(["ui","api","audit","performance"]).default("ui"),timeout:m.z.number().int().positive().optional(),createdAt:m.z.string().datetime(),updatedAt:m.z.string().datetime()}),tr=m.z.enum(["before_all","before_each","after_each","after_all"]),nr=m.z.object({before_all:m.z.array(U).default([]),before_each:m.z.array(U).default([]),after_each:m.z.array(U).default([]),after_all:m.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)}},Z=class extends v{provider;constructor(t,n,r="PROVIDER_ERROR"){super(t,r),this.name="ProviderError",this.provider=n}},Q=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}},ee=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 Se=h(require("pino")),mn=h(require("fs-extra"));var un=process.env.NODE_ENV!=="production",Me=un?{target:"pino-pretty",options:{colorize:!0,translateTime:"HH:MM:ss",ignore:"pid,hostname",messageFormat:"[assuremind] {msg}"}}:void 0,ye=(0,Se.default)({level:process.env.LOG_LEVEL??"info",base:{name:"assuremind"}},Me?Se.default.transport(Me):void 0);function b(e){return ye.child({component:e})}function pn(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 dn=[/\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 gn(e){for(let t of dn)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 fn=/\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(fn,"").trim();return t.length>0?t:e}function hn(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 xn(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 bn(e){let t=e;return t=xn(t),t=t.replace(/\.or\((?:[^()]*|\([^()]*\))*\)(?:\.(?:first|last)\(\))?/g,""),t=t.replace(/\.(?:first|last)\(\)(?=\.\w)/g,""),t=hn(t),t}function We(e){let t=pn(e);if(!t)throw new p("AI returned an empty code response. Please try regenerating.","generatedCode","EMPTY_CODE");let n=bn(t);return gn(n),n}function $(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 Ee=h(require("path")),I=h(require("fs-extra"));async function x(e,t){let n=Ee.default.dirname(e);await I.default.ensureDir(n);let r=`${e}.${process.pid}.tmp`;try{await I.default.writeJson(r,t,{spaces:2}),await I.default.rename(r,e)}catch(i){throw await I.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 I.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=Ee.default.dirname(e);await I.default.ensureDir(n);let r=`${e}.${process.pid}.tmp`;try{await I.default.writeFile(r,t,"utf8"),await I.default.rename(r,e)}catch(i){throw await I.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"),te="suite.json";async function G(e){let t=S.default.join(e,te);if(!await j.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=be.safeParse(n);if(!r.success){let a=r.error.issues.map(l=>` \u2022 ${l.path.join(".")}: ${l.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 ne(e,t){await j.default.ensureDir(e);let n=S.default.join(e,te),r=be.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 Xe(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),l=S.default.join(a,$(i.name));if(await j.default.pathExists(S.default.join(l,te)))throw new g(`Suite directory already exists at "${l}". Choose a different name or delete the existing suite first.`,l,"SUITE_ALREADY_EXISTS");return await ne(l,i),k.info({suiteId:i.id,path:l},"Suite created"),{suiteDir:l,suiteId:i.id}}async function qe(e,t){let n=await G(e),r={...n,...t,id:n.id,createdAt:n.createdAt,updatedAt:new Date().toISOString()};return await ne(e,r),r}async function Ze(e){if(!await j.default.pathExists(e))throw new g(`Suite directory not found at "${e}".`,e,"SUITE_NOT_FOUND");await j.default.remove(e),k.info({path:e},"Suite deleted")}async function re(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 j.default.pathExists(r))continue;let i=await j.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 l=S.default.join(r,a.name,te);await j.default.pathExists(l)&&t.push(S.default.join(r,a.name))}}return t}async function Qe(e){let t=await re(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 re(e),n=[];for(let r of t)try{let i=await G(r),l=(await j.default.readdir(r,{withFileTypes:!0})).filter(y=>y.isFile()&&y.name.endsWith(".test.json")).length;n.push({...i,caseCount:l})}catch(i){k.warn({path:r,err:i},"Failed to read suite \u2014 skipping")}return n}var ie=h(require("path")),D=h(require("fs-extra")),tt=require("uuid");var ae=b("case-store"),we=".test.json";async function oe(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=xe.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 se(e,t){let n=xe.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),ae.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=ie.default.join(e,`${$(r.name)}${we}`);return await se(i,r),ae.info({caseId:r.id,path:i},"Test case created"),i}async function rt(e,t){let n=await oe(e),r={...n,...t,id:n.id,createdAt:n.createdAt,updatedAt:new Date().toISOString()};return await se(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),ae.info({path:e},"Test case deleted")}async function ve(e){return await D.default.pathExists(e)?(await D.default.readdir(e,{withFileTypes:!0})).filter(n=>n.isFile()&&n.name.endsWith(we)).map(n=>ie.default.join(e,n.name)):[]}async function at(e){let t=await ve(e),n=[];for(let r of t)try{n.push(await oe(r))}catch(i){ae.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 ie.default.join(e,`${$(t)}${we}`)}var C=h(require("path")),M=h(require("fs-extra"));var P=require("zod"),Sn=P.z.object({value:P.z.string(),secret:P.z.literal(!0)}),yn=P.z.union([P.z.string(),Sn]),Ae=P.z.record(P.z.string(),yn);function En(e){return typeof e=="object"&&e.secret===!0}function st(e){return En(e)?e.value:e}var ct=b("variable-store"),B="variables",Re="global.json";function wn(e){return`${e}.env.json`}async function H(e){if(!await M.default.pathExists(e))return{};let t=await E(e),n=Ae.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 ce(e,t){let n=Ae.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),ct.debug({path:e},"Variables written")}async function Ie(e){let t=C.default.join(e,B,Re);return H(t)}async function je(e,t){let n=C.default.join(e,B,wn(t));return H(n)}async function lt(e,t){let n=await Ie(e),r=t?await je(e,t):{},i={...n,...r},a={};for(let[l,y]of Object.entries(i)){let he=process.env[`AM_${l}`];he!==void 0&&he!==""?(ct.debug({key:l},`Variable overridden by AM_${l} CI secret`),a[l]=he):a[l]=st(y)}return a}async function mt(e,t,n){let r=C.default.join(e,B,Re);await M.default.ensureDir(C.default.dirname(r));let i=await H(r);i[t]=n,await ce(r,i)}async function ut(e,t){let n=C.default.join(e,B,Re),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 ce(n,r)}async function pt(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")),le=h(require("fs-extra"));var Te=b("config-store"),Pe="autotest.config.json",dt="autotest.config.ts";async function me(e){let t=F.default.join(e,Pe);if(!await le.default.pathExists(t))return Te.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(l=>` \u2022 ${l.path.join(".")}: ${l.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 l of Object.keys(i.environmentUrls??{}))a.add(l);i.environment&&a.add(i.environment),a.size>0&&(i.environments=[...a])}return i}async function Ce(e,t){let n=z.safeParse(t);if(!n.success){let a=n.error.issues.map(l=>` \u2022 ${l.path.join(".")}: ${l.message}`).join(`
18
+ `);throw new p(`Cannot write invalid config:
19
+ ${a}`,"config","INVALID_CONFIG")}let r=F.default.join(e,Pe);await x(r,n.data);let i=F.default.join(e,dt);await Ke(i,vn(n.data)),Te.info({rootDir:e},"Config saved")}async function gt(e,t){let n=await me(e),r={...n,...t,healing:{...n.healing,...t.healing??{}},reporting:{...n.reporting,...t.reporting??{}},environmentUrls:{...n.environmentUrls,...t.environmentUrls??{}}};return await Ce(e,r),r}async function ft(e){let t=F.default.join(e,Pe),n=F.default.join(e,dt);return await le.default.pathExists(t)||await le.default.pathExists(n)}async function ht(e){let t=await me(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");Te.debug({config:t},"Config validated successfully")}function vn(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 R=h(require("path")),_=h(require("fs-extra"));var s=require("zod"),ue=s.z.enum(["pending","running","passed","failed","skipped"]),An=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(),Rn=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),xt=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()}),In=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(xt).optional(),seoAudits:s.z.array(xt).optional(),lighthouseError:s.z.string().optional()}),jn=s.z.object({stepId:s.z.string(),instruction:s.z.string(),status:ue,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:An,apiResponse:Rn,navigatedToUrl:s.z.string().optional(),auditUrl:s.z.string().optional()}),Tn=s.z.object({caseId:s.z.string(),caseName:s.z.string(),status:ue,steps:s.z.array(jn),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(In).default([])}),Pn=s.z.object({suiteId:s.z.string(),suiteName:s.z.string(),suiteType:s.z.enum(["ui","api","audit","performance"]).optional(),status:ue,cases:s.z.array(Tn),duration:s.z.number(),browser:s.z.string(),startedAt:s.z.string().datetime(),finishedAt:s.z.string().datetime()}),_e=s.z.object({runId:s.z.string(),status:ue,environment:s.z.string().optional(),suites:s.z.array(Pn),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(),healed:s.z.number().int().optional(),logFilePath:s.z.string().optional()});var W=b("result-store"),O="results",St="runs",bt=15;function pe(e,t){return R.default.join(e,St,`${t}.json`)}async function yt(e,t){let n=_e.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=pe(R.default.join(e,O),t.runId);await x(r,n.data),W.info({runId:t.runId,status:t.status},"Run result saved"),await Cn(e).catch(i=>{W.warn({err:i},"Failed to prune old run results")})}async function Cn(e){let n=(await de(e)).slice(bt);if(n.length===0)return;let r=R.default.join(e,O);for(let i of n)await _.default.remove(pe(r,i)).catch(()=>{});W.info({pruned:n.length,retained:bt},"Pruned old run results")}async function Oe(e,t){let n=pe(R.default.join(e,O),t);if(!await _.default.pathExists(n))throw new g(`Run result not found for runId "${t}".`,n,"RESULT_NOT_FOUND");let r=await E(n),i=_e.safeParse(r);if(!i.success){let a=i.error.issues.map(l=>` \u2022 ${l.path.join(".")}: ${l.message}`).join(`
47
+ `);throw new p(`Invalid run result at "${n}":
48
+ ${a}`,"result","INVALID_RESULT")}return i.data}async function de(e){let t=R.default.join(e,O,St);if(!await _.default.pathExists(t))return[];let r=(await _.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 l=await _.default.stat(R.default.join(t,`${a}.json`));return{id:a,mtime:l.mtimeMs}}))).sort((a,l)=>l.mtime-a.mtime).map(a=>a.id)}async function Et(e,t=20){let n=await de(e),r=[];for(let i of n.slice(0,t))try{let a=await Oe(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(l=>l.suiteId)})}catch(a){W.warn({runId:i,err:a},"Failed to read run result \u2014 skipping")}return r}async function wt(e,t){let n=pe(R.default.join(e,O),t);if(!await _.default.pathExists(n))throw new g(`Run result not found for runId "${t}".`,n,"RESULT_NOT_FOUND");await _.default.remove(n),W.info({runId:t},"Run result deleted")}function vt(e){return R.default.join(e,O,"screenshots")}function At(e){return R.default.join(e,O,"videos")}function Rt(e){return R.default.join(e,O,"traces")}var w=h(require("path")),V=h(require("fs-extra"));var d=require("zod"),_n=d.z.enum(["pending","accepted","rejected"]),On=d.z.enum(["retry","regenerate","multi-selector","visual","decompose","manual"]),ge=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:On,level:d.z.number().int().min(1).max(6),status:_n,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(ge)});var J=b("healing-store"),N=w.default.join("results","healing"),Nn="pending.json",fe="healing-report-";function Tt(e,t){return w.default.join(e,`${fe}${t}.json`)}function K(e){return w.default.join(e,Nn)}async function Pt(e,t){let n=Ne.safeParse(t);if(!n.success){let a=n.error.issues.map(l=>` \u2022 ${l.path.join(".")}: ${l.message}`).join(`
49
+ `);throw new p(`Cannot write invalid healing report:
50
+ ${a}`,"healingReport","INVALID_HEALING_REPORT")}let r=w.default.join(e,N),i=Tt(r,t.runId);await x(i,n.data),J.info({runId:t.runId,totalHeals:t.totalHeals},"Healing report saved")}async function Ct(e,t){let n=w.default.join(e,N),r=Tt(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 l=a.error.issues.map(y=>` \u2022 ${y.path.join(".")}: ${y.message}`).join(`
51
+ `);throw new p(`Invalid healing report at "${r}":
52
+ ${l}`,"healingReport","INVALID_HEALING_REPORT")}return a.data}async function L(e){let t=w.default.join(e,N),n=K(t);if(!await V.default.pathExists(n))return[];let r=await E(n),i=ge.array().safeParse(r);return i.success?i.data:(J.warn({path:n},"Pending healing file is malformed \u2014 resetting"),[])}var It=50,jt=["pending","rejected","accepted"];function $n(e){if(e.length<=It)return e;let t=[...e].sort((i,a)=>{let l=jt.indexOf(i.status),y=jt.indexOf(a.status);return l!==y?l-y:i.timestamp<a.timestamp?-1:1}),n=e.length-It,r=new Set(t.slice(0,n).map(i=>i.id));return J.info({excess:n,deleted:r.size},"Auto-pruning healing events to enforce cap"),e.filter(i=>!r.has(i.id))}async function _t(e,t){let n=ge.safeParse(t);if(!n.success)throw new p(`Invalid healing event: ${n.error.message}`,"healingEvent","INVALID_HEALING_EVENT");let r=w.default.join(e,N);await V.default.ensureDir(r);let i=await L(e);i.push(n.data),await x(K(r),$n(i))}async function Ot(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,N);return await x(K(i),n),J.info({eventId:t},"Healing event accepted"),n[r]}async function Nt(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,N);return await x(K(i),n),J.info({eventId:t},"Healing event rejected"),n[r]}async function $t(e,t=30){let n=await L(e),r=Date.now()-t*24*60*60*1e3,i=n.length,a=n.filter(l=>{if(l.status==="pending")return!0;let y=l.acceptedAt??l.rejectedAt;return y?new Date(y).getTime()>r:!0});if(a.length<i){let l=w.default.join(e,N);await x(K(l),a)}return i-a.length}async function Vt(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 Lt(e){let t=w.default.join(e,N);if(!await V.default.pathExists(t))return[];let r=(await V.default.readdir(t,{withFileTypes:!0})).filter(a=>a.isFile()&&a.name.startsWith(fe)&&a.name.endsWith(".json")).map(a=>a.name.slice(fe.length,-5));return(await Promise.all(r.map(async a=>{let l=await V.default.stat(w.default.join(t,`${fe}${a}.json`));return{id:a,mtime:l.mtimeMs}}))).sort((a,l)=>l.mtime-a.mtime).map(a=>a.id)}var Dt=require("crypto");function $e(e){return(0,Dt.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 Ht(e,t){let n=e.toLowerCase().replace(/\s+/g," ").trim(),r=Ve(t);return $e(`${n}|${r}`).slice(0,16)}var zt=require("dotenv"),u=require("zod");(0,zt.config)();var Ft=["anthropic","openai","google","azure-openai","bedrock","deepseek","groq","together","qwen","perplexity","ollama","custom"],Vn=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(Ft),AI_TIERED_ENABLED:u.z.string().transform(e=>e==="true").default("false"),AI_TIERED_FAST_PROVIDER:u.z.enum(Ft).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)}),Ln=u.z.object({ANTHROPIC_API_KEY:u.z.string().min(1),ANTHROPIC_MODEL:u.z.string().default("claude-sonnet-4-20250514")}),Dn=u.z.object({OPENAI_API_KEY:u.z.string().min(1),OPENAI_MODEL:u.z.string().default("gpt-4o")}),Hn=u.z.object({GOOGLE_API_KEY:u.z.string().min(1),GOOGLE_MODEL:u.z.string().default("gemini-2.5-pro")}),Fn=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")}),zn=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")}),Un=u.z.object({DEEPSEEK_API_KEY:u.z.string().min(1),DEEPSEEK_MODEL:u.z.string().default("deepseek-chat")}),kn=u.z.object({GROQ_API_KEY:u.z.string().min(1),GROQ_MODEL:u.z.string().default("llama-3.3-70b-versatile")}),Gn=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")}),Mn=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")}),Bn=u.z.object({PERPLEXITY_API_KEY:u.z.string().min(1),PERPLEXITY_MODEL:u.z.string().default("sonar-pro")}),Wn=u.z.object({OLLAMA_BASE_URL:u.z.string().url().default("http://localhost:11434"),OLLAMA_MODEL:u.z.string().default("llama3.3")}),Jn=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)}),Kn={anthropic:Ln,openai:Dn,google:Hn,"azure-openai":Fn,bedrock:zn,deepseek:Un,groq:kn,together:Gn,qwen:Mn,perplexity:Bn,ollama:Wn,custom:Jn},Y=null;function Le(){if(Y!==null)return Y;let e=Vn.safeParse(process.env);if(!e.success){let a=e.error.issues.map(l=>` \u2022 ${l.path.join(".")}: ${l.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=Kn[t].safeParse(process.env);if(!r.success){let a=r.error.issues.map(l=>` \u2022 ${l.path.join(".")}: ${l.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 Y={...e.data,...r.data},Y}function Ut(){Y=null}function kt(){try{return Le()}catch{return null}}var o=require("@faker-js/faker");function Gt(){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 Yn={"internet.userName":"username"};function Mt(e,t){let n=o.faker[e],r=Yn[`${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 Xn(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 Qe=c.enum(["off","on","only-on-failure"]),et=c.enum(["off","on","on-first-retry","retain-on-failure"]),tt=c.enum(["off","on","on-first-retry","retain-on-failure"]),Re=c.enum(["chromium","firefox","webkit"]),nt=c.enum(["commit","domcontentloaded","load","networkidle"]),Ie=c.string().min(1),je=["DEV","TEST","STAGE","INT","PROD"],rt=c.record(c.string(),c.string()).default({}),it=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)}),at=c.object({allure:c.boolean(),html:c.boolean(),json:c.boolean()}),ot=c.object({width:c.number().int().positive(),height:c.number().int().positive()}),st=c.object({name:c.string().min(1),environment:Ie,baseUrl:c.string().url(),browsers:c.array(Re).min(1),headless:c.boolean().optional()}),D=c.object({baseUrl:c.string().url(),environment:Ie.default("DEV"),environments:c.array(c.string().min(1)).default([...je]),environmentUrls:rt.default({DEV:"",TEST:"",STAGE:"",INT:"",PROD:""}),browsers:c.array(Re).min(1),headless:c.boolean(),viewport:ot.default({width:1280,height:720}),timeout:c.number().int().positive(),retries:c.number().int().min(0),parallel:c.number().int().positive(),pageLoad:nt.default("domcontentloaded"),screenshot:Qe,video:et,trace:tt,healing:it,reporting:at,studioPort:c.number().int().min(1024).max(65535),profiles:c.array(st).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})}),K={baseUrl:"http://localhost:3000",environment:"DEV",environments:[...je],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 j from"fs-extra";import{v4 as wt}from"uuid";import{z as m}from"zod";var H=m.object({id:m.string().min(1),order:m.number().int().positive(),instruction:m.string().min(1),generatedCode:m.string(),strategy:m.enum(["template","cache","rag","batch","fast","primary","recorder"]),stepType:m.enum(["ui","api","mock"]).default("ui"),lastHealed:m.string().nullable(),timeout:m.number().int().positive().optional(),retries:m.number().int().min(0).optional(),mockUrl:m.string().optional(),mockResponse:m.string().optional(),mockStatus:m.number().int().optional(),runAudit:m.boolean().optional(),soft:m.boolean().optional(),visualCheck:m.boolean().optional()}),ct=m.object({type:m.enum(["inline","json-file","csv-file"]),path:m.string().optional(),data:m.array(m.record(m.string())).optional()}).optional(),Te=m.object({id:m.string(),instruction:m.string(),generatedCode:m.string().default(""),order:m.number().int().default(0)}),lt=m.object({before:m.array(Te).default([]),after:m.array(Te).default([])}).default({before:[],after:[]}),ie=m.object({id:m.string().min(1),name:m.string().min(1),description:m.string(),tags:m.array(m.string()),priority:m.enum(["critical","high","medium","low"]),timeout:m.number().int().positive().optional(),dataSource:ct,steps:m.array(H),caseHooks:lt,lighthouseCategories:m.array(m.enum(["performance","accessibility","seo"])).default(["performance","accessibility","seo"]),createdAt:m.string().datetime(),updatedAt:m.string().datetime()}),ae=m.object({id:m.string().min(1),name:m.string().min(1),description:m.string(),tags:m.array(m.string()),type:m.enum(["ui","api","audit","performance"]).default("ui"),timeout:m.number().int().positive().optional(),createdAt:m.string().datetime(),updatedAt:m.string().datetime()}),Mn=m.enum(["before_all","before_each","after_each","after_all"]),Bn=m.object({before_all:m.array(H).default([]),before_each:m.array(H).default([]),after_each:m.array(H).default([]),after_all:m.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)}},oe=class extends v{provider;constructor(t,n,r="PROVIDER_ERROR"){super(t,r),this.name="ProviderError",this.provider=n}},se=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}},ce=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 mt(e){return e instanceof v}function ut(e){return e instanceof v?`[${e.code}] ${e.message}`:e instanceof Error?e.message:String(e)}import Pe from"pino";import Zn from"fs-extra";var pt=process.env.NODE_ENV!=="production",Ce=pt?{target:"pino-pretty",options:{colorize:!0,translateTime:"HH:MM:ss",ignore:"pid,hostname",messageFormat:"[assuremind] {msg}"}}:void 0,_e=Pe({level:process.env.LOG_LEVEL??"info",base:{name:"assuremind"}},Ce?Pe.transport(Ce):void 0);function S(e){return _e.child({component:e})}function dt(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 gt=[/\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 ft(e){for(let t of gt)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 ht=/\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 Oe(e){let t=e.replace(ht,"").trim();return t.length>0?t:e}function xt(e){let t=e;return t=t.replace(/(getBy(?:Label|Placeholder)\(\s*)(['"`])([\s\S]*?)\2/g,(n,r,i,a)=>`${r}${i}${Oe(a)}${i}`),t=t.replace(/(name:\s*)(['"`])([\s\S]*?)\2/g,(n,r,i,a)=>`${r}${i}${Oe(a)}${i}`),t}function bt(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 St(e){let t=e;return t=bt(t),t=t.replace(/\.or\((?:[^()]*|\([^()]*\))*\)(?:\.(?:first|last)\(\))?/g,""),t=t.replace(/\.(?:first|last)\(\)(?=\.\w)/g,""),t=xt(t),t}function yt(e){let t=dt(e);if(!t)throw new p("AI returned an empty code response. Please try regenerating.","generatedCode","EMPTY_CODE");let n=St(t);return ft(n),n}function $(e){return e.toLowerCase().trim().replace(/[^a-z0-9]+/g,"-").replace(/^-+|-+$/g,"")}function Et(e,t){let n=e;for(let r of t)r.length>0&&(n=n.replaceAll(r,"[REDACTED]"));return n}import Ne from"path";import I from"fs-extra";async function x(e,t){let n=Ne.dirname(e);await I.ensureDir(n);let r=`${e}.${process.pid}.tmp`;try{await I.writeJson(r,t,{spaces:2}),await I.rename(r,e)}catch(i){throw await I.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 I.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=Ne.dirname(e);await I.ensureDir(n);let r=`${e}.${process.pid}.tmp`;try{await I.writeFile(r,t,"utf8"),await I.rename(r,e)}catch(i){throw await I.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"),Y="suite.json";async function X(e){let t=E.join(e,Y);if(!await j.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=ae.safeParse(n);if(!r.success){let a=r.error.issues.map(l=>` \u2022 ${l.path.join(".")}: ${l.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 le(e,t){await j.ensureDir(e);let n=E.join(e,Y),r=ae.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 vt(e,t){let n=new Date().toISOString(),r=t.type??"ui",i={...t,type:r,id:wt(),createdAt:n,updatedAt:n},a=E.join(e,r),l=E.join(a,$(i.name));if(await j.pathExists(E.join(l,Y)))throw new g(`Suite directory already exists at "${l}". Choose a different name or delete the existing suite first.`,l,"SUITE_ALREADY_EXISTS");return await le(l,i),F.info({suiteId:i.id,path:l},"Suite created"),{suiteDir:l,suiteId:i.id}}async function At(e,t){let n=await X(e),r={...n,...t,id:n.id,createdAt:n.createdAt,updatedAt:new Date().toISOString()};return await le(e,r),r}async function Rt(e){if(!await j.pathExists(e))throw new g(`Suite directory not found at "${e}".`,e,"SUITE_NOT_FOUND");await j.remove(e),F.info({path:e},"Suite deleted")}async function me(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 j.pathExists(r))continue;let i=await j.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 l=E.join(r,a.name,Y);await j.pathExists(l)&&t.push(E.join(r,a.name))}}return t}async function It(e){let t=await me(e),n=[];for(let r of t)try{n.push(await X(r))}catch(i){F.warn({path:r,err:i},"Failed to read suite \u2014 skipping")}return n}async function jt(e){let t=await me(e),n=[];for(let r of t)try{let i=await X(r),l=(await j.readdir(r,{withFileTypes:!0})).filter(b=>b.isFile()&&b.name.endsWith(".test.json")).length;n.push({...i,caseCount:l})}catch(i){F.warn({path:r,err:i},"Failed to read suite \u2014 skipping")}return n}import ue from"path";import z from"fs-extra";import{v4 as Tt}from"uuid";var q=S("case-store"),pe=".test.json";async function de(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=ie.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 ge(e,t){let n=ie.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 Pt(e,t){let n=new Date().toISOString(),r={...t,id:Tt(),createdAt:n,updatedAt:n},i=ue.join(e,`${$(r.name)}${pe}`);return await ge(i,r),q.info({caseId:r.id,path:i},"Test case created"),i}async function Ct(e,t){let n=await de(e),r={...n,...t,id:n.id,createdAt:n.createdAt,updatedAt:new Date().toISOString()};return await ge(e,r),r}async function _t(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 Ve(e){return await z.pathExists(e)?(await z.readdir(e,{withFileTypes:!0})).filter(n=>n.isFile()&&n.name.endsWith(pe)).map(n=>ue.join(e,n.name)):[]}async function Ot(e){let t=await Ve(e),n=[];for(let r of t)try{n.push(await de(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 Nt(e,t){return ue.join(e,`${$(t)}${pe}`)}import O from"path";import Z from"fs-extra";import{z as _}from"zod";var $t=_.object({value:_.string(),secret:_.literal(!0)}),Vt=_.union([_.string(),$t]),fe=_.record(_.string(),Vt);function Lt(e){return typeof e=="object"&&e.secret===!0}function Le(e){return Lt(e)?e.value:e}var De=S("variable-store"),U="variables",he="global.json";function Dt(e){return`${e}.env.json`}async function k(e){if(!await Z.pathExists(e))return{};let t=await y(e),n=fe.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 xe(e,t){let n=fe.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),De.debug({path:e},"Variables written")}async function He(e){let t=O.join(e,U,he);return k(t)}async function Fe(e,t){let n=O.join(e,U,Dt(t));return k(n)}async function Ht(e,t){let n=await He(e),r=t?await Fe(e,t):{},i={...n,...r},a={};for(let[l,b]of Object.entries(i)){let re=process.env[`AM_${l}`];re!==void 0&&re!==""?(De.debug({key:l},`Variable overridden by AM_${l} CI secret`),a[l]=re):a[l]=Le(b)}return a}async function Ft(e,t,n){let r=O.join(e,U,he);await Z.ensureDir(O.dirname(r));let i=await k(r);i[t]=n,await xe(r,i)}async function zt(e,t){let n=O.join(e,U,he),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 xe(n,r)}async function Ut(e){let t=O.join(e,U);return await Z.pathExists(t)?(await Z.readdir(t,{withFileTypes:!0})).filter(r=>r.isFile()&&r.name.endsWith(".json")).map(r=>O.join(t,r.name)):[]}import G from"path";import be from"fs-extra";var Se=S("config-store"),ye="autotest.config.json",ze="autotest.config.ts";async function Ee(e){let t=G.join(e,ye);if(!await be.pathExists(t))return Se.debug({rootDir:e},"No autotest.config.json found \u2014 using defaults"),K;let n=await y(t),r=D.safeParse(n);if(!r.success){let a=r.error.issues.map(l=>` \u2022 ${l.path.join(".")}: ${l.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 l of Object.keys(i.environmentUrls??{}))a.add(l);i.environment&&a.add(i.environment),a.size>0&&(i.environments=[...a])}return i}async function Ue(e,t){let n=D.safeParse(t);if(!n.success){let a=n.error.issues.map(l=>` \u2022 ${l.path.join(".")}: ${l.message}`).join(`
18
+ `);throw new p(`Cannot write invalid config:
19
+ ${a}`,"config","INVALID_CONFIG")}let r=G.join(e,ye);await x(r,n.data);let i=G.join(e,ze);await $e(i,Bt(n.data)),Se.info({rootDir:e},"Config saved")}async function kt(e,t){let n=await Ee(e),r={...n,...t,healing:{...n.healing,...t.healing??{}},reporting:{...n.reporting,...t.reporting??{}},environmentUrls:{...n.environmentUrls,...t.environmentUrls??{}}};return await Ue(e,r),r}async function Gt(e){let t=G.join(e,ye),n=G.join(e,ze);return await be.pathExists(t)||await be.pathExists(n)}async function Mt(e){let t=await Ee(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");Se.debug({config:t},"Config validated successfully")}function Bt(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 R from"path";import N from"fs-extra";import{z as s}from"zod";var Q=s.enum(["pending","running","passed","failed","skipped"]),Wt=s.object({method:s.string(),url:s.string(),headers:s.record(s.string()).optional(),body:s.string().optional()}).optional(),Jt=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),ke=s.object({id:s.string(),title:s.string(),passed:s.boolean(),partial:s.boolean().optional(),na:s.boolean().optional()}),Kt=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(ke).optional(),seoAudits:s.array(ke).optional(),lighthouseError:s.string().optional()}),Yt=s.object({stepId:s.string(),instruction:s.string(),status:Q,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:Wt,apiResponse:Jt,navigatedToUrl:s.string().optional(),auditUrl:s.string().optional()}),Xt=s.object({caseId:s.string(),caseName:s.string(),status:Q,steps:s.array(Yt),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(Kt).default([])}),qt=s.object({suiteId:s.string(),suiteName:s.string(),suiteType:s.enum(["ui","api","audit","performance"]).optional(),status:Q,cases:s.array(Xt),duration:s.number(),browser:s.string(),startedAt:s.string().datetime(),finishedAt:s.string().datetime()}),we=s.object({runId:s.string(),status:Q,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(),healed:s.number().int().optional(),logFilePath:s.string().optional()});var M=S("result-store"),P="results",Me="runs",Ge=15;function ee(e,t){return R.join(e,Me,`${t}.json`)}async function Zt(e,t){let n=we.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=ee(R.join(e,P),t.runId);await x(r,n.data),M.info({runId:t.runId,status:t.status},"Run result saved"),await Qt(e).catch(i=>{M.warn({err:i},"Failed to prune old run results")})}async function Qt(e){let n=(await ve(e)).slice(Ge);if(n.length===0)return;let r=R.join(e,P);for(let i of n)await N.remove(ee(r,i)).catch(()=>{});M.info({pruned:n.length,retained:Ge},"Pruned old run results")}async function Be(e,t){let n=ee(R.join(e,P),t);if(!await N.pathExists(n))throw new g(`Run result not found for runId "${t}".`,n,"RESULT_NOT_FOUND");let r=await y(n),i=we.safeParse(r);if(!i.success){let a=i.error.issues.map(l=>` \u2022 ${l.path.join(".")}: ${l.message}`).join(`
47
+ `);throw new p(`Invalid run result at "${n}":
48
+ ${a}`,"result","INVALID_RESULT")}return i.data}async function ve(e){let t=R.join(e,P,Me);if(!await N.pathExists(t))return[];let r=(await N.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 l=await N.stat(R.join(t,`${a}.json`));return{id:a,mtime:l.mtimeMs}}))).sort((a,l)=>l.mtime-a.mtime).map(a=>a.id)}async function en(e,t=20){let n=await ve(e),r=[];for(let i of n.slice(0,t))try{let a=await Be(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(l=>l.suiteId)})}catch(a){M.warn({runId:i,err:a},"Failed to read run result \u2014 skipping")}return r}async function tn(e,t){let n=ee(R.join(e,P),t);if(!await N.pathExists(n))throw new g(`Run result not found for runId "${t}".`,n,"RESULT_NOT_FOUND");await N.remove(n),M.info({runId:t},"Run result deleted")}function nn(e){return R.join(e,P,"screenshots")}function rn(e){return R.join(e,P,"videos")}function an(e){return R.join(e,P,"traces")}import w from"path";import V from"fs-extra";import{z as d}from"zod";var on=d.enum(["pending","accepted","rejected"]),sn=d.enum(["retry","regenerate","multi-selector","visual","decompose","manual"]),te=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:sn,level:d.number().int().min(1).max(6),status:on,pageUrl:d.string(),timestamp:d.string().datetime(),acceptedAt:d.string().datetime().optional(),rejectedAt:d.string().datetime().optional()}),Ae=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(te)});var B=S("healing-store"),C=w.join("results","healing"),cn="pending.json",ne="healing-report-";function Ke(e,t){return w.join(e,`${ne}${t}.json`)}function W(e){return w.join(e,cn)}async function ln(e,t){let n=Ae.safeParse(t);if(!n.success){let a=n.error.issues.map(l=>` \u2022 ${l.path.join(".")}: ${l.message}`).join(`
49
+ `);throw new p(`Cannot write invalid healing report:
50
+ ${a}`,"healingReport","INVALID_HEALING_REPORT")}let r=w.join(e,C),i=Ke(r,t.runId);await x(i,n.data),B.info({runId:t.runId,totalHeals:t.totalHeals},"Healing report saved")}async function mn(e,t){let n=w.join(e,C),r=Ke(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=Ae.safeParse(i);if(!a.success){let l=a.error.issues.map(b=>` \u2022 ${b.path.join(".")}: ${b.message}`).join(`
51
+ `);throw new p(`Invalid healing report at "${r}":
52
+ ${l}`,"healingReport","INVALID_HEALING_REPORT")}return a.data}async function L(e){let t=w.join(e,C),n=W(t);if(!await V.pathExists(n))return[];let r=await y(n),i=te.array().safeParse(r);return i.success?i.data:(B.warn({path:n},"Pending healing file is malformed \u2014 resetting"),[])}var We=50,Je=["pending","rejected","accepted"];function un(e){if(e.length<=We)return e;let t=[...e].sort((i,a)=>{let l=Je.indexOf(i.status),b=Je.indexOf(a.status);return l!==b?l-b:i.timestamp<a.timestamp?-1:1}),n=e.length-We,r=new Set(t.slice(0,n).map(i=>i.id));return B.info({excess:n,deleted:r.size},"Auto-pruning healing events to enforce cap"),e.filter(i=>!r.has(i.id))}async function pn(e,t){let n=te.safeParse(t);if(!n.success)throw new p(`Invalid healing event: ${n.error.message}`,"healingEvent","INVALID_HEALING_EVENT");let r=w.join(e,C);await V.ensureDir(r);let i=await L(e);i.push(n.data),await x(W(r),un(i))}async function dn(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,C);return await x(W(i),n),B.info({eventId:t},"Healing event accepted"),n[r]}async function gn(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,C);return await x(W(i),n),B.info({eventId:t},"Healing event rejected"),n[r]}async function fn(e,t=30){let n=await L(e),r=Date.now()-t*24*60*60*1e3,i=n.length,a=n.filter(l=>{if(l.status==="pending")return!0;let b=l.acceptedAt??l.rejectedAt;return b?new Date(b).getTime()>r:!0});if(a.length<i){let l=w.join(e,C);await x(W(l),a)}return i-a.length}async function hn(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 xn(e){let t=w.join(e,C);if(!await V.pathExists(t))return[];let r=(await V.readdir(t,{withFileTypes:!0})).filter(a=>a.isFile()&&a.name.startsWith(ne)&&a.name.endsWith(".json")).map(a=>a.name.slice(ne.length,-5));return(await Promise.all(r.map(async a=>{let l=await V.stat(w.join(t,`${ne}${a}.json`));return{id:a,mtime:l.mtimeMs}}))).sort((a,l)=>l.mtime-a.mtime).map(a=>a.id)}import{createHash as bn}from"crypto";function Ye(e){return bn("sha256").update(e,"utf8").digest("hex")}function Xe(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 Sn(e,t){let n=e.toLowerCase().replace(/\s+/g," ").trim(),r=Xe(t);return Ye(`${n}|${r}`).slice(0,16)}import{config as yn}from"dotenv";import{z as u}from"zod";yn();var qe=["anthropic","openai","google","azure-openai","bedrock","deepseek","groq","together","qwen","perplexity","ollama","custom"],En=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(qe),AI_TIERED_ENABLED:u.string().transform(e=>e==="true").default("false"),AI_TIERED_FAST_PROVIDER:u.enum(qe).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)}),wn=u.object({ANTHROPIC_API_KEY:u.string().min(1),ANTHROPIC_MODEL:u.string().default("claude-sonnet-4-20250514")}),vn=u.object({OPENAI_API_KEY:u.string().min(1),OPENAI_MODEL:u.string().default("gpt-4o")}),An=u.object({GOOGLE_API_KEY:u.string().min(1),GOOGLE_MODEL:u.string().default("gemini-2.5-pro")}),Rn=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")}),In=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")}),jn=u.object({DEEPSEEK_API_KEY:u.string().min(1),DEEPSEEK_MODEL:u.string().default("deepseek-chat")}),Tn=u.object({GROQ_API_KEY:u.string().min(1),GROQ_MODEL:u.string().default("llama-3.3-70b-versatile")}),Pn=u.object({TOGETHER_API_KEY:u.string().min(1),TOGETHER_MODEL:u.string().default("meta-llama/Llama-3.3-70B-Instruct-Turbo")}),Cn=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")}),_n=u.object({PERPLEXITY_API_KEY:u.string().min(1),PERPLEXITY_MODEL:u.string().default("sonar-pro")}),On=u.object({OLLAMA_BASE_URL:u.string().url().default("http://localhost:11434"),OLLAMA_MODEL:u.string().default("llama3.3")}),Nn=u.object({CUSTOM_API_KEY:u.string().min(1),CUSTOM_BASE_URL:u.string().url(),CUSTOM_MODEL:u.string().min(1)}),$n={anthropic:wn,openai:vn,google:An,"azure-openai":Rn,bedrock:In,deepseek:jn,groq:Tn,together:Pn,qwen:Cn,perplexity:_n,ollama:On,custom:Nn},J=null;function Ze(){if(J!==null)return J;let e=En.safeParse(process.env);if(!e.success){let a=e.error.issues.map(l=>` \u2022 ${l.path.join(".")}: ${l.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=$n[t].safeParse(process.env);if(!r.success){let a=r.error.issues.map(l=>` \u2022 ${l.path.join(".")}: ${l.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 J={...e.data,...r.data},J}function Vn(){J=null}function Ln(){try{return Ze()}catch{return null}}import{faker as o}from"@faker-js/faker";function Dn(){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 Hn={"internet.userName":"username"};function Fn(e,t){let n=o[e],r=Hn[`${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 Mi(e){let t={...K,...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,se as ExecutionError,ce as HealingError,oe as ProviderError,g as StorageError,p as ValidationError,dn as acceptHealingEvent,pn as appendPendingEvent,Fn as callFaker,Vn as clearEnvCache,Gt as configExists,Pt as createCase,S as createChildLogger,vt as createSuite,Mi as defineConfig,_t as deleteCase,zt as deleteGlobalVariable,tn as deleteResult,Rt as deleteSuite,ut as formatError,Sn as generateCacheKey,Dn as getAvailableGenerators,Nt as getCasePath,hn as getHealingStats,mt as isAssuremindError,Ve as listCasePaths,Ot as listCases,xn as listHealingReportIds,ve as listResultIds,en as listResults,me as listSuiteDirs,It as listSuites,jt as listSuitesWithCounts,Ut as listVariableFiles,_e as logger,Xe as normalizeUrl,fn as pruneResolvedEvents,de as readCase,Ee as readConfig,Fe as readEnvVariables,He as readGlobalVariables,mn as readHealingReport,L as readPendingEvents,Be as readResult,X as readSuite,k as readVariables,Et as redactSecrets,gn as rejectHealingEvent,Ht as resolveVariables,yt as sanitizeGeneratedCode,nn as screenshotsDir,Ft as setGlobalVariable,Ye as sha256,$ as toSlug,an as tracesDir,Ln as tryGetEnv,Ct as updateCase,kt as updateConfig,At as updateSuite,Mt as validateConfig,Ze as validateEnv,rn as videosDir,ge as writeCase,Ue as writeConfig,ln as writeHealingReport,Zt as writeResult,le as writeSuite,xe as writeVariables};