@lisa.ai/agent 2.9.0 → 2.9.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/README.md CHANGED
@@ -28,11 +28,20 @@ Runs your test command, identifies every failing spec, and autonomously fixes th
28
28
 
29
29
  ```bash
30
30
  lisa-agent heal --command "npm test" --model gemini
31
+
32
+ # Heal specific files only (skip discovery)
33
+ lisa-agent heal --files src/app/todo.spec.ts,src/app/auth.spec.ts
34
+
35
+ # Heal E2E tests
36
+ lisa-agent heal --type e2e
37
+
38
+ # Heal specific E2E files
39
+ lisa-agent heal --type e2e --files e2e/login.spec.ts
31
40
  ```
32
41
 
33
42
  **How it works:**
34
- 1. Runs a single global test pass to discover all failures
35
- 2. Extracts every failing spec file (Karma suite-name matching, Jest `FAIL` header parsing)
43
+ 1. Runs a single global test pass to discover all failures (skipped with `--files`)
44
+ 2. Extracts every failing spec file (Karma suite-name matching, Jest `FAIL` header parsing, Playwright/Cypress)
36
45
  3. For each file: queries the Memory Engine for proven fix patterns, sends context + error log to the LLM, writes the fix, verifies in isolation
37
46
  4. Runs a single final global test pass to confirm all fixes together
38
47
  5. Files that regress are quarantined after 3 strikes
@@ -46,6 +55,9 @@ Runs your test suite with coverage enabled, identifies files below 100% coverage
46
55
  ```bash
47
56
  lisa-agent unit --model gemini
48
57
  lisa-agent unit --command "npx jest --coverage --coverageReporters=json-summary" --model claude
58
+
59
+ # Generate tests for specific source files only
60
+ lisa-agent unit --files src/services/auth.service.ts,src/services/user.service.ts
49
61
  ```
50
62
 
51
63
  **How it works:**
@@ -71,6 +83,9 @@ Generates Playwright end-to-end tests by discovering your app's routes and creat
71
83
 
72
84
  ```bash
73
85
  lisa-agent e2e --model gemini
86
+
87
+ # Generate E2E test for a specific spec path
88
+ lisa-agent e2e --files e2e/login.spec.ts
74
89
  ```
75
90
 
76
91
  **How it works:**
@@ -86,6 +101,9 @@ Generates integration tests that exercise module seams — testing 2+ modules to
86
101
 
87
102
  ```bash
88
103
  lisa-agent integration --model gemini
104
+
105
+ # Generate integration test for specific files
106
+ lisa-agent integration --files src/services/auth.service.ts
89
107
  ```
90
108
 
91
109
  **How it works:**
@@ -140,6 +158,8 @@ All test commands (`heal`, `unit`, `e2e`, `integration`, `audit`) accept:
140
158
  | `-c, --command <cmd>` | Test/coverage command to run | Auto-detected |
141
159
  | `-m, --model <provider>` | `gemini`, `claude`, or `openai` | `gemini` |
142
160
  | `-p, --project-id <id>` | Control Plane project for remote config + telemetry | `local` |
161
+ | `-f, --files <paths>` | Target specific files (comma-separated, bypasses discovery) | All files |
162
+ | `-t, --type <scope>` | (heal only) Test type to heal: `unit`, `e2e`, `integration` | `unit` |
143
163
 
144
164
  ## Configuration
145
165
 
@@ -252,6 +272,14 @@ lisa-agent integration --model openai
252
272
  lisa-agent audit --model gemini
253
273
  ```
254
274
 
275
+ ### Target specific files (skip discovery for large projects)
276
+ ```bash
277
+ lisa-agent heal --files src/app/todo.spec.ts,src/app/auth.spec.ts --model gemini
278
+ lisa-agent unit --files src/services/auth.service.ts --model claude
279
+ lisa-agent e2e --files e2e/login.spec.ts --model gemini
280
+ lisa-agent integration --files src/services/user.service.ts --model openai
281
+ ```
282
+
255
283
  ### Full CI/CD pipeline with Control Plane
256
284
  ```bash
