ft-scout 3.0.9 → 4.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/bin/src/commands/agent.d.ts.map +1 -1
- package/bin/src/commands/agent.js +130 -101
- package/bin/src/commands/agent.js.map +1 -1
- package/bin/src/engine/agentEngine.d.ts.map +1 -1
- package/bin/src/engine/agentEngine.js +47 -17
- package/bin/src/engine/agentEngine.js.map +1 -1
- package/bin/src/engine/llm.js +3 -3
- package/bin/src/engine/llm.js.map +1 -1
- package/bin/src/engine/verifier.d.ts.map +1 -0
- package/bin/src/engine/verifier.js +275 -0
- package/bin/src/engine/verifier.js.map +1 -0
- package/bin/src/index.js +4 -4
- package/bin/src/utils/branding.js +1 -1
- package/package.json +1 -1
|
@@ -0,0 +1,275 @@
|
|
|
1
|
+
import fs from 'fs';
|
|
2
|
+
import path from 'path';
|
|
3
|
+
import { exec } from 'child_process';
|
|
4
|
+
import { promisify } from 'util';
|
|
5
|
+
import chalk from 'chalk';
|
|
6
|
+
import { spinner } from '@clack/prompts';
|
|
7
|
+
import { generateCodeFix } from './llm.js';
|
|
8
|
+
const execAsync = promisify(exec);
|
|
9
|
+
/**
|
|
10
|
+
* Perform automated syntax, type, and compilation check on a target file
|
|
11
|
+
*/
|
|
12
|
+
export async function checkFileSyntax(filePath, cwd) {
|
|
13
|
+
const fullPath = path.isAbsolute(filePath) ? filePath : path.resolve(cwd, filePath);
|
|
14
|
+
if (!fs.existsSync(fullPath) || !fs.statSync(fullPath).isFile()) {
|
|
15
|
+
return { valid: false, errors: [`File not found: ${filePath}`], output: `File not found: ${filePath}` };
|
|
16
|
+
}
|
|
17
|
+
const ext = path.extname(filePath).toLowerCase();
|
|
18
|
+
// 1. JSON Syntax Check
|
|
19
|
+
if (ext === '.json') {
|
|
20
|
+
try {
|
|
21
|
+
const content = fs.readFileSync(fullPath, 'utf-8');
|
|
22
|
+
JSON.parse(content);
|
|
23
|
+
return { valid: true, errors: [], output: 'Valid JSON syntax.' };
|
|
24
|
+
}
|
|
25
|
+
catch (err) {
|
|
26
|
+
return { valid: false, errors: [`JSON Syntax Error: ${err?.message || String(err)}`], output: err?.message || String(err) };
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
// 2. JavaScript / TypeScript Check
|
|
30
|
+
if (['.js', '.mjs', '.cjs', '.ts', '.tsx', '.jsx'].includes(ext)) {
|
|
31
|
+
const hasTsConfig = fs.existsSync(path.join(cwd, 'tsconfig.json'));
|
|
32
|
+
if (hasTsConfig && ['.ts', '.tsx'].includes(ext)) {
|
|
33
|
+
try {
|
|
34
|
+
const { stdout, stderr } = await execAsync('npx tsc --noEmit', { cwd, maxBuffer: 10 * 1024 * 1024 });
|
|
35
|
+
return { valid: true, errors: [], output: stdout || 'TypeScript compilation clean.' };
|
|
36
|
+
}
|
|
37
|
+
catch (err) {
|
|
38
|
+
const errOut = (err.stdout || '') + '\n' + (err.stderr || '') + '\n' + (err.message || '');
|
|
39
|
+
const lines = errOut.split('\n');
|
|
40
|
+
const fileErrors = lines.filter((l) => l.includes(filePath) || l.includes(path.basename(filePath)));
|
|
41
|
+
const relevantOut = fileErrors.length > 0 ? fileErrors.join('\n') : errOut.slice(0, 3000);
|
|
42
|
+
return { valid: false, errors: [relevantOut], output: errOut.slice(0, 4000) };
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
try {
|
|
46
|
+
const { stderr } = await execAsync(`node --check "${fullPath}"`, { cwd });
|
|
47
|
+
if (stderr && stderr.includes('SyntaxError')) {
|
|
48
|
+
return { valid: false, errors: [stderr], output: stderr };
|
|
49
|
+
}
|
|
50
|
+
return { valid: true, errors: [], output: 'Node syntax check passed.' };
|
|
51
|
+
}
|
|
52
|
+
catch (err) {
|
|
53
|
+
const errOut = (err.stderr || '') || (err.stdout || '') || err.message || String(err);
|
|
54
|
+
return { valid: false, errors: [errOut], output: errOut };
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
// 3. Python Syntax Check
|
|
58
|
+
if (ext === '.py') {
|
|
59
|
+
try {
|
|
60
|
+
const pyCmd = process.platform === 'win32' ? 'python' : 'python3';
|
|
61
|
+
const { stdout, stderr } = await execAsync(`${pyCmd} -m py_compile "${fullPath}"`, { cwd });
|
|
62
|
+
return { valid: true, errors: [], output: stdout || 'Python syntax clean.' };
|
|
63
|
+
}
|
|
64
|
+
catch (err) {
|
|
65
|
+
const errOut = (err.stderr || '') || (err.stdout || '') || err.message || String(err);
|
|
66
|
+
return { valid: false, errors: [errOut], output: errOut };
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
// 4. Go Syntax Check
|
|
70
|
+
if (ext === '.go') {
|
|
71
|
+
try {
|
|
72
|
+
const { stdout, stderr } = await execAsync(`go vet "${fullPath}"`, { cwd });
|
|
73
|
+
return { valid: true, errors: [], output: stdout || 'Go check clean.' };
|
|
74
|
+
}
|
|
75
|
+
catch (err) {
|
|
76
|
+
const errOut = (err.stderr || '') || (err.stdout || '') || err.message || String(err);
|
|
77
|
+
return { valid: false, errors: [errOut], output: errOut };
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
// 5. Rust Syntax Check
|
|
81
|
+
if (ext === '.rs') {
|
|
82
|
+
try {
|
|
83
|
+
const { stdout, stderr } = await execAsync(`cargo check`, { cwd });
|
|
84
|
+
return { valid: true, errors: [], output: stdout || 'Cargo check clean.' };
|
|
85
|
+
}
|
|
86
|
+
catch (err) {
|
|
87
|
+
const errOut = (err.stderr || '') || (err.stdout || '') || err.message || String(err);
|
|
88
|
+
return { valid: false, errors: [errOut], output: errOut };
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
return { valid: true, errors: [], output: 'File extension has no standalone compiler check.' };
|
|
92
|
+
}
|
|
93
|
+
/**
|
|
94
|
+
* Execute custom verification command or package build check
|
|
95
|
+
*/
|
|
96
|
+
export async function runProjectVerification(cwd, verifyCmd) {
|
|
97
|
+
if (verifyCmd && verifyCmd.trim()) {
|
|
98
|
+
try {
|
|
99
|
+
const { stdout, stderr } = await execAsync(verifyCmd.trim(), { cwd, maxBuffer: 10 * 1024 * 1024 });
|
|
100
|
+
return { valid: true, errors: [], output: (stdout || '') + (stderr ? `\n${stderr}` : '') };
|
|
101
|
+
}
|
|
102
|
+
catch (err) {
|
|
103
|
+
const combined = (err.stdout || '') + '\n' + (err.stderr || '') + '\n' + (err.message || '');
|
|
104
|
+
return { valid: false, errors: [combined.slice(0, 4000)], output: combined.slice(0, 8000) };
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
const pkgPath = path.join(cwd, 'package.json');
|
|
108
|
+
if (fs.existsSync(pkgPath)) {
|
|
109
|
+
try {
|
|
110
|
+
const pkg = JSON.parse(fs.readFileSync(pkgPath, 'utf-8'));
|
|
111
|
+
if (pkg.scripts && pkg.scripts.build && !pkg.scripts.build.includes('no test specified')) {
|
|
112
|
+
try {
|
|
113
|
+
const { stdout, stderr } = await execAsync('npm run build', { cwd, maxBuffer: 10 * 1024 * 1024 });
|
|
114
|
+
return { valid: true, errors: [], output: stdout || 'npm run build clean.' };
|
|
115
|
+
}
|
|
116
|
+
catch (err) {
|
|
117
|
+
const combined = (err.stdout || '') + '\n' + (err.stderr || '') + '\n' + (err.message || '');
|
|
118
|
+
return { valid: false, errors: [combined.slice(0, 4000)], output: combined.slice(0, 8000) };
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
catch { }
|
|
123
|
+
}
|
|
124
|
+
return { valid: true, errors: [], output: 'No build verification command executed.' };
|
|
125
|
+
}
|
|
126
|
+
/**
|
|
127
|
+
* Auto-fix and recheck files iteratively until errors are resolved or max retries reached
|
|
128
|
+
*/
|
|
129
|
+
export async function verifyAndSelfHealFiles(targetFiles, cwd, projectName, filesList, options) {
|
|
130
|
+
const maxRetries = options?.maxRetries || 3;
|
|
131
|
+
const verifiedFiles = [];
|
|
132
|
+
const remainingErrors = [];
|
|
133
|
+
for (const file of targetFiles) {
|
|
134
|
+
let attempts = 0;
|
|
135
|
+
let isClean = false;
|
|
136
|
+
while (attempts < maxRetries) {
|
|
137
|
+
attempts++;
|
|
138
|
+
const checkRes = await checkFileSyntax(file, cwd);
|
|
139
|
+
if (checkRes.valid) {
|
|
140
|
+
isClean = true;
|
|
141
|
+
break;
|
|
142
|
+
}
|
|
143
|
+
// Error detected! Auto-fix and recheck!
|
|
144
|
+
const vSpin = spinner();
|
|
145
|
+
vSpin.start(chalk.yellow(`🔍 Error detected in ${file}. Running auto-fix attempt ${attempts}/${maxRetries}...`));
|
|
146
|
+
const fullPath = path.isAbsolute(file) ? file : path.resolve(cwd, file);
|
|
147
|
+
let currentContent = '';
|
|
148
|
+
try {
|
|
149
|
+
currentContent = fs.readFileSync(fullPath, 'utf-8');
|
|
150
|
+
}
|
|
151
|
+
catch {
|
|
152
|
+
remainingErrors.push(`Could not read file ${file} for auto-fix.`);
|
|
153
|
+
break;
|
|
154
|
+
}
|
|
155
|
+
try {
|
|
156
|
+
const fixResult = await generateCodeFix(`Fix syntax, runtime, or logical error in file "${file}":\n${checkRes.errors.join('\n')}`, projectName, filesList, file, currentContent, options?.language, options?.native);
|
|
157
|
+
if (fixResult.fixedCode && fixResult.fixedCode.trim()) {
|
|
158
|
+
fs.writeFileSync(fullPath, fixResult.fixedCode, 'utf-8');
|
|
159
|
+
}
|
|
160
|
+
// Recheck file after applying fix!
|
|
161
|
+
const recheck = await checkFileSyntax(file, cwd);
|
|
162
|
+
if (recheck.valid) {
|
|
163
|
+
vSpin.stop(chalk.green(`✓ Fix confirmed! ${file} is now error-free (Verified on attempt ${attempts}).`));
|
|
164
|
+
isClean = true;
|
|
165
|
+
break;
|
|
166
|
+
}
|
|
167
|
+
else {
|
|
168
|
+
vSpin.stop(chalk.yellow(`⚠️ Fix applied to ${file}, but recheck found remaining error. Retrying (${attempts}/${maxRetries})...`));
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
catch (fixErr) {
|
|
172
|
+
vSpin.stop(chalk.red(`Failed fix attempt on ${file}: ${fixErr?.message || String(fixErr)}`));
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
if (isClean) {
|
|
176
|
+
verifiedFiles.push(file);
|
|
177
|
+
}
|
|
178
|
+
else {
|
|
179
|
+
remainingErrors.push(`File ${file} failed verification after ${maxRetries} self-healing attempt(s).`);
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
// Check overall project build verification if custom verifyCmd or tsconfig exists
|
|
183
|
+
if (options?.verifyCmd || fs.existsSync(path.join(cwd, 'tsconfig.json'))) {
|
|
184
|
+
const projCheck = await runProjectVerification(cwd, options?.verifyCmd);
|
|
185
|
+
if (!projCheck.valid) {
|
|
186
|
+
remainingErrors.push(`Project build/test verification failed:\n${projCheck.errors.join('\n')}`);
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
return {
|
|
190
|
+
success: remainingErrors.length === 0,
|
|
191
|
+
verifiedFiles,
|
|
192
|
+
remainingErrors,
|
|
193
|
+
};
|
|
194
|
+
}
|
|
195
|
+
/**
|
|
196
|
+
* Executes a shell command smartly: fast commands return exit code immediately,
|
|
197
|
+
* while persistent server/daemon processes (e.g. node server.js, npm start) are left running in background
|
|
198
|
+
* so Scout Agent does not hang.
|
|
199
|
+
*/
|
|
200
|
+
export function executeSmartCommand(cmd, cwd, initialWaitMs = 3000, maxWaitMs = 20000) {
|
|
201
|
+
return new Promise((resolve) => {
|
|
202
|
+
const proc = exec(cmd, { cwd });
|
|
203
|
+
const outputBuffers = [];
|
|
204
|
+
let hasResolved = false;
|
|
205
|
+
const isLikelyServer = /\b(?:node|nodemon|python|python3|flask|uvicorn|vite|next|http-server|live-server|serve|pm2|npm\s+(?:start|run\s+dev|run\s+server))\b/i.test(cmd) ||
|
|
206
|
+
/\b(?:server|app|main|index|dev|watch)\.(?:js|ts|py|go)\b/i.test(cmd) ||
|
|
207
|
+
/\b(?:--watch|-w|watch)\b/i.test(cmd);
|
|
208
|
+
proc.stdout?.on('data', (data) => {
|
|
209
|
+
outputBuffers.push(data.toString());
|
|
210
|
+
});
|
|
211
|
+
proc.stderr?.on('data', (data) => {
|
|
212
|
+
outputBuffers.push(data.toString());
|
|
213
|
+
});
|
|
214
|
+
proc.on('close', (code) => {
|
|
215
|
+
if (!hasResolved) {
|
|
216
|
+
hasResolved = true;
|
|
217
|
+
clearTimeout(timer);
|
|
218
|
+
resolve({
|
|
219
|
+
exitCode: code ?? 0,
|
|
220
|
+
output: outputBuffers.join(''),
|
|
221
|
+
isBackgroundServer: false,
|
|
222
|
+
pid: proc.pid,
|
|
223
|
+
});
|
|
224
|
+
}
|
|
225
|
+
});
|
|
226
|
+
proc.on('error', (err) => {
|
|
227
|
+
if (!hasResolved) {
|
|
228
|
+
hasResolved = true;
|
|
229
|
+
clearTimeout(timer);
|
|
230
|
+
resolve({
|
|
231
|
+
exitCode: 1,
|
|
232
|
+
output: `Process Error: ${err.message}`,
|
|
233
|
+
isBackgroundServer: false,
|
|
234
|
+
});
|
|
235
|
+
}
|
|
236
|
+
});
|
|
237
|
+
const timer = setTimeout(() => {
|
|
238
|
+
if (hasResolved)
|
|
239
|
+
return;
|
|
240
|
+
const currentOutput = outputBuffers.join('');
|
|
241
|
+
const hasServerKeywords = /\b(?:listening|running|started|connected|ready|port|http:\/\/|https:\/\/)\b/i.test(currentOutput);
|
|
242
|
+
if (isLikelyServer || hasServerKeywords) {
|
|
243
|
+
hasResolved = true;
|
|
244
|
+
try {
|
|
245
|
+
proc.unref();
|
|
246
|
+
}
|
|
247
|
+
catch { }
|
|
248
|
+
resolve({
|
|
249
|
+
exitCode: 0,
|
|
250
|
+
output: (currentOutput || 'Server process started successfully.') + `\n[Process is running continuously in background (PID ${proc.pid})].`,
|
|
251
|
+
isBackgroundServer: true,
|
|
252
|
+
pid: proc.pid,
|
|
253
|
+
});
|
|
254
|
+
}
|
|
255
|
+
else {
|
|
256
|
+
setTimeout(() => {
|
|
257
|
+
if (!hasResolved) {
|
|
258
|
+
hasResolved = true;
|
|
259
|
+
try {
|
|
260
|
+
proc.unref();
|
|
261
|
+
}
|
|
262
|
+
catch { }
|
|
263
|
+
resolve({
|
|
264
|
+
exitCode: 0,
|
|
265
|
+
output: outputBuffers.join('') + `\n[Command took over ${maxWaitMs / 1000}s, continuing in background (PID ${proc.pid})].`,
|
|
266
|
+
isBackgroundServer: true,
|
|
267
|
+
pid: proc.pid,
|
|
268
|
+
});
|
|
269
|
+
}
|
|
270
|
+
}, Math.max(1000, maxWaitMs - initialWaitMs));
|
|
271
|
+
}
|
|
272
|
+
}, initialWaitMs);
|
|
273
|
+
});
|
|
274
|
+
}
|
|
275
|
+
//# sourceMappingURL=verifier.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"verifier.js","sourceRoot":"","sources":["verifier.ts"],"names":[],"mappings":"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"}
|
package/bin/src/index.js
CHANGED
|
@@ -24,12 +24,12 @@ program
|
|
|
24
24
|
.name('scout')
|
|
25
25
|
.alias('ft')
|
|
26
26
|
.description('FrontTerrain — The Onboarding Co-Pilot for New Codebases')
|
|
27
|
-
.version('
|
|
27
|
+
.version('4.0.1');
|
|
28
28
|
// Header UI on execution with FrontTerrain proprietary logo & version auto-checker
|
|
29
29
|
program.hook('preAction', async (_thisCommand, actionCommand) => {
|
|
30
|
-
intro(renderBranding('
|
|
30
|
+
intro(renderBranding('4.0.1'));
|
|
31
31
|
if (actionCommand && actionCommand.name() !== 'upgrade') {
|
|
32
|
-
await checkForUpdates('
|
|
32
|
+
await checkForUpdates('4.0.1');
|
|
33
33
|
}
|
|
34
34
|
});
|
|
35
35
|
// PostAction hook for Discovery Layer (runs on successful command completion)
|
|
@@ -182,7 +182,7 @@ program
|
|
|
182
182
|
.command('upgrade')
|
|
183
183
|
.description('Check for updates and auto-upgrade Scout to the latest version')
|
|
184
184
|
.action(async () => {
|
|
185
|
-
await checkForUpdates('
|
|
185
|
+
await checkForUpdates('4.0.1', true);
|
|
186
186
|
outro(chalk.cyan('Upgrade check complete.'));
|
|
187
187
|
});
|
|
188
188
|
program.parse(process.argv);
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import chalk from 'chalk';
|
|
2
|
-
export function renderBranding(version = '
|
|
2
|
+
export function renderBranding(version = '4.0.1') {
|
|
3
3
|
const logo = chalk.cyan.bold(' ███████╗████████╗') + ' ' + chalk.white.bold('███████╗██████╗ ██████╗ ██╗ ██╗████████╗') + '\n' +
|
|
4
4
|
chalk.cyan.bold(' ██╔════╝╚══██╔══╝') + ' ' + chalk.white.bold('██╔════╝██╔════╝██╔═══██╗██║ ██║╚══██╔══╝') + '\n' +
|
|
5
5
|
chalk.cyan.bold(' █████╗ ██║ ') + ' ' + chalk.white.bold('███████╗██║ ██║ ██║██║ ██║ ██║ ') + '\n' +
|