ft-scout 3.0.0 â 3.0.2
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 +55 -33
- package/bin/src/commands/chat.d.ts.map +1 -1
- package/bin/src/commands/chat.js +113 -11
- package/bin/src/commands/chat.js.map +1 -1
- package/bin/src/commands/configCommand.d.ts.map +1 -1
- package/bin/src/commands/configCommand.js +29 -3
- package/bin/src/commands/configCommand.js.map +1 -1
- package/bin/src/commands/create.d.ts.map +1 -0
- package/bin/src/commands/create.js +163 -0
- package/bin/src/commands/create.js.map +1 -0
- package/bin/src/commands/fix.d.ts.map +1 -1
- package/bin/src/commands/fix.js +9 -2
- package/bin/src/commands/fix.js.map +1 -1
- package/bin/src/commands/history.js +1 -1
- package/bin/src/commands/history.js.map +1 -1
- package/bin/src/commands/runCommand.d.ts.map +1 -0
- package/bin/src/commands/runCommand.js +106 -0
- package/bin/src/commands/runCommand.js.map +1 -0
- package/bin/src/commands/undo.d.ts.map +1 -1
- package/bin/src/commands/undo.js +11 -3
- package/bin/src/commands/undo.js.map +1 -1
- package/bin/src/discovery/config.d.ts.map +1 -0
- package/bin/src/discovery/config.js +41 -0
- package/bin/src/discovery/config.js.map +1 -0
- package/bin/src/discovery/display.d.ts.map +1 -0
- package/bin/src/discovery/display.js +57 -0
- package/bin/src/discovery/display.js.map +1 -0
- package/bin/src/discovery/messages.d.ts.map +1 -0
- package/bin/src/discovery/messages.js +7 -0
- package/bin/src/discovery/messages.js.map +1 -0
- package/bin/src/discovery/signals.d.ts.map +1 -0
- package/bin/src/discovery/signals.js +33 -0
- package/bin/src/discovery/signals.js.map +1 -0
- package/bin/src/engine/llm.d.ts.map +1 -1
- package/bin/src/engine/llm.js +99 -0
- package/bin/src/engine/llm.js.map +1 -1
- package/bin/src/index.js +63 -4
- package/bin/src/index.js.map +1 -1
- package/bin/src/utils/branding.js +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,8 +1,12 @@
|
|
|
1
|
-
# scout
|
|
1
|
+
# đ scout (FrontTerrain CLI)
|
|
2
2
|
|
|
3
|
-
FrontTerrain (`scout`) â The AI
|
|
3
|
+
**FrontTerrain (`scout`)** â The Agentic AI Engineering & Onboarding Co-Pilot for Codebases.
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
Scout works like GitHub Copilot directly inside your terminal â fixing bugs, creating new source code files, executing shell commands with AI failure diagnostics, scanning codebases, and interactive agentic chat.
|
|
6
|
+
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
## đĻ Installation
|
|
6
10
|
|
|
7
11
|
Install globally using npm:
|
|
8
12
|
|
|
@@ -10,36 +14,46 @@ Install globally using npm:
|
|
|
10
14
|
npm install -g ft-scout@latest
|
|
11
15
|
```
|
|
12
16
|
|
|
13
|
-
|
|
17
|
+
---
|
|
14
18
|
|
|
15
|
-
|
|
19
|
+
## ⥠Quick Start & Commands
|
|
16
20
|
|
|
17
|
-
|
|
18
|
-
# Initialize learning on a local or remote repository
|
|
19
|
-
scout init [repoUrl]
|
|
21
|
+
Once installed, use `scout` or `ft` in any project directory:
|
|
20
22
|
|
|
21
|
-
|
|
22
|
-
scout init [repoUrl] --lang spanish
|
|
23
|
-
scout init [repoUrl] -l hi
|
|
23
|
+
### đ¤ Agentic AI Actions
|
|
24
24
|
|
|
25
|
-
|
|
26
|
-
|
|
25
|
+
```bash
|
|
26
|
+
# ⨠Generate and create a new source code file
|
|
27
|
+
scout create src/utils/math.ts "Create helper functions for sum, average, and array chunking"
|
|
28
|
+
scout gen src/components/Header.tsx "Create a responsive React navigation header"
|
|
27
29
|
|
|
28
|
-
#
|
|
29
|
-
scout fix "Fix null pointer check in
|
|
30
|
+
# đ ī¸ Auto-fix code using AI based on prompt, target file, or scan issue ID
|
|
31
|
+
scout fix "Fix null pointer check in calculateTotal function"
|
|
32
|
+
scout fix -f src/sampleBug.ts "Handle optional prices defensively"
|
|
30
33
|
scout fix -i 1
|
|
31
|
-
scout fix
|
|
32
34
|
|
|
33
|
-
#
|
|
34
|
-
scout
|
|
35
|
+
# ⥠Run terminal/shell commands with automated AI error diagnosis
|
|
36
|
+
scout run npm test
|
|
37
|
+
scout exec tsc
|
|
38
|
+
scout run python main.py
|
|
35
39
|
|
|
36
|
-
#
|
|
40
|
+
# đŦ Interactive Agentic AI Chat session (with slash commands & action triggers)
|
|
37
41
|
scout chat
|
|
38
42
|
scout chat --web --lang spanish
|
|
39
43
|
|
|
40
|
-
#
|
|
41
|
-
scout
|
|
42
|
-
|
|
44
|
+
# âŠī¸ Revert Scout's last action & restore backed-up file contents
|
|
45
|
+
scout undo
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
### đ Codebase Understanding & Due-Diligence
|
|
49
|
+
|
|
50
|
+
```bash
|
|
51
|
+
# Initialize understanding map of a local or remote repository
|
|
52
|
+
scout init [repoUrl]
|
|
53
|
+
|
|
54
|
+
# Multilingual AI teardowns & onboarding summaries (e.g. spanish, hindi, french, japanese, etc.)
|
|
55
|
+
scout init [repoUrl] --lang spanish
|
|
56
|
+
scout init [repoUrl] -l hi
|
|
43
57
|
|
|
44
58
|
# Human-readable onboarding summary (the "week-one explainer")
|
|
45
59
|
scout brief
|
|
@@ -62,22 +76,30 @@ scout owners <path>
|
|
|
62
76
|
# Show a code fragility map based on churn and hotfixes
|
|
63
77
|
scout risky
|
|
64
78
|
|
|
65
|
-
#
|
|
66
|
-
scout
|
|
79
|
+
# Live internet search for live web context & up-to-date documentation
|
|
80
|
+
scout search "Next.js 15 App Router"
|
|
81
|
+
scout web "Tailwind CSS v4" --ask --lang french
|
|
67
82
|
|
|
68
|
-
# History log of everything
|
|
83
|
+
# History log of everything Scout has done in this repository
|
|
69
84
|
scout history
|
|
70
85
|
|
|
71
|
-
#
|
|
72
|
-
scout config --confidential
|
|
73
|
-
|
|
74
|
-
# Check for updates and auto-upgrade Scout to the latest version
|
|
86
|
+
# Check for updates and auto-upgrade Scout
|
|
75
87
|
scout upgrade
|
|
76
88
|
```
|
|
77
89
|
|
|
90
|
+
---
|
|
91
|
+
|
|
78
92
|
## ⨠Key Capabilities
|
|
79
93
|
|
|
80
|
-
-
|
|
81
|
-
-
|
|
82
|
-
-
|
|
83
|
-
-
|
|
94
|
+
- ⨠**AI File Generation (`scout create`)**: Specify a file path and a requirement prompt. Scout generates clean, production-ready code, creates missing directories, and provides an interactive review prompt (**Keep** vs **Revert**).
|
|
95
|
+
- đ ī¸ **Prompt-Driven Auto-Fix (`scout fix`)**: Fix bugs and refactor code across single or multiple files. Scout analyzes the root cause, applies code edits, displays a technical explanation, and backs up original code.
|
|
96
|
+
- ⥠**Terminal Execution & Failure Diagnosis (`scout run`)**: Run tests, builds, or scripts directly. If execution fails, Scout analyzes stdout/stderr logs with AI, pinpoints the root cause, and offers to auto-fix the failing code automatically.
|
|
97
|
+
- đ¤ **Agentic Copilot Chat (`scout chat`)**: An interactive terminal session with Slash Commands (`/create`, `/fix`, `/run`, `/read`, `/scan`, `/undo`, `/help`) and natural language tool execution.
|
|
98
|
+
- âŠī¸ **Safety & Instant Revert (`scout undo`)**: Every code modification or file creation is logged in `.ft/history.json` with file backups, allowing instant restoration anytime.
|
|
99
|
+
- đ **Multilingual Teardowns & Web Search (`scout search`)**: Access live internet documentation and generate breakdowns in 20+ languages.
|
|
100
|
+
|
|
101
|
+
---
|
|
102
|
+
|
|
103
|
+
## đ License
|
|
104
|
+
|
|
105
|
+
ISC Š [FrontTerrain](https://github.com/Front-Terrain/FT-Check)
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"chat.d.ts","sourceRoot":"","sources":["chat.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"chat.d.ts","sourceRoot":"","sources":["chat.ts"],"names":[],"mappings":"AAkCA,wBAAsB,UAAU,CAAC,OAAO,CAAC,EAAE;IAAE,GAAG,CAAC,EAAE,OAAO,CAAC;IAAC,IAAI,CAAC,EAAE,MAAM,CAAC;IAAC,MAAM,CAAC,EAAE,OAAO,CAAA;CAAE,iBA2L5F"}
|
package/bin/src/commands/chat.js
CHANGED
|
@@ -1,11 +1,16 @@
|
|
|
1
1
|
import fs from 'fs';
|
|
2
2
|
import path from 'path';
|
|
3
|
-
import { spinner, isCancel, text } from '@clack/prompts';
|
|
3
|
+
import { spinner, isCancel, text, confirm } from '@clack/prompts';
|
|
4
4
|
import chalk from 'chalk';
|
|
5
5
|
import { askRepoQuestion } from '../engine/llm.js';
|
|
6
6
|
import { loadContext } from '../utils/config.js';
|
|
7
7
|
import { renderMarkdown, safeNote } from '../utils/markdown.js';
|
|
8
8
|
import { normalizeLanguage } from '../utils/language.js';
|
|
9
|
+
import { handleCreate } from './create.js';
|
|
10
|
+
import { handleFix } from './fix.js';
|
|
11
|
+
import { handleRunCommand } from './runCommand.js';
|
|
12
|
+
import { handleScan } from './scan.js';
|
|
13
|
+
import { handleUndo } from './undo.js';
|
|
9
14
|
function getDirectoryFiles(dir, baseDir = dir, maxFiles = 150) {
|
|
10
15
|
let results = [];
|
|
11
16
|
try {
|
|
@@ -26,9 +31,7 @@ function getDirectoryFiles(dir, baseDir = dir, maxFiles = 150) {
|
|
|
26
31
|
}
|
|
27
32
|
}
|
|
28
33
|
}
|
|
29
|
-
catch {
|
|
30
|
-
// Ignore read errors for inaccessible folders
|
|
31
|
-
}
|
|
34
|
+
catch { }
|
|
32
35
|
return results;
|
|
33
36
|
}
|
|
34
37
|
export async function handleChat(options) {
|
|
@@ -47,17 +50,26 @@ export async function handleChat(options) {
|
|
|
47
50
|
manifestContent = '{}';
|
|
48
51
|
}
|
|
49
52
|
}
|
|
50
|
-
|
|
53
|
+
const welcomeBanner = `
|
|
54
|
+
${chalk.bold.cyan('Interactive Agentic AI Chat Session Active')} ${targetLang ? `(${targetLang})` : ''}
|
|
55
|
+
|
|
56
|
+
${chalk.bold('Slash Commands Available:')}
|
|
57
|
+
${chalk.cyan('/create <file> <prompt>')} - Create a new source file
|
|
58
|
+
${chalk.cyan('/fix [file] [prompt]')} - Auto-fix code in file or codebase
|
|
59
|
+
${chalk.cyan('/run <command>')} - Execute terminal/shell command
|
|
60
|
+
${chalk.cyan('/read <file>')} - Read and display file contents
|
|
61
|
+
${chalk.cyan('/scan')} - Scan codebase for bugs
|
|
62
|
+
${chalk.cyan('/undo')} - Revert Scout's last action
|
|
63
|
+
${chalk.cyan('/help')} - Show slash commands help
|
|
64
|
+
${chalk.cyan('exit / quit')} - Quit chat session
|
|
65
|
+
`.trim();
|
|
66
|
+
safeNote(welcomeBanner, 'đ¤ Scout Agentic Copilot Chat');
|
|
51
67
|
const chatHistory = [];
|
|
52
68
|
while (true) {
|
|
53
69
|
const query = await text({
|
|
54
70
|
message: chalk.bold('You:'),
|
|
55
|
-
placeholder: 'Ask
|
|
56
|
-
validate: (value) =>
|
|
57
|
-
if (!value || !value.trim())
|
|
58
|
-
return 'Message cannot be empty';
|
|
59
|
-
return undefined;
|
|
60
|
-
},
|
|
71
|
+
placeholder: 'Ask question, run slash command (/create, /fix, /run...), or request code generation...',
|
|
72
|
+
validate: (value) => (!value || !value.trim() ? 'Message cannot be empty' : undefined),
|
|
61
73
|
});
|
|
62
74
|
if (isCancel(query)) {
|
|
63
75
|
safeNote(chalk.yellow('Exiting interactive chat session. Goodbye!'), 'đ Chat Ended');
|
|
@@ -68,6 +80,55 @@ export async function handleChat(options) {
|
|
|
68
80
|
safeNote(chalk.yellow('Exiting interactive chat session. Goodbye!'), 'đ Chat Ended');
|
|
69
81
|
break;
|
|
70
82
|
}
|
|
83
|
+
// Slash command processing
|
|
84
|
+
if (qText.startsWith('/')) {
|
|
85
|
+
const parts = qText.split(' ');
|
|
86
|
+
const slashCmd = parts[0]?.toLowerCase();
|
|
87
|
+
const restArg = parts.slice(1).join(' ').trim();
|
|
88
|
+
if (slashCmd === '/help') {
|
|
89
|
+
safeNote(welcomeBanner, 'đ¤ Slash Command Help');
|
|
90
|
+
continue;
|
|
91
|
+
}
|
|
92
|
+
if (slashCmd === '/create') {
|
|
93
|
+
const fileParts = restArg.split(' ');
|
|
94
|
+
const targetPath = fileParts[0];
|
|
95
|
+
const promptStr = fileParts.slice(1).join(' ');
|
|
96
|
+
await handleCreate(targetPath, { prompt: promptStr, lang: targetLang, native: options?.native });
|
|
97
|
+
continue;
|
|
98
|
+
}
|
|
99
|
+
if (slashCmd === '/fix') {
|
|
100
|
+
await handleFix({ prompt: restArg, lang: targetLang, native: options?.native });
|
|
101
|
+
continue;
|
|
102
|
+
}
|
|
103
|
+
if (slashCmd === '/run' || slashCmd === '/exec') {
|
|
104
|
+
await handleRunCommand(restArg, { lang: targetLang, native: options?.native });
|
|
105
|
+
continue;
|
|
106
|
+
}
|
|
107
|
+
if (slashCmd === '/read') {
|
|
108
|
+
if (!restArg) {
|
|
109
|
+
safeNote(chalk.yellow('Please specify a file path to read (e.g. /read src/index.ts)'), 'â ī¸ Read Command');
|
|
110
|
+
continue;
|
|
111
|
+
}
|
|
112
|
+
const fullP = path.resolve(cwd, restArg);
|
|
113
|
+
if (fs.existsSync(fullP)) {
|
|
114
|
+
const content = fs.readFileSync(fullP, 'utf-8');
|
|
115
|
+
safeNote(renderMarkdown(`### đ \`${restArg}\`\n\`\`\`\n${content.slice(0, 5000)}\n\`\`\``), 'đ File Contents');
|
|
116
|
+
}
|
|
117
|
+
else {
|
|
118
|
+
safeNote(chalk.yellow(`File \`${restArg}\` not found in workspace.`), 'â ī¸ File Not Found');
|
|
119
|
+
}
|
|
120
|
+
continue;
|
|
121
|
+
}
|
|
122
|
+
if (slashCmd === '/scan') {
|
|
123
|
+
await handleScan();
|
|
124
|
+
continue;
|
|
125
|
+
}
|
|
126
|
+
if (slashCmd === '/undo') {
|
|
127
|
+
await handleUndo();
|
|
128
|
+
continue;
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
// Regular AI Q&A Synthesis
|
|
71
132
|
const askSpinner = spinner();
|
|
72
133
|
const isWebNeeded = options?.web ||
|
|
73
134
|
/^\/(web|internet|search)\b/i.test(qText) ||
|
|
@@ -84,6 +145,47 @@ export async function handleChat(options) {
|
|
|
84
145
|
safeNote(formattedAnswer, 'đĄ AI Response');
|
|
85
146
|
chatHistory.push({ role: 'user', content: qText });
|
|
86
147
|
chatHistory.push({ role: 'assistant', content: answer });
|
|
148
|
+
// Agentic Intent Detection for File Creation, Code Fix, or Shell Execution
|
|
149
|
+
const lowerQ = qText.toLowerCase();
|
|
150
|
+
// Intent 1: Create File
|
|
151
|
+
const createMatch = qText.match(/(?:create|generate|add|make)\s+(?:a\s+)?(?:new\s+)?(?:file\s+)?([a-zA-Z0-9_\-./]+\.[a-zA-Z0-9]+)\b/i);
|
|
152
|
+
if (createMatch && createMatch[1] && !createMatch[1].includes('package.json')) {
|
|
153
|
+
const targetFile = createMatch[1];
|
|
154
|
+
const shouldCreate = await confirm({
|
|
155
|
+
message: chalk.bold(`Would you like Scout to create file ${chalk.cyan(targetFile)} now?`),
|
|
156
|
+
initialValue: true,
|
|
157
|
+
});
|
|
158
|
+
if (!isCancel(shouldCreate) && shouldCreate) {
|
|
159
|
+
await handleCreate(targetFile, { prompt: qText, lang: targetLang, native: options?.native });
|
|
160
|
+
continue;
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
// Intent 2: Run Command
|
|
164
|
+
const runMatch = qText.match(/(?:run|execute|test|build)\s+(?:command\s+)?`(npm|npx|tsc|git|python|node|cargo|go|make|yarn|pnpm)[^`]+`/i) ||
|
|
165
|
+
qText.match(/^(?:run|execute|run command)\s+["']?([^"']+)["']?$/i);
|
|
166
|
+
if (runMatch && runMatch[1]) {
|
|
167
|
+
const targetCmd = runMatch[1];
|
|
168
|
+
const shouldRun = await confirm({
|
|
169
|
+
message: chalk.bold(`Would you like Scout to run command \`${chalk.cyan(targetCmd)}\` now?`),
|
|
170
|
+
initialValue: true,
|
|
171
|
+
});
|
|
172
|
+
if (!isCancel(shouldRun) && shouldRun) {
|
|
173
|
+
await handleRunCommand(targetCmd, { lang: targetLang, native: options?.native });
|
|
174
|
+
continue;
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
// Intent 3: Auto-fix Code
|
|
178
|
+
const fixMatch = lowerQ.includes('fix bug') || lowerQ.includes('auto-fix') || lowerQ.includes('refactor file') || lowerQ.includes('fix code');
|
|
179
|
+
if (fixMatch) {
|
|
180
|
+
const shouldFix = await confirm({
|
|
181
|
+
message: chalk.bold('Would you like Scout to apply this auto-fix to your codebase now?'),
|
|
182
|
+
initialValue: true,
|
|
183
|
+
});
|
|
184
|
+
if (!isCancel(shouldFix) && shouldFix) {
|
|
185
|
+
await handleFix({ prompt: qText, lang: targetLang, native: options?.native });
|
|
186
|
+
continue;
|
|
187
|
+
}
|
|
188
|
+
}
|
|
87
189
|
}
|
|
88
190
|
}
|
|
89
191
|
//# sourceMappingURL=chat.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"chat.js","sourceRoot":"","sources":["chat.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,IAAI,CAAC;AACpB,OAAO,IAAI,MAAM,MAAM,CAAC;AACxB,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,IAAI,EAAE,MAAM,gBAAgB,CAAC;
|
|
1
|
+
{"version":3,"file":"chat.js","sourceRoot":"","sources":["chat.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"configCommand.d.ts","sourceRoot":"","sources":["configCommand.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"configCommand.d.ts","sourceRoot":"","sources":["configCommand.ts"],"names":[],"mappings":"AAKA,MAAM,WAAW,aAAa;IAC5B,YAAY,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;IACnC,IAAI,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;IAC3B,IAAI,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;CAC3B;AAED,wBAAsB,YAAY,CAAC,OAAO,CAAC,EAAE,aAAa,iBA6DzD"}
|
|
@@ -1,7 +1,30 @@
|
|
|
1
1
|
import chalk from 'chalk';
|
|
2
2
|
import { loadFtConfig, saveFtConfig } from '../utils/config.js';
|
|
3
|
+
import { loadDiscoveryConfig, saveDiscoveryConfig } from '../discovery/config.js';
|
|
3
4
|
import { safeNote } from '../utils/markdown.js';
|
|
4
5
|
export async function handleConfig(options) {
|
|
6
|
+
if (options?.tips) {
|
|
7
|
+
const val = options.tips.toLowerCase().trim();
|
|
8
|
+
const discoveryCfg = loadDiscoveryConfig();
|
|
9
|
+
if (val === 'on') {
|
|
10
|
+
discoveryCfg.tipsEnabled = true;
|
|
11
|
+
saveDiscoveryConfig(discoveryCfg);
|
|
12
|
+
console.log(chalk.green('Discovery tips enabled.'));
|
|
13
|
+
return;
|
|
14
|
+
}
|
|
15
|
+
if (val === 'off') {
|
|
16
|
+
discoveryCfg.tipsEnabled = false;
|
|
17
|
+
saveDiscoveryConfig(discoveryCfg);
|
|
18
|
+
console.log(chalk.yellow('Discovery tips disabled.'));
|
|
19
|
+
return;
|
|
20
|
+
}
|
|
21
|
+
if (val === 'status') {
|
|
22
|
+
console.log(`tipsEnabled: ${discoveryCfg.tipsEnabled}, commandCount: ${discoveryCfg.commandCount}`);
|
|
23
|
+
return;
|
|
24
|
+
}
|
|
25
|
+
console.log(chalk.yellow(`Invalid tips setting: "${options.tips}". Valid options are: on, off, status.`));
|
|
26
|
+
return;
|
|
27
|
+
}
|
|
5
28
|
let cfg = loadFtConfig();
|
|
6
29
|
if (options?.confidential) {
|
|
7
30
|
cfg.allowConfidential = true;
|
|
@@ -18,10 +41,13 @@ export async function handleConfig(options) {
|
|
|
18
41
|
`FT will restrict scanning of sensitive configuration files and environment definitions.`, 'âī¸ FrontTerrain Permission Config');
|
|
19
42
|
return;
|
|
20
43
|
}
|
|
44
|
+
const discoveryCfg = loadDiscoveryConfig();
|
|
21
45
|
safeNote(`Current Configuration Settings:\n` +
|
|
22
|
-
` âĸ Confidential Data Access: ${cfg.allowConfidential ? chalk.bold.green('ALLOWED') : chalk.bold.yellow('DENIED')}\n
|
|
46
|
+
` âĸ Confidential Data Access: ${cfg.allowConfidential ? chalk.bold.green('ALLOWED') : chalk.bold.yellow('DENIED')}\n` +
|
|
47
|
+
` âĸ Discovery Tips Enabled: ${discoveryCfg.tipsEnabled ? chalk.bold.green('ENABLED') : chalk.bold.yellow('DISABLED')} (Commands run: ${discoveryCfg.commandCount})\n\n` +
|
|
23
48
|
`Usage options:\n` +
|
|
24
|
-
` âĸ Allow access:
|
|
25
|
-
` âĸ Deny access:
|
|
49
|
+
` âĸ Allow access: ${chalk.cyan('ft config --confidential')}\n` +
|
|
50
|
+
` âĸ Deny access: ${chalk.cyan('ft config --deny')}\n` +
|
|
51
|
+
` âĸ Toggle tips: ${chalk.cyan('ft config --tips on | off | status')}`, 'âī¸ FrontTerrain Permission Config');
|
|
26
52
|
}
|
|
27
53
|
//# sourceMappingURL=configCommand.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"configCommand.js","sourceRoot":"","sources":["configCommand.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAChE,OAAO,EAAE,QAAQ,EAAE,MAAM,sBAAsB,CAAC;
|
|
1
|
+
{"version":3,"file":"configCommand.js","sourceRoot":"","sources":["configCommand.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAChE,OAAO,EAAE,mBAAmB,EAAE,mBAAmB,EAAE,MAAM,wBAAwB,CAAC;AAClF,OAAO,EAAE,QAAQ,EAAE,MAAM,sBAAsB,CAAC;AAQhD,MAAM,CAAC,KAAK,UAAU,YAAY,CAAC,OAAuB;IACxD,IAAI,OAAO,EAAE,IAAI,EAAE,CAAC;QAClB,MAAM,GAAG,GAAG,OAAO,CAAC,IAAI,CAAC,WAAW,EAAE,CAAC,IAAI,EAAE,CAAC;QAC9C,MAAM,YAAY,GAAG,mBAAmB,EAAE,CAAC;QAC3C,IAAI,GAAG,KAAK,IAAI,EAAE,CAAC;YACjB,YAAY,CAAC,WAAW,GAAG,IAAI,CAAC;YAChC,mBAAmB,CAAC,YAAY,CAAC,CAAC;YAClC,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,yBAAyB,CAAC,CAAC,CAAC;YACpD,OAAO;QACT,CAAC;QACD,IAAI,GAAG,KAAK,KAAK,EAAE,CAAC;YAClB,YAAY,CAAC,WAAW,GAAG,KAAK,CAAC;YACjC,mBAAmB,CAAC,YAAY,CAAC,CAAC;YAClC,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC,0BAA0B,CAAC,CAAC,CAAC;YACtD,OAAO;QACT,CAAC;QACD,IAAI,GAAG,KAAK,QAAQ,EAAE,CAAC;YACrB,OAAO,CAAC,GAAG,CAAC,gBAAgB,YAAY,CAAC,WAAW,mBAAmB,YAAY,CAAC,YAAY,EAAE,CAAC,CAAC;YACpG,OAAO;QACT,CAAC;QACD,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC,0BAA0B,OAAO,CAAC,IAAI,wCAAwC,CAAC,CAAC,CAAC;QAC1G,OAAO;IACT,CAAC;IAED,IAAI,GAAG,GAAG,YAAY,EAAE,CAAC;IAEzB,IAAI,OAAO,EAAE,YAAY,EAAE,CAAC;QAC1B,GAAG,CAAC,iBAAiB,GAAG,IAAI,CAAC;QAC7B,YAAY,CAAC,GAAG,CAAC,CAAC;QAClB,QAAQ,CACN,6BAA6B,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,SAAS,CAAC,MAAM;YAC5D,kHAAkH;YAClH,6FAA6F,EAC/F,mCAAmC,CACpC,CAAC;QACF,OAAO;IACT,CAAC;IAED,IAAI,OAAO,EAAE,IAAI,EAAE,CAAC;QAClB,GAAG,CAAC,iBAAiB,GAAG,KAAK,CAAC;QAC9B,YAAY,CAAC,GAAG,CAAC,CAAC;QAClB,QAAQ,CACN,6BAA6B,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC,MAAM;YACzD,yFAAyF,EAC3F,mCAAmC,CACpC,CAAC;QACF,OAAO;IACT,CAAC;IAED,MAAM,YAAY,GAAG,mBAAmB,EAAE,CAAC;IAE3C,QAAQ,CACN,mCAAmC;QACjC,iCAAiC,GAAG,CAAC,iBAAiB,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,IAAI;QACtH,iCAAiC,YAAY,CAAC,WAAW,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,UAAU,CAAC,mBAAmB,YAAY,CAAC,YAAY,OAAO;QAC1K,kBAAkB;QAClB,wBAAwB,KAAK,CAAC,IAAI,CAAC,0BAA0B,CAAC,IAAI;QAClE,wBAAwB,KAAK,CAAC,IAAI,CAAC,kBAAkB,CAAC,IAAI;QAC1D,wBAAwB,KAAK,CAAC,IAAI,CAAC,oCAAoC,CAAC,EAAE,EAC5E,mCAAmC,CACpC,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"create.d.ts","sourceRoot":"","sources":["create.ts"],"names":[],"mappings":"AAWA,MAAM,WAAW,aAAa;IAC5B,MAAM,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC5B,IAAI,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC1B,MAAM,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;CAC9B;AAsBD,wBAAsB,YAAY,CAAC,aAAa,CAAC,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,aAAa,iBAwJjF"}
|
|
@@ -0,0 +1,163 @@
|
|
|
1
|
+
import chalk from 'chalk';
|
|
2
|
+
import fs from 'fs';
|
|
3
|
+
import path from 'path';
|
|
4
|
+
import { spinner, text, select, isCancel } from '@clack/prompts';
|
|
5
|
+
import { simpleGit } from 'simple-git';
|
|
6
|
+
import { safeNote, renderMarkdown } from '../utils/markdown.js';
|
|
7
|
+
import { recordHistoryAction, loadContext } from '../utils/config.js';
|
|
8
|
+
import { generateCodeFile } from '../engine/llm.js';
|
|
9
|
+
import { handleUndo } from './undo.js';
|
|
10
|
+
import { normalizeLanguage } from '../utils/language.js';
|
|
11
|
+
function getDirectoryFiles(dir, baseDir = dir, maxFiles = 150) {
|
|
12
|
+
let results = [];
|
|
13
|
+
try {
|
|
14
|
+
const list = fs.readdirSync(dir);
|
|
15
|
+
for (const file of list) {
|
|
16
|
+
if (results.length >= maxFiles)
|
|
17
|
+
break;
|
|
18
|
+
if (['node_modules', '.git', '.ft', 'dist', 'build', '.next', 'coverage'].includes(file))
|
|
19
|
+
continue;
|
|
20
|
+
const filePath = path.join(dir, file);
|
|
21
|
+
const stat = fs.statSync(filePath);
|
|
22
|
+
if (stat && stat.isDirectory()) {
|
|
23
|
+
results = results.concat(getDirectoryFiles(filePath, baseDir, maxFiles - results.length));
|
|
24
|
+
}
|
|
25
|
+
else {
|
|
26
|
+
const relativePath = path.relative(baseDir, filePath).replace(/\\/g, '/');
|
|
27
|
+
results.push(relativePath);
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
catch { }
|
|
32
|
+
return results;
|
|
33
|
+
}
|
|
34
|
+
export async function handleCreate(filePathInput, options) {
|
|
35
|
+
const existingContext = loadContext();
|
|
36
|
+
const targetLang = normalizeLanguage(options?.lang) || normalizeLanguage(existingContext?.language);
|
|
37
|
+
const cwd = process.cwd();
|
|
38
|
+
const filesList = getDirectoryFiles(cwd);
|
|
39
|
+
const projectName = existingContext?.projectName || path.basename(cwd) || 'Codebase';
|
|
40
|
+
let targetFilePath = filePathInput;
|
|
41
|
+
if (!targetFilePath || !targetFilePath.trim()) {
|
|
42
|
+
const userInputPath = await text({
|
|
43
|
+
message: chalk.bold('Enter relative file path to create (e.g. src/utils/math.ts):'),
|
|
44
|
+
placeholder: 'src/utils/helpers.ts',
|
|
45
|
+
validate: (val) => (!val || !val.trim() ? 'File path is required' : undefined),
|
|
46
|
+
});
|
|
47
|
+
if (isCancel(userInputPath)) {
|
|
48
|
+
safeNote(chalk.yellow('File creation operation cancelled.'), '⨠Scout File Creation');
|
|
49
|
+
return;
|
|
50
|
+
}
|
|
51
|
+
targetFilePath = userInputPath.trim();
|
|
52
|
+
}
|
|
53
|
+
let finalPrompt = options?.prompt;
|
|
54
|
+
if (!finalPrompt || !finalPrompt.trim()) {
|
|
55
|
+
const userPromptInput = await text({
|
|
56
|
+
message: chalk.bold(`What should Scout generate inside ${chalk.cyan(targetFilePath)}?`),
|
|
57
|
+
placeholder: 'e.g. Create a utility module with functions for string formatting and timestamp parsing',
|
|
58
|
+
validate: (val) => (!val || !val.trim() ? 'Please provide a prompt describing the file requirements' : undefined),
|
|
59
|
+
});
|
|
60
|
+
if (isCancel(userPromptInput)) {
|
|
61
|
+
safeNote(chalk.yellow('File creation operation cancelled.'), '⨠Scout File Creation');
|
|
62
|
+
return;
|
|
63
|
+
}
|
|
64
|
+
finalPrompt = userPromptInput.trim();
|
|
65
|
+
}
|
|
66
|
+
const resolvedPath = path.resolve(cwd, targetFilePath);
|
|
67
|
+
const fileExists = fs.existsSync(resolvedPath);
|
|
68
|
+
const originalContent = fileExists ? fs.readFileSync(resolvedPath, 'utf-8') : '__FT_WAS_NEW__';
|
|
69
|
+
const git = simpleGit();
|
|
70
|
+
const isRepo = await git.checkIsRepo();
|
|
71
|
+
let currentBranch = 'main';
|
|
72
|
+
if (isRepo) {
|
|
73
|
+
try {
|
|
74
|
+
const branchSummary = await git.branch();
|
|
75
|
+
currentBranch = branchSummary.current || 'main';
|
|
76
|
+
}
|
|
77
|
+
catch { }
|
|
78
|
+
}
|
|
79
|
+
const cleanTitle = path.basename(targetFilePath)
|
|
80
|
+
.toLowerCase()
|
|
81
|
+
.replace(/[^a-z0-9]+/g, '-')
|
|
82
|
+
.replace(/^-|-$/g, '')
|
|
83
|
+
.slice(0, 20);
|
|
84
|
+
const branchName = `ft/create-${Date.now().toString().slice(-4)}-${cleanTitle}`;
|
|
85
|
+
if (isRepo) {
|
|
86
|
+
try {
|
|
87
|
+
await git.checkoutLocalBranch(branchName);
|
|
88
|
+
}
|
|
89
|
+
catch {
|
|
90
|
+
try {
|
|
91
|
+
await git.checkout(branchName);
|
|
92
|
+
}
|
|
93
|
+
catch { }
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
const s = spinner();
|
|
97
|
+
s.start(`Scout is generating code for ${targetFilePath} with AI...`);
|
|
98
|
+
let genResult;
|
|
99
|
+
try {
|
|
100
|
+
genResult = await generateCodeFile(targetFilePath, finalPrompt, projectName, filesList, targetLang, options?.native);
|
|
101
|
+
}
|
|
102
|
+
catch (err) {
|
|
103
|
+
s.stop(chalk.red('Failed to generate code file.'));
|
|
104
|
+
safeNote(chalk.red(`Error: ${err?.message || String(err)}`), 'â ī¸ Code Generation Error');
|
|
105
|
+
return;
|
|
106
|
+
}
|
|
107
|
+
// Ensure parent directory exists
|
|
108
|
+
const parentDir = path.dirname(resolvedPath);
|
|
109
|
+
if (!fs.existsSync(parentDir)) {
|
|
110
|
+
fs.mkdirSync(parentDir, { recursive: true });
|
|
111
|
+
}
|
|
112
|
+
try {
|
|
113
|
+
fs.writeFileSync(resolvedPath, genResult.code, 'utf-8');
|
|
114
|
+
}
|
|
115
|
+
catch (writeErr) {
|
|
116
|
+
s.stop(chalk.red('Failed to write generated code to disk.'));
|
|
117
|
+
safeNote(chalk.red(`Write error: ${writeErr?.message || String(writeErr)}`), 'â ī¸ File Write Error');
|
|
118
|
+
return;
|
|
119
|
+
}
|
|
120
|
+
recordHistoryAction({
|
|
121
|
+
command: `ft create "${targetFilePath}" "${finalPrompt}"`,
|
|
122
|
+
description: `Scout created file ${targetFilePath}`,
|
|
123
|
+
branchName,
|
|
124
|
+
previousBranch: currentBranch,
|
|
125
|
+
affectedFiles: [targetFilePath],
|
|
126
|
+
backups: [{ filePath: targetFilePath, originalContent }],
|
|
127
|
+
});
|
|
128
|
+
s.stop(chalk.green(`File ${targetFilePath} created successfully!`));
|
|
129
|
+
const teardownContent = `
|
|
130
|
+
### đ Created File
|
|
131
|
+
\`${targetFilePath}\`
|
|
132
|
+
|
|
133
|
+
### đĄ Description & Overview
|
|
134
|
+
${genResult.description}
|
|
135
|
+
|
|
136
|
+
### đģ Preview
|
|
137
|
+
\`\`\`
|
|
138
|
+
${genResult.code.slice(0, 500)}${genResult.code.length > 500 ? '\n... (truncated)' : ''}
|
|
139
|
+
\`\`\`
|
|
140
|
+
|
|
141
|
+
---
|
|
142
|
+
*File has been written to \`${targetFilePath}\`${isRepo ? ` on branch \`${branchName}\`` : ''}.*
|
|
143
|
+
`.trim();
|
|
144
|
+
safeNote(renderMarkdown(teardownContent), '⨠Scout File Creation Teardown');
|
|
145
|
+
const revertChoice = await select({
|
|
146
|
+
message: chalk.bold('Review Scout\'s generated file. What would you like to do?'),
|
|
147
|
+
options: [
|
|
148
|
+
{ value: 'keep', label: 'â
Keep File', hint: 'Retain the newly created file in your project' },
|
|
149
|
+
{ value: 'revert', label: 'âŠī¸ Revert / Delete File', hint: 'Remove the created file and restore branch state' },
|
|
150
|
+
],
|
|
151
|
+
});
|
|
152
|
+
if (isCancel(revertChoice) || revertChoice === 'revert') {
|
|
153
|
+
const revSpinner = spinner();
|
|
154
|
+
revSpinner.start('Reverting Scout\'s file creation...');
|
|
155
|
+
await handleUndo();
|
|
156
|
+
revSpinner.stop('Creation reverted successfully.');
|
|
157
|
+
}
|
|
158
|
+
else {
|
|
159
|
+
safeNote(`${chalk.green('â')} Saved ${chalk.bold.cyan(targetFilePath)}.\n` +
|
|
160
|
+
`đĄ ${chalk.dim('You can revert this creation anytime by running:')} ${chalk.cyan('scout undo')}`, 'â
Creation Confirmed');
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
//# sourceMappingURL=create.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"create.js","sourceRoot":"","sources":["create.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"fix.d.ts","sourceRoot":"","sources":["fix.ts"],"names":[],"mappings":"AAYA,MAAM,WAAW,UAAU;IACzB,KAAK,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;
|
|
1
|
+
{"version":3,"file":"fix.d.ts","sourceRoot":"","sources":["fix.ts"],"names":[],"mappings":"AAYA,MAAM,WAAW,UAAU;IACzB,KAAK,CAAC,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAAC;IACpC,IAAI,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC1B,MAAM,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC5B,IAAI,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC1B,MAAM,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;CAC9B;AAiCD,wBAAsB,SAAS,CAAC,OAAO,CAAC,EAAE,UAAU,iBAwLnD"}
|
package/bin/src/commands/fix.js
CHANGED
|
@@ -49,7 +49,7 @@ export async function handleFix(options) {
|
|
|
49
49
|
const filesList = getDirectoryFiles(cwd);
|
|
50
50
|
const projectName = existingContext?.projectName || path.basename(cwd) || 'Codebase';
|
|
51
51
|
let finalPrompt = options?.prompt;
|
|
52
|
-
let specifiedTargetFile =
|
|
52
|
+
let specifiedTargetFile = options?.file;
|
|
53
53
|
if (!finalPrompt && options?.issue) {
|
|
54
54
|
const report = loadScanReport();
|
|
55
55
|
const issueId = Number(options.issue);
|
|
@@ -82,8 +82,15 @@ export async function handleFix(options) {
|
|
|
82
82
|
filesList.find((f) => f.endsWith('.ts') || f.endsWith('.js') || f.endsWith('.py')) ||
|
|
83
83
|
filesList[0];
|
|
84
84
|
}
|
|
85
|
+
if (targetFile && !fs.existsSync(path.resolve(cwd, targetFile))) {
|
|
86
|
+
// If target file specified or found from prompt doesn't exist, offer file creation!
|
|
87
|
+
const { handleCreate } = await import('./create.js');
|
|
88
|
+
safeNote(chalk.cyan(`Target file \`${targetFile}\` does not exist yet. Switching to Scout File Creation...`), '⨠Creating New File');
|
|
89
|
+
await handleCreate(targetFile, { prompt: finalPrompt, lang: targetLang, native: options?.native });
|
|
90
|
+
return;
|
|
91
|
+
}
|
|
85
92
|
if (!targetFile || !fs.existsSync(path.resolve(cwd, targetFile))) {
|
|
86
|
-
safeNote(chalk.yellow(`Could not locate a target source file to fix in this codebase.\nPlease specify a valid file name in your prompt
|
|
93
|
+
safeNote(chalk.yellow(`Could not locate a target source file to fix in this codebase.\nPlease specify a valid file name in your prompt or use --file <filename>.`), 'â ī¸ Target File Not Found');
|
|
87
94
|
return;
|
|
88
95
|
}
|
|
89
96
|
const currentContent = fs.readFileSync(path.resolve(cwd, targetFile), 'utf-8');
|