ft-scout 6.0.4 → 6.0.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +23 -22
- package/bin/src/commands/agent.d.ts.map +1 -1
- package/bin/src/commands/agent.js +76 -75
- package/bin/src/commands/agent.js.map +1 -1
- package/bin/src/commands/audit.js +1 -1
- package/bin/src/commands/audit.js.map +1 -1
- package/bin/src/commands/authCommand.js +4 -4
- package/bin/src/commands/authCommand.js.map +1 -1
- package/bin/src/commands/brief.js +4 -4
- package/bin/src/commands/brief.js.map +1 -1
- package/bin/src/commands/configCommand.d.ts.map +1 -1
- package/bin/src/commands/configCommand.js +7 -7
- package/bin/src/commands/configCommand.js.map +1 -1
- package/bin/src/commands/dashboard.js +4 -4
- package/bin/src/commands/dashboard.js.map +1 -1
- package/bin/src/commands/history.js +5 -5
- package/bin/src/commands/history.js.map +1 -1
- package/bin/src/commands/init.js +26 -26
- package/bin/src/commands/init.js.map +1 -1
- package/bin/src/commands/login.d.ts.map +1 -1
- package/bin/src/commands/login.js +21 -21
- package/bin/src/commands/login.js.map +1 -1
- package/bin/src/commands/logout.js +1 -1
- package/bin/src/commands/logout.js.map +1 -1
- package/bin/src/commands/owners.js +5 -5
- package/bin/src/commands/owners.js.map +1 -1
- package/bin/src/commands/quota.d.ts.map +1 -0
- package/bin/src/commands/quota.js +48 -0
- package/bin/src/commands/quota.js.map +1 -0
- package/bin/src/commands/recommend.js +1 -1
- package/bin/src/commands/recommend.js.map +1 -1
- package/bin/src/commands/risky.d.ts.map +1 -1
- package/bin/src/commands/risky.js +9 -9
- package/bin/src/commands/risky.js.map +1 -1
- package/bin/src/commands/setup.js +24 -24
- package/bin/src/commands/setup.js.map +1 -1
- package/bin/src/commands/signup.d.ts.map +1 -1
- package/bin/src/commands/signup.js +7 -7
- package/bin/src/commands/signup.js.map +1 -1
- package/bin/src/commands/undo.js +8 -8
- package/bin/src/commands/undo.js.map +1 -1
- package/bin/src/commands/web.js +8 -8
- package/bin/src/commands/web.js.map +1 -1
- package/bin/src/discovery/config.d.ts.map +1 -1
- package/bin/src/discovery/config.js.map +1 -1
- package/bin/src/discovery/display.js +1 -1
- package/bin/src/discovery/display.js.map +1 -1
- package/bin/src/discovery/messages.js.map +1 -1
- package/bin/src/discovery/signals.d.ts.map +1 -1
- package/bin/src/discovery/signals.js.map +1 -1
- package/bin/src/engine/agentEngine.d.ts.map +1 -1
- package/bin/src/engine/agentEngine.js +47 -46
- package/bin/src/engine/agentEngine.js.map +1 -1
- package/bin/src/engine/git.d.ts.map +1 -1
- package/bin/src/engine/git.js.map +1 -1
- package/bin/src/engine/llm.d.ts.map +1 -1
- package/bin/src/engine/llm.js +118 -73
- package/bin/src/engine/llm.js.map +1 -1
- package/bin/src/engine/verifier.d.ts.map +1 -1
- package/bin/src/engine/verifier.js +6 -6
- package/bin/src/engine/verifier.js.map +1 -1
- package/bin/src/engine/web.d.ts.map +1 -1
- package/bin/src/engine/web.js +1 -1
- package/bin/src/engine/web.js.map +1 -1
- package/bin/src/index.js +78 -68
- package/bin/src/index.js.map +1 -1
- package/bin/src/server/server.js.map +1 -1
- package/bin/src/utils/auth.d.ts.map +1 -1
- package/bin/src/utils/auth.js.map +1 -1
- package/bin/src/utils/branding.js +7 -7
- package/bin/src/utils/branding.js.map +1 -1
- package/bin/src/utils/config.d.ts.map +1 -1
- package/bin/src/utils/config.js.map +1 -1
- package/bin/src/utils/email.d.ts.map +1 -1
- package/bin/src/utils/email.js +42 -42
- package/bin/src/utils/email.js.map +1 -1
- package/bin/src/utils/firebaseAuth.d.ts.map +1 -1
- package/bin/src/utils/firebaseAuth.js.map +1 -1
- package/bin/src/utils/holoseneAuth.d.ts.map +1 -1
- package/bin/src/utils/holoseneAuth.js +22 -22
- package/bin/src/utils/holoseneAuth.js.map +1 -1
- package/bin/src/utils/language.d.ts.map +1 -1
- package/bin/src/utils/language.js.map +1 -1
- package/bin/src/utils/markdown.js +4 -4
- package/bin/src/utils/markdown.js.map +1 -1
- package/bin/src/utils/updateCheck.js +5 -5
- package/bin/src/utils/updateCheck.js.map +1 -1
- package/package.json +1 -1
- package/web/app.js +927 -927
package/README.md
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
#
|
|
1
|
+
# scout (FrontTerrain CLI v6.0.5)
|
|
2
2
|
|
|
3
3
|
**FrontTerrain (`scout`)** — The Autonomous AI Principal Software Engineer & Codebase Co-Pilot in your terminal.
|
|
4
4
|
|
|
@@ -6,7 +6,7 @@ Scout executes autonomous multi-step engineering loops, builds complete projects
|
|
|
6
6
|
|
|
7
7
|
---
|
|
8
8
|
|
|
9
|
-
##
|
|
9
|
+
## Installation
|
|
10
10
|
|
|
11
11
|
Install globally using npm:
|
|
12
12
|
|
|
@@ -16,48 +16,48 @@ npm install -g ft-scout@latest
|
|
|
16
16
|
|
|
17
17
|
---
|
|
18
18
|
|
|
19
|
-
##
|
|
19
|
+
## Quick Start & Commands
|
|
20
20
|
|
|
21
21
|
Once installed, use `scout` or `ft` in any project directory:
|
|
22
22
|
|
|
23
|
-
###
|
|
23
|
+
### Agentic AI Actions & Interactive Sessions
|
|
24
24
|
|
|
25
25
|
```bash
|
|
26
|
-
#
|
|
26
|
+
# Autonomous Multi-Step AI Agent (Direct prompt execution, full context inspection, automated test/build verification)
|
|
27
27
|
scout agent "Build a responsive snake game in HTML and JS with smooth animations"
|
|
28
28
|
scout agent "Add score high-score persistent storage and level progression"
|
|
29
29
|
scout task "Fix typescript build errors in src/utils" -v "npm run build"
|
|
30
30
|
scout goal "Refactor database query logic" -y
|
|
31
31
|
|
|
32
|
-
#
|
|
32
|
+
# Interactive Scout Agent Session (Persistent chat loop with Slash Commands & full ReAct tool execution)
|
|
33
33
|
scout agent
|
|
34
34
|
# Inside session:
|
|
35
35
|
# Agent Prompt: Add dark mode toggle button
|
|
36
36
|
# Slash commands: /help /diff /clear /compact /undo /scan /plan /history /exit
|
|
37
37
|
|
|
38
|
-
#
|
|
38
|
+
# Generate and create a new source code file
|
|
39
39
|
scout create src/utils/math.ts "Create helper functions for sum, average, and array chunking"
|
|
40
40
|
scout gen src/components/Header.tsx "Create a responsive React navigation header"
|
|
41
41
|
|
|
42
|
-
#
|
|
42
|
+
# Prompt-Driven Auto-Fix & Debugging
|
|
43
43
|
scout fix "Fix null pointer check in calculateTotal function"
|
|
44
44
|
scout fix -f src/sampleBug.ts "Handle optional prices defensively" -y
|
|
45
45
|
scout fix -i 1
|
|
46
46
|
|
|
47
|
-
#
|
|
47
|
+
# Run terminal/shell commands with automated AI error diagnosis & self-healing
|
|
48
48
|
scout run npm test
|
|
49
49
|
scout exec tsc
|
|
50
50
|
scout run python main.py
|
|
51
51
|
|
|
52
|
-
#
|
|
52
|
+
# Interactive Agentic AI Chat session
|
|
53
53
|
scout chat
|
|
54
54
|
scout chat --web --lang spanish
|
|
55
55
|
|
|
56
|
-
#
|
|
56
|
+
# Revert Scout's last action & restore backed-up file contents
|
|
57
57
|
scout undo
|
|
58
58
|
```
|
|
59
59
|
|
|
60
|
-
###
|
|
60
|
+
### Codebase Understanding & Due-Diligence
|
|
61
61
|
|
|
62
62
|
```bash
|
|
63
63
|
# Initialize understanding map of a local or remote repository
|
|
@@ -101,19 +101,20 @@ scout upgrade
|
|
|
101
101
|
|
|
102
102
|
---
|
|
103
103
|
|
|
104
|
-
##
|
|
104
|
+
## Key v6.0.5 Capabilities
|
|
105
105
|
|
|
106
|
-
-
|
|
107
|
-
-
|
|
108
|
-
-
|
|
109
|
-
-
|
|
110
|
-
-
|
|
111
|
-
-
|
|
112
|
-
-
|
|
113
|
-
-
|
|
106
|
+
- **High-Agency Autonomous ReAct Loop (`scout agent`)**: Takes immediate action using `write_file`, `edit_file`, `run_command`, `read_file`, `grep_search`, and `glob_search` without prompt duplication or double-asking.
|
|
107
|
+
- **Fail-Fast Quota & Concurrency Protection**: Enforces strict single-request concurrency queueing (`LLM_CONCURRENCY=1`) and immediate fail-fast handling on account quota exhaustion (`insufficient_quota`), preventing wasteful retry loops across fallback models.
|
|
108
|
+
- **Interactive `/diff` Slash Command**: Type `/diff` anytime during an interactive `scout agent` session to view colorized, real-time git diffs of uncommitted workspace changes.
|
|
109
|
+
- **Full File Context Inspection**: Loads complete line-numbered reference context (up to 250 lines) into active memory during file auto-discovery for precision editing and bug fixing.
|
|
110
|
+
- **Automated Verification & Self-Healing**: Validates JavaScript, TypeScript, Python, Rust, Go, JSON, and embedded `<script>` HTML tags using compiler checks (`node --check`, `tsc`, `py_compile`, etc.). Automatically diagnoses and self-heals syntax or test errors before concluding.
|
|
111
|
+
- **3-Tier Robust Snippet Editing (`edit_file`)**: Edits files using exact matching, trailing-space normalization, and full line-trim matching (ignoring indentation differences). Automatically falls back to `write_file` if snippet targets mismatch.
|
|
112
|
+
- **AI File Generation (`scout create`)**: Specify a target path and prompt requirement to create production-ready files with automated syntax verification.
|
|
113
|
+
- **Terminal Execution & Failure Diagnosis (`scout run`)**: Run tests, builds, or scripts live. If a command fails, Scout pinpoints the root cause and auto-fixes the failing code.
|
|
114
|
+
- **Safety & Instant Revert (`scout undo`)**: Every code modification or file creation is backed up with timestamped history, enabling 1-command rollback.
|
|
114
115
|
|
|
115
116
|
---
|
|
116
117
|
|
|
117
|
-
##
|
|
118
|
+
## License
|
|
118
119
|
|
|
119
120
|
ISC © [FrontTerrain](https://npmjs.com/package/ft-scout)
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"agent.d.ts","sourceRoot":"","sources":["agent.ts"],"names":[],"mappings":"AA0BA,MAAM,WAAW,YAAY;
|
|
1
|
+
{"version":3,"file":"agent.d.ts","sourceRoot":"","sources":["agent.ts"],"names":[],"mappings":"AA0BA,MAAM,WAAW,YAAY;IAC5B,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,GAAG,QAAQ,GAAG,KAAK,CAAC;IACpC,WAAW,EAAE,MAAM,CAAC;CACpB;AAKD,wBAAgB,cAAc,CAAC,MAAM,EAAE,YAAY,EAAE,QAIpD;AAED,wBAAgB,cAAc,IAAI,YAAY,EAAE,CAO/C;AAED,MAAM,WAAW,YAAY;IAC5B,IAAI,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC1B,MAAM,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC5B,IAAI,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC1B,KAAK,CAAC,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAAC;IACpC,GAAG,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,GAAG,SAAS,CAAC;IACpC,IAAI,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;IAC3B,GAAG,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IACzB,IAAI,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC1B,SAAS,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC/B,UAAU,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAChC,IAAI,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC1B,MAAM,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;IAC7B,GAAG,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;CAC1B;AAED,wBAAgB,wBAAwB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,EAAE,CAsDlE;AAED,wBAAgB,uBAAuB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAG3E;AAED,MAAM,WAAW,gBAAgB;IAChC,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,UAAU,GAAG,QAAQ,GAAG,QAAQ,GAAG,MAAM,GAAG,MAAM,GAAG,KAAK,CAAC;IACvE,UAAU,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAChC,WAAW,CAAC,EAAE,MAAM,EAAE,GAAG,SAAS,CAAC;CACnC;AAED,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,GAAG,gBAAgB,CAoF5F;AAED,wBAAgB,yBAAyB,CACxC,UAAU,EAAE,MAAM,EAClB,aAAa,EAAE,MAAM,GAAG,SAAS,EACjC,SAAS,EAAE,MAAM,EAAE,GACjB,MAAM,EAAE,CAgGV;AAID,wBAAsB,WAAW,CAAC,SAAS,CAAC,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,YAAY,iBAonB3E"}
|
|
@@ -233,8 +233,8 @@ export async function handleAgent(goalInput, options) {
|
|
|
233
233
|
console.log(`\n${chalk.bold.red('Credit Quota Exhausted!')}`);
|
|
234
234
|
console.log(chalk.yellow(tierCheck.reason || 'Credit limit reached for Free Tier.'));
|
|
235
235
|
console.log(chalk.cyan('\nTo continue using Scout CLI AI Agent:'));
|
|
236
|
-
console.log(`
|
|
237
|
-
console.log(`
|
|
236
|
+
console.log(` 1. Upgrade to ${chalk.bold.green('Pro Tier ($19/mo)')} in dashboard (${chalk.underline('scout dashboard')})`);
|
|
237
|
+
console.log(` 2. Or enable ${chalk.bold.magenta('BYOK Mode')} in dashboard to use your custom API key / proxy endpoint.\n`);
|
|
238
238
|
return;
|
|
239
239
|
}
|
|
240
240
|
const creditRes = consumeCredit(1);
|
|
@@ -251,7 +251,7 @@ export async function handleAgent(goalInput, options) {
|
|
|
251
251
|
console.log(`${chalk.dim(`Scout Credit Consumed | ${creditRes.remaining} credits remaining`)}`);
|
|
252
252
|
if (creditRes.isLowCredit) {
|
|
253
253
|
console.log(`\n${chalk.bold.yellow('Low Credit Warning:')} Only ${chalk.bold(creditRes.remaining)} credits remaining on your current plan.`);
|
|
254
|
-
console.log(`
|
|
254
|
+
console.log(` ${chalk.cyan('Run `scout dashboard` to upgrade your tier or activate BYOK mode.')}\n`);
|
|
255
255
|
}
|
|
256
256
|
}
|
|
257
257
|
const existingContext = loadContext();
|
|
@@ -270,13 +270,14 @@ export async function handleAgent(goalInput, options) {
|
|
|
270
270
|
const welcomeBanner = `
|
|
271
271
|
${chalk.bold.cyan('Scout Autonomous AI Agent')} ${targetLang ? `(${targetLang})` : ''}
|
|
272
272
|
${chalk.dim('Type your goal, or use slash commands:')}
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
273
|
+
${chalk.cyan('/help')} - Show agent tools & commands.
|
|
274
|
+
${chalk.cyan('/diff')} - Show git diff for uncommited changes.
|
|
275
|
+
${chalk.cyan('/clear')} - Reset conversation context.
|
|
276
|
+
${chalk.cyan('/undo')} - Revert last file modifications.
|
|
277
|
+
${chalk.cyan('/scan')} - Run vulnerability scan.
|
|
278
|
+
${chalk.cyan('/plan')} - Generate implementation roadmap.
|
|
279
|
+
${chalk.cyan('/exit')} - Exit session.
|
|
280
|
+
`.trim();
|
|
280
281
|
safeNote(welcomeBanner, 'Scout Agent Active Session');
|
|
281
282
|
while (true) {
|
|
282
283
|
let rawGoal = undefined;
|
|
@@ -293,17 +294,17 @@ ${chalk.dim('Type your goal, or use slash commands:')}
|
|
|
293
294
|
validate: (val) => (!val || !val.trim() ? 'Please enter a prompt or /exit to quit' : undefined),
|
|
294
295
|
});
|
|
295
296
|
if (isCancel(userGoalInput)) {
|
|
296
|
-
safeNote(chalk.yellow('Exiting Scout Agent session.
|
|
297
|
+
safeNote(chalk.yellow('Exiting Scout Agent session. see you soon!'), 'Scout Agent Ended');
|
|
297
298
|
break;
|
|
298
299
|
}
|
|
299
300
|
const trimmedInput = userGoalInput.trim();
|
|
300
301
|
if (['exit', 'quit', 'q', ':q', '/exit', '/quit'].includes(trimmedInput.toLowerCase())) {
|
|
301
|
-
safeNote(chalk.yellow('Exiting Scout Agent session.
|
|
302
|
+
safeNote(chalk.yellow('Exiting Scout Agent session. see you soon!'), 'Scout Agent Ended');
|
|
302
303
|
break;
|
|
303
304
|
}
|
|
304
305
|
if (trimmedInput.toLowerCase() === '/help') {
|
|
305
306
|
const helpText = `
|
|
306
|
-
###
|
|
307
|
+
### ️ Scout Agent Tools
|
|
307
308
|
- **read_file**: Read content & line ranges of codebase files.
|
|
308
309
|
- **write_file**: Create new files or overwrite existing code.
|
|
309
310
|
- **edit_file**: Search-and-replace exact code snippets.
|
|
@@ -311,7 +312,7 @@ ${chalk.dim('Type your goal, or use slash commands:')}
|
|
|
311
312
|
- **grep_search**: Regex/string search across all files.
|
|
312
313
|
- **glob_search**: Pattern search for workspace files.
|
|
313
314
|
|
|
314
|
-
###
|
|
315
|
+
### Slash Commands
|
|
315
316
|
- \`/help\`: View this assistance screen.
|
|
316
317
|
- \`/diff\`: Display colorized git diff of uncommitted workspace changes.
|
|
317
318
|
- \`/clear\` or \`/compact\`: Clear session context window.
|
|
@@ -320,8 +321,8 @@ ${chalk.dim('Type your goal, or use slash commands:')}
|
|
|
320
321
|
- \`/plan <idea>\`: Generate feature feasibility roadmap.
|
|
321
322
|
- \`/history\`: View recent Scout actions.
|
|
322
323
|
- \`/exit\`: Quit Scout Agent session.
|
|
323
|
-
|
|
324
|
-
safeNote(renderMarkdown(helpText), '
|
|
324
|
+
`.trim();
|
|
325
|
+
safeNote(renderMarkdown(helpText), ' Scout Slash Commands & Tools');
|
|
325
326
|
continue;
|
|
326
327
|
}
|
|
327
328
|
if (trimmedInput.toLowerCase() === '/diff') {
|
|
@@ -329,22 +330,22 @@ ${chalk.dim('Type your goal, or use slash commands:')}
|
|
|
329
330
|
const { execSync } = await import('child_process');
|
|
330
331
|
const gitDiff = execSync('git diff', { encoding: 'utf-8', cwd: process.cwd() });
|
|
331
332
|
if (!gitDiff || !gitDiff.trim()) {
|
|
332
|
-
safeNote(chalk.green('No uncommitted changes found in the workspace.'), '
|
|
333
|
+
safeNote(chalk.green('No uncommitted changes found in the workspace.'), ' Workspace Git Diff');
|
|
333
334
|
}
|
|
334
335
|
else {
|
|
335
336
|
const previewLines = gitDiff.split('\n');
|
|
336
337
|
const truncated = previewLines.length > 200 ? previewLines.slice(0, 200).join('\n') + `\n... [truncated, ${previewLines.length} total lines]` : gitDiff;
|
|
337
|
-
safeNote(truncated, '
|
|
338
|
+
safeNote(truncated, ' Workspace Git Diff');
|
|
338
339
|
}
|
|
339
340
|
}
|
|
340
341
|
catch {
|
|
341
|
-
safeNote(chalk.yellow('Could not retrieve git diff. Ensure this directory is a git repository.'), '
|
|
342
|
+
safeNote(chalk.yellow('Could not retrieve git diff. Ensure this directory is a git repository.'), '️ Git Diff Failed');
|
|
342
343
|
}
|
|
343
344
|
continue;
|
|
344
345
|
}
|
|
345
346
|
if (['/clear', '/compact'].includes(trimmedInput.toLowerCase())) {
|
|
346
347
|
agentLoop.resetContext();
|
|
347
|
-
safeNote(chalk.green('Agent context reset successfully.'), '
|
|
348
|
+
safeNote(chalk.green('Agent context reset successfully.'), ' Session Context Cleared');
|
|
348
349
|
continue;
|
|
349
350
|
}
|
|
350
351
|
if (trimmedInput.toLowerCase() === '/undo') {
|
|
@@ -354,7 +355,7 @@ ${chalk.dim('Type your goal, or use slash commands:')}
|
|
|
354
355
|
if (trimmedInput.toLowerCase() === '/history') {
|
|
355
356
|
const history = (await import('../utils/config.js')).loadHistory();
|
|
356
357
|
const historyMd = history.slice(0, 10).map((h) => `- **${h.timestamp}**: \`${h.command}\` — ${h.description}`).join('\n') || 'No action history recorded yet.';
|
|
357
|
-
safeNote(renderMarkdown(historyMd), '
|
|
358
|
+
safeNote(renderMarkdown(historyMd), ' Scout History Log');
|
|
358
359
|
continue;
|
|
359
360
|
}
|
|
360
361
|
rawGoal = trimmedInput;
|
|
@@ -371,7 +372,7 @@ ${chalk.dim('Type your goal, or use slash commands:')}
|
|
|
371
372
|
const isScanIntent = Boolean(options?.scan || (rawGoal && rawGoal.trim().startsWith('/scan')));
|
|
372
373
|
if (isScanIntent) {
|
|
373
374
|
const s = spinner();
|
|
374
|
-
s.start('
|
|
375
|
+
s.start(' Scout Agent: Performing read-only bug & vulnerability scan...');
|
|
375
376
|
let codeSample = '';
|
|
376
377
|
const pkgPath = path.join(cwd, 'package.json');
|
|
377
378
|
if (fs.existsSync(pkgPath)) {
|
|
@@ -391,13 +392,13 @@ ${chalk.dim('Type your goal, or use slash commands:')}
|
|
|
391
392
|
}
|
|
392
393
|
};
|
|
393
394
|
const reportLines = issues.map((iss) => `${chalk.bold.cyan(`[Issue #${iss.id}]`)} ${severityBadge(iss.severity)} ${chalk.bold(iss.title)}\n` +
|
|
394
|
-
`
|
|
395
|
-
`
|
|
395
|
+
` • File: ${chalk.yellow(iss.file)}\n` +
|
|
396
|
+
` • Detail: ${iss.description}`);
|
|
396
397
|
safeNote(`Found ${issues.length} potential issues matching past hotfix patterns:\n\n` +
|
|
397
398
|
reportLines.join('\n\n') +
|
|
398
|
-
`\n\n${chalk.bold.green('
|
|
399
|
-
`
|
|
400
|
-
`
|
|
399
|
+
`\n\n${chalk.bold.green(' How to Auto-Fix Any Issue with Agent:')}\n` +
|
|
400
|
+
` • Auto-fix Issue #${issues[0]?.id || 1}: ${chalk.bold.cyan(`scout agent --issue ${issues[0]?.id || 1}`)}\n` +
|
|
401
|
+
` • Custom prompt auto-fix: ${chalk.bold.cyan('scout agent "Fix null check in src/index.ts"')}`, ' Scout Agent Bug Scan');
|
|
401
402
|
continue;
|
|
402
403
|
}
|
|
403
404
|
// -------------------------------------------------------------
|
|
@@ -407,10 +408,10 @@ ${chalk.dim('Type your goal, or use slash commands:')}
|
|
|
407
408
|
const addIdea = options?.add || options?.plan || (planMatch ? planMatch[1] : undefined);
|
|
408
409
|
if (addIdea && !options?.create) {
|
|
409
410
|
const s = spinner();
|
|
410
|
-
s.start(
|
|
411
|
+
s.start(` Scout Agent: Evaluating feasibility & generating roadmap for "${chalk.cyan(addIdea)}"...`);
|
|
411
412
|
const plan = await generateFeaturePlan(addIdea, projectName, filesList, targetLang, options?.native);
|
|
412
413
|
s.stop('Feasibility assessment & roadmap complete.');
|
|
413
|
-
safeNote(renderMarkdown(plan),
|
|
414
|
+
safeNote(renderMarkdown(plan), ` Feature Implementation Roadmap: "${addIdea}"`);
|
|
414
415
|
continue;
|
|
415
416
|
}
|
|
416
417
|
// -------------------------------------------------------------
|
|
@@ -420,20 +421,20 @@ ${chalk.dim('Type your goal, or use slash commands:')}
|
|
|
420
421
|
const runCmdInput = options?.run || (runMatch ? runMatch[1] : undefined);
|
|
421
422
|
if (runCmdInput) {
|
|
422
423
|
const fullCommand = Array.isArray(runCmdInput) ? runCmdInput.join(' ') : runCmdInput;
|
|
423
|
-
safeNote(`Running command: ${chalk.bold.cyan(fullCommand)}\n${chalk.dim('Working directory: ' + cwd)}`, '
|
|
424
|
+
safeNote(`Running command: ${chalk.bold.cyan(fullCommand)}\n${chalk.dim('Working directory: ' + cwd)}`, ' Scout Shell Execution');
|
|
424
425
|
const runSpinner = spinner();
|
|
425
426
|
runSpinner.start(`Executing \`${fullCommand}\`...`);
|
|
426
427
|
const res = await executeSmartCommand(fullCommand, cwd, 3000);
|
|
427
428
|
if (res.isBackgroundServer) {
|
|
428
429
|
runSpinner.stop(chalk.green(`Command \`${fullCommand}\` started in background (PID ${res.pid}).`));
|
|
429
|
-
safeNote(`${chalk.green('
|
|
430
|
+
safeNote(`${chalk.green('')} Background server process started (PID ${res.pid}). Output so far:\n\`\`\`\n${res.output}\n\`\`\``, ' Background Execution Active');
|
|
430
431
|
continue;
|
|
431
432
|
}
|
|
432
433
|
const exitCode = res.exitCode;
|
|
433
434
|
const fullOutput = res.output;
|
|
434
435
|
if (exitCode === 0) {
|
|
435
436
|
runSpinner.stop(chalk.green(`Command \`${fullCommand}\` executed successfully (Exit Code 0).`));
|
|
436
|
-
safeNote(`${chalk.green('
|
|
437
|
+
safeNote(`${chalk.green('')} Process completed with exit code 0.`, ' Execution Successful');
|
|
437
438
|
continue;
|
|
438
439
|
}
|
|
439
440
|
runSpinner.stop(chalk.red(`Command \`${fullCommand}\` failed with exit code ${exitCode}.`));
|
|
@@ -442,17 +443,17 @@ ${chalk.dim('Type your goal, or use slash commands:')}
|
|
|
442
443
|
const analysis = await analyzeCommandError(fullCommand, exitCode, fullOutput, projectName, filesList, targetLang, options?.native);
|
|
443
444
|
diagSpinner.stop(chalk.yellow('Failure diagnosis complete.'));
|
|
444
445
|
const diagMarkdown = `
|
|
445
|
-
###
|
|
446
|
+
### Process Failure Diagnosis
|
|
446
447
|
Command: \`${fullCommand}\` (Exit Code ${exitCode})
|
|
447
448
|
|
|
448
|
-
###
|
|
449
|
+
### Root Cause Analysis
|
|
449
450
|
${analysis.rootCause}
|
|
450
451
|
|
|
451
|
-
###
|
|
452
|
+
### Suggested Fix
|
|
452
453
|
${analysis.suggestedFix}
|
|
453
|
-
${analysis.targetFileToFix ? `\n###
|
|
454
|
-
|
|
455
|
-
safeNote(renderMarkdown(diagMarkdown), '
|
|
454
|
+
${analysis.targetFileToFix ? `\n### Suspected File\n\`${analysis.targetFileToFix}\`` : ''}
|
|
455
|
+
`.trim();
|
|
456
|
+
safeNote(renderMarkdown(diagMarkdown), '️ Scout AI Failure Diagnosis');
|
|
456
457
|
const shouldFix = await confirm({
|
|
457
458
|
message: chalk.bold('Would you like Scout Agent to auto-fix the failing code automatically?'),
|
|
458
459
|
initialValue: true,
|
|
@@ -480,7 +481,7 @@ ${analysis.targetFileToFix ? `\n### 🎯 Suspected File\n\`${analysis.targetFile
|
|
|
480
481
|
validate: (val) => (!val || !val.trim() ? 'Please provide a prompt describing the file requirements' : undefined),
|
|
481
482
|
});
|
|
482
483
|
if (isCancel(userPromptInput)) {
|
|
483
|
-
safeNote(chalk.yellow('File creation operation cancelled.'), '
|
|
484
|
+
safeNote(chalk.yellow('File creation operation cancelled.'), ' Scout File Creation');
|
|
484
485
|
continue;
|
|
485
486
|
}
|
|
486
487
|
finalPrompt = userPromptInput.trim();
|
|
@@ -499,7 +500,7 @@ ${analysis.targetFileToFix ? `\n### 🎯 Suspected File\n\`${analysis.targetFile
|
|
|
499
500
|
catch { }
|
|
500
501
|
}
|
|
501
502
|
const s = spinner();
|
|
502
|
-
s.start(
|
|
503
|
+
s.start(` Scout Agent: Generating ${targetCreateFiles.length} file(s) (${targetCreateFiles.join(', ')})...`);
|
|
503
504
|
let hasError = false;
|
|
504
505
|
for (const targetFilePath of targetCreateFiles) {
|
|
505
506
|
const resolvedPath = path.resolve(cwd, targetFilePath);
|
|
@@ -523,14 +524,14 @@ ${analysis.targetFileToFix ? `\n### 🎯 Suspected File\n\`${analysis.targetFile
|
|
|
523
524
|
catch (err) {
|
|
524
525
|
hasError = true;
|
|
525
526
|
s.stop(chalk.red(`Failed to generate code for ${targetFilePath}.`));
|
|
526
|
-
safeNote(chalk.red(`Error: ${err?.message || String(err)}`), '
|
|
527
|
+
safeNote(chalk.red(`Error: ${err?.message || String(err)}`), '️ Code Generation Error');
|
|
527
528
|
break;
|
|
528
529
|
}
|
|
529
530
|
}
|
|
530
531
|
if (hasError || createdFilesSummary.length === 0) {
|
|
531
532
|
if (!hasError) {
|
|
532
533
|
s.stop(chalk.red('Failed to generate code files.'));
|
|
533
|
-
safeNote(chalk.yellow(`Scout AI returned empty code content. Please refine your prompt describing what code to write.`), '
|
|
534
|
+
safeNote(chalk.yellow(`Scout AI returned empty code content. Please refine your prompt describing what code to write.`), '️ Empty Code Generated');
|
|
534
535
|
}
|
|
535
536
|
continue;
|
|
536
537
|
}
|
|
@@ -550,31 +551,31 @@ ${analysis.targetFileToFix ? `\n### 🎯 Suspected File\n\`${analysis.targetFile
|
|
|
550
551
|
native: options?.native,
|
|
551
552
|
});
|
|
552
553
|
if (healRes.verifiedFiles.length > 0) {
|
|
553
|
-
safeNote(chalk.green(
|
|
554
|
+
safeNote(chalk.green(` Automated Verification Confirmed: ${healRes.verifiedFiles.length} file(s) syntax & build verified clean!`), ' Code Verification Clean');
|
|
554
555
|
}
|
|
555
556
|
if (healRes.remainingErrors.length > 0) {
|
|
556
|
-
safeNote(chalk.yellow(
|
|
557
|
+
safeNote(chalk.yellow(`️ Remaining verification issues:\n${healRes.remainingErrors.join('\n')}`), '️ Verification Warning');
|
|
557
558
|
}
|
|
558
|
-
const filePreviews = createdFilesSummary.map((f) => `####
|
|
559
|
+
const filePreviews = createdFilesSummary.map((f) => `#### \`${f.path}\`\n${f.description}\n\`\`\`\n${f.code.slice(0, 400)}${f.code.length > 400 ? '\n... (truncated)' : ''}\n\`\`\``).join('\n\n');
|
|
559
560
|
const teardownContent = `
|
|
560
|
-
###
|
|
561
|
+
### Created Files (${createdFilesSummary.length})
|
|
561
562
|
${createdFilesSummary.map(f => ` • \`${f.path}\``).join('\n')}
|
|
562
563
|
|
|
563
|
-
###
|
|
564
|
+
### Overview & Previews
|
|
564
565
|
${filePreviews}
|
|
565
|
-
|
|
566
|
-
safeNote(renderMarkdown(teardownContent), '
|
|
566
|
+
`.trim();
|
|
567
|
+
safeNote(renderMarkdown(teardownContent), ' Scout File Creation Teardown');
|
|
567
568
|
if (options?.yes || !process.stdout.isTTY) {
|
|
568
|
-
safeNote(`${chalk.green('
|
|
569
|
-
|
|
569
|
+
safeNote(`${chalk.green('')} Saved ${chalk.bold.cyan(affectedFiles.length + ' file(s)')} on branch ${chalk.bold.green(currentBranch)}.\n` +
|
|
570
|
+
` ${chalk.dim('You can revert this creation anytime by running:')} ${chalk.cyan('scout undo')}`, ' Creation Confirmed');
|
|
570
571
|
continue;
|
|
571
572
|
}
|
|
572
573
|
const actionChoice = await select({
|
|
573
574
|
message: chalk.bold('Review Scout Agent\'s generated file(s). What would you like to do?'),
|
|
574
575
|
options: [
|
|
575
|
-
{ value: 'keep', label: '
|
|
576
|
-
{ value: 'pr', label: '
|
|
577
|
-
{ value: 'revert', label: '
|
|
576
|
+
{ value: 'keep', label: ' Keep Files', hint: `Retain newly created files directly on current branch (${currentBranch})` },
|
|
577
|
+
{ value: 'pr', label: ' Create Pull Request', hint: 'Push created files to a new branch & open a Pull Request' },
|
|
578
|
+
{ value: 'revert', label: '️ Revert / Delete Files', hint: 'Remove created files immediately' },
|
|
578
579
|
],
|
|
579
580
|
});
|
|
580
581
|
if (isCancel(actionChoice) || actionChoice === 'revert') {
|
|
@@ -594,12 +595,12 @@ ${filePreviews}
|
|
|
594
595
|
commitMessage: `feat: Create ${affectedFiles.join(', ')}`,
|
|
595
596
|
});
|
|
596
597
|
prSpinner.stop('Pull Request workflow processed.');
|
|
597
|
-
safeNote(`${chalk.green('
|
|
598
|
-
|
|
598
|
+
safeNote(`${chalk.green('')} ${prRes.message}\n` +
|
|
599
|
+
` ${chalk.dim('You remain on active branch:')} ${chalk.cyan(currentBranch)}`, ' Pull Request Status');
|
|
599
600
|
continue;
|
|
600
601
|
}
|
|
601
|
-
safeNote(`${chalk.green('
|
|
602
|
-
|
|
602
|
+
safeNote(`${chalk.green('')} Saved ${chalk.bold.cyan(affectedFiles.length + ' file(s)')} on branch ${chalk.bold.green(currentBranch)}.\n` +
|
|
603
|
+
` ${chalk.dim('You can revert this creation anytime by running:')} ${chalk.cyan('scout undo')}`, ' Creation Confirmed');
|
|
603
604
|
continue;
|
|
604
605
|
}
|
|
605
606
|
// -------------------------------------------------------------
|
|
@@ -615,11 +616,11 @@ ${filePreviews}
|
|
|
615
616
|
}
|
|
616
617
|
}
|
|
617
618
|
if (!finalGoal || !finalGoal.trim()) {
|
|
618
|
-
safeNote(chalk.yellow('No active goal specified.'), '
|
|
619
|
+
safeNote(chalk.yellow('No active goal specified.'), ' Scout Agent');
|
|
619
620
|
continue;
|
|
620
621
|
}
|
|
621
|
-
safeNote(`${chalk.bold.cyan('
|
|
622
|
-
`${chalk.dim('Goal:')} ${finalGoal}`, '
|
|
622
|
+
safeNote(`${chalk.bold.cyan(' Scout Autonomous Execution Initialized')}\n` +
|
|
623
|
+
`${chalk.dim('Goal:')} ${finalGoal}`, ' Scout Agent Execution');
|
|
623
624
|
const execResult = await agentLoop.executeGoal(finalGoal);
|
|
624
625
|
const modifiedFiles = agentLoop.getModifiedFiles();
|
|
625
626
|
const backups = agentLoop.getBackups();
|
|
@@ -643,29 +644,29 @@ ${filePreviews}
|
|
|
643
644
|
});
|
|
644
645
|
}
|
|
645
646
|
const teardownMd = `
|
|
646
|
-
###
|
|
647
|
+
### Agent Goal
|
|
647
648
|
${finalGoal}
|
|
648
649
|
|
|
649
|
-
###
|
|
650
|
+
### Modified File(s)
|
|
650
651
|
${modifiedFiles.map((f) => ` • \`${f}\``).join('\n') || ' • None'}
|
|
651
652
|
|
|
652
|
-
###
|
|
653
|
+
### Execution Summary
|
|
653
654
|
${execResult.summary}
|
|
654
|
-
|
|
655
|
-
safeNote(renderMarkdown(teardownMd), '
|
|
655
|
+
`.trim();
|
|
656
|
+
safeNote(renderMarkdown(teardownMd), ' Scout Agent Teardown Report');
|
|
656
657
|
if (modifiedFiles.length === 0)
|
|
657
658
|
continue;
|
|
658
659
|
if (options?.yes || !process.stdout.isTTY) {
|
|
659
|
-
safeNote(`${chalk.green('
|
|
660
|
-
|
|
660
|
+
safeNote(`${chalk.green('')} Agent changes retained on ${modifiedFiles.length} file(s) (Branch: ${chalk.bold.green(currentBranch)}).\n` +
|
|
661
|
+
` ${chalk.dim('You can revert anytime by running:')} ${chalk.cyan('scout undo')}`, ' Agent Execution Confirmed');
|
|
661
662
|
continue;
|
|
662
663
|
}
|
|
663
664
|
const actionChoice = await select({
|
|
664
665
|
message: chalk.bold('Review Scout Agent result. What would you like to do?'),
|
|
665
666
|
options: [
|
|
666
|
-
{ value: 'keep', label: '
|
|
667
|
-
{ value: 'pr', label: '
|
|
668
|
-
{ value: 'revert', label: '
|
|
667
|
+
{ value: 'keep', label: ' Keep Changes', hint: `Retain agent changes on current branch (${currentBranch})` },
|
|
668
|
+
{ value: 'pr', label: ' Create Pull Request', hint: 'Push fix to a new branch & open a Pull Request' },
|
|
669
|
+
{ value: 'revert', label: '️ Revert Changes', hint: 'Restore original code immediately' },
|
|
669
670
|
],
|
|
670
671
|
});
|
|
671
672
|
if (actionChoice === 'revert') {
|
|
@@ -685,12 +686,12 @@ ${execResult.summary}
|
|
|
685
686
|
commitMessage: `feat: ${finalGoal}`,
|
|
686
687
|
});
|
|
687
688
|
prSpinner.stop('Pull Request workflow processed.');
|
|
688
|
-
safeNote(`${chalk.green('
|
|
689
|
-
|
|
689
|
+
safeNote(`${chalk.green('')} ${prRes.message}\n` +
|
|
690
|
+
` ${chalk.dim('You remain on active branch:')} ${chalk.cyan(currentBranch)}`, ' Pull Request Status');
|
|
690
691
|
continue;
|
|
691
692
|
}
|
|
692
|
-
safeNote(`${chalk.green('
|
|
693
|
-
|
|
693
|
+
safeNote(`${chalk.green('')} Agent changes retained on ${modifiedFiles.length} file(s) (Branch: ${chalk.bold.green(currentBranch)}).\n` +
|
|
694
|
+
` ${chalk.dim('You can revert these changes anytime by running:')} ${chalk.cyan('scout undo')}`, ' Agent Workflow Finished');
|
|
694
695
|
}
|
|
695
696
|
}
|
|
696
697
|
//# sourceMappingURL=agent.js.map
|