@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.
- package/dist/commands/coverage.js +29 -3
- package/dist/commands/heal.js +74 -7
- package/package.json +1 -1
|
@@ -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
|
|
50
|
-
console.log(`[Lisa.ai Coverage] Booting testing framework
|
|
51
|
-
|
|
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) {
|
package/dist/commands/heal.js
CHANGED
|
@@ -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
|
-
|
|
46
|
+
const parsed = path.parse(targetFile);
|
|
47
|
+
// 1. Explicit Frameworks
|
|
47
48
|
if (cmd.includes('ng test') || cmd.includes('karma')) {
|
|
48
|
-
return `${globalCommand} --include
|
|
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
|
-
|
|
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
|
-
|
|
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
|
}
|