ft-scout 7.0.9 → 8.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +25 -5
- package/bin/src/engine/voiceEngine.d.ts.map +1 -1
- package/bin/src/engine/voiceEngine.js +67 -199
- package/bin/src/engine/voiceEngine.js.map +1 -1
- package/bin/src/index.js +4 -4
- package/bin/src/utils/branding.js +1 -1
- package/package.json +1 -1
- package/web/app.js +2 -2
- package/web/styles.css +1 -1
package/README.md
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
# scout (FrontTerrain CLI
|
|
1
|
+
# scout (FrontTerrain CLI v8.0.1)
|
|
2
2
|
|
|
3
3
|
**FrontTerrain (`scout`)** — The Autonomous AI Principal Software Engineer & Codebase Co-Pilot in your terminal.
|
|
4
4
|
|
|
@@ -29,12 +29,17 @@ scout agent "Add persistent score tracking 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
|
|
|
35
|
+
# Select Interaction Mode: 💬 Text Interaction OR 🎙️ Audio Interaction (Voice STT + TTS)
|
|
36
|
+
# Force Voice Mode directly via CLI flag:
|
|
37
|
+
scout agent -V
|
|
38
|
+
scout agent --voice
|
|
39
|
+
|
|
35
40
|
# Inside session:
|
|
36
41
|
# Agent Prompt: Add dark mode toggle button
|
|
37
|
-
# Slash commands: /help /tree /stats /test /explain /export /diff /undo /clear /scan /plan /history /exit
|
|
42
|
+
# Slash commands: /help /scratchpad /voice /speak /tree /stats /test /explain /export /diff /undo /clear /scan /plan /history /exit
|
|
38
43
|
|
|
39
44
|
# Generate and create a new source code file
|
|
40
45
|
scout agent --create src/utils/math.ts "Create helper functions for sum, average, and array chunking"
|
|
@@ -89,7 +94,7 @@ scout upgrade
|
|
|
89
94
|
|
|
90
95
|
---
|
|
91
96
|
|
|
92
|
-
## Scout Autonomous ReAct Tools (
|
|
97
|
+
## Scout Autonomous ReAct Tools (18 Tools Available)
|
|
93
98
|
|
|
94
99
|
| Tool | Description |
|
|
95
100
|
|---|---|
|
|
@@ -108,15 +113,28 @@ scout upgrade
|
|
|
108
113
|
| `ask_user` | Request missing secret credentials or API keys |
|
|
109
114
|
| `open_app` | Launch or focus external applications (browser, terminal, editor, etc.) |
|
|
110
115
|
| `app_action` | Perform interactive actions & navigation inside opened app contexts |
|
|
116
|
+
| `agent_scratchpad` | Update, read, or clear agent working memory, step checklist, & notes (`.ft/scratchpad.md`) |
|
|
117
|
+
| `speak_text` | Read text phrases out loud using Text-to-Speech (TTS) voice synthesis |
|
|
111
118
|
| `task_completed` | Conclude autonomous goal execution with structured teardown report |
|
|
112
119
|
|
|
113
120
|
---
|
|
114
121
|
|
|
122
|
+
## Dual Interaction Modes (Text vs Audio)
|
|
123
|
+
|
|
124
|
+
When starting interactive sessions in `scout agent`, `scout init` (ask mode), or `scout search`, Scout presents a **2-Option Interaction Selector**:
|
|
125
|
+
1. **Text Interaction**: Standard prompt input -> Text response in terminal.
|
|
126
|
+
2. **Audio Interaction**: Voice command input via microphone Speech-to-Text (STT) -> Text response + Audio response spoken out loud via Text-to-Speech (TTS).
|
|
127
|
+
|
|
128
|
+
---
|
|
129
|
+
|
|
115
130
|
## Interactive Slash Commands in Session
|
|
116
131
|
|
|
117
132
|
Inside an active `scout agent` interactive session, type any slash command to trigger agent actions:
|
|
118
133
|
|
|
119
|
-
- `/help` — Display comprehensive guide to all
|
|
134
|
+
- `/help` — Display comprehensive guide to all 18 tools and interactive slash commands.
|
|
135
|
+
- `/scratchpad` — View active working memory plan & step checklist (`.ft/scratchpad.md`).
|
|
136
|
+
- `/voice` — Activate microphone Speech-to-Text (STT) listener to speak your prompt into CLI.
|
|
137
|
+
- `/speak <text>` — Read entered text out loud via Text-to-Speech (TTS) voice synthesis.
|
|
120
138
|
- `/tree [dir]` — Render an interactive visual directory tree of any workspace folder.
|
|
121
139
|
- `/status` or `/stats` — View real-time session telemetry (steps executed, tool call count, modified files, elapsed time, branch info).
|
|
122
140
|
- `/test [cmd]` — Auto-detect and run project verification test suite directly inside session context.
|
|
@@ -132,6 +150,8 @@ Inside an active `scout agent` interactive session, type any slash command to tr
|
|
|
132
150
|
|
|
133
151
|
## Overhauled Features & Performance
|
|
134
152
|
|
|
153
|
+
- **Working Memory Scratchpad (`.ft/scratchpad.md`)**: Maintains working memory notes, step-by-step checklists, and plan state across execution loops.
|
|
154
|
+
- **In-Terminal Native STT & TTS Voice Engine**: Direct in-terminal microphone voice input (PowerShell `System.Speech.Recognition` on Windows) and OS native speech synthesis (`System.Speech.Synthesis`, `say` on Mac) directly inside your terminal with **zero browser webpage popups** and zero extra API keys required.
|
|
135
155
|
- **High-Agency Multi-File Scaffolding**: Automatically creates, implements, tests, and verifies multi-file codebases from scratch.
|
|
136
156
|
- **Atomic Multi-Snippet Editing (`multi_edit_file`)**: Executes multiple code replacements in a single turn for complex multi-point refactoring.
|
|
137
157
|
- **App Control & Desktop Automation (`open_app`, `app_action`)**: Seamlessly launch, navigate, and automate external apps, web browsers, terminals, and code editors.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"voiceEngine.d.ts","sourceRoot":"","sources":["voiceEngine.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"voiceEngine.d.ts","sourceRoot":"","sources":["voiceEngine.ts"],"names":[],"mappings":"AAOA,wBAAsB,qBAAqB,IAAI,OAAO,CAAC,MAAM,GAAG,OAAO,CAAC,CAcvE;AAED,MAAM,WAAW,YAAY;IACzB,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,MAAM,CAAC,EAAE,MAAM,CAAC;CACnB;AAED;;GAEG;AACH,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CASvD;AAED;;GAEG;AACH,wBAAsB,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,YAAY,GAAG,OAAO,CAAC,IAAI,CAAC,CA2CnF;AAED;;GAEG;AACH,wBAAgB,kBAAkB,CAAC,OAAO,CAAC,EAAE;IAAE,SAAS,CAAC,EAAE,MAAM,CAAA;CAAE,GAAG,OAAO,CAAC,MAAM,CAAC,CAoEpF"}
|
|
@@ -1,9 +1,7 @@
|
|
|
1
|
-
import
|
|
2
|
-
import { exec } from 'child_process';
|
|
1
|
+
import { exec, spawn } from 'child_process';
|
|
3
2
|
import { promisify } from 'util';
|
|
4
3
|
import chalk from 'chalk';
|
|
5
|
-
import { select, isCancel } from '@clack/prompts';
|
|
6
|
-
import { openApp } from './appControl.js';
|
|
4
|
+
import { select, isCancel, spinner } from '@clack/prompts';
|
|
7
5
|
const execAsync = promisify(exec);
|
|
8
6
|
export async function promptInteractionMode() {
|
|
9
7
|
try {
|
|
@@ -47,15 +45,18 @@ export async function speakText(text, options) {
|
|
|
47
45
|
const truncatedText = cleanStr.length > 500 ? cleanStr.slice(0, 500) + '...' : cleanStr;
|
|
48
46
|
try {
|
|
49
47
|
if (platform === 'win32') {
|
|
50
|
-
|
|
51
|
-
const escaped = truncatedText.replace(/`/g, '``').replace(/"/g, '`"').replace(/'/g, "''");
|
|
48
|
+
const escaped = truncatedText.replace(/"/g, '`"').replace(/'/g, "''");
|
|
52
49
|
const psScript = `Add-Type -AssemblyName System.Speech; $synth = New-Object System.Speech.Synthesis.SpeechSynthesizer; $synth.Speak("${escaped}");`;
|
|
53
|
-
const cmd = `powershell -NoProfile -ExecutionPolicy Bypass -Command "${psScript}"`;
|
|
54
50
|
if (options?.async) {
|
|
55
|
-
|
|
51
|
+
const child = spawn('powershell', ['-NoProfile', '-ExecutionPolicy', 'Bypass', '-Command', psScript], { detached: true, stdio: 'ignore' });
|
|
52
|
+
child.unref();
|
|
56
53
|
}
|
|
57
54
|
else {
|
|
58
|
-
await
|
|
55
|
+
await new Promise((resolve) => {
|
|
56
|
+
const child = spawn('powershell', ['-NoProfile', '-ExecutionPolicy', 'Bypass', '-Command', psScript]);
|
|
57
|
+
child.on('close', () => resolve());
|
|
58
|
+
child.on('error', () => resolve());
|
|
59
|
+
});
|
|
59
60
|
}
|
|
60
61
|
}
|
|
61
62
|
else if (platform === 'darwin') {
|
|
@@ -85,202 +86,69 @@ export async function speakText(text, options) {
|
|
|
85
86
|
}
|
|
86
87
|
}
|
|
87
88
|
/**
|
|
88
|
-
* Speech-to-Text (STT)
|
|
89
|
+
* Native Speech-to-Text (STT) directly inside the terminal (no browser webpage).
|
|
89
90
|
*/
|
|
90
91
|
export function listenSpeechToText(options) {
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
}
|
|
130
|
-
}
|
|
131
|
-
catch {
|
|
132
|
-
res.writeHead(400, { 'Content-Type': 'application/json' });
|
|
133
|
-
res.end(JSON.stringify({ error: 'invalid payload' }));
|
|
92
|
+
const timeoutSecs = Math.max(5, Math.round((options?.timeoutMs || 15000) / 1000));
|
|
93
|
+
const s = spinner();
|
|
94
|
+
s.start(chalk.cyan(` Listening to your microphone in terminal (${timeoutSecs}s timeout)... Speak now!`));
|
|
95
|
+
const platform = process.platform;
|
|
96
|
+
if (platform === 'win32') {
|
|
97
|
+
return new Promise((resolve) => {
|
|
98
|
+
const psScript = `
|
|
99
|
+
[Console]::OutputEncoding = [System.Text.Encoding]::UTF8
|
|
100
|
+
Add-Type -AssemblyName System.Speech
|
|
101
|
+
try {
|
|
102
|
+
$culture = New-Object System.Globalization.CultureInfo("en-US")
|
|
103
|
+
$engine = New-Object System.Speech.Recognition.SpeechRecognitionEngine($culture)
|
|
104
|
+
$engine.SetInputToDefaultAudioDevice()
|
|
105
|
+
$grammar = New-Object System.Speech.Recognition.DictationGrammar
|
|
106
|
+
$engine.LoadGrammar($grammar)
|
|
107
|
+
$result = $engine.Recognize([TimeSpan]::FromSeconds(${timeoutSecs}))
|
|
108
|
+
if ($result -and $result.Text) {
|
|
109
|
+
[Console]::WriteLine("TRANSCRIPT:" + $result.Text)
|
|
110
|
+
} else {
|
|
111
|
+
[Console]::WriteLine("NO_SPEECH")
|
|
112
|
+
}
|
|
113
|
+
} catch {
|
|
114
|
+
[Console]::WriteLine("ERROR:" + $_.Exception.Message)
|
|
115
|
+
}
|
|
116
|
+
`.trim();
|
|
117
|
+
const child = spawn('powershell', ['-NoProfile', '-ExecutionPolicy', 'Bypass', '-Command', psScript]);
|
|
118
|
+
let output = '';
|
|
119
|
+
child.stdout?.on('data', (data) => {
|
|
120
|
+
output += data.toString();
|
|
121
|
+
});
|
|
122
|
+
child.on('close', () => {
|
|
123
|
+
s.stop('Terminal microphone recording complete.');
|
|
124
|
+
let transcript = '';
|
|
125
|
+
const lines = output.split('\n').map((l) => l.trim());
|
|
126
|
+
for (const line of lines) {
|
|
127
|
+
if (line.startsWith('TRANSCRIPT:')) {
|
|
128
|
+
transcript = line.replace('TRANSCRIPT:', '').trim();
|
|
129
|
+
break;
|
|
134
130
|
}
|
|
135
|
-
});
|
|
136
|
-
return;
|
|
137
|
-
}
|
|
138
|
-
// Options CORS preflight
|
|
139
|
-
if (req.method === 'OPTIONS') {
|
|
140
|
-
res.writeHead(204, {
|
|
141
|
-
'Access-Control-Allow-Origin': '*',
|
|
142
|
-
'Access-Control-Allow-Methods': 'GET, POST, OPTIONS',
|
|
143
|
-
'Access-Control-Allow-Headers': 'Content-Type',
|
|
144
|
-
});
|
|
145
|
-
res.end();
|
|
146
|
-
return;
|
|
147
|
-
}
|
|
148
|
-
// HTML Page for Web Speech API Microphone listener
|
|
149
|
-
const html = `<!DOCTYPE html>
|
|
150
|
-
<html lang="en">
|
|
151
|
-
<head>
|
|
152
|
-
<meta charset="UTF-8">
|
|
153
|
-
<title>Scout Agent Voice Listener</title>
|
|
154
|
-
<style>
|
|
155
|
-
* { box-sizing: border-box; margin: 0; padding: 0; }
|
|
156
|
-
body {
|
|
157
|
-
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
|
|
158
|
-
background: #0f172a;
|
|
159
|
-
color: #f8fafc;
|
|
160
|
-
display: flex;
|
|
161
|
-
align-items: center;
|
|
162
|
-
justify-content: center;
|
|
163
|
-
height: 100vh;
|
|
164
|
-
text-align: center;
|
|
165
|
-
}
|
|
166
|
-
.card {
|
|
167
|
-
background: #1e293b;
|
|
168
|
-
padding: 40px 30px;
|
|
169
|
-
border-radius: 20px;
|
|
170
|
-
box-shadow: 0 20px 25px -5px rgba(0, 0, 0, 0.5);
|
|
171
|
-
max-width: 450px;
|
|
172
|
-
width: 90%;
|
|
173
|
-
border: 1px solid #334155;
|
|
174
|
-
}
|
|
175
|
-
.mic-icon {
|
|
176
|
-
width: 80px;
|
|
177
|
-
height: 80px;
|
|
178
|
-
background: #0284c7;
|
|
179
|
-
border-radius: 50%;
|
|
180
|
-
display: flex;
|
|
181
|
-
align-items: center;
|
|
182
|
-
justify-content: center;
|
|
183
|
-
margin: 0 auto 20px;
|
|
184
|
-
box-shadow: 0 0 0 0 rgba(2, 132, 199, 0.7);
|
|
185
|
-
animation: pulse 1.5s infinite;
|
|
186
|
-
}
|
|
187
|
-
@keyframes pulse {
|
|
188
|
-
0% { box-shadow: 0 0 0 0 rgba(2, 132, 199, 0.7); }
|
|
189
|
-
70% { box-shadow: 0 0 0 20px rgba(2, 132, 199, 0); }
|
|
190
|
-
100% { box-shadow: 0 0 0 0 rgba(2, 132, 199, 0); }
|
|
191
|
-
}
|
|
192
|
-
h2 { font-size: 24px; color: #38bdf8; margin-bottom: 10px; }
|
|
193
|
-
p { font-size: 15px; color: #94a3b8; margin-bottom: 20px; }
|
|
194
|
-
.transcript {
|
|
195
|
-
font-size: 18px;
|
|
196
|
-
font-weight: 600;
|
|
197
|
-
color: #f1f5f9;
|
|
198
|
-
min-height: 50px;
|
|
199
|
-
background: #0f172a;
|
|
200
|
-
padding: 15px;
|
|
201
|
-
border-radius: 10px;
|
|
202
|
-
border: 1px dashed #475569;
|
|
203
|
-
margin-bottom: 15px;
|
|
204
|
-
word-wrap: break-word;
|
|
205
|
-
}
|
|
206
|
-
.status { font-size: 13px; color: #64748b; }
|
|
207
|
-
</style>
|
|
208
|
-
</head>
|
|
209
|
-
<body>
|
|
210
|
-
<div class="card">
|
|
211
|
-
<div class="mic-icon">
|
|
212
|
-
<svg width="40" height="40" viewBox="0 0 24 24" fill="none" stroke="white" stroke-width="2">
|
|
213
|
-
<path d="M12 1a3 3 0 0 0-3 3v8a3 3 0 0 0 6 0V4a3 3 0 0 0-3-3z"/>
|
|
214
|
-
<path d="M19 10v2a7 7 0 0 1-14 0v-2"/>
|
|
215
|
-
<line x1="12" y1="19" x2="12" y2="23"/>
|
|
216
|
-
<line x1="8" y1="23" x2="16" y2="23"/>
|
|
217
|
-
</svg>
|
|
218
|
-
</div>
|
|
219
|
-
<h2>Listening to your voice...</h2>
|
|
220
|
-
<p>Speak your prompt or goal clearly into your microphone.</p>
|
|
221
|
-
<div class="transcript" id="transcript">Listening...</div>
|
|
222
|
-
<div class="status" id="status">Scout Agent Voice Bridge Active</div>
|
|
223
|
-
</div>
|
|
224
|
-
<script>
|
|
225
|
-
const SpeechRecognition = window.SpeechRecognition || window.webkitSpeechRecognition;
|
|
226
|
-
const transcriptEl = document.getElementById('transcript');
|
|
227
|
-
const statusEl = document.getElementById('status');
|
|
228
|
-
|
|
229
|
-
if (!SpeechRecognition) {
|
|
230
|
-
transcriptEl.textContent = "Web Speech API not supported in this browser.";
|
|
231
|
-
statusEl.textContent = "Please use Chrome, Edge, or Brave.";
|
|
232
|
-
} else {
|
|
233
|
-
const recognition = new SpeechRecognition();
|
|
234
|
-
recognition.continuous = false;
|
|
235
|
-
recognition.interimResults = true;
|
|
236
|
-
recognition.lang = 'en-US';
|
|
237
|
-
|
|
238
|
-
recognition.onresult = (event) => {
|
|
239
|
-
let current = '';
|
|
240
|
-
for (let i = event.resultIndex; i < event.results.length; i++) {
|
|
241
|
-
current += event.results[i][0].transcript;
|
|
242
131
|
}
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
if (event.results[0].isFinal) {
|
|
246
|
-
statusEl.textContent = "Sending transcript to Scout CLI...";
|
|
247
|
-
fetch('/api/speech', {
|
|
248
|
-
method: 'POST',
|
|
249
|
-
headers: { 'Content-Type': 'application/json' },
|
|
250
|
-
body: JSON.stringify({ transcript: current })
|
|
251
|
-
}).then(() => {
|
|
252
|
-
statusEl.textContent = "Done! Closing window...";
|
|
253
|
-
setTimeout(() => window.close(), 1000);
|
|
254
|
-
}).catch(err => {
|
|
255
|
-
console.error(err);
|
|
256
|
-
});
|
|
132
|
+
if (transcript) {
|
|
133
|
+
resolve(transcript);
|
|
257
134
|
}
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
};
|
|
267
|
-
|
|
268
|
-
recognition.start();
|
|
269
|
-
}
|
|
270
|
-
</script>
|
|
271
|
-
</body>
|
|
272
|
-
</html>`;
|
|
273
|
-
res.writeHead(200, { 'Content-Type': 'text/html' });
|
|
274
|
-
res.end(html);
|
|
135
|
+
else {
|
|
136
|
+
resolve('');
|
|
137
|
+
}
|
|
138
|
+
});
|
|
139
|
+
child.on('error', () => {
|
|
140
|
+
s.stop(chalk.yellow('Terminal microphone listener ended.'));
|
|
141
|
+
resolve('');
|
|
142
|
+
});
|
|
275
143
|
});
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
}
|
|
144
|
+
}
|
|
145
|
+
else {
|
|
146
|
+
return new Promise((resolve) => {
|
|
147
|
+
setTimeout(() => {
|
|
148
|
+
s.stop(chalk.yellow('Terminal microphone listening finished.'));
|
|
149
|
+
resolve('');
|
|
150
|
+
}, 3000);
|
|
283
151
|
});
|
|
284
|
-
}
|
|
152
|
+
}
|
|
285
153
|
}
|
|
286
154
|
//# sourceMappingURL=voiceEngine.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"voiceEngine.js","sourceRoot":"","sources":["voiceEngine.ts"],"names":[],"mappings":"AAAA,OAAO,IAAI,
|
|
1
|
+
{"version":3,"file":"voiceEngine.js","sourceRoot":"","sources":["voiceEngine.ts"],"names":[],"mappings":"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"}
|
package/bin/src/index.js
CHANGED
|
@@ -32,13 +32,13 @@ program
|
|
|
32
32
|
.name('scout')
|
|
33
33
|
.alias('ft')
|
|
34
34
|
.description('FrontTerrain — The Onboarding Co-Pilot for New Codebases')
|
|
35
|
-
.version('
|
|
35
|
+
.version('8.0.1');
|
|
36
36
|
// Header UI on execution with FrontTerrain proprietary logo & version auto-checker
|
|
37
37
|
program.hook('preAction', async (_thisCommand, actionCommand) => {
|
|
38
|
-
intro(renderBranding('
|
|
38
|
+
intro(renderBranding('8.0.1'));
|
|
39
39
|
const cmdName = actionCommand ? actionCommand.name() : '';
|
|
40
40
|
if (cmdName !== 'upgrade') {
|
|
41
|
-
await checkForUpdates('
|
|
41
|
+
await checkForUpdates('8.0.1');
|
|
42
42
|
}
|
|
43
43
|
// Auth Guard: enforce authentication for all commands except login, signup, upgrade, help, dashboard, auth, status
|
|
44
44
|
const EXEMPT_COMMANDS = ['login', 'signin', 'signup', 'register', 'upgrade', 'help', 'dashboard', 'web-ui', 'gui', 'auth', 'status', 'quota', 'usage', 'credits'];
|
|
@@ -233,7 +233,7 @@ program
|
|
|
233
233
|
.command('upgrade')
|
|
234
234
|
.description('Check for updates and auto-upgrade Scout to the latest version')
|
|
235
235
|
.action(async () => {
|
|
236
|
-
await checkForUpdates('
|
|
236
|
+
await checkForUpdates('8.0.1', true);
|
|
237
237
|
outro(chalk.cyan('Upgrade check complete.'));
|
|
238
238
|
});
|
|
239
239
|
program
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import chalk from 'chalk';
|
|
2
|
-
export function renderBranding(version = '
|
|
2
|
+
export function renderBranding(version = '8.0.1') {
|
|
3
3
|
const logo = chalk.cyan.bold(' ███████╗████████╗') + ' ' + chalk.cyan.bold('███████╗ ██████╗ ██████╗ ██╗ ██╗████████╗') + '\n' +
|
|
4
4
|
chalk.cyan.bold(' ██╔════╝╚══██╔══╝') + ' ' + chalk.cyan.bold('██╔════╝ ██╔════╝██╔═══██╗ ██║ ██║╚══██╔══╝') + '\n' +
|
|
5
5
|
chalk.cyan.bold(' █████╗ ██║ ') + ' ' + chalk.cyan.bold(' ███████╗ ██║ ██║ ██║ ██║ ██║ ██║ ') + '\n' +
|
package/package.json
CHANGED
package/web/app.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/* ==========================================================================
|
|
2
|
-
FrontTerrain Scout — Multi-Page Application Engine
|
|
2
|
+
FrontTerrain Scout — Multi-Page Application Engine v8.0.1
|
|
3
3
|
========================================================================== */
|
|
4
4
|
|
|
5
5
|
const FIREBASE_CONFIG = {
|
|
@@ -452,7 +452,7 @@ function initTerminalSimulator() {
|
|
|
452
452
|
`;
|
|
453
453
|
} else if (lower.includes('status')) {
|
|
454
454
|
response.innerHTML = `
|
|
455
|
-
<span class="term-green">✔ Scout CLI Engine:
|
|
455
|
+
<span class="term-green">✔ Scout CLI Engine: v8.0.1 Online</span><br>
|
|
456
456
|
↳ User: <strong>${escapeHtml(state.user ? state.user.name : 'Guest Session')}</strong><br>
|
|
457
457
|
↳ Active Subscription: <strong>${escapeHtml(TIER_DETAILS[state.currentTier].name)}</strong><br>
|
|
458
458
|
↳ Credit Quota: <strong>${state.byokEnabled ? 'BYOK Mode (Unlimited)' : `${state.creditsUsed} / ${state.creditsTotal} Credits Used`}</strong><br>
|
package/web/styles.css
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/* ==========================================================================
|
|
2
|
-
FrontTerrain Scout — Design System & Visual Engine
|
|
2
|
+
FrontTerrain Scout — Design System & Visual Engine v8.0.1
|
|
3
3
|
Inspired by HappyRobot, Linear.app & Vercel aesthetics
|
|
4
4
|
========================================================================== */
|
|
5
5
|
|