@lisa.ai/agent 1.1.9 → 1.1.12

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.
@@ -44,11 +44,37 @@ const telemetry_service_1 = require("../services/telemetry.service");
44
44
  async function coverageCommand(command, modelProvider, attempt = 1, maxRetries = 3, projectId = 'local', apiKey) {
45
45
  console.log(`\n[Lisa.ai Coverage] ${command} (Attempt ${attempt}/${maxRetries}) Using Model: ${modelProvider}`);
46
46
  let executionPassed = true;
47
+ const runSilentlyAndIntercept = (cmd, printProgress = false) => {
48
+ return new Promise((resolve, reject) => {
49
+ // Node 21+ Deprecation Fix: When shell is true, pass the entire raw command string
50
+ // rather than explicitly escaping array arguments to bypass DEP0190.
51
+ const child = (0, child_process_1.spawn)(cmd, { shell: true, stdio: ['ignore', 'pipe', 'pipe'] });
52
+ child.stdout?.on('data', (data) => {
53
+ const text = data.toString();
54
+ if (printProgress) {
55
+ const lines = text.split('\n');
56
+ for (const line of lines) {
57
+ if (line.includes('Executed')) {
58
+ process.stdout.write(line + '\n');
59
+ }
60
+ }
61
+ }
62
+ });
63
+ child.on('close', (code) => {
64
+ if (code === 0) {
65
+ resolve();
66
+ }
67
+ else {
68
+ reject(new Error(`Test process exited with code ${code}`));
69
+ }
70
+ });
71
+ });
72
+ };
47
73
  try {
48
74
  // 1. Run the test command which should ideally produce coverage-summary.json
49
- // Use 'pipe' to strictly capture output and prevent generic test suite spam in the terminal.
50
- console.log(`[Lisa.ai Coverage] Booting testing framework silently in the background. This may take a moment...`);
51
- (0, child_process_1.execSync)(command, { encoding: 'utf-8', stdio: 'pipe' });
75
+ // Use the native interceptor to stream the live Karma/Jest progress bar without error spam
76
+ console.log(`[Lisa.ai Coverage] Booting testing framework in the background. This may take a moment...`);
77
+ await runSilentlyAndIntercept(command, true);
52
78
  console.log(`\n✅ [Lisa.ai Coverage] Tests passed successfully on attempt ${attempt}.`);
53
79
  }
54
80
  catch (error) {
@@ -43,25 +43,92 @@ const git_service_1 = require("../services/git.service");
43
43
  const telemetry_service_1 = require("../services/telemetry.service");
44
44
  function isolateTestCommand(globalCommand, targetFile) {
45
45
  const cmd = globalCommand.toLowerCase();
46
- // Angular/Karma
46
+ const parsed = path.parse(targetFile);
47
+ // 1. Explicit Frameworks
47
48
  if (cmd.includes('ng test') || cmd.includes('karma')) {
48
- return `${globalCommand} --include ${targetFile}`;
49
+ return `${globalCommand} --include **/${parsed.base}`;
49
50
  }
50
- // Jest/Vitest/Playwright
51
51
  if (cmd.includes('jest') || cmd.includes('vitest') || cmd.includes('playwright')) {
52
52
  return `${globalCommand} ${targetFile}`;
53
53
  }
54
- // Cypress
55
54
  if (cmd.includes('cypress')) {
56
55
  return `${globalCommand} --spec ${targetFile}`;
57
56
  }
57
+ // 2. Generic Package Manager Scripts (npm run test, yarn test)
58
+ if (cmd.includes('npm') || cmd.includes('yarn') || cmd.includes('pnpm')) {
59
+ try {
60
+ const packageJsonPath = path.resolve(process.cwd(), 'package.json');
61
+ if (fs.existsSync(packageJsonPath)) {
62
+ const pkg = JSON.parse(fs.readFileSync(packageJsonPath, 'utf8'));
63
+ let scriptName = 'test';
64
+ if (cmd.includes('npm run ')) {
65
+ scriptName = cmd.split('npm run ')[1].split(' ')[0];
66
+ }
67
+ else if (cmd.includes('yarn ')) {
68
+ scriptName = cmd.split('yarn ')[1].split(' ')[0];
69
+ }
70
+ else if (cmd.includes('pnpm ')) {
71
+ scriptName = cmd.split('pnpm ')[1].split(' ')[0];
72
+ }
73
+ const testScript = pkg.scripts?.[scriptName]?.toLowerCase() || '';
74
+ const dashDash = cmd.includes('npm') ? ' --' : '';
75
+ // Deducing underlying framework from package manager translation
76
+ if (testScript.includes('ng test') || testScript.includes('karma')) {
77
+ return `${globalCommand}${dashDash} --include **/${parsed.base}`;
78
+ }
79
+ if (testScript.includes('jest') || testScript.includes('vitest') || testScript.includes('playwright')) {
80
+ return `${globalCommand}${dashDash} ${targetFile}`;
81
+ }
82
+ }
83
+ }
84
+ catch (e) {
85
+ // Silently fallback if package.json is inaccessible
86
+ }
87
+ // 3. Ultimate Fallback: Assume it behaves like standard generic node environments
88
+ const dashDash = cmd.includes('npm') ? ' --' : '';
89
+ return `${globalCommand}${dashDash} ${targetFile}`;
90
+ }
58
91
  return globalCommand;
59
92
  }
60
93
  async function healCommand(command, modelProvider, attempt = 1, healedFilePath = null, maxRetries = 3, projectId = 'local', lastFixDetails, apiKey, skipLedger = [], consecutiveFails = 0, failTracker = {}) {
61
94
  console.log(`\n[Lisa.ai Executing] ${command} (Global Engine) Using Model: ${modelProvider}`);
95
+ const runSilentlyAndIntercept = (cmd, printProgress = false) => {
96
+ return new Promise((resolve, reject) => {
97
+ // Node 21+ Deprecation Fix: When shell is true, pass the entire raw command string
98
+ // rather than explicitly escaping array arguments to bypass DEP0190.
99
+ const child = (0, child_process_1.spawn)(cmd, { shell: true, stdio: ['ignore', 'pipe', 'pipe'] });
100
+ let stdoutData = '';
101
+ let stderrData = '';
102
+ child.stdout?.on('data', (data) => {
103
+ const text = data.toString();
104
+ stdoutData += text;
105
+ // [Lisa.ai Stream Interceptor]
106
+ // The user explicitly requested to see the progress bar, but not the gigantic error dumps.
107
+ // We filter the stdout to only print lines containing "Executed" (Karma/Jasmine standard).
108
+ if (printProgress) {
109
+ const lines = text.split('\n');
110
+ for (const line of lines) {
111
+ if (line.includes('Executed')) {
112
+ process.stdout.write(line + '\n');
113
+ }
114
+ }
115
+ }
116
+ });
117
+ child.stderr?.on('data', (data) => {
118
+ stderrData += data.toString();
119
+ });
120
+ child.on('close', (code) => {
121
+ if (code === 0) {
122
+ resolve({ stdout: stdoutData, stderr: stderrData });
123
+ }
124
+ else {
125
+ reject({ message: `Process exited with code ${code}`, stdout: stdoutData, stderr: stderrData });
126
+ }
127
+ });
128
+ });
129
+ };
62
130
  try {
63
- const output = (0, child_process_1.execSync)(command, { encoding: 'utf-8', stdio: 'pipe' });
64
- console.log(output);
131
+ await runSilentlyAndIntercept(command, true); // True = stream progress globally
65
132
  console.log(`\n✅ [Lisa.ai Success] Global Command executed successfully.`);
66
133
  if (healedFilePath) {
67
134
  await (0, git_service_1.createPullRequestForHeal)(healedFilePath);
@@ -112,7 +179,7 @@ async function healCommand(command, modelProvider, attempt = 1, healedFilePath =
112
179
  try {
113
180
  // Verify the isolated file silently without exploding the Global terminal with 400 other spec errors
114
181
  console.log(`[Lisa.ai Micro-Heal] Verifying fix with isolated command: ${isolatedCommand}`);
115
- (0, child_process_1.execSync)(isolatedCommand, { encoding: 'utf-8', stdio: 'pipe' });
182
+ await runSilentlyAndIntercept(isolatedCommand, false); // False = completely invisible isolated healing
116
183
  console.log(`✅ [Lisa.ai Micro-Heal] Isolated verification passed for ${filePath}!`);
117
184
  isFixed = true;
118
185
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lisa.ai/agent",
3
- "version": "1.1.9",
3
+ "version": "1.1.12",
4
4
  "description": "Lisa.ai Autonomous CI/CD Worker Agent",
5
5
  "main": "dist/index.js",
6
6
  "bin": {