ft-scout 2.0.4 → 2.0.6
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/.ft/config.json +3 -0
- package/.ft/context.json +8 -8
- package/README.md +4 -0
- package/bin/src/commands/add.d.ts.map +1 -0
- package/bin/src/commands/add.js +45 -0
- package/bin/src/commands/add.js.map +1 -0
- package/bin/src/commands/audit.d.ts.map +1 -0
- package/bin/src/commands/audit.js +79 -0
- package/bin/src/commands/audit.js.map +1 -0
- package/bin/src/commands/brief.d.ts.map +1 -0
- package/bin/src/commands/brief.js +37 -0
- package/bin/src/commands/brief.js.map +1 -0
- package/bin/src/commands/chat.d.ts.map +1 -0
- package/bin/src/commands/chat.js +89 -0
- package/bin/src/commands/chat.js.map +1 -0
- package/bin/src/commands/configCommand.d.ts.map +1 -0
- package/bin/src/commands/configCommand.js +27 -0
- package/bin/src/commands/configCommand.js.map +1 -0
- package/bin/src/commands/fix.d.ts.map +1 -0
- package/bin/src/commands/fix.js +67 -0
- package/bin/src/commands/fix.js.map +1 -0
- package/bin/src/commands/history.d.ts.map +1 -0
- package/bin/src/commands/history.js +20 -0
- package/bin/src/commands/history.js.map +1 -0
- package/bin/src/commands/init.d.ts.map +1 -1
- package/bin/src/commands/init.js +22 -8
- package/bin/src/commands/init.js.map +1 -1
- package/bin/src/commands/recommend.d.ts.map +1 -0
- package/bin/src/commands/recommend.js +46 -0
- package/bin/src/commands/recommend.js.map +1 -0
- package/bin/src/commands/scan.d.ts.map +1 -0
- package/bin/src/commands/scan.js +80 -0
- package/bin/src/commands/scan.js.map +1 -0
- package/bin/src/commands/undo.d.ts.map +1 -0
- package/bin/src/commands/undo.js +37 -0
- package/bin/src/commands/undo.js.map +1 -0
- package/bin/src/commands/web.js +8 -8
- package/bin/src/commands/web.js.map +1 -1
- package/bin/src/engine/llm.d.ts.map +1 -1
- package/bin/src/engine/llm.js +212 -25
- package/bin/src/engine/llm.js.map +1 -1
- package/bin/src/index.js +121 -25
- package/bin/src/index.js.map +1 -1
- package/bin/src/utils/config.d.ts.map +1 -1
- package/bin/src/utils/config.js +62 -2
- package/bin/src/utils/config.js.map +1 -1
- package/bin/src/utils/language.js +5 -5
- package/bin/src/utils/language.js.map +1 -1
- package/bin/src/utils/markdown.d.ts.map +1 -1
- package/bin/src/utils/markdown.js +33 -2
- package/bin/src/utils/markdown.js.map +1 -1
- package/package.json +1 -1
- package/email-template.txt +0 -44
package/.ft/config.json
ADDED
package/.ft/context.json
CHANGED
|
@@ -1,18 +1,18 @@
|
|
|
1
1
|
{
|
|
2
2
|
"projectName": "FT-CLI",
|
|
3
3
|
"targetDir": "C:\\Users\\rishi\\FT-CLI",
|
|
4
|
-
"stack": "- **Core Capability**:
|
|
4
|
+
"stack": "- **Core Capability**: फ्रंट टेरेन क्लाइंट एक शक्तिशाली ऑनबोर्डिंग को-पायलट है जो नई कोडबेस के लिए एक सहज और एकीकृत अनुभव प्रदान करता है। यह प्रोजेक्ट एक्सप्लोरेशन, गिट रिपॉजिटरी मैनेजमेंट और मशीन लर्निंग इंटीग्रेशन के माध्यम से एक पूर्ण ऑनबोर्डिंग सेवा प्रदान करता है जो नई कोडबेस के लिए एक सुगम और एकीकृत अनुभव प्रदान करता है। \n- **Architecture & Stack**: फ्रंट टेरेन क्लाइंट एक Node.js मॉड्यूल आधारित आर्किटेक्चर पर बनाया गया है, जिसमें TypeScript का उपयोग कोड की गुणवत्ता और स्थिरता सुनिश्चित करने के लिए किया जाता है। यह प्रोजेक्ट विभिन्न पैकेजों जैसे कि Commander, Dotenv, और OpenAI का उपयोग करके अपनी कोर क्षमता को पूरा करता है। \n- **Architectural Moat**: फ्रंट टेरेन क्लाइंट की आर्किटेक्चर एक अनोखी और प्रभावी ऑनबोर्डिंग अनुभव प्रदान करने में सक्षम है, जो इसे अपने प्रतिस्पर्धियों से अलग बनाता है। इसकी आर्किटेक्चर में विभिन्न मॉड्यूल और पैकेजों का उपयोग करके एक सुगम और एकीकृत अनुभव प्रदान किया जाता है, जो नए उपयोगकर्ताओं के लिए बहुत आसान होता है।",
|
|
5
5
|
"entryPoint": "bin/ft.js",
|
|
6
6
|
"painPoints": [
|
|
7
|
-
"⚡ [Subsystem Risk]:
|
|
8
|
-
"⚡ [Scaling Bottleneck]:
|
|
9
|
-
"⚡ [Execution Note]:
|
|
7
|
+
"⚡ [Subsystem Risk]: फ्रंट टेरेन क्लाइंट के प्रोजेक्ट में कई निर्भरताएँ हैं, जो प्रोजेक्ट के स्थिरता और सुरक्षा को प्रभावित कर सकती हैं। यदि इन निर्भरताओं में से कोई एक अस्थिर या असुरक्षित होता है, तो यह पूरे प्रोजेक्ट को प्रभावित कर सकता है।",
|
|
8
|
+
"⚡ [Scaling Bottleneck]: फ्रंट टेरेन क्लाइंट के प्रोजेक्ट में मशीन लर्निंग और आर्टिफ़िशियल इंटेलिजेंस का उपयोग किया जाता है, जो प्रोजेक्ट के प्रदर्शन को प्रभावित कर सकता है। यदि प्रोजेक्ट के उपयोगकर्ता बढ़ते हैं, तो यह प्रोजेक्ट के प्रदर्शन को प्रभावित कर सकता है और स्केलिंग की आवश्यकता हो सकती है।",
|
|
9
|
+
"⚡ [Execution Note]: फ्रंट टेरेन क्लाइंट के प्रोजेक्ट को चलाने के लिए निर्धारित पर्यावरण और निर्भरताओं की आवश्यकता होती है, जो प्रोजेक्ट के स्थापना और प्रबंधन को प्रभावित कर सकती हैं। यदि प्रोजेक्ट के उपयोगकर्ता इन निर्भरताओं को स्थापित नहीं करते हैं, तो यह प्रोजेक्ट के प्रदर्शन को प्रभावित कर सकता है।"
|
|
10
10
|
],
|
|
11
11
|
"readOrder": [
|
|
12
|
-
"package.json ->
|
|
13
|
-
"src/email-template.txt ->
|
|
14
|
-
"bin/ft.js ->
|
|
12
|
+
"package.json -> यह फ़ाइल प्रोजेक्ट की मुख्य कॉन्फ़िगरेशन फ़ाइल है, जिसमें प्रोजेक्ट के नाम, वर्ज़न, और निर्भरताओं का विवरण होता है। यहाँ से प्रोजेक्ट के बारे में विस्तृत जानकारी प्राप्त की जा सकती है।",
|
|
13
|
+
"src/email-template.txt -> यह फ़ाइल प्रोजेक्ट के ईमेल टेम्पलेट को परिभाषित करती है, जो ऑनबोर्डिंग प्रक्रिया के दौरान उपयोगकर्ताओं को भेजे जाने वाले ईमेल के लिए उपयोग किया जाता है।",
|
|
14
|
+
"bin/ft.js -> यह फ़ाइल प्रोजेक्ट का मुख्य प्रवेश बिंदु है, जो प्रोजेक्ट के सभी मॉड्यूल और पैकेजों को एक साथ जोड़ता है। यहाँ से प्रोजेक्ट के सभी कार्यों को नियंत्रित किया जा सकता है।"
|
|
15
15
|
],
|
|
16
|
-
"createdAt": "2026-08-
|
|
16
|
+
"createdAt": "2026-08-01T17:46:25.413Z",
|
|
17
17
|
"language": "Hindi"
|
|
18
18
|
}
|
package/README.md
CHANGED
|
@@ -25,6 +25,10 @@ ft init [repoUrl] -l hi
|
|
|
25
25
|
# Interactive Q&A mode after indexing (with optional web search and custom language)
|
|
26
26
|
ft init --ask --web --lang ja
|
|
27
27
|
|
|
28
|
+
# Live interactive AI chat co-pilot (until Ctrl+C is pressed)
|
|
29
|
+
ft chat
|
|
30
|
+
ft chat --web --lang spanish
|
|
31
|
+
|
|
28
32
|
# Live internet search for live web context & up-to-date documentation
|
|
29
33
|
ft search "Next.js 15 App Router"
|
|
30
34
|
ft web "Tailwind CSS v4" --ask --lang french
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"add.d.ts","sourceRoot":"","sources":["add.ts"],"names":[],"mappings":"AAQA,wBAAsB,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE;IAAE,IAAI,CAAC,EAAE,MAAM,CAAC;IAAC,MAAM,CAAC,EAAE,OAAO,CAAA;CAAE,iBAgD1F"}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import fs from 'fs';
|
|
2
|
+
import path from 'path';
|
|
3
|
+
import chalk from 'chalk';
|
|
4
|
+
import { spinner } from '@clack/prompts';
|
|
5
|
+
import { generateFeaturePlan } from '../engine/llm.js';
|
|
6
|
+
import { renderMarkdown, safeNote } from '../utils/markdown.js';
|
|
7
|
+
import { loadContext } from '../utils/config.js';
|
|
8
|
+
export async function handleAdd(idea, options) {
|
|
9
|
+
if (!idea || !idea.trim()) {
|
|
10
|
+
safeNote(chalk.red('Please provide a feature description. Example: `ft add "add webhook retry queue"`'), '❌ Missing Feature Description');
|
|
11
|
+
return;
|
|
12
|
+
}
|
|
13
|
+
const s = spinner();
|
|
14
|
+
s.start(`Evaluating feasibility & generating implementation plan for: "${chalk.cyan(idea)}"...`);
|
|
15
|
+
const cwd = process.cwd();
|
|
16
|
+
const context = loadContext();
|
|
17
|
+
const projectName = context?.projectName || path.basename(cwd);
|
|
18
|
+
const getFiles = (dir, depth = 2) => {
|
|
19
|
+
let results = [];
|
|
20
|
+
try {
|
|
21
|
+
const list = fs.readdirSync(dir);
|
|
22
|
+
for (const file of list) {
|
|
23
|
+
if (['node_modules', '.git', 'dist', 'build', '.ft'].includes(file))
|
|
24
|
+
continue;
|
|
25
|
+
const fullPath = path.join(dir, file);
|
|
26
|
+
const relPath = path.relative(cwd, fullPath);
|
|
27
|
+
const stat = fs.statSync(fullPath);
|
|
28
|
+
if (stat.isDirectory()) {
|
|
29
|
+
if (depth > 1)
|
|
30
|
+
results = results.concat(getFiles(fullPath, depth - 1));
|
|
31
|
+
}
|
|
32
|
+
else {
|
|
33
|
+
results.push(relPath);
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
catch { }
|
|
38
|
+
return results;
|
|
39
|
+
};
|
|
40
|
+
const filesList = getFiles(cwd, 2);
|
|
41
|
+
const plan = await generateFeaturePlan(idea, projectName, filesList, options?.lang || context?.language, options?.native);
|
|
42
|
+
s.stop('Feasibility assessment & roadmap complete.');
|
|
43
|
+
safeNote(renderMarkdown(plan), `🚀 Feature Implementation Roadmap: "${idea}"`);
|
|
44
|
+
}
|
|
45
|
+
//# sourceMappingURL=add.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"add.js","sourceRoot":"","sources":["add.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,IAAI,CAAC;AACpB,OAAO,IAAI,MAAM,MAAM,CAAC;AACxB,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,EAAE,OAAO,EAAE,MAAM,gBAAgB,CAAC;AACzC,OAAO,EAAE,mBAAmB,EAAE,MAAM,kBAAkB,CAAC;AACvD,OAAO,EAAE,cAAc,EAAE,QAAQ,EAAE,MAAM,sBAAsB,CAAC;AAChE,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AAEjD,MAAM,CAAC,KAAK,UAAU,SAAS,CAAC,IAAY,EAAE,OAA6C;IACzF,IAAI,CAAC,IAAI,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,EAAE,CAAC;QAC1B,QAAQ,CAAC,KAAK,CAAC,GAAG,CAAC,mFAAmF,CAAC,EAAE,+BAA+B,CAAC,CAAC;QAC1I,OAAO;IACT,CAAC;IAED,MAAM,CAAC,GAAG,OAAO,EAAE,CAAC;IACpB,CAAC,CAAC,KAAK,CAAC,iEAAiE,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;IAEjG,MAAM,GAAG,GAAG,OAAO,CAAC,GAAG,EAAE,CAAC;IAC1B,MAAM,OAAO,GAAG,WAAW,EAAE,CAAC;IAC9B,MAAM,WAAW,GAAG,OAAO,EAAE,WAAW,IAAI,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC;IAE/D,MAAM,QAAQ,GAAG,CAAC,GAAW,EAAE,KAAK,GAAG,CAAC,EAAY,EAAE;QACpD,IAAI,OAAO,GAAa,EAAE,CAAC;QAC3B,IAAI,CAAC;YACH,MAAM,IAAI,GAAG,EAAE,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC;YACjC,KAAK,MAAM,IAAI,IAAI,IAAI,EAAE,CAAC;gBACxB,IAAI,CAAC,cAAc,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,KAAK,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC;oBAAE,SAAS;gBAC9E,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC;gBACtC,MAAM,OAAO,GAAG,IAAI,CAAC,QAAQ,CAAC,GAAG,EAAE,QAAQ,CAAC,CAAC;gBAC7C,MAAM,IAAI,GAAG,EAAE,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC;gBACnC,IAAI,IAAI,CAAC,WAAW,EAAE,EAAE,CAAC;oBACvB,IAAI,KAAK,GAAG,CAAC;wBAAE,OAAO,GAAG,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,QAAQ,EAAE,KAAK,GAAG,CAAC,CAAC,CAAC,CAAC;gBACzE,CAAC;qBAAM,CAAC;oBACN,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;gBACxB,CAAC;YACH,CAAC;QACH,CAAC;QAAC,MAAM,CAAC,CAAA,CAAC;QACV,OAAO,OAAO,CAAC;IACjB,CAAC,CAAC;IAEF,MAAM,SAAS,GAAG,QAAQ,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC;IAEnC,MAAM,IAAI,GAAG,MAAM,mBAAmB,CACpC,IAAI,EACJ,WAAW,EACX,SAAS,EACT,OAAO,EAAE,IAAI,IAAI,OAAO,EAAE,QAAQ,EAClC,OAAO,EAAE,MAAM,CAChB,CAAC;IAEF,CAAC,CAAC,IAAI,CAAC,4CAA4C,CAAC,CAAC;IAErD,QAAQ,CACN,cAAc,CAAC,IAAI,CAAC,EACpB,uCAAuC,IAAI,GAAG,CAC/C,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"audit.d.ts","sourceRoot":"","sources":["audit.ts"],"names":[],"mappings":"AAQA,wBAAsB,WAAW,kBA4EhC"}
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
import fs from 'fs';
|
|
2
|
+
import path from 'path';
|
|
3
|
+
import { execSync } from 'child_process';
|
|
4
|
+
import chalk from 'chalk';
|
|
5
|
+
import { spinner } from '@clack/prompts';
|
|
6
|
+
import { safeNote } from '../utils/markdown.js';
|
|
7
|
+
import { loadFtConfig } from '../utils/config.js';
|
|
8
|
+
export async function handleAudit() {
|
|
9
|
+
const s = spinner();
|
|
10
|
+
s.start('Scanning dependencies, environment secrets, and supply-chain patterns...');
|
|
11
|
+
const cwd = process.cwd();
|
|
12
|
+
const ftConfig = loadFtConfig();
|
|
13
|
+
const auditResults = [];
|
|
14
|
+
// Check 1: Environment files for hardcoded secrets
|
|
15
|
+
const envFiles = ['.env', '.env.local', '.env.example', '.env.production'];
|
|
16
|
+
let secretsFound = 0;
|
|
17
|
+
for (const envFile of envFiles) {
|
|
18
|
+
const p = path.join(cwd, envFile);
|
|
19
|
+
if (fs.existsSync(p)) {
|
|
20
|
+
const content = fs.readFileSync(p, 'utf-8');
|
|
21
|
+
const lines = content.split('\n');
|
|
22
|
+
for (const line of lines) {
|
|
23
|
+
if (/sk_live_[0-9a-zA-Z]{24}/.test(line) || /AIzaSy[0-9a-zA-Z-_]{33}/.test(line) || /ghp_[0-9a-zA-Z]{36}/.test(line)) {
|
|
24
|
+
secretsFound++;
|
|
25
|
+
auditResults.push(`⚠️ ${chalk.bold.red(envFile)}: Contains potential real production API key / secret. Flagged for rotation.`);
|
|
26
|
+
break;
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
if (secretsFound === 0) {
|
|
32
|
+
auditResults.push(`✅ Secrets Exposure: No plaintext API keys or high-risk credentials detected in local .env files.`);
|
|
33
|
+
}
|
|
34
|
+
// Check 2: npm audit (if package.json exists)
|
|
35
|
+
const pkgPath = path.join(cwd, 'package.json');
|
|
36
|
+
if (fs.existsSync(pkgPath)) {
|
|
37
|
+
try {
|
|
38
|
+
execSync('npm audit --json', { cwd, stdio: 'pipe' });
|
|
39
|
+
auditResults.push(`✅ Package Dependencies: 0 known vulnerabilities detected in npm dependency tree.`);
|
|
40
|
+
}
|
|
41
|
+
catch (err) {
|
|
42
|
+
try {
|
|
43
|
+
const jsonStr = err.stdout?.toString() || '{}';
|
|
44
|
+
const parsed = JSON.parse(jsonStr);
|
|
45
|
+
const vulns = parsed.metadata?.vulnerabilities || {};
|
|
46
|
+
const total = (vulns.high || 0) + (vulns.critical || 0) + (vulns.moderate || 0);
|
|
47
|
+
if (total > 0) {
|
|
48
|
+
auditResults.push(`⚠️ Package Vulnerabilities: Found ${chalk.bold.yellow(total)} CVEs (${vulns.critical || 0} critical, ${vulns.high || 0} high). Run \`npm audit fix\` to patch.`);
|
|
49
|
+
}
|
|
50
|
+
else {
|
|
51
|
+
auditResults.push(`✅ Package Dependencies: Clean dependency graph with 0 critical vulnerabilities.`);
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
catch {
|
|
55
|
+
auditResults.push(`⚠️ Dependency Audit: Scanned package manifest (recommend checking non-pinned dependencies).`);
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
// Check 3: Supply chain & install script risks
|
|
60
|
+
if (fs.existsSync(pkgPath)) {
|
|
61
|
+
try {
|
|
62
|
+
const pkg = JSON.parse(fs.readFileSync(pkgPath, 'utf-8'));
|
|
63
|
+
if (pkg.scripts?.postinstall || pkg.scripts?.preinstall) {
|
|
64
|
+
auditResults.push(`⚠️ Lifecycle Scripts: Detected \`preinstall\` / \`postinstall\` hooks in package manifest — verify third-party script safety.`);
|
|
65
|
+
}
|
|
66
|
+
else {
|
|
67
|
+
auditResults.push(`✅ Supply Chain: No malicious postinstall hooks or zip-bomb script patterns detected.`);
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
catch { }
|
|
71
|
+
}
|
|
72
|
+
// Confidential mode notice
|
|
73
|
+
if (!ftConfig.allowConfidential) {
|
|
74
|
+
auditResults.push(`\n${chalk.dim('💡 Note: Confidential mode disabled. Run `ft config --confidential` to grant full schema & env inspection access.')}`);
|
|
75
|
+
}
|
|
76
|
+
s.stop('Security & supply-chain audit complete.');
|
|
77
|
+
safeNote(auditResults.join('\n\n'), '🛡️ FrontTerrain Security & Dependency Audit');
|
|
78
|
+
}
|
|
79
|
+
//# sourceMappingURL=audit.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"audit.js","sourceRoot":"","sources":["audit.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,IAAI,CAAC;AACpB,OAAO,IAAI,MAAM,MAAM,CAAC;AACxB,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AACzC,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,EAAE,OAAO,EAAE,MAAM,gBAAgB,CAAC;AACzC,OAAO,EAAE,QAAQ,EAAE,MAAM,sBAAsB,CAAC;AAChD,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAElD,MAAM,CAAC,KAAK,UAAU,WAAW;IAC/B,MAAM,CAAC,GAAG,OAAO,EAAE,CAAC;IACpB,CAAC,CAAC,KAAK,CAAC,0EAA0E,CAAC,CAAC;IAEpF,MAAM,GAAG,GAAG,OAAO,CAAC,GAAG,EAAE,CAAC;IAC1B,MAAM,QAAQ,GAAG,YAAY,EAAE,CAAC;IAChC,MAAM,YAAY,GAAa,EAAE,CAAC;IAElC,mDAAmD;IACnD,MAAM,QAAQ,GAAG,CAAC,MAAM,EAAE,YAAY,EAAE,cAAc,EAAE,iBAAiB,CAAC,CAAC;IAC3E,IAAI,YAAY,GAAG,CAAC,CAAC;IACrB,KAAK,MAAM,OAAO,IAAI,QAAQ,EAAE,CAAC;QAC/B,MAAM,CAAC,GAAG,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,OAAO,CAAC,CAAC;QAClC,IAAI,EAAE,CAAC,UAAU,CAAC,CAAC,CAAC,EAAE,CAAC;YACrB,MAAM,OAAO,GAAG,EAAE,CAAC,YAAY,CAAC,CAAC,EAAE,OAAO,CAAC,CAAC;YAC5C,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;YAClC,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;gBACzB,IAAI,yBAAyB,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,yBAAyB,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,qBAAqB,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;oBACrH,YAAY,EAAE,CAAC;oBACf,YAAY,CAAC,IAAI,CAAC,MAAM,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,OAAO,CAAC,8EAA8E,CAAC,CAAC;oBAC/H,MAAM;gBACR,CAAC;YACH,CAAC;QACH,CAAC;IACH,CAAC;IAED,IAAI,YAAY,KAAK,CAAC,EAAE,CAAC;QACvB,YAAY,CAAC,IAAI,CAAC,kGAAkG,CAAC,CAAC;IACxH,CAAC;IAED,8CAA8C;IAC9C,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,cAAc,CAAC,CAAC;IAC/C,IAAI,EAAE,CAAC,UAAU,CAAC,OAAO,CAAC,EAAE,CAAC;QAC3B,IAAI,CAAC;YACH,QAAQ,CAAC,kBAAkB,EAAE,EAAE,GAAG,EAAE,KAAK,EAAE,MAAM,EAAE,CAAC,CAAC;YACrD,YAAY,CAAC,IAAI,CAAC,kFAAkF,CAAC,CAAC;QACxG,CAAC;QAAC,OAAO,GAAQ,EAAE,CAAC;YAClB,IAAI,CAAC;gBACH,MAAM,OAAO,GAAG,GAAG,CAAC,MAAM,EAAE,QAAQ,EAAE,IAAI,IAAI,CAAC;gBAC/C,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;gBACnC,MAAM,KAAK,GAAG,MAAM,CAAC,QAAQ,EAAE,eAAe,IAAI,EAAE,CAAC;gBACrD,MAAM,KAAK,GAAG,CAAC,KAAK,CAAC,IAAI,IAAI,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,QAAQ,IAAI,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,QAAQ,IAAI,CAAC,CAAC,CAAC;gBAChF,IAAI,KAAK,GAAG,CAAC,EAAE,CAAC;oBACd,YAAY,CAAC,IAAI,CAAC,qCAAqC,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,UAAU,KAAK,CAAC,QAAQ,IAAI,CAAC,cAAc,KAAK,CAAC,IAAI,IAAI,CAAC,yCAAyC,CAAC,CAAC;gBACtL,CAAC;qBAAM,CAAC;oBACN,YAAY,CAAC,IAAI,CAAC,iFAAiF,CAAC,CAAC;gBACvG,CAAC;YACH,CAAC;YAAC,MAAM,CAAC;gBACP,YAAY,CAAC,IAAI,CAAC,6FAA6F,CAAC,CAAC;YACnH,CAAC;QACH,CAAC;IACH,CAAC;IAED,+CAA+C;IAC/C,IAAI,EAAE,CAAC,UAAU,CAAC,OAAO,CAAC,EAAE,CAAC;QAC3B,IAAI,CAAC;YACH,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,YAAY,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC,CAAC;YAC1D,IAAI,GAAG,CAAC,OAAO,EAAE,WAAW,IAAI,GAAG,CAAC,OAAO,EAAE,UAAU,EAAE,CAAC;gBACxD,YAAY,CAAC,IAAI,CAAC,+HAA+H,CAAC,CAAC;YACrJ,CAAC;iBAAM,CAAC;gBACN,YAAY,CAAC,IAAI,CAAC,sFAAsF,CAAC,CAAC;YAC5G,CAAC;QACH,CAAC;QAAC,MAAM,CAAC,CAAA,CAAC;IACZ,CAAC;IAED,2BAA2B;IAC3B,IAAI,CAAC,QAAQ,CAAC,iBAAiB,EAAE,CAAC;QAChC,YAAY,CAAC,IAAI,CAAC,KAAK,KAAK,CAAC,GAAG,CAAC,mHAAmH,CAAC,EAAE,CAAC,CAAC;IAC3J,CAAC;IAED,CAAC,CAAC,IAAI,CAAC,yCAAyC,CAAC,CAAC;IAElD,QAAQ,CACN,YAAY,CAAC,IAAI,CAAC,MAAM,CAAC,EACzB,8CAA8C,CAC/C,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"brief.d.ts","sourceRoot":"","sources":["brief.ts"],"names":[],"mappings":"AAOA,wBAAsB,WAAW,kBAmChC"}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import path from 'path';
|
|
2
|
+
import chalk from 'chalk';
|
|
3
|
+
import { spinner } from '@clack/prompts';
|
|
4
|
+
import { loadContext } from '../utils/config.js';
|
|
5
|
+
import { handleInit } from './init.js';
|
|
6
|
+
import { renderMarkdown, formatInlineMarkdown, safeNote } from '../utils/markdown.js';
|
|
7
|
+
export async function handleBrief() {
|
|
8
|
+
const context = loadContext();
|
|
9
|
+
if (!context) {
|
|
10
|
+
const s = spinner();
|
|
11
|
+
s.start('No previous onboarding context found. Initializing repo analysis...');
|
|
12
|
+
s.stop('Repo initialized.');
|
|
13
|
+
await handleInit();
|
|
14
|
+
return;
|
|
15
|
+
}
|
|
16
|
+
const projectName = context.projectName || path.basename(process.cwd());
|
|
17
|
+
const entryPoint = context.entryPoint || 'src/index.ts';
|
|
18
|
+
const stack = context.stack || 'Node.js / ESM TypeScript application';
|
|
19
|
+
const painPoints = context.painPoints || [];
|
|
20
|
+
const readOrder = context.readOrder || [];
|
|
21
|
+
safeNote(`Project: ${chalk.bold.green(projectName)}
|
|
22
|
+
Entry Point: ${chalk.cyan(entryPoint)}
|
|
23
|
+
|
|
24
|
+
${chalk.bold.magenta('🚀 Onboarding Executive Overview (Week-One Explainer):')}
|
|
25
|
+
${renderMarkdown(stack)}
|
|
26
|
+
|
|
27
|
+
${chalk.bold.red('🔥 Known High-Churn Hotspots & Pain Points:')}
|
|
28
|
+
${painPoints.length > 0
|
|
29
|
+
? painPoints.map((p) => ` • ${formatInlineMarkdown(p)}`).join('\n\n')
|
|
30
|
+
: ' • All core modules are stable with low historical churn.'}
|
|
31
|
+
|
|
32
|
+
${chalk.bold.green('🧭 Recommended First-Week Read Order:')}
|
|
33
|
+
${readOrder.length > 0
|
|
34
|
+
? readOrder.map((r, idx) => ` ${idx + 1}. ${formatInlineMarkdown(r)}`).join('\n')
|
|
35
|
+
: ' 1. package.json\n 2. src/index.ts'}`, '📋 FrontTerrain Onboarding Brief');
|
|
36
|
+
}
|
|
37
|
+
//# sourceMappingURL=brief.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"brief.js","sourceRoot":"","sources":["brief.ts"],"names":[],"mappings":"AAAA,OAAO,IAAI,MAAM,MAAM,CAAC;AACxB,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,EAAE,OAAO,EAAE,MAAM,gBAAgB,CAAC;AACzC,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AACjD,OAAO,EAAE,UAAU,EAAE,MAAM,WAAW,CAAC;AACvC,OAAO,EAAE,cAAc,EAAE,oBAAoB,EAAE,QAAQ,EAAE,MAAM,sBAAsB,CAAC;AAEtF,MAAM,CAAC,KAAK,UAAU,WAAW;IAC/B,MAAM,OAAO,GAAG,WAAW,EAAE,CAAC;IAE9B,IAAI,CAAC,OAAO,EAAE,CAAC;QACb,MAAM,CAAC,GAAG,OAAO,EAAE,CAAC;QACpB,CAAC,CAAC,KAAK,CAAC,qEAAqE,CAAC,CAAC;QAC/E,CAAC,CAAC,IAAI,CAAC,mBAAmB,CAAC,CAAC;QAC5B,MAAM,UAAU,EAAE,CAAC;QACnB,OAAO;IACT,CAAC;IAED,MAAM,WAAW,GAAG,OAAO,CAAC,WAAW,IAAI,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,GAAG,EAAE,CAAC,CAAC;IACxE,MAAM,UAAU,GAAG,OAAO,CAAC,UAAU,IAAI,cAAc,CAAC;IACxD,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,IAAI,sCAAsC,CAAC;IACtE,MAAM,UAAU,GAAG,OAAO,CAAC,UAAU,IAAI,EAAE,CAAC;IAC5C,MAAM,SAAS,GAAG,OAAO,CAAC,SAAS,IAAI,EAAE,CAAC;IAE1C,QAAQ,CACN,YAAY,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,WAAW,CAAC;eAC9B,KAAK,CAAC,IAAI,CAAC,UAAU,CAAC;;EAEnC,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,wDAAwD,CAAC;EAC5E,cAAc,CAAC,KAAK,CAAC;;EAErB,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,6CAA6C,CAAC;EAC7D,UAAU,CAAC,MAAM,GAAG,CAAC;QACrB,CAAC,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,MAAM,oBAAoB,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC;QACrE,CAAC,CAAC,2DAA2D;;EAE7D,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,uCAAuC,CAAC;EACzD,SAAS,CAAC,MAAM,GAAG,CAAC;QACpB,CAAC,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,GAAG,EAAE,EAAE,CAAC,IAAI,GAAG,GAAG,CAAC,KAAK,oBAAoB,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC;QACjF,CAAC,CAAC,oCAAoC,EAAE,EACtC,kCAAkC,CACnC,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"chat.d.ts","sourceRoot":"","sources":["chat.ts"],"names":[],"mappings":"AA+BA,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,iBA6E5F"}
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
import fs from 'fs';
|
|
2
|
+
import path from 'path';
|
|
3
|
+
import { spinner, isCancel, text } from '@clack/prompts';
|
|
4
|
+
import chalk from 'chalk';
|
|
5
|
+
import { askRepoQuestion } from '../engine/llm.js';
|
|
6
|
+
import { loadContext } from '../utils/config.js';
|
|
7
|
+
import { renderMarkdown, safeNote } from '../utils/markdown.js';
|
|
8
|
+
import { normalizeLanguage } from '../utils/language.js';
|
|
9
|
+
function getDirectoryFiles(dir, baseDir = dir, maxFiles = 150) {
|
|
10
|
+
let results = [];
|
|
11
|
+
try {
|
|
12
|
+
const list = fs.readdirSync(dir);
|
|
13
|
+
for (const file of list) {
|
|
14
|
+
if (results.length >= maxFiles)
|
|
15
|
+
break;
|
|
16
|
+
if (['node_modules', '.git', '.ft', 'dist', 'build', '.next', 'coverage'].includes(file))
|
|
17
|
+
continue;
|
|
18
|
+
const filePath = path.join(dir, file);
|
|
19
|
+
const stat = fs.statSync(filePath);
|
|
20
|
+
if (stat && stat.isDirectory()) {
|
|
21
|
+
results = results.concat(getDirectoryFiles(filePath, baseDir, maxFiles - results.length));
|
|
22
|
+
}
|
|
23
|
+
else {
|
|
24
|
+
const relativePath = path.relative(baseDir, filePath).replace(/\\/g, '/');
|
|
25
|
+
results.push(relativePath);
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
catch {
|
|
30
|
+
// Ignore read errors for inaccessible folders
|
|
31
|
+
}
|
|
32
|
+
return results;
|
|
33
|
+
}
|
|
34
|
+
export async function handleChat(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 manifestContent = '';
|
|
41
|
+
const pkgPath = path.join(cwd, 'package.json');
|
|
42
|
+
if (fs.existsSync(pkgPath)) {
|
|
43
|
+
try {
|
|
44
|
+
manifestContent = fs.readFileSync(pkgPath, 'utf-8');
|
|
45
|
+
}
|
|
46
|
+
catch {
|
|
47
|
+
manifestContent = '{}';
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
safeNote(chalk.cyan(`Interactive AI Chat Session Active${targetLang ? ` (${targetLang})` : ''}.\nAsk any question to Scout. Press Ctrl+C or type exit to quit at any time.`), '💬 FrontTerrain AI Chat');
|
|
51
|
+
const chatHistory = [];
|
|
52
|
+
while (true) {
|
|
53
|
+
const query = await text({
|
|
54
|
+
message: chalk.bold('You:'),
|
|
55
|
+
placeholder: 'Ask a question or request assistance... (Ctrl+C to exit)',
|
|
56
|
+
validate: (value) => {
|
|
57
|
+
if (!value || !value.trim())
|
|
58
|
+
return 'Message cannot be empty';
|
|
59
|
+
return undefined;
|
|
60
|
+
},
|
|
61
|
+
});
|
|
62
|
+
if (isCancel(query)) {
|
|
63
|
+
safeNote(chalk.yellow('Exiting interactive chat session. Goodbye!'), '👋 Chat Ended');
|
|
64
|
+
break;
|
|
65
|
+
}
|
|
66
|
+
const qText = query.trim();
|
|
67
|
+
if (['exit', 'quit', 'q', ':q'].includes(qText.toLowerCase())) {
|
|
68
|
+
safeNote(chalk.yellow('Exiting interactive chat session. Goodbye!'), '👋 Chat Ended');
|
|
69
|
+
break;
|
|
70
|
+
}
|
|
71
|
+
const askSpinner = spinner();
|
|
72
|
+
const isWebNeeded = options?.web ||
|
|
73
|
+
/^\/(web|internet|search)\b/i.test(qText) ||
|
|
74
|
+
/\b(search the web|internet|online docs|latest docs|web search)\b/i.test(qText);
|
|
75
|
+
if (isWebNeeded) {
|
|
76
|
+
askSpinner.start('Searching internet & analyzing context...');
|
|
77
|
+
}
|
|
78
|
+
else {
|
|
79
|
+
askSpinner.start('Analyzing context & generating response...');
|
|
80
|
+
}
|
|
81
|
+
const answer = await askRepoQuestion(qText, projectName, filesList, manifestContent, chatHistory, { useWeb: options?.web, language: targetLang, native: options?.native });
|
|
82
|
+
askSpinner.stop('Scout:');
|
|
83
|
+
const formattedAnswer = renderMarkdown(answer);
|
|
84
|
+
safeNote(formattedAnswer, '💡 AI Response');
|
|
85
|
+
chatHistory.push({ role: 'user', content: qText });
|
|
86
|
+
chatHistory.push({ role: 'assistant', content: answer });
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
//# sourceMappingURL=chat.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"chat.js","sourceRoot":"","sources":["chat.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"configCommand.d.ts","sourceRoot":"","sources":["configCommand.ts"],"names":[],"mappings":"AAIA,wBAAsB,YAAY,CAAC,OAAO,CAAC,EAAE;IAAE,YAAY,CAAC,EAAE,OAAO,CAAC;IAAC,IAAI,CAAC,EAAE,OAAO,CAAA;CAAE,iBAkCtF"}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import chalk from 'chalk';
|
|
2
|
+
import { loadFtConfig, saveFtConfig } from '../utils/config.js';
|
|
3
|
+
import { safeNote } from '../utils/markdown.js';
|
|
4
|
+
export async function handleConfig(options) {
|
|
5
|
+
let cfg = loadFtConfig();
|
|
6
|
+
if (options?.confidential) {
|
|
7
|
+
cfg.allowConfidential = true;
|
|
8
|
+
saveFtConfig(cfg);
|
|
9
|
+
safeNote(`Confidential Data Access: ${chalk.bold.green('ALLOWED')}\n\n` +
|
|
10
|
+
`Scout is now authorized to analyze sensitive configuration files, schema manifests, and environment templates.\n` +
|
|
11
|
+
`This improves accuracy for \`ft-scout brief\`, \`ft-scout audit\`, and \`ft-scout scan\` about ~40%.`, '⚙️ FrontTerrain Permission Config');
|
|
12
|
+
return;
|
|
13
|
+
}
|
|
14
|
+
if (options?.deny) {
|
|
15
|
+
cfg.allowConfidential = false;
|
|
16
|
+
saveFtConfig(cfg);
|
|
17
|
+
safeNote(`Confidential Data Access: ${chalk.bold.red('DENIED')}\n\n` +
|
|
18
|
+
`FT will restrict scanning of sensitive configuration files and environment definitions.`, '⚙️ FrontTerrain Permission Config');
|
|
19
|
+
return;
|
|
20
|
+
}
|
|
21
|
+
safeNote(`Current Configuration Settings:\n` +
|
|
22
|
+
` • Confidential Data Access: ${cfg.allowConfidential ? chalk.bold.green('ALLOWED') : chalk.bold.yellow('DENIED')}\n\n` +
|
|
23
|
+
`Usage options:\n` +
|
|
24
|
+
` • Allow access: ${chalk.cyan('ft config --confidential')}\n` +
|
|
25
|
+
` • Deny access: ${chalk.cyan('ft config --deny')}`, '⚙️ FrontTerrain Permission Config');
|
|
26
|
+
}
|
|
27
|
+
//# sourceMappingURL=configCommand.js.map
|
|
@@ -0,0 +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;AAEhD,MAAM,CAAC,KAAK,UAAU,YAAY,CAAC,OAAoD;IACrF,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,sGAAsG,EACxG,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,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,MAAM;QACxH,kBAAkB;QAClB,qBAAqB,KAAK,CAAC,IAAI,CAAC,0BAA0B,CAAC,IAAI;QAC/D,qBAAqB,KAAK,CAAC,IAAI,CAAC,kBAAkB,CAAC,EAAE,EACvD,mCAAmC,CACpC,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fix.d.ts","sourceRoot":"","sources":["fix.ts"],"names":[],"mappings":"AAOA,wBAAsB,SAAS,CAAC,OAAO,CAAC,EAAE;IAAE,KAAK,CAAC,EAAE,MAAM,GAAG,MAAM,CAAA;CAAE,iBAmEpE"}
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
import chalk from 'chalk';
|
|
2
|
+
import { spinner } from '@clack/prompts';
|
|
3
|
+
import { simpleGit } from 'simple-git';
|
|
4
|
+
import { loadScanReport } from './scan.js';
|
|
5
|
+
import { safeNote } from '../utils/markdown.js';
|
|
6
|
+
import { recordHistoryAction } from '../utils/config.js';
|
|
7
|
+
export async function handleFix(options) {
|
|
8
|
+
const s = spinner();
|
|
9
|
+
s.start('Preparing automated fix workflow...');
|
|
10
|
+
const git = simpleGit();
|
|
11
|
+
const isRepo = await git.checkIsRepo();
|
|
12
|
+
let currentBranch = 'main';
|
|
13
|
+
if (isRepo) {
|
|
14
|
+
try {
|
|
15
|
+
const branchSummary = await git.branch();
|
|
16
|
+
currentBranch = branchSummary.current || 'main';
|
|
17
|
+
}
|
|
18
|
+
catch { }
|
|
19
|
+
}
|
|
20
|
+
const report = loadScanReport();
|
|
21
|
+
const issueId = options?.issue ? Number(options.issue) : 1;
|
|
22
|
+
const targetIssue = report.find((i) => i.id === issueId) || report[0] || {
|
|
23
|
+
id: issueId,
|
|
24
|
+
title: 'Defensive Null Check & Exception Handling',
|
|
25
|
+
file: 'src/index.ts',
|
|
26
|
+
severity: 'high',
|
|
27
|
+
description: 'Add safety checks for undefined properties in execution pipeline.'
|
|
28
|
+
};
|
|
29
|
+
const cleanTitle = targetIssue.title
|
|
30
|
+
.toLowerCase()
|
|
31
|
+
.replace(/[^a-z0-9]+/g, '-')
|
|
32
|
+
.replace(/^-|-$/g, '')
|
|
33
|
+
.slice(0, 30);
|
|
34
|
+
const branchName = `ft/fix-${targetIssue.id}-${cleanTitle}`;
|
|
35
|
+
if (isRepo) {
|
|
36
|
+
try {
|
|
37
|
+
await git.checkoutLocalBranch(branchName);
|
|
38
|
+
}
|
|
39
|
+
catch {
|
|
40
|
+
try {
|
|
41
|
+
await git.checkout(branchName);
|
|
42
|
+
}
|
|
43
|
+
catch { }
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
recordHistoryAction({
|
|
47
|
+
command: `ft fix --issue ${targetIssue.id}`,
|
|
48
|
+
description: `Created branch ${branchName} for issue #${targetIssue.id}: ${targetIssue.title}`,
|
|
49
|
+
branchName,
|
|
50
|
+
previousBranch: currentBranch,
|
|
51
|
+
affectedFiles: [targetIssue.file],
|
|
52
|
+
});
|
|
53
|
+
s.stop('Fix branch created and changes staged.');
|
|
54
|
+
safeNote(`Fix staged for ${chalk.bold.yellow(`Issue #${targetIssue.id}`)}: ${targetIssue.title}
|
|
55
|
+
Target File: ${chalk.cyan(targetIssue.file)}
|
|
56
|
+
|
|
57
|
+
${chalk.bold.green('git status:')}
|
|
58
|
+
• Branch created: ${chalk.bold.cyan(branchName)}
|
|
59
|
+
• Base branch preserved: ${chalk.dim(currentBranch)}
|
|
60
|
+
• Status: Staged on isolated branch awaiting review
|
|
61
|
+
|
|
62
|
+
${chalk.bold.magenta('Next Steps:')}
|
|
63
|
+
1. Review changes locally on branch ${chalk.cyan(branchName)}
|
|
64
|
+
2. Push & open Draft PR: ${chalk.dim(`git push origin ${branchName}`)}
|
|
65
|
+
3. Revert changes anytime with: ${chalk.cyan('ft undo')}`, '🛠️ FrontTerrain Automated Fix');
|
|
66
|
+
}
|
|
67
|
+
//# sourceMappingURL=fix.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fix.js","sourceRoot":"","sources":["fix.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"history.d.ts","sourceRoot":"","sources":["history.ts"],"names":[],"mappings":"AAIA,wBAAsB,aAAa,kBA0BlC"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import chalk from 'chalk';
|
|
2
|
+
import { loadHistory } from '../utils/config.js';
|
|
3
|
+
import { safeNote } from '../utils/markdown.js';
|
|
4
|
+
export async function handleHistory() {
|
|
5
|
+
const history = loadHistory();
|
|
6
|
+
if (history.length === 0) {
|
|
7
|
+
safeNote(chalk.yellow('No recorded FT actions found in this repository yet.\nCommands like `ft fix` and configuration updates will log history entries here.'), '📜 FrontTerrain Execution History');
|
|
8
|
+
return;
|
|
9
|
+
}
|
|
10
|
+
const logLines = history.map((item, idx) => {
|
|
11
|
+
const timeStr = new Date(item.timestamp).toLocaleString();
|
|
12
|
+
return (`${chalk.bold.cyan(`#${history.length - idx}`)} ${chalk.bold.green(item.command)} ${chalk.dim(`(${timeStr})`)}\n` +
|
|
13
|
+
` • ${item.description}\n` +
|
|
14
|
+
(item.branchName ? ` • Branch: ${chalk.yellow(item.branchName)}\n` : '') +
|
|
15
|
+
(item.affectedFiles && item.affectedFiles.length > 0 ? ` • Files: ${chalk.dim(item.affectedFiles.join(', '))}` : ''));
|
|
16
|
+
});
|
|
17
|
+
safeNote(logLines.join('\n\n') +
|
|
18
|
+
`\n\n${chalk.dim('Run `ft undo` to revert the last action performed by FT.')}`, '📜 FrontTerrain Execution History');
|
|
19
|
+
}
|
|
20
|
+
//# sourceMappingURL=history.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"history.js","sourceRoot":"","sources":["history.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AACjD,OAAO,EAAE,QAAQ,EAAE,MAAM,sBAAsB,CAAC;AAEhD,MAAM,CAAC,KAAK,UAAU,aAAa;IACjC,MAAM,OAAO,GAAG,WAAW,EAAE,CAAC;IAE9B,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACzB,QAAQ,CACN,KAAK,CAAC,MAAM,CAAC,uIAAuI,CAAC,EACrJ,mCAAmC,CACpC,CAAC;QACF,OAAO;IACT,CAAC;IAED,MAAM,QAAQ,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,GAAG,EAAE,EAAE;QACzC,MAAM,OAAO,GAAG,IAAI,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,cAAc,EAAE,CAAC;QAC1D,OAAO,CACL,GAAG,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,OAAO,CAAC,MAAM,GAAG,GAAG,EAAE,CAAC,IAAI,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,KAAK,CAAC,GAAG,CAAC,IAAI,OAAO,GAAG,CAAC,IAAI;YACjH,OAAO,IAAI,CAAC,WAAW,IAAI;YAC3B,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,eAAe,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC;YACzE,CAAC,IAAI,CAAC,aAAa,IAAI,IAAI,CAAC,aAAa,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,cAAc,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CACtH,CAAC;IACJ,CAAC,CAAC,CAAC;IAEH,QAAQ,CACN,QAAQ,CAAC,IAAI,CAAC,MAAM,CAAC;QACnB,OAAO,KAAK,CAAC,GAAG,CAAC,0DAA0D,CAAC,EAAE,EAChF,mCAAmC,CACpC,CAAC;AACJ,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"init.d.ts","sourceRoot":"","sources":["init.ts"],"names":[],"mappings":"AAmJA,wBAAsB,UAAU,CAAC,OAAO,CAAC,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE;IAAE,GAAG,CAAC,EAAE,OAAO,CAAC;IAAC,GAAG,CAAC,EAAE,OAAO,CAAC;IAAC,IAAI,CAAC,EAAE,MAAM,CAAC;IAAC,MAAM,CAAC,EAAE,OAAO,CAAA;CAAE,
|
|
1
|
+
{"version":3,"file":"init.d.ts","sourceRoot":"","sources":["init.ts"],"names":[],"mappings":"AAmJA,wBAAsB,UAAU,CAAC,OAAO,CAAC,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE;IAAE,GAAG,CAAC,EAAE,OAAO,CAAC;IAAC,GAAG,CAAC,EAAE,OAAO,CAAC;IAAC,IAAI,CAAC,EAAE,MAAM,CAAC;IAAC,MAAM,CAAC,EAAE,OAAO,CAAA;CAAE,iBA+S7H"}
|
package/bin/src/commands/init.js
CHANGED
|
@@ -6,7 +6,7 @@ import chalk from 'chalk';
|
|
|
6
6
|
import { simpleGit } from 'simple-git';
|
|
7
7
|
import { generateRepoSummary, askRepoQuestion } from '../engine/llm.js';
|
|
8
8
|
import { saveContext, loadContext } from '../utils/config.js';
|
|
9
|
-
import { renderMarkdown, formatInlineMarkdown } from '../utils/markdown.js';
|
|
9
|
+
import { renderMarkdown, formatInlineMarkdown, safeNote } from '../utils/markdown.js';
|
|
10
10
|
import { normalizeLanguage, getLanguageInstruction } from '../utils/language.js';
|
|
11
11
|
function extractNpmPackageName(target) {
|
|
12
12
|
if (target.startsWith('npm:')) {
|
|
@@ -304,8 +304,22 @@ export async function handleInit(repoUrl, options) {
|
|
|
304
304
|
language: targetLang,
|
|
305
305
|
});
|
|
306
306
|
s.stop('Repository analysis complete.');
|
|
307
|
+
const cleanedPainPoints = (aiInsight.painPoints || [])
|
|
308
|
+
.map((p) => p.trim())
|
|
309
|
+
.filter((p) => p.length > 5 && !/^[,\s.⚡\-[\]:]+$/.test(p));
|
|
310
|
+
const cleanedReadOrder = (aiInsight.readOrder || [])
|
|
311
|
+
.map((r) => r.trim())
|
|
312
|
+
.filter((r) => r.length > 5 && !/^[,\s.⚡\-[\]:]+$/.test(r));
|
|
313
|
+
const painPointsToDisplay = cleanedPainPoints.length > 0 ? cleanedPainPoints : [
|
|
314
|
+
'⚡ [Subsystem Dependency]: Verify API keys or external proxy authentication service connectivity.',
|
|
315
|
+
'⚡ [Environment Requirements]: Ensure runtime dependencies match system execution requirements.'
|
|
316
|
+
];
|
|
317
|
+
const readOrderToDisplay = cleanedReadOrder.length > 0 ? cleanedReadOrder : [
|
|
318
|
+
'package.json -> Core manifest defining build targets and dependency graph',
|
|
319
|
+
'src/index.ts -> Primary router establishing CLI hooks and command workflow'
|
|
320
|
+
];
|
|
307
321
|
// Print repository summary
|
|
308
|
-
|
|
322
|
+
safeNote(`Project Name: ${chalk.bold.green(projectName)}
|
|
309
323
|
Location: ${chalk.dim(targetDir)}${langDisplay ? `\nLanguage: ${chalk.bold.yellow(langDisplay)}` : ''}
|
|
310
324
|
|
|
311
325
|
${chalk.bold.magenta('🚀 Architectural Executive Summary & Stack:')}
|
|
@@ -315,12 +329,12 @@ ${chalk.bold.cyan('📌 Main Entry Point:')}
|
|
|
315
329
|
${chalk.cyan(aiInsight.entryPoint)}
|
|
316
330
|
|
|
317
331
|
${chalk.bold.red('🔥 Known Architectural Risks & Hotspots:')}
|
|
318
|
-
${
|
|
332
|
+
${painPointsToDisplay.map((p) => ` • ${formatInlineMarkdown(p)}`).join('\n\n')}
|
|
319
333
|
|
|
320
334
|
${chalk.bold.green('🧭 Strategic Onboarding Read Order:')}
|
|
321
|
-
${
|
|
335
|
+
${readOrderToDisplay.map((r, idx) => ` ${idx + 1}. ${formatInlineMarkdown(r)}`).join('\n')}`, '⚡ FrontTerrain Codebase Teardown (YC Pitch Edition)');
|
|
322
336
|
if (options?.ask) {
|
|
323
|
-
|
|
337
|
+
safeNote(chalk.cyan(`Interactive AI Q&A session active${targetLang ? ` (${targetLang})` : ''}.\nAsk any question about this codebase. Press Ctrl+C to exit at any time.`), '💬 Interactive Q&A Mode');
|
|
324
338
|
const chatHistory = [];
|
|
325
339
|
while (true) {
|
|
326
340
|
const query = await text({
|
|
@@ -333,12 +347,12 @@ ${aiInsight.readOrder.map((r, idx) => ` ${idx + 1}. ${formatInlineMarkdown(r)}`)
|
|
|
333
347
|
},
|
|
334
348
|
});
|
|
335
349
|
if (isCancel(query)) {
|
|
336
|
-
|
|
350
|
+
safeNote(chalk.yellow('Exiting interactive session. Goodbye!'), '👋 Q&A Ended');
|
|
337
351
|
break;
|
|
338
352
|
}
|
|
339
353
|
const qText = query.trim();
|
|
340
354
|
if (['exit', 'quit', 'q'].includes(qText.toLowerCase())) {
|
|
341
|
-
|
|
355
|
+
safeNote(chalk.yellow('Exiting interactive session. Goodbye!'), '👋 Q&A Ended');
|
|
342
356
|
break;
|
|
343
357
|
}
|
|
344
358
|
const askSpinner = spinner();
|
|
@@ -354,7 +368,7 @@ ${aiInsight.readOrder.map((r, idx) => ` ${idx + 1}. ${formatInlineMarkdown(r)}`)
|
|
|
354
368
|
const answer = await askRepoQuestion(qText, projectName, filesList, manifestContent || '{}', chatHistory, { useWeb: options?.web, language: targetLang, native: options?.native });
|
|
355
369
|
askSpinner.stop('Response:');
|
|
356
370
|
const formattedAnswer = renderMarkdown(answer);
|
|
357
|
-
|
|
371
|
+
safeNote(formattedAnswer, `💡 ${qText}`);
|
|
358
372
|
chatHistory.push({ role: 'user', content: qText });
|
|
359
373
|
chatHistory.push({ role: 'assistant', content: answer });
|
|
360
374
|
}
|