@lisa.ai/agent 2.6.0 → 2.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.
Files changed (2) hide show
  1. package/dist/index.js +60 -60
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -1,10 +1,10 @@
1
1
  #!/usr/bin/env node
2
- "use strict";var et=Object.create;var ve=Object.defineProperty;var tt=Object.getOwnPropertyDescriptor;var st=Object.getOwnPropertyNames;var ot=Object.getPrototypeOf,nt=Object.prototype.hasOwnProperty;var it=(t,e)=>()=>(e||t((e={exports:{}}).exports,e),e.exports);var rt=(t,e,s,o)=>{if(e&&typeof e=="object"||typeof e=="function")for(let n of st(e))!nt.call(t,n)&&n!==s&&ve(t,n,{get:()=>e[n],enumerable:!(o=tt(e,n))||o.enumerable});return t};var C=(t,e,s)=>(s=t!=null?et(ot(t)):{},rt(e||!t||!t.__esModule?ve(s,"default",{value:t,enumerable:!0}):s,t));var ze=it((Qt,pt)=>{pt.exports={name:"@lisa.ai/agent",version:"2.6.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 Ze=require("commander"),ce=C(require("fs")),Ke=C(require("path")),Je=C(require("readline"));var Le=C(require("dotenv"));Le.config({quiet:!0});async function X(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 o=await fetch(s);if(!o.ok){let i=o.status===404?"not_found":"unreachable";return console.warn(i==="not_found"?`[Lisa.ai Agent Warning] Control Plane returned 404. Project '${t}' not found.`:`[Lisa.ai Agent Warning] Control Plane returned ${o.status}. Falling back to local defaults.`),{ok:!1,reason:i}}return{ok:!0,config:await o.json()}}catch{return console.warn(`[Lisa.ai Agent Warning] Failed to reach Control Plane (${e}). Using local fallback configuration.`),{ok:!1,reason:"unreachable"}}}var Ge=require("child_process"),I=C(require("fs")),U=C(require("path"));var $=C(require("path")),S=C(require("fs"));function Q(t,e=[],s=process.cwd()){let o=t.replace(/\x1B\[[0-9;]*[a-zA-Z]/g,""),n=e.map(a=>$.resolve(a));{let a=/(?:Chrome|Firefox|Safari)(?:\s+Headless)?\s+[\d.]+(?:\s+[\d.]+)*\s+\([^)]+\)\s+(.+?)\s+FAILED/g,h=new Set,u;for(;(u=a.exec(o))!==null;){let L=u[1].trim().split(" ");for(let x=1;x<Math.min(L.length,5);x++){let k=L.slice(0,x).join(" ");if(h.has(k))continue;h.add(k);let w=we(k,s,n);if(w)return $.relative(s,w)}}}let i=/([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=i.exec(o))!==null;){let a=r[1];if(a){if(/(?:^|[/\\])(node_modules|dist|build)[/\\]/.test(a))continue;let h=$.isAbsolute(a)?a:$.resolve(s,a);if(!n.includes(h)&&S.existsSync(h))return a}}let l=/FAIL\s+([a-zA-Z0-9_.\-\/\\]+\.(?:ts|tsx|js|jsx|vue))/gi,g;for(;(g=l.exec(o))!==null;){let a=g[1],h=$.isAbsolute(a)?a:$.resolve(s,a);if(!n.includes(h)&&S.existsSync(h))return a}let f=/([a-zA-Z]:[a-zA-Z0-9_.\-\/\\]+\.(?:ts|tsx|js|jsx|vue)|[a-zA-Z0-9_.\-\/\\]+\.(?:ts|tsx|js|jsx|vue))/g,m;for(;(m=f.exec(o))!==null;){let a=m[1];if(a){if(/(?:^|[/\\])(node_modules|dist|build)[/\\]/.test(a))continue;let h=$.isAbsolute(a)?a:$.resolve(s,a);if(!n.includes(h)&&S.existsSync(h))return a}}let d=/\b([A-Z][a-zA-Z0-9]{3,})\b/g,c,p=new Set,v=["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(;(c=d.exec(o))!==null;){let a=c[1];if(!a||v.includes(a)||p.has(a)||/^[A-Z][A-Z0-9]{5,11}$/.test(a)||/^[A-Za-z0-9]{16,}$/.test(a))continue;p.add(a);let h=xe(a,s,n);if(h)return $.relative(s,h)}return null}function we(t,e,s){if(!S.existsSync(e))return null;let o=S.readdirSync(e);for(let n of o){let i=$.join(e,n);if(["node_modules","dist","build",".git",".angular"].includes(n))continue;let r;try{r=S.statSync(i)}catch{continue}if(r.isDirectory()){let l=we(t,i,s);if(l)return l}else if(/\.(spec|test)\.(ts|tsx|js|jsx)$/.test(n)){if(s.includes($.resolve(i)))continue;try{let l=S.readFileSync(i,"utf8");if(l.includes(`describe('${t}'`)||l.includes(`describe("${t}"`))return i}catch{continue}}}return null}function xe(t,e,s){if(!S.existsSync(e))return null;let o=S.readdirSync(e);for(let n of o){let i=$.join(e,n);if(n==="node_modules"||n==="dist"||n==="build"||n===".git"||n===".angular")continue;let r;try{r=S.statSync(i)}catch{continue}if(r.isDirectory()){let l=xe(t,i,s);if(l)return l}else if(n.match(/\.(ts|tsx|js|jsx|vue)$/)){let l=S.readFileSync(i,"utf8");if(l.includes(`class ${t}`)||l.includes(`function ${t}`)||l.includes(`const ${t}`)||l.includes(`let ${t}`)||l.includes(`exports.${t}`)||l.includes(`module.exports.${t}`)){let g=i,f=$.extname(i),m=i.slice(0,-f.length);if(!n.includes(".spec.")&&!n.includes(".test.")){let d=[`${m}.spec${f}`,`${m}.test${f}`,`${m}.spec.js`,`${m}.test.js`];for(let c of d)if(S.existsSync(c)){g=c;break}}if(!s.includes($.resolve(g)))return g}}}return null}var J=require("ai"),Ce=require("@ai-sdk/openai"),$e=require("@ai-sdk/anthropic"),ke=require("@ai-sdk/google"),Ae=C(require("dotenv"));Ae.config({quiet:!0});var pe=15e3;function Se(t,e){return t.length<=pe?t:(console.warn(`[Lisa.ai LLM] ${e} is ${t.length} chars \u2014 truncating to ${pe} to stay within context window.`),t.slice(0,pe)+`
2
+ "use strict";var nt=Object.create;var ve=Object.defineProperty;var it=Object.getOwnPropertyDescriptor;var rt=Object.getOwnPropertyNames;var at=Object.getPrototypeOf,lt=Object.prototype.hasOwnProperty;var ct=(t,e)=>()=>(e||t((e={exports:{}}).exports,e),e.exports);var ut=(t,e,s,o)=>{if(e&&typeof e=="object"||typeof e=="function")for(let n of rt(e))!lt.call(t,n)&&n!==s&&ve(t,n,{get:()=>e[n],enumerable:!(o=it(e,n))||o.enumerable});return t};var C=(t,e,s)=>(s=t!=null?nt(at(t)):{},ut(e||!t||!t.__esModule?ve(s,"default",{value:t,enumerable:!0}):s,t));var Ke=ct((ts,ft)=>{ft.exports={name:"@lisa.ai/agent",version:"2.6.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 Je=require("commander"),ue=C(require("fs")),Ve=C(require("path")),Xe=C(require("readline"));var Le=C(require("dotenv"));Le.config({quiet:!0});async function Q(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 o=await fetch(s);if(!o.ok){let i=o.status===404?"not_found":"unreachable";return console.warn(i==="not_found"?`[Lisa.ai Agent Warning] Control Plane returned 404. Project '${t}' not found.`:`[Lisa.ai Agent Warning] Control Plane returned ${o.status}. Falling back to local defaults.`),{ok:!1,reason:i}}return{ok:!0,config:await o.json()}}catch{return console.warn(`[Lisa.ai Agent Warning] Failed to reach Control Plane (${e}). Using local fallback configuration.`),{ok:!1,reason:"unreachable"}}}var qe=require("child_process"),F=C(require("fs")),H=C(require("path"));var $=C(require("path")),S=C(require("fs"));function ee(t,e=[],s=process.cwd()){let o=t.replace(/\x1B\[[0-9;]*[a-zA-Z]/g,""),n=e.map(a=>$.resolve(a));{let a=/(?:Chrome|Firefox|Safari)(?:\s+Headless)?\s+[\d.]+(?:\s+[\d.]+)*\s+\([^)]+\)\s+(.+?)\s+FAILED/g,h=new Set,u;for(;(u=a.exec(o))!==null;){let L=u[1].trim().split(" ");for(let x=1;x<Math.min(L.length,5);x++){let k=L.slice(0,x).join(" ");if(h.has(k))continue;h.add(k);let w=we(k,s,n);if(w)return $.relative(s,w)}}}let i=/([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=i.exec(o))!==null;){let a=r[1];if(a){if(/(?:^|[/\\])(node_modules|dist|build)[/\\]/.test(a))continue;let h=$.isAbsolute(a)?a:$.resolve(s,a);if(!n.includes(h)&&S.existsSync(h))return a}}let l=/FAIL\s+([a-zA-Z0-9_.\-\/\\]+\.(?:ts|tsx|js|jsx|vue))/gi,d;for(;(d=l.exec(o))!==null;){let a=d[1],h=$.isAbsolute(a)?a:$.resolve(s,a);if(!n.includes(h)&&S.existsSync(h))return a}let f=/([a-zA-Z]:[a-zA-Z0-9_.\-\/\\]+\.(?:ts|tsx|js|jsx|vue)|[a-zA-Z0-9_.\-\/\\]+\.(?:ts|tsx|js|jsx|vue))/g,m;for(;(m=f.exec(o))!==null;){let a=m[1];if(a){if(/(?:^|[/\\])(node_modules|dist|build)[/\\]/.test(a))continue;let h=$.isAbsolute(a)?a:$.resolve(s,a);if(!n.includes(h)&&S.existsSync(h))return a}}let p=/\b([A-Z][a-zA-Z0-9]{3,})\b/g,c,g=new Set,v=["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(;(c=p.exec(o))!==null;){let a=c[1];if(!a||v.includes(a)||g.has(a)||/^[A-Z][A-Z0-9]{5,11}$/.test(a)||/^[A-Za-z0-9]{16,}$/.test(a))continue;g.add(a);let h=xe(a,s,n);if(h)return $.relative(s,h)}return null}function we(t,e,s){if(!S.existsSync(e))return null;let o=S.readdirSync(e);for(let n of o){let i=$.join(e,n);if(["node_modules","dist","build",".git",".angular"].includes(n))continue;let r;try{r=S.statSync(i)}catch{continue}if(r.isDirectory()){let l=we(t,i,s);if(l)return l}else if(/\.(spec|test)\.(ts|tsx|js|jsx)$/.test(n)){if(s.includes($.resolve(i)))continue;try{let l=S.readFileSync(i,"utf8");if(l.includes(`describe('${t}'`)||l.includes(`describe("${t}"`))return i}catch{continue}}}return null}function xe(t,e,s){if(!S.existsSync(e))return null;let o=S.readdirSync(e);for(let n of o){let i=$.join(e,n);if(n==="node_modules"||n==="dist"||n==="build"||n===".git"||n===".angular")continue;let r;try{r=S.statSync(i)}catch{continue}if(r.isDirectory()){let l=xe(t,i,s);if(l)return l}else if(n.match(/\.(ts|tsx|js|jsx|vue)$/)){let l=S.readFileSync(i,"utf8");if(l.includes(`class ${t}`)||l.includes(`function ${t}`)||l.includes(`const ${t}`)||l.includes(`let ${t}`)||l.includes(`exports.${t}`)||l.includes(`module.exports.${t}`)){let d=i,f=$.extname(i),m=i.slice(0,-f.length);if(!n.includes(".spec.")&&!n.includes(".test.")){let p=[`${m}.spec${f}`,`${m}.test${f}`,`${m}.spec.js`,`${m}.test.js`];for(let c of p)if(S.existsSync(c)){d=c;break}}if(!s.includes($.resolve(d)))return d}}}return null}var V=require("ai"),Ce=require("@ai-sdk/openai"),$e=require("@ai-sdk/anthropic"),ke=require("@ai-sdk/google"),Ae=C(require("dotenv"));Ae.config({quiet:!0});var ge=15e3;function Se(t,e){return t.length<=ge?t:(console.warn(`[Lisa.ai LLM] ${e} is ${t.length} chars \u2014 truncating to ${ge} to stay within context window.`),t.slice(0,ge)+`
3
3
 
4
4
  // ... (truncated)`)}function be(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 je(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(o=>` \u2022 ${e[o]??o}`).join(`
6
6
  `)}
7
- `}function ee(t,e){if(t==="claude"){let n=e||process.env.ANTHROPIC_API_KEY;if(!n)throw new Error("No Anthropic API key provided by local ENV or Control Plane");let i=process.env.LISA_CLAUDE_MODEL||"claude-haiku-4-5";return(0,$e.createAnthropic)({apiKey:n})(i)}if(t==="openai"){let n=e||process.env.OPENAI_API_KEY;if(!n)throw new Error("No OpenAI API key provided by local ENV or Control Plane");let i=process.env.LISA_OPENAI_MODEL||"gpt-4o-mini";return(0,Ce.createOpenAI)({apiKey:n})(i)}let s=e||process.env.GOOGLE_GENERATIVE_AI_API_KEY;if(!s)throw new Error("No Google API key provided by local ENV or Control Plane");let o=process.env.LISA_GOOGLE_MODEL||"gemini-2.0-flash";return(0,ke.createGoogleGenerativeAI)({apiKey:s})(o)}async function Ee(t,e,s,o,n,i,r,l){console.log(`[Lisa.ai Auto-Heal] Requesting fix from ${o} for ${t}...`);let g=ee(o,n),f=`You are Lisa.ai, an autonomous CI/CD expert platform.
7
+ `}function te(t,e){if(t==="claude"){let n=e||process.env.ANTHROPIC_API_KEY;if(!n)throw new Error("No Anthropic API key provided by local ENV or Control Plane");let i=process.env.LISA_CLAUDE_MODEL||"claude-haiku-4-5";return(0,$e.createAnthropic)({apiKey:n})(i)}if(t==="openai"){let n=e||process.env.OPENAI_API_KEY;if(!n)throw new Error("No OpenAI API key provided by local ENV or Control Plane");let i=process.env.LISA_OPENAI_MODEL||"gpt-4o-mini";return(0,Ce.createOpenAI)({apiKey:n})(i)}let s=e||process.env.GOOGLE_GENERATIVE_AI_API_KEY;if(!s)throw new Error("No Google API key provided by local ENV or Control Plane");let o=process.env.LISA_GOOGLE_MODEL||"gemini-2.0-flash";return(0,ke.createGoogleGenerativeAI)({apiKey:s})(o)}async function Ee(t,e,s,o,n,i,r,l){console.log(`[Lisa.ai Auto-Heal] Requesting fix from ${o} for ${t}...`);let d=te(o,n),f=`You are Lisa.ai, an autonomous CI/CD expert platform.
8
8
  A build/compilation error occurred. Your task is to fix the provided file so that the error resolves.
9
9
 
10
10
  --- Error Log ---
@@ -21,7 +21,7 @@ A build/compilation error occurred. Your task is to fix the provided file so tha
21
21
  5. FRAMEWORK TEST RULE: If fixing a testing file ('.spec' or '.test') and an Angular error happens like 'NullInjectorError: No provider for X', you MUST add X to the 'providers' array in 'TestBed.configureTestingModule' or import the required testing module. If a React testing library error arises, fix the render context.
22
22
  6. CRITICAL ANGULAR RULE: If an Angular component imports 'RouterLink' or uses '[routerLink]' in its template, you MUST provide 'ActivatedRoute' in the providers array or import 'RouterTestingModule'. If it uses HTTP, import 'HttpClientTestingModule'.
23
23
  7. CRITICAL STANDALONE RULE: If a component has 'standalone: true' in its decorator (check the Sibling Context!), you MUST NOT add it to the 'declarations' array. Instead, you MUST add it to the 'imports' array within 'TestBed.configureTestingModule'.
24
- 8. Return the code wrapped in a markdown code block (\`\`\`typescript ... \`\`\`). Do not include any explanation or intro text.`;if(r){if(/standalone\s*:\s*true/.test(r)){let p=r.match(/export class (\w+)/),v=p?p[1]:"the component";f+=`
24
+ 8. Return the code wrapped in a markdown code block (\`\`\`typescript ... \`\`\`). Do not include any explanation or intro text.`;if(r){if(/standalone\s*:\s*true/.test(r)){let g=r.match(/export class (\w+)/),v=g?g[1]:"the component";f+=`
25
25
 
26
26
  --- CRITICAL ARCHITECTURAL REQUIREMENT ---
27
27
  The component `+v+` is marked as STANDALONE (standalone: true).
@@ -35,8 +35,8 @@ Use this to identify EXACTLY which imports, Services, and Variables need to be m
35
35
 
36
36
  --- MEMORY ENGINE: PROVEN FIX PATTERNS ---
37
37
  The following fix patterns were SUCCESSFULLY used to resolve identical errors in past runs. Prioritise these approaches before trying anything novel:
38
- `+l.map((c,p)=>`
39
- [Pattern ${p+1}]
38
+ `+l.map((c,g)=>`
39
+ [Pattern ${g+1}]
40
40
  ${c}`).join(`
41
41
  `)),i&&(console.log(`[Lisa.ai Auto-Heal] Warning! Agent is looping on ${t}. Injecting previous failed context...`),f+=`
42
42
 
@@ -45,16 +45,16 @@ You previously attempted to fix this file but the compiler REJECTED your fix!
45
45
  Here is the previous analysis and failed fix you attempted:
46
46
  `+i+`
47
47
 
48
- DO NOT repeat the identical code changes. Try a completely different programming approach, fix syntax typos, or check for missing imports.`);let{text:m}=await(0,J.generateText)({model:g,prompt:f}),d=m.match(/```(?:typescript|ts|javascript|js)?\n([\s\S]*?)```/);return d?d[1].trim():m.trim()}async function Pe(t,e,s,o,n,i){console.log(`[Lisa.ai Coverage] Requesting test generation from ${s} for ${t}...`);let r=ee(s,o),l=n?`3. You MUST use the '${n}' testing framework exclusively. All imports, describe/it/test blocks, and mock utilities must follow '${n}' conventions.
48
+ DO NOT repeat the identical code changes. Try a completely different programming approach, fix syntax typos, or check for missing imports.`);let{text:m}=await(0,V.generateText)({model:d,prompt:f}),p=m.match(/```(?:typescript|ts|javascript|js)?\n([\s\S]*?)```/);return p?p[1].trim():m.trim()}async function Pe(t,e,s,o,n,i){console.log(`[Lisa.ai Coverage] Requesting test generation from ${s} for ${t}...`);let r=te(s,o),l=n?`3. You MUST use the '${n}' testing framework exclusively. All imports, describe/it/test blocks, and mock utilities must follow '${n}' conventions.
49
49
  `:`3. Include all necessary imports assuming a standard testing framework (Jest/Karma/Vitest) is available.
50
- `,g=je(i),f=`You are Lisa.ai, an autonomous CI/CD expert platform.
50
+ `,d=je(i),f=`You are Lisa.ai, an autonomous CI/CD expert platform.
51
51
  A source file lacks 100% test coverage. Your task is to generate a comprehensive testing suite covering all branches, lines, and functions.
52
52
 
53
53
  --- Target File Content (`+t+`) ---
54
54
  `+Se(e,t)+"\n\n--- Constraints ---\n1. Return the generated test code wrapped in a markdown code block (```typescript ... ```).\n2. Do not include any explanation or intro text.\n"+l+`4. Aim for 100% logic coverage.
55
- `+g,{text:m}=await(0,J.generateText)({model:r,prompt:f}),d=m.match(/```(?:typescript|ts|javascript|js)?\n([\s\S]*?)```/),c=d?d[1].trim():m.trim();return be(c,t),c}async function Ie(t,e,s,o,n,i,r,l){console.log(`[Lisa.ai Coverage] Requesting test update from ${n} for ${t}...`);let g=ee(n,i),f=r?`3. You MUST use the '${r}' testing framework exclusively. All new tests must follow '${r}' conventions and integrate cleanly with the existing suite.
55
+ `+d,{text:m}=await(0,V.generateText)({model:r,prompt:f}),p=m.match(/```(?:typescript|ts|javascript|js)?\n([\s\S]*?)```/),c=p?p[1].trim():m.trim();return be(c,t),c}async function Fe(t,e,s,o,n,i,r,l){console.log(`[Lisa.ai Coverage] Requesting test update from ${n} for ${t}...`);let d=te(n,i),f=r?`3. You MUST use the '${r}' testing framework exclusively. All new tests must follow '${r}' conventions and integrate cleanly with the existing suite.
56
56
  `:`3. Append missing tests to the existing suite. Do not delete existing passing tests unless they are fundamentally broken.
57
- `,m=je(l),d=`You are Lisa.ai, an autonomous CI/CD expert platform.
57
+ `,m=je(l),p=`You are Lisa.ai, an autonomous CI/CD expert platform.
58
58
  A source file lacks 100% test coverage. You must update its existing test suite to achieve full coverage.
59
59
 
60
60
  --- Target File Content (`+t+`) ---
@@ -62,17 +62,17 @@ A source file lacks 100% test coverage. You must update its existing test suite
62
62
 
63
63
  --- Existing Test Suite (`+s+`) ---
64
64
  `+o+"\n\n--- Constraints ---\n1. Return the updated complete test code wrapped in a markdown code block (```typescript ... ```).\n2. Do not include any explanation or intro text.\n"+f+`4. Aim for 100% logic coverage across branches, lines, and functions.
65
- `+m,{text:c}=await(0,J.generateText)({model:g,prompt:d}),p=c.match(/```(?:typescript|ts|javascript|js)?\n([\s\S]*?)```/),v=p?p[1].trim():c.trim();return be(v,t),v}async function te(t,e,s){let o=ee(e,s),{text:n}=await(0,J.generateText)({model:o,prompt:t}),i=n.match(/```(?:typescript|ts|javascript|js)?\n([\s\S]*?)```/);return i?i[1].trim():n.trim()}var Te=C(require("simple-git")),Fe=require("@octokit/rest"),Lt=require("dotenv/config");async function Re(t){console.log(`
66
- [Lisa.ai PR Engine] Initializing Pull Request for ${t}...`);let e=(0,Te.default)(),o=`lisa-fix/build-error-${new Date().getTime()}`,n=`fix: automated auto-heal by Lisa.ai for ${t}`,i="main";try{i=(await e.revparse(["--abbrev-ref","HEAD"])).trim()}catch{}try{await e.addConfig("user.name","Lisa.ai"),await e.addConfig("user.email","lisa@lisa.ai"),await e.checkoutLocalBranch(o),await e.add(t),await e.commit(n),console.log(`[Lisa.ai PR Engine] Committed changes to branch ${o}`),console.log("[Lisa.ai PR Engine] Pushing branch to remote origin..."),await e.push("origin",o,{"--set-upstream":null});let r=new Fe.Octokit({auth:process.env.GITHUB_TOKEN}),l=process.env.GITHUB_REPOSITORY;if(l&&process.env.GITHUB_TOKEN){let[g,f]=l.split("/");console.log(`[Lisa.ai PR Engine] Opening Pull Request against ${g}/${f}...`);let m=await r.rest.pulls.create({owner:g,repo:f,title:n,body:`### Lisa.ai Auto-Healed Pull Request
65
+ `+m,{text:c}=await(0,V.generateText)({model:d,prompt:p}),g=c.match(/```(?:typescript|ts|javascript|js)?\n([\s\S]*?)```/),v=g?g[1].trim():c.trim();return be(v,t),v}async function se(t,e,s){let o=te(e,s),{text:n}=await(0,V.generateText)({model:o,prompt:t}),i=n.match(/```(?:typescript|ts|javascript|js)?\n([\s\S]*?)```/);return i?i[1].trim():n.trim()}var Ie=C(require("simple-git")),Te=require("@octokit/rest"),xt=require("dotenv/config");async function Re(t){console.log(`
66
+ [Lisa.ai PR Engine] Initializing Pull Request for ${t}...`);let e=(0,Ie.default)(),o=`lisa-fix/build-error-${new Date().getTime()}`,n=`fix: automated auto-heal by Lisa.ai for ${t}`,i="main";try{i=(await e.revparse(["--abbrev-ref","HEAD"])).trim()}catch{}try{await e.addConfig("user.name","Lisa.ai"),await e.addConfig("user.email","lisa@lisa.ai"),await e.checkoutLocalBranch(o),await e.add(t),await e.commit(n),console.log(`[Lisa.ai PR Engine] Committed changes to branch ${o}`),console.log("[Lisa.ai PR Engine] Pushing branch to remote origin..."),await e.push("origin",o,{"--set-upstream":null});let r=new Te.Octokit({auth:process.env.GITHUB_TOKEN}),l=process.env.GITHUB_REPOSITORY;if(l&&process.env.GITHUB_TOKEN){let[d,f]=l.split("/");console.log(`[Lisa.ai PR Engine] Opening Pull Request against ${d}/${f}...`);let m=await r.rest.pulls.create({owner:d,repo:f,title:n,body:`### Lisa.ai Auto-Healed Pull Request
67
67
  This PR was automatically generated by Lisa.ai to resolve a failing compilation/build step.
68
68
 
69
69
  **Healed File:** \`${t}\`
70
70
 
71
71
  Please review the changes.`,head:o,base:i});console.log(`\u2705 [Lisa.ai PR Engine] Pull Request created successfully: ${m.data.html_url}`)}else console.log("\u26A0\uFE0F [Lisa.ai PR Engine] GITHUB_TOKEN or GITHUB_REPOSITORY not set. Skipping GitHub Pull Request creation.")}catch(r){console.error(`
72
- \u{1F6A8} [Lisa.ai PR Engine Error] Failed to create Pull Request:`,r.message)}finally{try{await e.checkout(i)}catch{}}}var De=C(require("dotenv"));De.config({quiet:!0});async function D(t){let s=`${process.env.LISA_CONTROL_PLANE_URL||"http://localhost:3000"}/api/telemetry`;fetch(s,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(t)}).catch(o=>{console.debug(`[Lisa.ai Agent Debug] Failed to report telemetry: ${o.message}`)})}var R=C(require("fs")),P=C(require("path"));var se=C(require("fs")),Me=C(require("path")),_=".lisai.json",A=class{static _config=null;static _loaded=!1;static load(e=process.cwd()){if(this._loaded)return this._config;this._loaded=!0;let s=Me.resolve(e,_);if(!se.existsSync(s))return null;try{let o=se.readFileSync(s,"utf-8");return this._config=JSON.parse(o),console.log(`[Lisa.ai Config] Loaded project config from ${_}`),this._config}catch(o){return console.warn(`[Lisa.ai Config] Warning: ${_} found but failed to parse \u2014 ${o.message}. Using defaults.`),null}}static get(){return this._config}static applyEnvDefaults(e){if(!e.model)return;let s={claude:"LISA_CLAUDE_MODEL",openai:"LISA_OPENAI_MODEL",gemini:"LISA_GOOGLE_MODEL"},o=e.provider;o&&s[o]&&!process.env[s[o]]&&(process.env[s[o]]=e.model,console.log(`[Lisa.ai Config] Model override applied: ${o} \u2192 ${e.model}`))}static printSummary(e){let s=[];e.provider&&s.push(`provider=${e.provider}`),e.model&&s.push(`model=${e.model}`),e.testingFramework&&s.push(`testingFramework=${e.testingFramework}`),e.testTypes?.length&&s.push(`testTypes=[${e.testTypes.join(",")}]`),e.maxRetries!==void 0&&s.push(`maxRetries=${e.maxRetries}`),e.testCommand&&s.push(`testCommand="${e.testCommand}"`),s.length&&console.log(`[Lisa.ai Config] Settings: ${s.join(", ")}`),e.skipFiles?.length&&console.log(`[Lisa.ai Config] Extra skip files : ${e.skipFiles.join(", ")}`),e.skipDirs?.length&&console.log(`[Lisa.ai Config] Extra skip dirs : ${e.skipDirs.join(", ")}`),e.skipPaths?.length&&console.log(`[Lisa.ai Config] Extra skip paths : ${e.skipPaths.join(", ")}`)}};var N=class{static scanRepository(e=process.cwd()){let s=P.resolve(e,"package.json"),o={type:"unknown",testingFramework:"none"};if(!R.existsSync(s))return console.warn(`[Lisa.ai AutoDiscovery] No package.json found at ${s}. Defaulting to Generic Node.`),o.type="node",o;let n=JSON.parse(R.readFileSync(s,"utf8")),i={...n.dependencies||{},...n.devDependencies||{}},r=n.scripts||{};return i["@angular/core"]?o.type="angular":i.react?o.type="react":i.vue?o.type="vue":o.type="node",i.jest||r.test?.includes("jest")?o.testingFramework="jest":i.karma||r.test?.includes("karma")||r.test?.includes("ng test")?o.testingFramework="karma":(i.vitest||r.test?.includes("vitest"))&&(o.testingFramework="vitest"),o.testingFramework!=="none"&&(r.test?o.suggestedTestCommand="npm run test":o.testingFramework==="karma"?o.suggestedTestCommand="npx karma start":o.testingFramework==="jest"?o.suggestedTestCommand="npx jest --coverage":o.testingFramework==="vitest"&&(o.suggestedTestCommand="npx vitest run --coverage")),o}static findUntestedFiles(e,s=[]){let o=[];if(!R.existsSync(e))return o;let n=R.readdirSync(e),i=A.get(),r=i?.skipDirs??[],l=i?.skipFiles??[],g=i?.skipPaths??[],f=["node_modules","dist","build",".git",".angular","coverage","public","assets",...r],m=["main.ts","index.ts","index.js","index.jsx","app.config.ts","app.routes.ts","styles.css","styles.scss","tailwind.config.js","tailwind.config.ts","eslint.config.js","eslint.config.ts","jest.config.js","jest.config.ts","jest.config.mjs","jest.setup.js","jest.setup.ts","webpack.config.js","webpack.config.ts","babel.config.js","babel.config.ts","rollup.config.js","rollup.config.ts","vite.config.js","vite.config.ts","vitest.config.js","vitest.config.ts","karma.conf.js","karma.config.js","prettier.config.js","prettier.config.ts","postcss.config.js","postcss.config.ts","gulpfile.js","Gulpfile.js",".eslintrc.js",".eslintrc.ts",".babelrc.js"],d=[/^\./,/\.config\.(js|ts|mjs|cjs)$/,/\.conf\.(js|ts|mjs|cjs)$/];for(let c of n){let p=P.join(e,c);if(f.includes(c))continue;let v;try{v=R.statSync(p)}catch{continue}if(v.isDirectory())o.push(...this.findUntestedFiles(p,s));else if(c.match(/\.(ts|tsx|js|jsx|vue)$/)&&!c.includes(".spec.")&&!c.includes(".test.")){if(m.includes(c)||l.includes(c)||d.some(L=>L.test(c)))continue;let a=P.extname(c),h=c.slice(0,-a.length);if(![P.join(e,`${h}.spec${a}`),P.join(e,`${h}.test${a}`),P.join(e,`${h}.spec.js`),P.join(e,`${h}.test.js`),P.join(e,`${h}.spec.ts`),P.join(e,`${h}.test.ts`)].some(L=>R.existsSync(L))){let L=P.relative(process.cwd(),p);if(g.some(x=>L.startsWith(x)))continue;s.includes(L)||o.push(L)}}}return o}};var Oe=require("child_process"),B=class{static async installMissingFramework(e,s=process.cwd()){if(e.testingFramework!=="none")return e;console.log(`
72
+ \u{1F6A8} [Lisa.ai PR Engine Error] Failed to create Pull Request:`,r.message)}finally{try{await e.checkout(i)}catch{}}}var De=C(require("dotenv"));De.config({quiet:!0});async function D(t){let s=`${process.env.LISA_CONTROL_PLANE_URL||"http://localhost:3000"}/api/telemetry`;fetch(s,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(t)}).catch(o=>{console.debug(`[Lisa.ai Agent Debug] Failed to report telemetry: ${o.message}`)})}var R=C(require("fs")),P=C(require("path"));var oe=C(require("fs")),Me=C(require("path")),N=".lisai.json",A=class{static _config=null;static _loaded=!1;static load(e=process.cwd()){if(this._loaded)return this._config;this._loaded=!0;let s=Me.resolve(e,N);if(!oe.existsSync(s))return null;try{let o=oe.readFileSync(s,"utf-8");return this._config=JSON.parse(o),console.log(`[Lisa.ai Config] Loaded project config from ${N}`),this._config}catch(o){return console.warn(`[Lisa.ai Config] Warning: ${N} found but failed to parse \u2014 ${o.message}. Using defaults.`),null}}static get(){return this._config}static applyEnvDefaults(e){if(!e.model)return;let s={claude:"LISA_CLAUDE_MODEL",openai:"LISA_OPENAI_MODEL",gemini:"LISA_GOOGLE_MODEL"},o=e.provider;o&&s[o]&&!process.env[s[o]]&&(process.env[s[o]]=e.model,console.log(`[Lisa.ai Config] Model override applied: ${o} \u2192 ${e.model}`))}static printSummary(e){let s=[];e.provider&&s.push(`provider=${e.provider}`),e.model&&s.push(`model=${e.model}`),e.testingFramework&&s.push(`testingFramework=${e.testingFramework}`),e.testTypes?.length&&s.push(`testTypes=[${e.testTypes.join(",")}]`),e.maxRetries!==void 0&&s.push(`maxRetries=${e.maxRetries}`),e.testCommand&&s.push(`testCommand="${e.testCommand}"`),s.length&&console.log(`[Lisa.ai Config] Settings: ${s.join(", ")}`),e.skipFiles?.length&&console.log(`[Lisa.ai Config] Extra skip files : ${e.skipFiles.join(", ")}`),e.skipDirs?.length&&console.log(`[Lisa.ai Config] Extra skip dirs : ${e.skipDirs.join(", ")}`),e.skipPaths?.length&&console.log(`[Lisa.ai Config] Extra skip paths : ${e.skipPaths.join(", ")}`)}};var U=class{static scanRepository(e=process.cwd()){let s=P.resolve(e,"package.json"),o={type:"unknown",testingFramework:"none"};if(!R.existsSync(s))return console.warn(`[Lisa.ai AutoDiscovery] No package.json found at ${s}. Defaulting to Generic Node.`),o.type="node",o;let n=JSON.parse(R.readFileSync(s,"utf8")),i={...n.dependencies||{},...n.devDependencies||{}},r=n.scripts||{};return i["@angular/core"]?o.type="angular":i.react?o.type="react":i.vue?o.type="vue":o.type="node",i.jest||r.test?.includes("jest")?o.testingFramework="jest":i.karma||r.test?.includes("karma")||r.test?.includes("ng test")?o.testingFramework="karma":(i.vitest||r.test?.includes("vitest"))&&(o.testingFramework="vitest"),o.testingFramework!=="none"&&(r.test?o.suggestedTestCommand="npm run test":o.testingFramework==="karma"?o.suggestedTestCommand="npx karma start":o.testingFramework==="jest"?o.suggestedTestCommand="npx jest --coverage":o.testingFramework==="vitest"&&(o.suggestedTestCommand="npx vitest run --coverage")),o}static findUntestedFiles(e,s=[]){let o=[];if(!R.existsSync(e))return o;let n=R.readdirSync(e),i=A.get(),r=i?.skipDirs??[],l=i?.skipFiles??[],d=i?.skipPaths??[],f=["node_modules","dist","build",".git",".angular","coverage","public","assets",...r],m=["main.ts","index.ts","index.js","index.jsx","app.config.ts","app.routes.ts","styles.css","styles.scss","tailwind.config.js","tailwind.config.ts","eslint.config.js","eslint.config.ts","jest.config.js","jest.config.ts","jest.config.mjs","jest.setup.js","jest.setup.ts","webpack.config.js","webpack.config.ts","babel.config.js","babel.config.ts","rollup.config.js","rollup.config.ts","vite.config.js","vite.config.ts","vitest.config.js","vitest.config.ts","karma.conf.js","karma.config.js","prettier.config.js","prettier.config.ts","postcss.config.js","postcss.config.ts","gulpfile.js","Gulpfile.js",".eslintrc.js",".eslintrc.ts",".babelrc.js"],p=[/^\./,/\.config\.(js|ts|mjs|cjs)$/,/\.conf\.(js|ts|mjs|cjs)$/];for(let c of n){let g=P.join(e,c);if(f.includes(c))continue;let v;try{v=R.statSync(g)}catch{continue}if(v.isDirectory())o.push(...this.findUntestedFiles(g,s));else if(c.match(/\.(ts|tsx|js|jsx|vue)$/)&&!c.includes(".spec.")&&!c.includes(".test.")){if(m.includes(c)||l.includes(c)||p.some(L=>L.test(c)))continue;let a=P.extname(c),h=c.slice(0,-a.length);if(![P.join(e,`${h}.spec${a}`),P.join(e,`${h}.test${a}`),P.join(e,`${h}.spec.js`),P.join(e,`${h}.test.js`),P.join(e,`${h}.spec.ts`),P.join(e,`${h}.test.ts`)].some(L=>R.existsSync(L))){let L=P.relative(process.cwd(),g);if(d.some(x=>L.startsWith(x)))continue;s.includes(L)||o.push(L)}}}return o}};var Oe=require("child_process"),B=class{static async installMissingFramework(e,s=process.cwd()){if(e.testingFramework!=="none")return e;console.log(`
73
73
  [Lisa.ai Auto-Installer] \u{1F6A8} No testing framework detected for ${e.type} architecture.`),console.log("[Lisa.ai Auto-Installer] \u{1FA84} Initiating Zero-Config Installation Protocol...");let o="",n="none";switch(e.type){case"angular":console.log("[Lisa.ai Auto-Installer] Provisioning Angular TestBed environment..."),o="npm install --save-dev karma karma-chrome-launcher karma-coverage karma-jasmine jasmine-core @types/jasmine",n="karma",e.suggestedTestCommand="npm run test";break;case"react":case"node":default:console.log("[Lisa.ai Auto-Installer] Provisioning Universal Jest environment..."),o="npm install --save-dev jest @types/jest ts-jest",n="jest",e.suggestedTestCommand="npx jest --coverage";break;case"vue":console.log("[Lisa.ai Auto-Installer] Provisioning Vue Vitest environment..."),o="npm install --save-dev vitest @vue/test-utils jsdom",n="vitest",e.suggestedTestCommand="npx vitest run --coverage";break}if(o){console.log(`[Lisa.ai Executing] ${o}`);let i=o.split(" "),r=process.platform==="win32"?`${i[0]}.cmd`:i[0];return(0,Oe.spawnSync)(r,i.slice(1),{cwd:s,stdio:"inherit"}).status!==0&&(console.error(`
74
- \u274C [Lisa.ai Auto-Installer] Failed to construct dynamic testing environment.`),process.exit(1)),console.log("\u2705 [Lisa.ai Auto-Installer] Framework successfully injected."),e.testingFramework=n,e}return e}};var oe=C(require("fs")),ge=C(require("path"));var q=class{static async provisionConfigurationFiles(e,s,o,n=process.cwd()){if(e.testingFramework==="none")return;if(console.log(`
75
- [Lisa.ai Auto-Generator] \u{1FA84} Analyzing ${e.type} architecture to generate ${e.testingFramework} configuration specs...`),["jest.config.js","jest.config.ts","karma.conf.js","vitest.config.ts","vitest.config.js"].some(g=>oe.existsSync(ge.join(n,g)))){console.log("[Lisa.ai Auto-Generator] Setup file detected. Bypassing initialization.");return}let l=`You are an expert ${e.type} architect.
74
+ \u274C [Lisa.ai Auto-Installer] Failed to construct dynamic testing environment.`),process.exit(1)),console.log("\u2705 [Lisa.ai Auto-Installer] Framework successfully injected."),e.testingFramework=n,e}return e}};var ne=C(require("fs")),fe=C(require("path"));var q=class{static async provisionConfigurationFiles(e,s,o,n=process.cwd()){if(e.testingFramework==="none")return;if(console.log(`
75
+ [Lisa.ai Auto-Generator] \u{1FA84} Analyzing ${e.type} architecture to generate ${e.testingFramework} configuration specs...`),["jest.config.js","jest.config.ts","karma.conf.js","vitest.config.ts","vitest.config.js"].some(d=>ne.existsSync(fe.join(n,d)))){console.log("[Lisa.ai Auto-Generator] Setup file detected. Bypassing initialization.");return}let l=`You are an expert ${e.type} architect.
76
76
  Write a production-ready '${e.testingFramework}' configuration file for a standard '${e.type}' application.
77
77
  The application resides in the root directory.
78
78
 
@@ -80,27 +80,27 @@ Requirements:
80
80
  1. Ensure it specifically instruments code coverage.
81
81
  2. Ensure standard transpilation (ts-jest for jest, or standard karma-webpack/karma-typescript implementations).
82
82
  3. Do NOT wrap your response in markdown formatting (no \`\`\`javascript).
83
- 4. Return ONLY the raw code string block.`;try{let g=await te(l,s,o),f="";e.testingFramework==="jest"&&(f="jest.config.js"),e.testingFramework==="karma"&&(f="karma.conf.js"),e.testingFramework==="vitest"&&(f="vitest.config.ts");let m=ge.join(n,f);oe.writeFileSync(m,g,"utf-8"),console.log(`\u2705 [Lisa.ai Auto-Generator] Natively wrote ${f} to repository root.`)}catch(g){console.error(`
84
- \u274C [Lisa.ai Auto-Generator] Failed to author configuration file: ${g.message}`),process.exit(1)}}};var _e=C(require("dotenv"));_e.config({quiet:!0});function Ne(t){let e=t.toLowerCase();return e.includes("karma")||e.includes("ng test")?"karma":e.includes("jest")?"jest":e.includes("vitest")?"vitest":e.includes("playwright")?"playwright":e.includes("cypress")?"cypress":e.includes("mocha")?"mocha":"unknown"}async function Ue(t,e,s){if(s==="local")return[];let o=process.env.LISA_CONTROL_PLANE_URL||"http://localhost:3000";try{let n=new URLSearchParams({projectId:s,errorLog:t.slice(0,1e3),framework:e}),i=await fetch(`${o}/api/memory/lookup?${n}`);return i.ok?await i.json():[]}catch{return[]}}async function He(t,e,s,o){if(o==="local")return;let n=process.env.LISA_CONTROL_PLANE_URL||"http://localhost:3000";try{await fetch(`${n}/api/memory/record`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({projectId:o,errorLog:t.slice(0,1e3),fixHint:e.slice(0,2e3),framework:s})}),console.log("[Lisa.ai Memory] Fix pattern recorded to Control Plane.")}catch(i){console.debug(`[Lisa.ai Agent Debug] Failed to record memory pattern: ${i.message}`)}}var ne=3,ie=0,re=0;function at(t){let e=[...t.matchAll(/Executed\s+(\d+)\s+of\s+(\d+)(?:\s+\((\d+)\s+FAILED\))?/g)];if(e.length===0)return null;let s=e[e.length-1],o=parseInt(s[2]),n=s[3]?parseInt(s[3]):0,i=parseInt(s[1])-n;return{total:o,passed:i,failed:n}}function lt(t){let e=[...t.matchAll(/Executed\s+(\d+)\s+of\s+(\d+)(?:\s+\((\d+)\s+FAILED\))?/g)];if(e.length===0)return null;let s=e[e.length-1],o=parseInt(s[2]),n=s[3]?parseInt(s[3]):0,i=parseInt(s[1])-n,r=o>0?Math.round(i/o*100):0;return` [${"\u2588".repeat(Math.round(r/5))+"\u2591".repeat(20-Math.round(r/5))}] ${r}% ${i} passed ${n} failed ${o} total`}function ct(t){let e=[];for(let s of t.split(`
85
- `)){let o=s.replace(/\x1B\[[0-9;]*[a-zA-Z]/g,"").trim();if((/^FAILED/.test(o)||/ FAILED$/.test(o))&&(e.push(o),e.length>=5))break}return e}function ut(t){let e=t.replace(/\.(spec|test)\.(ts|js|jsx|tsx)$/,".$2");if(e!==t&&I.existsSync(e))try{return console.log(`[Lisa.ai Context Engine] \u{1F9E0} Located sibling logic structure at ${e}`),I.readFileSync(e,"utf-8")}catch{return}}function dt(t,e){let s=t.toLowerCase(),o=U.parse(e);if(s.includes("ng test")||s.includes("karma"))return`${t} --include **/${o.base}`;if(s.includes("jest")||s.includes("vitest")||s.includes("playwright"))return`${t} ${e}`;if(s.includes("cypress"))return`${t} --spec ${e}`;if(s.includes("npm")||s.includes("yarn")||s.includes("pnpm")){try{let i=U.resolve(process.cwd(),"package.json");if(I.existsSync(i)){let r=JSON.parse(I.readFileSync(i,"utf8")),l="test";s.includes("npm run ")?l=s.split("npm run ")[1].split(" ")[0]:s.includes("yarn ")?l=s.split("yarn ")[1].split(" ")[0]:s.includes("pnpm ")&&(l=s.split("pnpm ")[1].split(" ")[0]);let g=r.scripts?.[l]?.toLowerCase()||"",f=s.includes("npm")?" --":"";if(g.includes("ng test")||g.includes("karma"))return`${t}${f} --include **/${o.base}`;if(g.includes("jest")||g.includes("vitest")||g.includes("playwright"))return`${t}${f} ${e}`}}catch{}let n=s.includes("npm")?" --":"";return`${t}${n} ${e}`}return t}async function Y(t,e,s=1,o=null,n=3,i="local",r,l,g=[],f=0,m={}){let d=A.load(process.cwd());if(d&&(A.applyEnvDefaults(d),!t&&d.testCommand&&(t=d.testCommand,console.log(`[Lisa.ai Config] Using testCommand from .lisai.json: ${t}`))),!t){console.log(`
86
- [Lisa.ai Auto-Discovery] No explicit --command provided. Initiating Autonomous Framework Fingerprinting...`);let p=N.scanRepository();p.testingFramework==="none"&&(p=await B.installMissingFramework(p),await q.provisionConfigurationFiles(p,e,l)),p.suggestedTestCommand?(t=p.suggestedTestCommand,console.log(`[Lisa.ai Auto-Discovery] Bootstrapping execution with natively discovered command: ${t}`)):(console.error(`
83
+ 4. Return ONLY the raw code string block.`;try{let d=await se(l,s,o),f="";e.testingFramework==="jest"&&(f="jest.config.js"),e.testingFramework==="karma"&&(f="karma.conf.js"),e.testingFramework==="vitest"&&(f="vitest.config.ts");let m=fe.join(n,f);ne.writeFileSync(m,d,"utf-8"),console.log(`\u2705 [Lisa.ai Auto-Generator] Natively wrote ${f} to repository root.`)}catch(d){console.error(`
84
+ \u274C [Lisa.ai Auto-Generator] Failed to author configuration file: ${d.message}`),process.exit(1)}}};var _e=C(require("dotenv"));_e.config({quiet:!0});function Ne(t){let e=t.toLowerCase();return e.includes("karma")||e.includes("ng test")?"karma":e.includes("jest")?"jest":e.includes("vitest")?"vitest":e.includes("playwright")?"playwright":e.includes("cypress")?"cypress":e.includes("mocha")?"mocha":"unknown"}async function Ue(t,e,s){if(s==="local")return[];let o=process.env.LISA_CONTROL_PLANE_URL||"http://localhost:3000";try{let n=new URLSearchParams({projectId:s,errorLog:t.slice(0,1e3),framework:e}),i=await fetch(`${o}/api/memory/lookup?${n}`);return i.ok?await i.json():[]}catch{return[]}}async function He(t,e,s,o){if(o==="local")return;let n=process.env.LISA_CONTROL_PLANE_URL||"http://localhost:3000";try{await fetch(`${n}/api/memory/record`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({projectId:o,errorLog:t.slice(0,1e3),fixHint:e.slice(0,2e3),framework:s})}),console.log("[Lisa.ai Memory] Fix pattern recorded to Control Plane.")}catch(i){console.debug(`[Lisa.ai Agent Debug] Failed to record memory pattern: ${i.message}`)}}var ie=3,re=0,ae=0;function dt(t){let e=[...t.matchAll(/Executed\s+(\d+)\s+of\s+(\d+)(?:\s+\((\d+)\s+FAILED\))?/g)];if(e.length===0)return null;let s=[...e].reverse().find(r=>r[3]!==void 0)??e[e.length-1],o=parseInt(s[2]),n=s[3]?parseInt(s[3]):0,i=parseInt(s[1])-n;return{total:o,passed:i,failed:n}}function Ge(t){let e=[...t.matchAll(/Executed\s+(\d+)\s+of\s+(\d+)(?:\s+\((\d+)\s+FAILED\))?/g)];if(e.length===0)return null;let s=[...e].reverse().find(d=>d[3]!==void 0)??e[e.length-1],o=parseInt(s[2]),n=s[3]?parseInt(s[3]):0,i=parseInt(s[1])-n,r=o>0?Math.round(i/o*100):0;return` [${"\u2588".repeat(Math.round(r/5))+"\u2591".repeat(20-Math.round(r/5))}] ${r}% ${i} passed ${n} failed ${o} total`}function Be(t){let e=[];for(let s of t.split(`
85
+ `)){let o=s.replace(/\x1B\[[0-9;]*[a-zA-Z]/g,"").trim();if((/^FAILED/.test(o)||/ FAILED$/.test(o))&&(e.push(o),e.length>=5))break}return e}function pt(t){let e=t.replace(/\.(spec|test)\.(ts|js|jsx|tsx)$/,".$2");if(e!==t&&F.existsSync(e))try{return console.log(`[Lisa.ai Context Engine] \u{1F9E0} Located sibling logic structure at ${e}`),F.readFileSync(e,"utf-8")}catch{return}}function gt(t,e){let s=t.toLowerCase(),o=H.parse(e);if(s.includes("ng test")||s.includes("karma"))return`${t} --include **/${o.base}`;if(s.includes("jest")||s.includes("vitest")||s.includes("playwright"))return`${t} ${e}`;if(s.includes("cypress"))return`${t} --spec ${e}`;if(s.includes("npm")||s.includes("yarn")||s.includes("pnpm")){try{let i=H.resolve(process.cwd(),"package.json");if(F.existsSync(i)){let r=JSON.parse(F.readFileSync(i,"utf8")),l="test";s.includes("npm run ")?l=s.split("npm run ")[1].split(" ")[0]:s.includes("yarn ")?l=s.split("yarn ")[1].split(" ")[0]:s.includes("pnpm ")&&(l=s.split("pnpm ")[1].split(" ")[0]);let d=r.scripts?.[l]?.toLowerCase()||"",f=s.includes("npm")?" --":"";if(d.includes("ng test")||d.includes("karma"))return`${t}${f} --include **/${o.base}`;if(d.includes("jest")||d.includes("vitest")||d.includes("playwright"))return`${t}${f} ${e}`}}catch{}let n=s.includes("npm")?" --":"";return`${t}${n} ${e}`}return t}async function Y(t,e,s=1,o=null,n=3,i="local",r,l,d=[],f=0,m={}){let p=A.load(process.cwd());if(p&&(A.applyEnvDefaults(p),!t&&p.testCommand&&(t=p.testCommand,console.log(`[Lisa.ai Config] Using testCommand from .lisai.json: ${t}`))),!t){console.log(`
86
+ [Lisa.ai Auto-Discovery] No explicit --command provided. Initiating Autonomous Framework Fingerprinting...`);let g=U.scanRepository();g.testingFramework==="none"&&(g=await B.installMissingFramework(g),await q.provisionConfigurationFiles(g,e,l)),g.suggestedTestCommand?(t=g.suggestedTestCommand,console.log(`[Lisa.ai Auto-Discovery] Bootstrapping execution with natively discovered command: ${t}`)):(console.error(`
87
87
  \u{1F6A8} [Lisa.ai Fatal Error] Agent could not dynamically extrapolate a testing command for a Generic Node Environment. Please pass --command explicitly.`),process.exit(1))}console.log(`
88
- [Lisa.ai Executing] ${t} (Global Engine) Using Model: ${e}`);let c=(p,v=!1)=>new Promise((a,h)=>{let u=(0,Ge.spawn)(p,{shell:!0,stdio:["ignore","pipe","pipe"]}),y="",L="";u.stdout?.on("data",x=>{let k=x.toString();if(y+=k,v)for(let w of k.split(`
88
+ [Lisa.ai Executing] ${t} (Global Engine) Using Model: ${e}`);let c=(g,v=!1)=>new Promise((a,h)=>{let u=(0,qe.spawn)(g,{shell:!0,stdio:["ignore","pipe","pipe"]}),y="",L="";u.stdout?.on("data",x=>{let k=x.toString();if(y+=k,v)for(let w of k.split(`
89
89
  `)){let j=w.replace(/\x1B\[[0-9;]*[a-zA-Z]/g,"").trim();j&&(/Executed\s+\d+\s+of\s+\d+/.test(j)?process.stdout.write(`\r ${j.padEnd(72)}`):/^\s*FAILED\b/.test(j)&&(process.stdout.write(`
90
90
  `),console.log(` \u2717 ${j.trim()}`)))}}),u.stderr?.on("data",x=>{L+=x.toString()}),u.on("close",x=>{x===0?a({stdout:y,stderr:L}):h({message:`Process exited with code ${x}`,stdout:y,stderr:L})})});try{console.log("\u23F3 [Lisa.ai Testing] Booting Headless Test Suite..."),await c(t,!0),console.log(`
91
- \u2705 [Lisa.ai Success] Global Command executed successfully.`),o&&await Re(o);return}catch(p){process.stdout.write(`
92
- `),console.log("\u274C [Lisa.ai Failure] Global Command failed.");let v=(p.stderr||"")+`
93
- `+(p.stdout||"")+`
94
- `+(p.message||""),a=at(v),h=lt(v);if(h){console.log(`
95
- ${h}`);let T=ct(v);T.length>0&&(console.log(" Failing:"),T.forEach(F=>console.log(` \u2717 ${F}`)))}(ie>0||re>0)&&console.log(` Session: ${ie} healed ${re} quarantined`),console.log(`
96
- [Lisa.ai Auto-Heal] Analyzing errors...`);let u=Q(v,g,process.cwd());u||(console.error(`
97
- \u{1F6A8} [Lisa.ai Error] Could not parse a valid failing file path from the logs (or all were explicitly skipped).`),process.exit(1));let y=U.resolve(process.cwd(),u);I.existsSync(y)||(console.error(`
91
+ \u2705 [Lisa.ai Success] Global Command executed successfully.`),o&&await Re(o);return}catch(g){process.stdout.write(`
92
+ `),console.log("\u274C [Lisa.ai Failure] Global Command failed.");let v=(g.stderr||"")+`
93
+ `+(g.stdout||"")+`
94
+ `+(g.message||""),a=dt(v),h=Ge(v);if(h){console.log(`
95
+ ${h}`);let I=Be(v);I.length>0&&(console.log(" Failing:"),I.forEach(T=>console.log(` \u2717 ${T}`)))}(re>0||ae>0)&&console.log(` Session: ${re} healed ${ae} quarantined`),console.log(`
96
+ [Lisa.ai Auto-Heal] Analyzing errors...`);let u=ee(v,d,process.cwd());u||(console.error(`
97
+ \u{1F6A8} [Lisa.ai Error] Could not parse a valid failing file path from the logs (or all were explicitly skipped).`),process.exit(1));let y=H.resolve(process.cwd(),u);F.existsSync(y)||(console.error(`
98
98
  \u{1F6A8} [Lisa.ai Error] Extracted file path does not exist: ${y}`),process.exit(1)),/[\\/](node_modules|dist|build)[\\/]/.test(y)&&(console.error(`
99
- \u{1F6A8} [Lisa.ai Error] Refusing to modify a library file outside the project source: ${y}`),process.exit(1));let L=m[u]||0;if(L>=ne){console.warn(`
100
- [Lisa.ai Auto-Heal] \u26A0\uFE0F ${u} has failed globally ${L} time(s) \u2014 exceeds threshold of ${ne}. Permanently skipping.`),g.push(u),await Y(t,e,1,null,n,i,void 0,l,g,0,m);return}console.log(`[Lisa.ai Auto-Heal] Identified bleeding file: ${u} (global fail count: ${L}/${ne})`);let x=1,k=!1,w=v,j,z="",Z="",he=dt(t,u),Xe=ut(y),K=Ne(t),ue=(await Ue(v,K,i)).filter(T=>T.confidence>=.5).map(T=>T.fixHint);for(ue.length>0&&console.log(`[Lisa.ai Memory] Found ${ue.length} proven fix pattern(s) from Control Plane \u2014 injecting as LLM hint.`),await D({projectId:i,type:"heal",filePath:u,modelUsed:e,status:"running",details:"Agent is currently analyzing and applying patches...",...a&&{testTotal:a.total,testPassed:a.passed,testFailed:a.failed},testFramework:K});x<=n&&!k;){console.log(`
101
- [Lisa.ai Micro-Heal] Isolating ${u} (Attempt ${x}/${n})`);let T=I.readFileSync(y,"utf-8"),F;for(let E=0;E<=3;E++)try{F=await Ee(u,T,w,e,l,j,Xe,ue);break}catch(O){let H=(O?.lastError??O)?.statusCode;if((H===529||H===500)&&E<3){let G=30*(E+1);console.warn(`
102
- \u26A0\uFE0F [Lisa.ai LLM] API overloaded (HTTP ${H}). Waiting ${G}s before retry (${E+1}/3)...`),await new Promise(de=>setTimeout(de,G*1e3))}else{let G=O?.message??String(O);console.error(`
103
- \u{1F6A8} [Lisa.ai LLM Error] API call failed for ${u}: ${G}`),console.warn("[Lisa.ai LLM Error] All retries exhausted \u2014 skipping this file for the current run.");break}}if(F===void 0)break;I.writeFileSync(y,F,"utf-8"),console.log(`[Lisa.ai Micro-Heal] Applied isolated patch to ${u}`),z=`### Auto-Heal Analysis Triggered
99
+ \u{1F6A8} [Lisa.ai Error] Refusing to modify a library file outside the project source: ${y}`),process.exit(1));let L=m[u]||0;if(L>=ie){console.warn(`
100
+ [Lisa.ai Auto-Heal] \u26A0\uFE0F ${u} has failed globally ${L} time(s) \u2014 exceeds threshold of ${ie}. Permanently skipping.`),d.push(u),await Y(t,e,1,null,n,i,void 0,l,d,0,m);return}console.log(`[Lisa.ai Auto-Heal] Identified bleeding file: ${u} (global fail count: ${L}/${ie})`);let x=1,k=!1,w=v,j,z="",Z="",ye=gt(t,u),et=pt(y),K=Ne(t),de=(await Ue(v,K,i)).filter(I=>I.confidence>=.5).map(I=>I.fixHint);for(de.length>0&&console.log(`[Lisa.ai Memory] Found ${de.length} proven fix pattern(s) from Control Plane \u2014 injecting as LLM hint.`),await D({projectId:i,type:"heal",filePath:u,modelUsed:e,status:"running",details:"Agent is currently analyzing and applying patches...",...a&&{testTotal:a.total,testPassed:a.passed,testFailed:a.failed},testFramework:K});x<=n&&!k;){console.log(`
101
+ [Lisa.ai Micro-Heal] Isolating ${u} (Attempt ${x}/${n})`);let I=F.readFileSync(y,"utf-8"),T;for(let E=0;E<=3;E++)try{T=await Ee(u,I,w,e,l,j,et,de);break}catch(O){let G=(O?.lastError??O)?.statusCode;if((G===529||G===500)&&E<3){let _=30*(E+1);console.warn(`
102
+ \u26A0\uFE0F [Lisa.ai LLM] API overloaded (HTTP ${G}). Waiting ${_}s before retry (${E+1}/3)...`),await new Promise(J=>setTimeout(J,_*1e3))}else{let _=O?.message??String(O);console.error(`
103
+ \u{1F6A8} [Lisa.ai LLM Error] API call failed for ${u}: ${_}`),console.warn("[Lisa.ai LLM Error] All retries exhausted \u2014 skipping this file for the current run.");break}}if(T===void 0)break;F.writeFileSync(y,T,"utf-8"),console.log(`[Lisa.ai Micro-Heal] Applied isolated patch to ${u}`),z=`### Auto-Heal Analysis Triggered
104
104
  **Caught Error:**
105
105
  \`\`\`bash
106
106
  ${w}
@@ -108,58 +108,58 @@ ${w}
108
108
 
109
109
  **Applied Fix (${e}):**
110
110
  \`\`\`typescript
111
- ${F}
112
- \`\`\``;try{console.log(`[Lisa.ai Micro-Heal] Verifying fix with isolated command: ${he}`),await c(he,!1),console.log(`\u2705 [Lisa.ai Micro-Heal] Isolated verification passed for ${u}!`),k=!0,Z=F}catch(E){console.log("\u274C [Lisa.ai Micro-Heal] Isolated verification failed.");let O=E.stdout?E.stdout.toString():"";w=(E.stderr?E.stderr.toString():"")+`
111
+ ${T}
112
+ \`\`\``;try{console.log(`[Lisa.ai Micro-Heal] Verifying fix with isolated command: ${ye}`),await c(ye,!1),console.log(`\u2705 [Lisa.ai Micro-Heal] Isolated verification passed for ${u}!`),k=!0,Z=T}catch(E){console.log("\u274C [Lisa.ai Micro-Heal] Isolated verification failed.");let O=E.stdout?E.stdout.toString():"";w=(E.stderr?E.stderr.toString():"")+`
113
113
  `+O+`
114
- `+(E.message||"");let H=(t||"").toLowerCase();if(H.includes("ng test")||H.includes("karma")){let ye=U.basename(u),G=w.includes(ye+":"),de=/ FAILED/.test(w);if(!G&&!de){console.log(`\u2705 [Lisa.ai Micro-Heal] Fix verified for ${u} \u2014 isolated error is from other spec files, not this one.`),k=!0,Z=F;continue}}j=`### Attempt ${x} Failed
114
+ `+(E.message||"");let G=Ge(w);G&&console.log(G);let pe=Be(w);pe.length>0&&(console.log(" Failing (isolated):"),pe.slice(0,3).forEach(J=>console.log(` \u2717 ${J}`)));let _=(t||"").toLowerCase();if(_.includes("ng test")||_.includes("karma")){let J=H.basename(u),st=w.includes(J+":"),ot=/ FAILED/.test(w);if(!st&&!ot){console.log(`\u2705 [Lisa.ai Micro-Heal] Fix verified for ${u} \u2014 isolated error is from other spec files, not this one.`),k=!0,Z=T;continue}}j=`### Attempt ${x} Failed
115
115
  \`\`\`typescript
116
- ${F}
116
+ ${T}
117
117
  \`\`\`
118
118
 
119
119
  **New Error:**
120
- ${w}`,x++}}if(k)ie++,console.log(`
121
- Healed: ${u}`),console.log(` Session: ${ie} healed ${re} quarantined`),await D({projectId:i,type:"heal",filePath:u,modelUsed:e,status:"success",details:z,...a&&{testTotal:a.total,testPassed:a.passed,testFailed:a.failed},testFramework:K}),await He(v,Z,K,i);else if(re++,console.warn(`
120
+ ${w}`,x++}}if(k)re++,console.log(`
121
+ Healed: ${u}`),console.log(` Session: ${re} healed ${ae} quarantined`),await D({projectId:i,type:"heal",filePath:u,modelUsed:e,status:"success",details:z,...a&&{testTotal:a.total,testPassed:a.passed,testFailed:a.failed},testFramework:K}),await He(v,Z,K,i);else if(ae++,console.warn(`
122
122
  [Lisa.ai Auto-Heal] \u26A0\uFE0F Agent failed to locally heal ${u} after ${n} isolated attempts. Marking as Skipped to avoid infinite Loop.`),await D({projectId:i,type:"heal",filePath:u,modelUsed:e,status:"error",details:`Agent exhausted all ${n} attempts without success.
123
123
 
124
- `+z,...a&&{testTotal:a.total,testPassed:a.passed,testFailed:a.failed},testFramework:K}),m[u]=(m[u]||0)+1,console.log(`[Lisa.ai Auto-Heal] Global fail counter for ${u}: ${m[u]}/${ne}`),g.push(u),u.match(/\.(spec|test)\.(ts|js|tsx|jsx|vue)$/)){let T=(t||"").toLowerCase();if(T.includes("ng test")||T.includes("karma"))try{I.writeFileSync(y,`// Quarantined by Lisa.ai \u2014 could not be automatically healed
124
+ `+z,...a&&{testTotal:a.total,testPassed:a.passed,testFailed:a.failed},testFramework:K}),m[u]=(m[u]||0)+1,console.log(`[Lisa.ai Auto-Heal] Global fail counter for ${u}: ${m[u]}/${ie}`),d.push(u),u.match(/\.(spec|test)\.(ts|js|tsx|jsx|vue)$/)){let I=(t||"").toLowerCase();if(I.includes("ng test")||I.includes("karma"))try{F.writeFileSync(y,`// Quarantined by Lisa.ai \u2014 could not be automatically healed
125
125
  describe('', () => {});
126
- `,"utf-8"),console.log(`[Lisa.ai Auto-Heal] \u{1F6A8} Quarantined unhealable spec ${u} \u2014 replaced with empty stub to keep Angular build clean.`)}catch{}else{let E=y+".broken";try{I.renameSync(y,E),console.log(`[Lisa.ai Auto-Heal] \u{1F6A8} Renamed unhealable spec to ${u}.broken to force the test runner to bypass it!`)}catch{}}}await Y(t,e,1,k?u:null,n,i,void 0,l,g,0,m)}}var We=require("child_process"),M=C(require("fs")),b=C(require("path"));var ae=C(require("fs")),Be=C(require("path"));function qe(t){let e=Be.resolve(process.cwd(),t);if(!ae.existsSync(e))throw new Error(`[Lisa.ai Coverage Error] Coverage file not found at ${e}`);let s=ae.readFileSync(e,"utf-8"),o=JSON.parse(s),n=[];for(let[i,r]of Object.entries(o))i!=="total"&&(r.lines.pct<100||r.statements.pct<100||r.functions.pct<100||r.branches.pct<100)&&n.push(i);return n}var Ye=new Set,le=0,fe=3;async function V(t,e,s=1,o=3,n="local",i){let r=A.load(process.cwd());r&&(A.applyEnvDefaults(r),!t&&r.testCommand&&(t=r.testCommand,console.log(`[Lisa.ai Config] Using testCommand from .lisai.json: ${t}`)));let l=N.scanRepository(),g=r?.testingFramework||(l.testingFramework!=="none"?l.testingFramework:void 0),f=r?.testTypes;if(!t){console.log(`
127
- [Lisa.ai Auto-Discovery] No explicit --command provided. Initiating Autonomous Framework Fingerprinting...`);let d=l;if(d.testingFramework==="none"&&(d=await B.installMissingFramework(d),await q.provisionConfigurationFiles(d,e,i)),d.suggestedTestCommand){t=d.suggestedTestCommand;let c=d.testingFramework;(c==="jest"||c==="vitest")&&!t.includes("--coverage")&&(t=t.includes("npm run")?`${t} -- --coverage`:`${t} --coverage`,console.log(`[Lisa.ai Coverage] Coverage flag appended: ${t}`)),console.log(`[Lisa.ai Auto-Discovery] Bootstrapping execution with natively discovered command: ${t}`)}else console.error(`
126
+ `,"utf-8"),console.log(`[Lisa.ai Auto-Heal] \u{1F6A8} Quarantined unhealable spec ${u} \u2014 replaced with empty stub to keep Angular build clean.`)}catch{}else{let E=y+".broken";try{F.renameSync(y,E),console.log(`[Lisa.ai Auto-Heal] \u{1F6A8} Renamed unhealable spec to ${u}.broken to force the test runner to bypass it!`)}catch{}}}await Y(t,e,1,k?u:null,n,i,void 0,l,d,0,m)}}var Ze=require("child_process"),M=C(require("fs")),b=C(require("path"));var le=C(require("fs")),Ye=C(require("path"));function We(t){let e=Ye.resolve(process.cwd(),t);if(!le.existsSync(e))throw new Error(`[Lisa.ai Coverage Error] Coverage file not found at ${e}`);let s=le.readFileSync(e,"utf-8"),o=JSON.parse(s),n=[];for(let[i,r]of Object.entries(o))i!=="total"&&(r.lines.pct<100||r.statements.pct<100||r.functions.pct<100||r.branches.pct<100)&&n.push(i);return n}var ze=new Set,ce=0,me=3;async function X(t,e,s=1,o=3,n="local",i){let r=A.load(process.cwd());r&&(A.applyEnvDefaults(r),!t&&r.testCommand&&(t=r.testCommand,console.log(`[Lisa.ai Config] Using testCommand from .lisai.json: ${t}`)));let l=U.scanRepository(),d=r?.testingFramework||(l.testingFramework!=="none"?l.testingFramework:void 0),f=r?.testTypes;if(!t){console.log(`
127
+ [Lisa.ai Auto-Discovery] No explicit --command provided. Initiating Autonomous Framework Fingerprinting...`);let p=l;if(p.testingFramework==="none"&&(p=await B.installMissingFramework(p),await q.provisionConfigurationFiles(p,e,i)),p.suggestedTestCommand){t=p.suggestedTestCommand;let c=p.testingFramework;(c==="jest"||c==="vitest")&&!t.includes("--coverage")&&(t=t.includes("npm run")?`${t} -- --coverage`:`${t} --coverage`,console.log(`[Lisa.ai Coverage] Coverage flag appended: ${t}`)),console.log(`[Lisa.ai Auto-Discovery] Bootstrapping execution with natively discovered command: ${t}`)}else console.error(`
128
128
  \u{1F6A8} [Lisa.ai Fatal Error] Agent could not dynamically extrapolate a testing command for a Generic Node Environment. Please pass --command explicitly.`),process.exit(1)}console.log(`
129
- [Lisa.ai Coverage] ${t} (Attempt ${s}/${o}) Using Model: ${e}`),await D({projectId:n,type:"coverage",filePath:"global-test-suite",modelUsed:e,status:"running",details:"Agent is currently executing testing suite and validating coverage drops..."});let m=(d,c=!1)=>new Promise((p,v)=>{let a=(0,We.spawn)(d,{shell:!0,stdio:["ignore","pipe","pipe"]}),h="",u="";a.stdout?.on("data",y=>{let L=y.toString();if(h+=L,c){let x=L.split(`
130
- `);for(let k of x){let w=k.match(/Executed\s+(\d+)\s+of\s+(\d+)/);if(w){let j=k.match(/(\d+)\s+FAILED/),z=j?j[1]:0,Z=`\r\u23F3 [Lisa.ai Testing] Executed ${w[1]} of ${w[2]} (${z} FAILED) `;process.stdout.write(Z)}}}}),a.stderr?.on("data",y=>{u+=y.toString()}),a.on("close",y=>{y===0?p():v({message:`Test process exited with code ${y}`,stdout:h,stderr:u})})});try{console.log("[Lisa.ai Coverage] Booting testing framework in the background. This may take a moment..."),await m(t,!0),console.log(`
131
- \u2705 [Lisa.ai Coverage] Tests passed successfully on attempt ${s}.`)}catch(d){let c=(d.stderr||"")+`
132
- `+(d.stdout||"")+`
133
- `+(d.message||"");if(Q(c,[],process.cwd())!==null){console.log(`
129
+ [Lisa.ai Coverage] ${t} (Attempt ${s}/${o}) Using Model: ${e}`),await D({projectId:n,type:"coverage",filePath:"global-test-suite",modelUsed:e,status:"running",details:"Agent is currently executing testing suite and validating coverage drops..."});let m=(p,c=!1)=>new Promise((g,v)=>{let a=(0,Ze.spawn)(p,{shell:!0,stdio:["ignore","pipe","pipe"]}),h="",u="";a.stdout?.on("data",y=>{let L=y.toString();if(h+=L,c){let x=L.split(`
130
+ `);for(let k of x){let w=k.match(/Executed\s+(\d+)\s+of\s+(\d+)/);if(w){let j=k.match(/(\d+)\s+FAILED/),z=j?j[1]:0,Z=`\r\u23F3 [Lisa.ai Testing] Executed ${w[1]} of ${w[2]} (${z} FAILED) `;process.stdout.write(Z)}}}}),a.stderr?.on("data",y=>{u+=y.toString()}),a.on("close",y=>{y===0?g():v({message:`Test process exited with code ${y}`,stdout:h,stderr:u})})});try{console.log("[Lisa.ai Coverage] Booting testing framework in the background. This may take a moment..."),await m(t,!0),console.log(`
131
+ \u2705 [Lisa.ai Coverage] Tests passed successfully on attempt ${s}.`)}catch(p){let c=(p.stderr||"")+`
132
+ `+(p.stdout||"")+`
133
+ `+(p.message||"");if(ee(c,[],process.cwd())!==null){console.log(`
134
134
  \u274C [Lisa.ai Coverage] Tests failed. Delegating to Auto-Heal...`),await Y(t,e,1,null,o,n,void 0,i),console.log(`
135
- \u{1F504} [Lisa.ai Coverage] Auto-Heal successful. Restarting coverage analysis...`),await V(t,e,s+1,o,n,i);return}console.log(`
136
- [Lisa.ai Coverage] No failing spec file detected in error output. Tests may not exist yet \u2014 initiating Cold-Start Discovery...`)}try{let d=b.resolve(process.cwd(),"coverage/coverage-summary.json"),c=[];if(M.existsSync(d))console.log("[Lisa.ai Coverage] Evaluating summary..."),c=qe("coverage/coverage-summary.json");else{if(console.log(`
137
- [Lisa.ai Coverage] No coverage-summary.json found. Initiating Cold-Start Project Crawler...`),c=N.findUntestedFiles(process.cwd(),[...Ye]),c.length===0){console.log("\u2705 [Lisa.ai Coverage] Zero-Test scan complete. No untested source files discovered.");return}console.log(`[Lisa.ai Coverage] Discovered ${c.length} untested file(s). Seeding first test suite...`)}if(c.length===0){console.log("\u2705 [Lisa.ai Coverage] 100% Logic Coverage Verified! No un-covered files remaining.");return}console.log(`[Lisa.ai Coverage] Found ${c.length} file(s) below 100% threshold:`,c);let p=c[0],v=b.resolve(process.cwd(),p),a=b.parse(v),h=[b.join(a.dir,`${a.name}.spec${a.ext}`),b.join(a.dir,`${a.name}.test${a.ext}`),b.join(a.dir,`${a.name}.spec.js`),b.join(a.dir,`${a.name}.test.js`),b.join(a.dir,`${a.name}.spec.ts`),b.join(a.dir,`${a.name}.test.ts`)],u=null,y=b.join(a.dir,`${a.name}.spec${a.ext}`);for(let w of h)if(M.existsSync(w)){y=w,u=M.readFileSync(w,"utf-8");break}let L="",x=!1,k=M.readFileSync(v,"utf-8");try{u?(console.log(`[Lisa.ai Coverage] Existing test suite discovered for ${p}. Requesting single-pass logic coverage append...`),L=await Ie(p,k,b.relative(process.cwd(),y),u,e,i,g,f)):(console.log(`[Lisa.ai Coverage] Requesting newly generated test suite for ${p}...`),L=await Pe(p,k,e,i,g,f)),le=0,x=!0}catch(w){le++,Ye.add(p);let j=w.cause?.message?`${w.message} (cause: ${w.cause.message})`:w.message;if(console.error(`
138
- \u274C [Lisa.ai Coverage] LLM call failed for ${p} \u2014 consecutive failure #${le}/${fe}`),console.error(` Error: ${j}`),le>=fe)throw new Error(`Systematic LLM failure: ${fe} consecutive API calls failed.
135
+ \u{1F504} [Lisa.ai Coverage] Auto-Heal successful. Restarting coverage analysis...`),await X(t,e,s+1,o,n,i);return}console.log(`
136
+ [Lisa.ai Coverage] No failing spec file detected in error output. Tests may not exist yet \u2014 initiating Cold-Start Discovery...`)}try{let p=b.resolve(process.cwd(),"coverage/coverage-summary.json"),c=[];if(M.existsSync(p))console.log("[Lisa.ai Coverage] Evaluating summary..."),c=We("coverage/coverage-summary.json");else{if(console.log(`
137
+ [Lisa.ai Coverage] No coverage-summary.json found. Initiating Cold-Start Project Crawler...`),c=U.findUntestedFiles(process.cwd(),[...ze]),c.length===0){console.log("\u2705 [Lisa.ai Coverage] Zero-Test scan complete. No untested source files discovered.");return}console.log(`[Lisa.ai Coverage] Discovered ${c.length} untested file(s). Seeding first test suite...`)}if(c.length===0){console.log("\u2705 [Lisa.ai Coverage] 100% Logic Coverage Verified! No un-covered files remaining.");return}console.log(`[Lisa.ai Coverage] Found ${c.length} file(s) below 100% threshold:`,c);let g=c[0],v=b.resolve(process.cwd(),g),a=b.parse(v),h=[b.join(a.dir,`${a.name}.spec${a.ext}`),b.join(a.dir,`${a.name}.test${a.ext}`),b.join(a.dir,`${a.name}.spec.js`),b.join(a.dir,`${a.name}.test.js`),b.join(a.dir,`${a.name}.spec.ts`),b.join(a.dir,`${a.name}.test.ts`)],u=null,y=b.join(a.dir,`${a.name}.spec${a.ext}`);for(let w of h)if(M.existsSync(w)){y=w,u=M.readFileSync(w,"utf-8");break}let L="",x=!1,k=M.readFileSync(v,"utf-8");try{u?(console.log(`[Lisa.ai Coverage] Existing test suite discovered for ${g}. Requesting single-pass logic coverage append...`),L=await Fe(g,k,b.relative(process.cwd(),y),u,e,i,d,f)):(console.log(`[Lisa.ai Coverage] Requesting newly generated test suite for ${g}...`),L=await Pe(g,k,e,i,d,f)),ce=0,x=!0}catch(w){ce++,ze.add(g);let j=w.cause?.message?`${w.message} (cause: ${w.cause.message})`:w.message;if(console.error(`
138
+ \u274C [Lisa.ai Coverage] LLM call failed for ${g} \u2014 consecutive failure #${ce}/${me}`),console.error(` Error: ${j}`),ce>=me)throw new Error(`Systematic LLM failure: ${me} consecutive API calls failed.
139
139
  This usually means your API key has insufficient credits, hit a rate limit, or the model is unavailable.
140
140
  Last error: ${j}
141
- Tip: Check your API key, account credits, and rate-limit quota for provider '${e}'.`)}if(!x){await V(t,e,s+1,o,n,i);return}M.writeFileSync(y,L,"utf-8"),console.log(`[Lisa.ai Coverage] Wrote Spec File to ${y}`),await D({projectId:n,type:"coverage",filePath:p,modelUsed:e,status:"success",details:`### Logic Coverage Action Detected
141
+ Tip: Check your API key, account credits, and rate-limit quota for provider '${e}'.`)}if(!x){await X(t,e,s+1,o,n,i);return}M.writeFileSync(y,L,"utf-8"),console.log(`[Lisa.ai Coverage] Wrote Spec File to ${y}`),await D({projectId:n,type:"coverage",filePath:g,modelUsed:e,status:"success",details:`### Logic Coverage Action Detected
142
142
  **Auto-Generated Specification Append (${e}):**
143
143
  \`\`\`typescript
144
144
  ${L}
145
- \`\`\``}),await V(t,e,s+1,o,n,i)}catch(d){console.error("[Lisa.ai Coverage loop failure]:",d.message),await D({projectId:n,type:"coverage",filePath:"coverage-loop",modelUsed:e,status:"error",details:`Coverage loop encountered an unrecoverable error: ${d.message}`})}}var Ve=ze();function me(){console.log(`
146
- ======================================================`),console.log(`\u2728 Lisa.ai Agent v${Ve.version} Running... `),console.log(" Where pure magic happens! \u{1FA84}"),console.log(`======================================================
147
- `)}var W=new Ze.Command;W.name("lisa-agent").description("Lisa.ai - Autonomous CI/CD Platform Worker Agent").version(Ve.version);W.command("heal").description("Run a command and autonomously heal errors").option("-c, --command <type>","Command to execute (Optional for Auto-Discovery)").option("-m, --model <provider>","LLM provider to use (gemini, claude, openai)","gemini").option("-p, --project-id <id>","Control Plane Project ID to fetch dynamic config").action(async t=>{me();let e=5,s=t.model,o;if(t.projectId){let i=await X(t.projectId);if(!i.ok)i.reason==="not_found"?(console.error(`
145
+ \`\`\``}),await X(t,e,s+1,o,n,i)}catch(p){console.error("[Lisa.ai Coverage loop failure]:",p.message),await D({projectId:n,type:"coverage",filePath:"coverage-loop",modelUsed:e,status:"error",details:`Coverage loop encountered an unrecoverable error: ${p.message}`})}}var Qe=Ke();function he(){console.log(`
146
+ ======================================================`),console.log(`\u2728 Lisa.ai Agent v${Qe.version} Running... `),console.log(" Where pure magic happens! \u{1FA84}"),console.log(`======================================================
147
+ `)}var W=new Je.Command;W.name("lisa-agent").description("Lisa.ai - Autonomous CI/CD Platform Worker Agent").version(Qe.version);W.command("heal").description("Run a command and autonomously heal errors").option("-c, --command <type>","Command to execute (Optional for Auto-Discovery)").option("-m, --model <provider>","LLM provider to use (gemini, claude, openai)","gemini").option("-p, --project-id <id>","Control Plane Project ID to fetch dynamic config").action(async t=>{he();let e=5,s=t.model,o;if(t.projectId){let i=await Q(t.projectId);if(!i.ok)i.reason==="not_found"?(console.error(`
148
148
  \u{1F6A8} [Lisa.ai Agent Error] Project '${t.projectId}' does not exist on the Control Plane. Please create it in the Dashboard first or run locally without a project ID.`),process.exit(1)):console.warn(`
149
149
  \u26A0\uFE0F [Lisa.ai Warning] Control Plane is unreachable. Continuing with local CLI defaults (model=${s}, maxRetries=${e}).`);else{let r=i.config;console.log(`[Lisa.ai Agent] Dynamic Config Loaded: Provider=${r.modelProvider}, MaxRetries=${r.maxRetries}`),r.maxRetries<5&&console.warn(`
150
- \u26A0\uFE0F [Lisa.ai Warning] Your Dashboard Analytics Config has maxRetries set to ${r.maxRetries}. Consider increasing this to 5+ in the WEB UI for complex Angular Healing!`),s=r.modelProvider,e=r.maxRetries,o=r.apiKey,r.autoHealEnabled===!1&&(console.log("[Lisa.ai Agent] Auto-heal is disabled by Control Plane."),process.exit(1))}}let n=A.load(process.cwd());n&&(A.applyEnvDefaults(n),!t.projectId&&n.maxRetries!==void 0&&(e=n.maxRetries),!t.projectId&&n.provider&&t.model==="gemini"&&(s=n.provider),A.printSummary(n)),await Y(t.command,s,1,null,e,t.projectId||"local",void 0,o)});W.command("coverage").description("Run test command dynamically generating missing specs for 100% coverage").option("-c, --command <type>","Test command to execute (Optional for Auto-Discovery)").option("-m, --model <provider>","LLM provider to use (gemini, claude, openai)","gemini").option("-p, --project-id <id>","Control Plane Project ID to fetch dynamic config").action(async t=>{me();let e=5,s=t.model,o;if(t.projectId){let i=await X(t.projectId);if(!i.ok)i.reason==="not_found"?(console.error(`
150
+ \u26A0\uFE0F [Lisa.ai Warning] Your Dashboard Analytics Config has maxRetries set to ${r.maxRetries}. Consider increasing this to 5+ in the WEB UI for complex Angular Healing!`),s=r.modelProvider,e=r.maxRetries,o=r.apiKey,r.autoHealEnabled===!1&&(console.log("[Lisa.ai Agent] Auto-heal is disabled by Control Plane."),process.exit(1))}}let n=A.load(process.cwd());n&&(A.applyEnvDefaults(n),!t.projectId&&n.maxRetries!==void 0&&(e=n.maxRetries),!t.projectId&&n.provider&&t.model==="gemini"&&(s=n.provider),A.printSummary(n)),await Y(t.command,s,1,null,e,t.projectId||"local",void 0,o)});W.command("coverage").description("Run test command dynamically generating missing specs for 100% coverage").option("-c, --command <type>","Test command to execute (Optional for Auto-Discovery)").option("-m, --model <provider>","LLM provider to use (gemini, claude, openai)","gemini").option("-p, --project-id <id>","Control Plane Project ID to fetch dynamic config").action(async t=>{he();let e=5,s=t.model,o;if(t.projectId){let i=await Q(t.projectId);if(!i.ok)i.reason==="not_found"?(console.error(`
151
151
  \u{1F6A8} [Lisa.ai Agent Error] Project '${t.projectId}' does not exist on the Control Plane. Please create it in the Dashboard first or run locally without a project ID.`),process.exit(1)):console.warn(`
152
152
  \u26A0\uFE0F [Lisa.ai Warning] Control Plane is unreachable. Continuing with local CLI defaults (model=${s}, maxRetries=${e}).`);else{let r=i.config;console.log(`[Lisa.ai Agent] Dynamic Config Loaded: Provider=${r.modelProvider}, MaxRetries=${r.maxRetries}`),r.maxRetries<5&&console.warn(`
153
- \u26A0\uFE0F [Lisa.ai Warning] Your Dashboard Analytics Config has maxRetries set to ${r.maxRetries}. Consider increasing this to 5+ in the WEB UI for complex Angular Healing!`),s=r.modelProvider,e=r.maxRetries,o=r.apiKey,r.autoHealEnabled===!1&&(console.log("[Lisa.ai Agent] Auto-heal is disabled by Control Plane."),process.exit(1))}}let n=A.load(process.cwd());n&&(A.applyEnvDefaults(n),!t.projectId&&n.maxRetries!==void 0&&(e=n.maxRetries),!t.projectId&&n.provider&&t.model==="gemini"&&(s=n.provider),A.printSummary(n)),await V(t.command,s,1,e,t.projectId||"local",o)});W.command("diagnose").description("Test LLM connectivity and API key health without running the full agent").option("-m, --model <provider>","LLM provider to test (gemini, claude, openai)","claude").option("-p, --project-id <id>","Control Plane Project ID to fetch API key from").action(async t=>{me();let e=t.model,s;if(t.projectId){let i=await X(t.projectId);i.ok?(e=i.config.modelProvider,s=i.config.apiKey,console.log(`[Lisa.ai Diagnose] Config fetched from Control Plane. Provider=${e}`)):console.warn(`[Lisa.ai Diagnose] Control Plane ${i.reason}. Using local env for API key.`)}let n={claude:process.env.LISA_CLAUDE_MODEL||"claude-haiku-4-5",openai:process.env.LISA_OPENAI_MODEL||"gpt-4o-mini",gemini:process.env.LISA_GOOGLE_MODEL||"gemini-2.0-flash"}[e]||e;console.log(`
154
- [Lisa.ai Diagnose] Testing ${e} \u2192 model ID: ${n}`);try{let i=await te("Reply with exactly: LISA_OK",e,s);console.log(`
153
+ \u26A0\uFE0F [Lisa.ai Warning] Your Dashboard Analytics Config has maxRetries set to ${r.maxRetries}. Consider increasing this to 5+ in the WEB UI for complex Angular Healing!`),s=r.modelProvider,e=r.maxRetries,o=r.apiKey,r.autoHealEnabled===!1&&(console.log("[Lisa.ai Agent] Auto-heal is disabled by Control Plane."),process.exit(1))}}let n=A.load(process.cwd());n&&(A.applyEnvDefaults(n),!t.projectId&&n.maxRetries!==void 0&&(e=n.maxRetries),!t.projectId&&n.provider&&t.model==="gemini"&&(s=n.provider),A.printSummary(n)),await X(t.command,s,1,e,t.projectId||"local",o)});W.command("diagnose").description("Test LLM connectivity and API key health without running the full agent").option("-m, --model <provider>","LLM provider to test (gemini, claude, openai)","claude").option("-p, --project-id <id>","Control Plane Project ID to fetch API key from").action(async t=>{he();let e=t.model,s;if(t.projectId){let i=await Q(t.projectId);i.ok?(e=i.config.modelProvider,s=i.config.apiKey,console.log(`[Lisa.ai Diagnose] Config fetched from Control Plane. Provider=${e}`)):console.warn(`[Lisa.ai Diagnose] Control Plane ${i.reason}. Using local env for API key.`)}let n={claude:process.env.LISA_CLAUDE_MODEL||"claude-haiku-4-5",openai:process.env.LISA_OPENAI_MODEL||"gpt-4o-mini",gemini:process.env.LISA_GOOGLE_MODEL||"gemini-2.0-flash"}[e]||e;console.log(`
154
+ [Lisa.ai Diagnose] Testing ${e} \u2192 model ID: ${n}`);try{let i=await se("Reply with exactly: LISA_OK",e,s);console.log(`
155
155
  \u2705 [Lisa.ai Diagnose] ${e} is working correctly.`),console.log(` Model response: "${i}"`)}catch(i){console.error(`
156
156
  \u274C [Lisa.ai Diagnose] ${e} call FAILED.`),console.error(` Error: ${i.message}`),i.cause&&console.error(` Cause: ${i.cause?.message??i.cause}`),console.error(`
157
- Common causes:`),console.error(" \u2022 API key is invalid, expired, or has no credits"),console.error(" \u2022 Model ID is deprecated (current: claude-sonnet-4-6, gemini-2.0-flash, gpt-4o-mini)"),console.error(" \u2022 Rate limit exceeded \u2014 wait a minute and retry"),console.error(" \u2022 Network/proxy issue blocking api.anthropic.com"),process.exit(1)}});W.command("init").description("Interactively create a .lisai.json config file in the current project").option("--force","Overwrite existing .lisai.json if it exists").action(async t=>{let e=Ke.resolve(process.cwd(),_);ce.existsSync(e)&&!t.force&&(console.error(`
158
- \u274C [Lisa.ai Init] ${_} already exists. Use --force to overwrite.`),process.exit(1));let s=Je.createInterface({input:process.stdin,output:process.stdout}),o=(m,d="")=>new Promise(c=>s.question(d?`${m} [${d}]: `:`${m}: `,p=>c(p.trim()||d)));console.log(`
157
+ Common causes:`),console.error(" \u2022 API key is invalid, expired, or has no credits"),console.error(" \u2022 Model ID is deprecated (current: claude-sonnet-4-6, gemini-2.0-flash, gpt-4o-mini)"),console.error(" \u2022 Rate limit exceeded \u2014 wait a minute and retry"),console.error(" \u2022 Network/proxy issue blocking api.anthropic.com"),process.exit(1)}});W.command("init").description("Interactively create a .lisai.json config file in the current project").option("--force","Overwrite existing .lisai.json if it exists").action(async t=>{let e=Ve.resolve(process.cwd(),N);ue.existsSync(e)&&!t.force&&(console.error(`
158
+ \u274C [Lisa.ai Init] ${N} already exists. Use --force to overwrite.`),process.exit(1));let s=Xe.createInterface({input:process.stdin,output:process.stdout}),o=(m,p="")=>new Promise(c=>s.question(p?`${m} [${p}]: `:`${m}: `,g=>c(g.trim()||p)));console.log(`
159
159
  \u{1F680} Lisa.ai Project Setup \u2014 press Enter to accept the default shown in [ ]
160
- `);let n=await o("LLM provider (gemini / claude / openai)","gemini"),i=await o("Testing framework (jest / vitest / mocha / karma / cypress / playwright \u2014 leave empty to auto-detect)",""),r=await o("Test types to generate (unit / integration / e2e \u2014 comma-separated)","unit"),l=await o("Test command (leave empty for auto-discovery)",""),g=await o("Max heal retries","5");s.close();let f={provider:n,testTypes:r.split(",").map(m=>m.trim()).filter(Boolean),maxRetries:parseInt(g,10)||5,skipFiles:[],skipDirs:[],skipPaths:[]};i&&(f.testingFramework=i),l&&(f.testCommand=l),ce.writeFileSync(e,JSON.stringify(f,null,2)+`
160
+ `);let n=await o("LLM provider (gemini / claude / openai)","gemini"),i=await o("Testing framework (jest / vitest / mocha / karma / cypress / playwright \u2014 leave empty to auto-detect)",""),r=await o("Test types to generate (unit / integration / e2e \u2014 comma-separated)","unit"),l=await o("Test command (leave empty for auto-discovery)",""),d=await o("Max heal retries","5");s.close();let f={provider:n,testTypes:r.split(",").map(m=>m.trim()).filter(Boolean),maxRetries:parseInt(d,10)||5,skipFiles:[],skipDirs:[],skipPaths:[]};i&&(f.testingFramework=i),l&&(f.testCommand=l),ue.writeFileSync(e,JSON.stringify(f,null,2)+`
161
161
  `,"utf-8"),console.log(`
162
- \u2705 Created ${_}:
162
+ \u2705 Created ${N}:
163
163
  `),console.log(JSON.stringify(f,null,2)),console.log(`
164
164
  Tip: add "model" to pin a specific model ID (e.g. "claude-sonnet-4-6").`),console.log(` Edit skipFiles / skipDirs / skipPaths to exclude files from coverage analysis.
165
165
  `)});W.parse(process.argv);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lisa.ai/agent",
3
- "version": "2.6.0",
3
+ "version": "2.6.1",
4
4
  "description": "Lisa.ai Autonomous CI/CD Worker Agent",
5
5
  "main": "dist/index.js",
6
6
  "bin": {