257
285
  lisa-agent heal --command "npm test" --model gemini --project-id "prod-api"
package/dist/index.js CHANGED
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env node
2
- "use strict";var Et=Object.create;var Ue=Object.defineProperty;var jt=Object.getOwnPropertyDescriptor;var Ct=Object.getOwnPropertyNames;var bt=Object.getPrototypeOf,At=Object.prototype.hasOwnProperty;var Ft=(t,e)=>()=>(e||t((e={exports:{}}).exports,e),e.exports);var Pt=(t,e,s,n)=>{if(e&&typeof e=="object"||typeof e=="function")for(let i of Ct(e))!At.call(t,i)&&i!==s&&Ue(t,i,{get:()=>e[i],enumerable:!(n=jt(e,i))||n.enumerable});return t};var j=(t,e,s)=>(s=t!=null?Et(bt(t)):{},Pt(e||!t||!t.__esModule?Ue(s,"default",{value:t,enumerable:!0}):s,t));var vt=Ft((Zs,Bt)=>{Bt.exports={name:"@lisa.ai/agent",version:"2.9.0",description:"Lisa.ai Autonomous CI/CD Worker Agent",main:"dist/index.js",bin:{"lisa-agent":"dist/index.js"},files:["dist/"],scripts:{build:"tsup",typecheck:"tsc --noEmit",start:"node dist/index.js",dev:"ts-node src/index.ts",prepublishOnly:"npm run typecheck && npm run build"},keywords:["lisa","ci","cd","agent"],author:"Lisa.ai",license:"ISC",dependencies:{"@ai-sdk/anthropic":"^3.0.46","@ai-sdk/google":"^3.0.30","@ai-sdk/openai":"^3.0.30","@octokit/rest":"^22.0.1",ai:"^6.0.94",commander:"^11.1.0",dotenv:"^17.3.1","simple-git":"^3.31.1"},devDependencies:{"@types/jest":"^30.0.0","@types/node":"^20.0.0","ts-node":"^10.9.1",tsup:"^8.5.1",typescript:"^5.0.0"}}});var xt=require("commander"),Ee=j(require("fs")),$t=j(require("path")),Lt=j(require("readline"));var Oe=j(require("dotenv"));Oe.config({quiet:!0});async function ge(t){let e=process.env.LISA_CONTROL_PLANE_URL||"http://localhost:3000";try{let s=`${e}/api/config/${t}`;console.log(`[Lisa.ai Agent] Fetching dynamic configuration from ${s}...`);let n=await fetch(s);if(!n.ok){let o=n.status===404?"not_found":"unreachable";return console.warn(o==="not_found"?`[Lisa.ai Agent Warning] Control Plane returned 404. Project '${t}' not found.`:`[Lisa.ai Agent Warning] Control Plane returned ${n.status}. Falling back to local defaults.`),{ok:!1,reason:o}}return{ok:!0,config:await n.json()}}catch{return console.warn(`[Lisa.ai Agent Warning] Failed to reach Control Plane (${e}). Using local fallback configuration.`),{ok:!1,reason:"unreachable"}}}var ot=require("child_process"),_=j(require("fs")),V=j(require("path"));var S=j(require("path")),T=j(require("fs"));function fe(t){return t.replace(/\x1B\[[0-9;]*[a-zA-Z]/g,"")}function Z(t){let e=fe(t),s=[...e.matchAll(/Executed\s+(\d+)\s+of\s+(\d+)(?:\s+\((\d+)\s+FAILED\))?/g)];if(s.length>0){let u=[...s].reverse().find(m=>m[3]!==void 0)??s[s.length-1],p=parseInt(u[2]),w=u[3]?parseInt(u[3]):0,h=parseInt(u[1])-w;return{total:p,passed:h,failed:w}}let n=e.match(/Tests:\s+(?:(\d+)\s+failed,?\s*)?(?:(\d+)\s+passed,?\s*)?(\d+)\s+total/);if(n){let u=parseInt(n[3]),p=n[1]?parseInt(n[1]):0,w=n[2]?parseInt(n[2]):0;return{total:u,passed:w,failed:p}}let i=e.match(/(\d+)\s+failed/),o=e.match(/(\d+)\s+passed/);if(o||i){let u=i?parseInt(i[1]):0,p=o?parseInt(o[1]):0,w=e.match(/(\d+)\s+skipped/),h=w?parseInt(w[1]):0;return{total:p+u+h,passed:p,failed:u}}let r=e.match(/Tests\s+(?:(\d+)\s+failed\s*\|?\s*)?(\d+)\s+passed\s*\((\d+)\)/);if(r){let u=parseInt(r[3]),p=r[1]?parseInt(r[1]):0,w=parseInt(r[2]);return{total:u,passed:w,failed:p}}let a=e.match(/(\d+)\s+passing/),g=e.match(/(\d+)\s+failing/);if(a){let u=parseInt(a[1]),p=g?parseInt(g[1]):0;return{total:u+p,passed:u,failed:p}}return null}function Ce(t,e=process.cwd(),s=[]){let n=t.replace(/\x1B\[[0-9;]*[a-zA-Z]/g,""),i=s.map(l=>S.resolve(e,l)),o=new Map,r=new Set,a=/(?:Chrome|Firefox|Safari)(?:\s+Headless)?\s+[\d.]+(?:\s+[\d.]+)*\s+\([^)]+\)\s+(.+?)\s+FAILED/g,g;for(;(g=a.exec(n))!==null;){let d=g[1].trim().split(" ");for(let v=1;v<Math.min(d.length,6);v++){let k=d.slice(0,v).join(" ");if(r.has(k))continue;r.add(k);let f=be(k,e,i);if(f){let c=S.resolve(f);o.has(c)||o.set(c,S.relative(e,f));break}}}let u=/^FAIL\s+([a-zA-Z0-9_./-\\]+\.(?:spec|test)\.(ts|tsx|js|jsx))/gm,p;for(;(p=u.exec(n))!==null;){let l=p[1],d=S.isAbsolute(l)?l:S.resolve(e,l);!i.includes(d)&&T.existsSync(d)&&!o.has(d)&&o.set(d,S.relative(e,d))}let w=/\[(?:chromium|firefox|webkit)\]\s+[>›]\s+([^\s:]+\.(?:spec|test)\.[tj]sx?):\d+:\d+\s+[>›]/g,h;for(;(h=w.exec(n))!==null;){let l=h[1],d=S.isAbsolute(l)?l:S.resolve(e,l);!i.includes(d)&&T.existsSync(d)&&!o.has(d)&&o.set(d,S.relative(e,d))}let m=/Running:\s+([^\s]+\.(?:cy|spec|test)\.[tj]sx?)/g,y;for(;(y=m.exec(n))!==null;){let l=y[1],d=S.isAbsolute(l)?l:S.resolve(e,l);if(!i.includes(d)&&T.existsSync(d)&&!o.has(d)){let v=l.replace(/[.*+?^${}()|[\]\\]/g,"\\$&");new RegExp(v+"\\s+\\d+\\s+\\d+\\s+([1-9]\\d*)").test(n)&&o.set(d,S.relative(e,d))}}return[...o.values()]}function me(t,e=[],s=process.cwd()){let n=t.replace(/\x1B\[[0-9;]*[a-zA-Z]/g,""),i=e.map(l=>S.resolve(l));{let l=/(?:Chrome|Firefox|Safari)(?:\s+Headless)?\s+[\d.]+(?:\s+[\d.]+)*\s+\([^)]+\)\s+(.+?)\s+FAILED/g,d=new Set,v;for(;(v=l.exec(n))!==null;){let f=v[1].trim().split(" ");for(let c=1;c<Math.min(f.length,5);c++){let x=f.slice(0,c).join(" ");if(d.has(x))continue;d.add(x);let L=be(x,s,i);if(L)return S.relative(s,L)}}}let o=/([a-zA-Z]:[a-zA-Z0-9_.\-\/\\]+\.(?:ts|tsx|js|jsx|vue)|[a-zA-Z0-9_.\-\/\\]+\.(?:ts|tsx|js|jsx|vue))(?:\s*[:(])/g,r;for(;(r=o.exec(n))!==null;){let l=r[1];if(l){if(/(?:^|[/\\])(node_modules|dist|build)[/\\]/.test(l))continue;let d=S.isAbsolute(l)?l:S.resolve(s,l);if(!i.includes(d)&&T.existsSync(d))return l}}let a=/FAIL\s+([a-zA-Z0-9_.\-\/\\]+\.(?:ts|tsx|js|jsx|vue))/gi,g;for(;(g=a.exec(n))!==null;){let l=g[1],d=S.isAbsolute(l)?l:S.resolve(s,l);if(!i.includes(d)&&T.existsSync(d))return l}{let l=/\[(?:chromium|firefox|webkit)\]\s+[>›]\s+([^\s:]+\.(?:spec|test)\.[tj]sx?):\d+:\d+\s+[>›]/g,d;for(;(d=l.exec(n))!==null;){let v=d[1],k=S.isAbsolute(v)?v:S.resolve(s,v);if(!i.includes(k)&&T.existsSync(k))return v}}let u=/([a-zA-Z]:[a-zA-Z0-9_.\-\/\\]+\.(?:ts|tsx|js|jsx|vue)|[a-zA-Z0-9_.\-\/\\]+\.(?:ts|tsx|js|jsx|vue))/g,p;for(;(p=u.exec(n))!==null;){let l=p[1];if(l){if(/(?:^|[/\\])(node_modules|dist|build)[/\\]/.test(l))continue;let d=S.isAbsolute(l)?l:S.resolve(s,l);if(!i.includes(d)&&T.existsSync(d))return l}}let w=/\b([A-Z][a-zA-Z0-9]{3,})\b/g,h,m=new Set,y=["Error","TypeError","SyntaxError","ReferenceError","RangeError","Object","Boolean","String","Number","Array","NullInjectorError","NullInjector","R3Injector","ChainedInjector","Module","Component","Standalone","Application","App2","TestBed","UserContext","Chrome","ChromeHeadless","Karma","Launching","Starting","Headless","Connected","Executed","INFO","SUCCESS","FAILED","Building","Initial","Names","Lazy","Source","Find","NotFound","NG0201","Windows","Linux","Macintosh","Users","AppData","Local","Temp","Process","Unexpected","Expected","Validation","Directory","Configuration","Documentation"];for(;(h=w.exec(n))!==null;){let l=h[1];if(!l||y.includes(l)||m.has(l)||/^[A-Z][A-Z0-9]{5,11}$/.test(l)||/^[A-Za-z0-9]{16,}$/.test(l))continue;m.add(l);let d=_e(l,s,i);if(d)return S.relative(s,d)}return null}function be(t,e,s){if(!T.existsSync(e))return null;let n=T.readdirSync(e);for(let i of n){let o=S.join(e,i);if(["node_modules","dist","build",".git",".angular"].includes(i))continue;let r;try{r=T.statSync(o)}catch{continue}if(r.isDirectory()){let a=be(t,o,s);if(a)return a}else if(/\.(spec|test)\.(ts|tsx|js|jsx)$/.test(i)){if(s.includes(S.resolve(o)))continue;try{let a=T.readFileSync(o,"utf8");if(a.includes(`describe('${t}'`)||a.includes(`describe("${t}"`))return o}catch{continue}}}return null}function _e(t,e,s){if(!T.existsSync(e))return null;let n=T.readdirSync(e);for(let i of n){let o=S.join(e,i);if(i==="node_modules"||i==="dist"||i==="build"||i===".git"||i===".angular")continue;let r;try{r=T.statSync(o)}catch{continue}if(r.isDirectory()){let a=_e(t,o,s);if(a)return a}else if(i.match(/\.(ts|tsx|js|jsx|vue)$/)){let a=T.readFileSync(o,"utf8");if(a.includes(`class ${t}`)||a.includes(`function ${t}`)||a.includes(`const ${t}`)||a.includes(`let ${t}`)||a.includes(`exports.${t}`)||a.includes(`module.exports.${t}`)){let g=o,u=S.extname(o),p=o.slice(0,-u.length);if(!i.includes(".spec.")&&!i.includes(".test.")){let w=[`${p}.spec${u}`,`${p}.test${u}`,`${p}.spec.js`,`${p}.test.js`];for(let h of w)if(T.existsSync(h)){g=h;break}}if(!s.includes(S.resolve(g)))return g}}}return null}var de=require("ai"),Ge=require("@ai-sdk/openai"),He=require("@ai-sdk/anthropic"),Be=require("@ai-sdk/google"),qe=j(require("dotenv"));qe.config({quiet:!0});var Ae=15e3;function We(t,e){return t.length<=Ae?t:(console.warn(`[Lisa.ai LLM] ${e} is ${t.length} chars \u2014 truncating to ${Ae} to stay within context window.`),t.slice(0,Ae)+`
2
+ "use strict";var Et=Object.create;var Ue=Object.defineProperty;var jt=Object.getOwnPropertyDescriptor;var Ct=Object.getOwnPropertyNames;var bt=Object.getPrototypeOf,At=Object.prototype.hasOwnProperty;var Ft=(t,e)=>()=>(e||t((e={exports:{}}).exports,e),e.exports);var Pt=(t,e,s,n)=>{if(e&&typeof e=="object"||typeof e=="function")for(let i of Ct(e))!At.call(t,i)&&i!==s&&Ue(t,i,{get:()=>e[i],enumerable:!(n=jt(e,i))||n.enumerable});return t};var j=(t,e,s)=>(s=t!=null?Et(bt(t)):{},Pt(e||!t||!t.__esModule?Ue(s,"default",{value:t,enumerable:!0}):s,t));var vt=Ft((Zs,Bt)=>{Bt.exports={name:"@lisa.ai/agent",version:"2.9.1",description:"Lisa.ai Autonomous CI/CD Worker Agent",main:"dist/index.js",bin:{"lisa-agent":"dist/index.js"},files:["dist/"],scripts:{build:"tsup",typecheck:"tsc --noEmit",start:"node dist/index.js",dev:"ts-node src/index.ts",prepublishOnly:"npm run typecheck && npm run build"},keywords:["lisa","ci","cd","agent"],author:"Lisa.ai",license:"ISC",dependencies:{"@ai-sdk/anthropic":"^3.0.46","@ai-sdk/google":"^3.0.30","@ai-sdk/openai":"^3.0.30","@octokit/rest":"^22.0.1",ai:"^6.0.94",commander:"^11.1.0",dotenv:"^17.3.1","simple-git":"^3.31.1"},devDependencies:{"@types/jest":"^30.0.0","@types/node":"^20.0.0","ts-node":"^10.9.1",tsup:"^8.5.1",typescript:"^5.0.0"}}});var xt=require("commander"),Ee=j(require("fs")),$t=j(require("path")),Lt=j(require("readline"));var Oe=j(require("dotenv"));Oe.config({quiet:!0});async function ge(t){let e=process.env.LISA_CONTROL_PLANE_URL||"http://localhost:3000";try{let s=`${e}/api/config/${t}`;console.log(`[Lisa.ai Agent] Fetching dynamic configuration from ${s}...`);let n=await fetch(s);if(!n.ok){let o=n.status===404?"not_found":"unreachable";return console.warn(o==="not_found"?`[Lisa.ai Agent Warning] Control Plane returned 404. Project '${t}' not found.`:`[Lisa.ai Agent Warning] Control Plane returned ${n.status}. Falling back to local defaults.`),{ok:!1,reason:o}}return{ok:!0,config:await n.json()}}catch{return console.warn(`[Lisa.ai Agent Warning] Failed to reach Control Plane (${e}). Using local fallback configuration.`),{ok:!1,reason:"unreachable"}}}var ot=require("child_process"),_=j(require("fs")),V=j(require("path"));var S=j(require("path")),T=j(require("fs"));function fe(t){return t.replace(/\x1B\[[0-9;]*[a-zA-Z]/g,"")}function Z(t){let e=fe(t),s=[...e.matchAll(/Executed\s+(\d+)\s+of\s+(\d+)(?:\s+\((\d+)\s+FAILED\))?/g)];if(s.length>0){let u=[...s].reverse().find(m=>m[3]!==void 0)??s[s.length-1],p=parseInt(u[2]),w=u[3]?parseInt(u[3]):0,h=parseInt(u[1])-w;return{total:p,passed:h,failed:w}}let n=e.match(/Tests:\s+(?:(\d+)\s+failed,?\s*)?(?:(\d+)\s+passed,?\s*)?(\d+)\s+total/);if(n){let u=parseInt(n[3]),p=n[1]?parseInt(n[1]):0,w=n[2]?parseInt(n[2]):0;return{total:u,passed:w,failed:p}}let i=e.match(/(\d+)\s+failed/),o=e.match(/(\d+)\s+passed/);if(o||i){let u=i?parseInt(i[1]):0,p=o?parseInt(o[1]):0,w=e.match(/(\d+)\s+skipped/),h=w?parseInt(w[1]):0;return{total:p+u+h,passed:p,failed:u}}let r=e.match(/Tests\s+(?:(\d+)\s+failed\s*\|?\s*)?(\d+)\s+passed\s*\((\d+)\)/);if(r){let u=parseInt(r[3]),p=r[1]?parseInt(r[1]):0,w=parseInt(r[2]);return{total:u,passed:w,failed:p}}let a=e.match(/(\d+)\s+passing/),g=e.match(/(\d+)\s+failing/);if(a){let u=parseInt(a[1]),p=g?parseInt(g[1]):0;return{total:u+p,passed:u,failed:p}}return null}function Ce(t,e=process.cwd(),s=[]){let n=t.replace(/\x1B\[[0-9;]*[a-zA-Z]/g,""),i=s.map(l=>S.resolve(e,l)),o=new Map,r=new Set,a=/(?:Chrome|Firefox|Safari)(?:\s+Headless)?\s+[\d.]+(?:\s+[\d.]+)*\s+\([^)]+\)\s+(.+?)\s+FAILED/g,g;for(;(g=a.exec(n))!==null;){let d=g[1].trim().split(" ");for(let v=1;v<Math.min(d.length,6);v++){let k=d.slice(0,v).join(" ");if(r.has(k))continue;r.add(k);let f=be(k,e,i);if(f){let c=S.resolve(f);o.has(c)||o.set(c,S.relative(e,f));break}}}let u=/^FAIL\s+([a-zA-Z0-9_./-\\]+\.(?:spec|test)\.(ts|tsx|js|jsx))/gm,p;for(;(p=u.exec(n))!==null;){let l=p[1],d=S.isAbsolute(l)?l:S.resolve(e,l);!i.includes(d)&&T.existsSync(d)&&!o.has(d)&&o.set(d,S.relative(e,d))}let w=/\[(?:chromium|firefox|webkit)\]\s+[>›]\s+([^\s:]+\.(?:spec|test)\.[tj]sx?):\d+:\d+\s+[>›]/g,h;for(;(h=w.exec(n))!==null;){let l=h[1],d=S.isAbsolute(l)?l:S.resolve(e,l);!i.includes(d)&&T.existsSync(d)&&!o.has(d)&&o.set(d,S.relative(e,d))}let m=/Running:\s+([^\s]+\.(?:cy|spec|test)\.[tj]sx?)/g,y;for(;(y=m.exec(n))!==null;){let l=y[1],d=S.isAbsolute(l)?l:S.resolve(e,l);if(!i.includes(d)&&T.existsSync(d)&&!o.has(d)){let v=l.replace(/[.*+?^${}()|[\]\\]/g,"\\$&");new RegExp(v+"\\s+\\d+\\s+\\d+\\s+([1-9]\\d*)").test(n)&&o.set(d,S.relative(e,d))}}return[...o.values()]}function me(t,e=[],s=process.cwd()){let n=t.replace(/\x1B\[[0-9;]*[a-zA-Z]/g,""),i=e.map(l=>S.resolve(l));{let l=/(?:Chrome|Firefox|Safari)(?:\s+Headless)?\s+[\d.]+(?:\s+[\d.]+)*\s+\([^)]+\)\s+(.+?)\s+FAILED/g,d=new Set,v;for(;(v=l.exec(n))!==null;){let f=v[1].trim().split(" ");for(let c=1;c<Math.min(f.length,5);c++){let x=f.slice(0,c).join(" ");if(d.has(x))continue;d.add(x);let L=be(x,s,i);if(L)return S.relative(s,L)}}}let o=/([a-zA-Z]:[a-zA-Z0-9_.\-\/\\]+\.(?:ts|tsx|js|jsx|vue)|[a-zA-Z0-9_.\-\/\\]+\.(?:ts|tsx|js|jsx|vue))(?:\s*[:(])/g,r;for(;(r=o.exec(n))!==null;){let l=r[1];if(l){if(/(?:^|[/\\])(node_modules|dist|build)[/\\]/.test(l))continue;let d=S.isAbsolute(l)?l:S.resolve(s,l);if(!i.includes(d)&&T.existsSync(d))return l}}let a=/FAIL\s+([a-zA-Z0-9_.\-\/\\]+\.(?:ts|tsx|js|jsx|vue))/gi,g;for(;(g=a.exec(n))!==null;){let l=g[1],d=S.isAbsolute(l)?l:S.resolve(s,l);if(!i.includes(d)&&T.existsSync(d))return l}{let l=/\[(?:chromium|firefox|webkit)\]\s+[>›]\s+([^\s:]+\.(?:spec|test)\.[tj]sx?):\d+:\d+\s+[>›]/g,d;for(;(d=l.exec(n))!==null;){let v=d[1],k=S.isAbsolute(v)?v:S.resolve(s,v);if(!i.includes(k)&&T.existsSync(k))return v}}let u=/([a-zA-Z]:[a-zA-Z0-9_.\-\/\\]+\.(?:ts|tsx|js|jsx|vue)|[a-zA-Z0-9_.\-\/\\]+\.(?:ts|tsx|js|jsx|vue))/g,p;for(;(p=u.exec(n))!==null;){let l=p[1];if(l){if(/(?:^|[/\\])(node_modules|dist|build)[/\\]/.test(l))continue;let d=S.isAbsolute(l)?l:S.resolve(s,l);if(!i.includes(d)&&T.existsSync(d))return l}}let w=/\b([A-Z][a-zA-Z0-9]{3,})\b/g,h,m=new Set,y=["Error","TypeError","SyntaxError","ReferenceError","RangeError","Object","Boolean","String","Number","Array","NullInjectorError","NullInjector","R3Injector","ChainedInjector","Module","Component","Standalone","Application","App2","TestBed","UserContext","Chrome","ChromeHeadless","Karma","Launching","Starting","Headless","Connected","Executed","INFO","SUCCESS","FAILED","Building","Initial","Names","Lazy","Source","Find","NotFound","NG0201","Windows","Linux","Macintosh","Users","AppData","Local","Temp","Process","Unexpected","Expected","Validation","Directory","Configuration","Documentation"];for(;(h=w.exec(n))!==null;){let l=h[1];if(!l||y.includes(l)||m.has(l)||/^[A-Z][A-Z0-9]{5,11}$/.test(l)||/^[A-Za-z0-9]{16,}$/.test(l))continue;m.add(l);let d=_e(l,s,i);if(d)return S.relative(s,d)}return null}function be(t,e,s){if(!T.existsSync(e))return null;let n=T.readdirSync(e);for(let i of n){let o=S.join(e,i);if(["node_modules","dist","build",".git",".angular"].includes(i))continue;let r;try{r=T.statSync(o)}catch{continue}if(r.isDirectory()){let a=be(t,o,s);if(a)return a}else if(/\.(spec|test)\.(ts|tsx|js|jsx)$/.test(i)){if(s.includes(S.resolve(o)))continue;try{let a=T.readFileSync(o,"utf8");if(a.includes(`describe('${t}'`)||a.includes(`describe("${t}"`))return o}catch{continue}}}return null}function _e(t,e,s){if(!T.existsSync(e))return null;let n=T.readdirSync(e);for(let i of n){let o=S.join(e,i);if(i==="node_modules"||i==="dist"||i==="build"||i===".git"||i===".angular")continue;let r;try{r=T.statSync(o)}catch{continue}if(r.isDirectory()){let a=_e(t,o,s);if(a)return a}else if(i.match(/\.(ts|tsx|js|jsx|vue)$/)){let a=T.readFileSync(o,"utf8");if(a.includes(`class ${t}`)||a.includes(`function ${t}`)||a.includes(`const ${t}`)||a.includes(`let ${t}`)||a.includes(`exports.${t}`)||a.includes(`module.exports.${t}`)){let g=o,u=S.extname(o),p=o.slice(0,-u.length);if(!i.includes(".spec.")&&!i.includes(".test.")){let w=[`${p}.spec${u}`,`${p}.test${u}`,`${p}.spec.js`,`${p}.test.js`];for(let h of w)if(T.existsSync(h)){g=h;break}}if(!s.includes(S.resolve(g)))return g}}}return null}var de=require("ai"),Ge=require("@ai-sdk/openai"),He=require("@ai-sdk/anthropic"),Be=require("@ai-sdk/google"),qe=j(require("dotenv"));qe.config({quiet:!0});var Ae=15e3;function We(t,e){return t.length<=Ae?t:(console.warn(`[Lisa.ai LLM] ${e} is ${t.length} chars \u2014 truncating to ${Ae} to stay within context window.`),t.slice(0,Ae)+`
3
3
 
4
4
  // ... (truncated)`)}function Ye(t,e){if(!/\b(describe|it\(|test\(|expect\(|beforeEach|afterEach|suite|assert\.|cy\.)\b/.test(t))throw new Error(`LLM returned a non-code response for ${e} (possible context overflow). Skipping to prevent file corruption.`)}function Ve(t){if(!t||t.length===0)return"";let e={unit:"unit tests \u2014 test every function/method in complete isolation, mocking ALL external dependencies, services, and I/O",integration:"integration tests \u2014 test how modules work together using real service/repository layers; for HTTP routes use supertest or equivalent",e2e:"end-to-end tests \u2014 simulate complete user flows using the configured e2e framework (Playwright/Cypress); cover the full path from HTTP request to response or UI action to assertion"};return`5. Test scope \u2014 generate ALL of the following test types for this file:
5
5
  ${t.map(n=>` \u2022 ${e[n]??n}`).join(`
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lisa.ai/agent",
3
- "version": "2.9.0",
3
+ "version": "2.9.1",
4
4
  "description": "Lisa.ai Autonomous CI/CD Worker Agent",
5
5
  "main": "dist/index.js",
6
6
  "bin": {