ft-scout 9.0.3 → 9.0.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (84) hide show
  1. package/.firebase/hosting.d2Vi.cache +7 -7
  2. package/README.md +76 -83
  3. package/bin/src/commands/agent.d.ts.map +1 -1
  4. package/bin/src/commands/agent.js +31 -228
  5. package/bin/src/commands/agent.js.map +1 -1
  6. package/bin/src/commands/plan.d.ts.map +1 -1
  7. package/bin/src/commands/plan.js +45 -18
  8. package/bin/src/commands/plan.js.map +1 -1
  9. package/bin/src/engine/actionVerifier.d.ts.map +1 -1
  10. package/bin/src/engine/actionVerifier.js +61 -9
  11. package/bin/src/engine/actionVerifier.js.map +1 -1
  12. package/bin/src/engine/agentEngine.d.ts.map +1 -1
  13. package/bin/src/engine/agentEngine.js +701 -553
  14. package/bin/src/engine/agentEngine.js.map +1 -1
  15. package/bin/src/engine/agentState.d.ts.map +1 -1
  16. package/bin/src/engine/agentState.js +0 -64
  17. package/bin/src/engine/agentState.js.map +1 -1
  18. package/bin/src/engine/browser/browserController.d.ts.map +1 -1
  19. package/bin/src/engine/browser/browserController.js +8 -0
  20. package/bin/src/engine/browser/browserController.js.map +1 -1
  21. package/bin/src/engine/computer/computerController.d.ts.map +1 -1
  22. package/bin/src/engine/computer/computerController.js +686 -240
  23. package/bin/src/engine/computer/computerController.js.map +1 -1
  24. package/bin/src/engine/computer/computerDiagnostic.d.ts.map +1 -0
  25. package/bin/src/engine/computer/computerDiagnostic.js +71 -0
  26. package/bin/src/engine/computer/computerDiagnostic.js.map +1 -0
  27. package/bin/src/engine/computer/index.d.ts.map +1 -1
  28. package/bin/src/engine/computer/index.js +2 -0
  29. package/bin/src/engine/computer/index.js.map +1 -1
  30. package/bin/src/engine/computer/mockComputer.d.ts.map +1 -0
  31. package/bin/src/engine/computer/mockComputer.js +260 -0
  32. package/bin/src/engine/computer/mockComputer.js.map +1 -0
  33. package/bin/src/engine/computer/scoutDriver.cs +873 -0
  34. package/bin/src/engine/computer/scout_driver.exe +0 -0
  35. package/bin/src/engine/runtime/agentRuntime.d.ts.map +1 -0
  36. package/bin/src/engine/runtime/agentRuntime.js +1160 -0
  37. package/bin/src/engine/runtime/agentRuntime.js.map +1 -0
  38. package/bin/src/engine/runtime/index.d.ts.map +1 -0
  39. package/bin/src/engine/runtime/index.js +2 -0
  40. package/bin/src/engine/runtime/index.js.map +1 -0
  41. package/bin/src/engine/safety.d.ts.map +1 -1
  42. package/bin/src/engine/safety.js +59 -25
  43. package/bin/src/engine/safety.js.map +1 -1
  44. package/bin/src/engine/toolRegistry.d.ts.map +1 -1
  45. package/bin/src/engine/toolRegistry.js +293 -68
  46. package/bin/src/engine/toolRegistry.js.map +1 -1
  47. package/bin/src/engine/voiceEngine.d.ts.map +1 -1
  48. package/bin/src/engine/voiceEngine.js +0 -1
  49. package/bin/src/engine/voiceEngine.js.map +1 -1
  50. package/bin/src/engine/workspace/agentWorkspace.d.ts.map +1 -0
  51. package/bin/src/engine/workspace/agentWorkspace.js +505 -0
  52. package/bin/src/engine/workspace/agentWorkspace.js.map +1 -0
  53. package/bin/src/engine/workspace/index.d.ts.map +1 -0
  54. package/bin/src/engine/workspace/index.js +2 -0
  55. package/bin/src/engine/workspace/index.js.map +1 -0
  56. package/bin/src/index.js +4 -5
  57. package/bin/src/index.js.map +1 -1
  58. package/bin/src/server/server.d.ts.map +1 -1
  59. package/bin/src/server/server.js +25 -4
  60. package/bin/src/server/server.js.map +1 -1
  61. package/bin/src/utils/auth.d.ts.map +1 -1
  62. package/bin/src/utils/auth.js +81 -50
  63. package/bin/src/utils/auth.js.map +1 -1
  64. package/bin/src/utils/branding.js +1 -1
  65. package/bin/src/utils/payment.d.ts.map +1 -1
  66. package/bin/src/utils/payment.js +15 -1
  67. package/bin/src/utils/payment.js.map +1 -1
  68. package/bin/src/utils/pricing.js +1 -1
  69. package/bin/src/utils/pricing.js.map +1 -1
  70. package/bin/src/utils/razorpay.d.ts.map +1 -1
  71. package/bin/src/utils/razorpay.js +10 -2
  72. package/bin/src/utils/razorpay.js.map +1 -1
  73. package/downloads/invoice-2026-03.pdf +1 -0
  74. package/package.json +1 -1
  75. package/web/app.js +54 -135
  76. package/web/styles.css +2 -2
  77. package/bin/src/engine/appControl.d.ts.map +0 -1
  78. package/bin/src/engine/appControl.js +0 -2413
  79. package/bin/src/engine/appControl.js.map +0 -1
  80. package/bin/src/engine/liveScreenEngine.d.ts.map +0 -1
  81. package/bin/src/engine/liveScreenEngine.js +0 -421
  82. package/bin/src/engine/liveScreenEngine.js.map +0 -1
  83. package/bin/src/engine/scripts/winCapture.ps1 +0 -248
  84. package/downloads/INVOICE_2026_ACME.pdf +0 -1
@@ -1,6 +1,5 @@
1
1
  import fs from 'fs';
2
2
  import path from 'path';
3
- import readline from 'readline';
4
3
  import { spinner, text, isCancel, select, confirm } from '@clack/prompts';
5
4
  import chalk from 'chalk';
6
5
  import { simpleGit } from 'simple-git';
@@ -9,12 +8,11 @@ import { loadContext, recordHistoryAction, saveAgentSession, getDirectoryFiles }
9
8
  import { renderMarkdown, safeNote } from '../utils/markdown.js';
10
9
  import { normalizeLanguage } from '../utils/language.js';
11
10
  import { createPullRequest } from '../engine/git.js';
12
- import { consumeCredit, checkTierAccess } from '../utils/auth.js';
11
+ import { consumeCredit, checkTierAccess, loadAuthConfig, isProOrHigher } from '../utils/auth.js';
13
12
  import { handleUndo } from './undo.js';
14
13
  import { AgentExecutionLoop, buildDirectoryTree, AGENT_TOOLS } from '../engine/agentEngine.js';
15
14
  import { verifyAndSelfHealFiles, executeSmartCommand, runProjectVerification } from '../engine/verifier.js';
16
15
  import { speakText, listenSpeechToText, promptInteractionMode } from '../engine/voiceEngine.js';
17
- import { startLiveScreenShare, stopLiveScreenShare, isLiveScreenShareActive } from '../engine/liveScreenEngine.js';
18
16
  import { exec } from 'child_process';
19
17
  import { promisify } from 'util';
20
18
  const execAsync = promisify(exec);
@@ -98,13 +96,6 @@ export function parseUserPromptIntent(rawGoal, filesList) {
98
96
  if (!cleaned)
99
97
  cleaned = rawGoal.trim();
100
98
  const lowerCleaned = cleaned.toLowerCase();
101
- const isAppControl = /\b(?:open|launch|take\s*over|takeover|control|switch\s+to|click|type|send\s+keys|scratchpad|desktop|keystroke|interact\s+with|automate)\s+(?:the\s+)?(?:app|apps|browser|chrome|edge|firefox|brave|safari|terminal|cmd|powershell|vscode|code|editor|notepad|desktop|window|screen|cursor|mouse|site|website|url|tab|page|maps|youtube|instagram|whatsapp|twitter|google)\b/i.test(lowerCleaned) ||
102
- /\b(?:scratchpad|desktop\s+automation|click_app|type_text|send_keys|takeover|take\s*over|mouse_cursor|mouse\s+cursor|screen\s+takeover|take\s+over\s+(?:the\s+)?screen)\b/i.test(lowerCleaned) ||
103
- /^(?:take\s*over|takeover)\b/i.test(lowerCleaned) ||
104
- /^(?:open|launch)\s+https?:\/\//i.test(lowerCleaned) ||
105
- /\b(?:open|launch)\s+(?:browser|chrome|edge|firefox|brave|maps|google|youtube|notepad|calc|terminal)\b/i.test(lowerCleaned);
106
- if (isAppControl)
107
- return { cleanGoal: cleaned, intentType: 'app' };
108
99
  let targetFiles = extractCreateTargetFiles(cleaned);
109
100
  if (targetFiles.length === 0) {
110
101
  targetFiles = extractCreateTargetFiles(rawGoal);
@@ -239,173 +230,10 @@ export function findTargetFilesFromPrompt(userPrompt, specifiedFile, filesList)
239
230
  return [];
240
231
  }
241
232
  export async function getAgentGoalInput(placeholderStr) {
242
- if (!process.stdin.isTTY) {
243
- return await text({
244
- message: chalk.bold('Agent Prompt:'),
245
- placeholder: placeholderStr,
246
- validate: (val) => (!val || !val.trim() ? 'Please enter a prompt or /exit to quit' : undefined),
247
- });
248
- }
249
- return new Promise((resolve) => {
250
- let buffer = '';
251
- let cursorIndex = 0;
252
- let isDone = false;
253
- const rl = readline.createInterface({
254
- input: process.stdin,
255
- output: undefined,
256
- });
257
- readline.emitKeypressEvents(process.stdin, rl);
258
- if (process.stdin.setRawMode) {
259
- process.stdin.setRawMode(true);
260
- }
261
- const prefix = `${chalk.cyan('│')} `;
262
- const prefixVisibleLen = 3;
263
- process.stdout.write(`\n${chalk.cyan('◇')} ${chalk.bold('Agent Prompt:')}\n${prefix}`);
264
- const renderLine = () => {
265
- readline.cursorTo(process.stdout, 0);
266
- readline.clearLine(process.stdout, 0);
267
- process.stdout.write(prefix + buffer);
268
- readline.cursorTo(process.stdout, prefixVisibleLen + cursorIndex);
269
- };
270
- const cleanup = () => {
271
- process.stdin.removeListener('keypress', onKeypress);
272
- if (process.stdin.setRawMode) {
273
- process.stdin.setRawMode(false);
274
- }
275
- rl.close();
276
- };
277
- const onKeypress = (str, key) => {
278
- if (isDone)
279
- return;
280
- const isCtrlC = str === '\u0003' || (key && key.ctrl && key.name === 'c');
281
- if (isCtrlC) {
282
- isDone = true;
283
- cleanup();
284
- process.stdout.write('\n');
285
- resolve(Symbol.for('clack:cancel'));
286
- return;
287
- }
288
- // Immediately catch '/' keypress as the very first typed character without requiring Enter!
289
- if (buffer.length === 0 && str === '/') {
290
- isDone = true;
291
- cleanup();
292
- readline.cursorTo(process.stdout, 0);
293
- readline.clearLine(process.stdout, 0);
294
- process.stdout.write(`${prefix}/\n`);
295
- resolve('/');
296
- return;
297
- }
298
- const isEnter = key && (key.name === 'return' || key.name === 'enter');
299
- if (isEnter) {
300
- isDone = true;
301
- cleanup();
302
- process.stdout.write('\n');
303
- resolve(buffer.trim());
304
- return;
305
- }
306
- // Left Arrow Navigation
307
- if (key && key.name === 'left') {
308
- if (key.ctrl || key.meta) {
309
- let newPos = cursorIndex;
310
- while (newPos > 0 && buffer[newPos - 1] === ' ')
311
- newPos--;
312
- while (newPos > 0 && buffer[newPos - 1] !== ' ')
313
- newPos--;
314
- cursorIndex = newPos;
315
- }
316
- else if (cursorIndex > 0) {
317
- cursorIndex--;
318
- }
319
- renderLine();
320
- return;
321
- }
322
- // Right Arrow Navigation
323
- if (key && key.name === 'right') {
324
- if (key.ctrl || key.meta) {
325
- let newPos = cursorIndex;
326
- while (newPos < buffer.length && buffer[newPos] === ' ')
327
- newPos++;
328
- while (newPos < buffer.length && buffer[newPos] !== ' ')
329
- newPos++;
330
- cursorIndex = newPos;
331
- }
332
- else if (cursorIndex < buffer.length) {
333
- cursorIndex++;
334
- }
335
- renderLine();
336
- return;
337
- }
338
- // Home / Ctrl+A
339
- if ((key && key.name === 'home') || (key && key.ctrl && key.name === 'a')) {
340
- cursorIndex = 0;
341
- renderLine();
342
- return;
343
- }
344
- // End / Ctrl+E
345
- if ((key && key.name === 'end') || (key && key.ctrl && key.name === 'e')) {
346
- cursorIndex = buffer.length;
347
- renderLine();
348
- return;
349
- }
350
- // Up / Down arrow keys (ignore to prevent terminal escape sequences from polluting buffer)
351
- if (key && (key.name === 'up' || key.name === 'down')) {
352
- return;
353
- }
354
- // Clear to start (Ctrl+U)
355
- if (key && key.ctrl && key.name === 'u') {
356
- buffer = buffer.slice(cursorIndex);
357
- cursorIndex = 0;
358
- renderLine();
359
- return;
360
- }
361
- // Clear to end (Ctrl+K)
362
- if (key && key.ctrl && key.name === 'k') {
363
- buffer = buffer.slice(0, cursorIndex);
364
- renderLine();
365
- return;
366
- }
367
- // Delete word left (Ctrl+W)
368
- if (key && key.ctrl && key.name === 'w') {
369
- let newPos = cursorIndex;
370
- while (newPos > 0 && buffer[newPos - 1] === ' ')
371
- newPos--;
372
- while (newPos > 0 && buffer[newPos - 1] !== ' ')
373
- newPos--;
374
- buffer = buffer.slice(0, newPos) + buffer.slice(cursorIndex);
375
- cursorIndex = newPos;
376
- renderLine();
377
- return;
378
- }
379
- // Backspace
380
- const isBackspace = (key && key.name === 'backspace') || str === '\b' || str === '\x7f';
381
- if (isBackspace) {
382
- if (cursorIndex > 0) {
383
- buffer = buffer.slice(0, cursorIndex - 1) + buffer.slice(cursorIndex);
384
- cursorIndex--;
385
- renderLine();
386
- }
387
- return;
388
- }
389
- // Delete (Forward delete)
390
- if (key && key.name === 'delete') {
391
- if (cursorIndex < buffer.length) {
392
- buffer = buffer.slice(0, cursorIndex) + buffer.slice(cursorIndex + 1);
393
- renderLine();
394
- }
395
- return;
396
- }
397
- // Regular character insertion
398
- if (str && !key?.ctrl && !key?.meta && key?.name !== 'escape' && !isEnter && !isBackspace) {
399
- const cleanStr = str.replace(/[\r\n]/g, '');
400
- if (cleanStr.length > 0) {
401
- buffer = buffer.slice(0, cursorIndex) + cleanStr + buffer.slice(cursorIndex);
402
- cursorIndex += cleanStr.length;
403
- renderLine();
404
- }
405
- return;
406
- }
407
- };
408
- process.stdin.on('keypress', onKeypress);
233
+ return await text({
234
+ message: chalk.bold('Agent Prompt:'),
235
+ placeholder: placeholderStr,
236
+ validate: (val) => (!val || !val.trim() ? 'Please enter a prompt or /exit to quit' : undefined),
409
237
  });
410
238
  }
411
239
  export async function handleAgent(goalInput, options) {
@@ -449,21 +277,18 @@ export async function handleAgent(goalInput, options) {
449
277
  let initialGoal = goalInput || options?.goal;
450
278
  let isFirstRun = true;
451
279
  let isAudioMode = options?.voice;
452
- let isScreenShareMode = options?.screenShare;
453
- if (isAudioMode === undefined && isScreenShareMode === undefined && !initialGoal && process.stdout.isTTY) {
280
+ if (isAudioMode === undefined && !initialGoal && process.stdout.isTTY) {
454
281
  const selectedMode = await promptInteractionMode();
455
282
  isAudioMode = selectedMode === 'audio';
456
- isScreenShareMode = selectedMode === 'screen_share';
457
- }
458
- if (isScreenShareMode) {
459
- await startLiveScreenShare();
460
283
  }
284
+ const authCfg = loadAuthConfig();
285
+ const userTier = (authCfg.currentTier || 'free').toLowerCase();
286
+ const isPro = isProOrHigher(userTier);
461
287
  const agentLoop = new AgentExecutionLoop({
462
288
  autoApprove: options?.yes,
463
289
  maxSteps: options?.steps || options?.maxSteps || 30,
464
290
  language: targetLang,
465
- projectName,
466
- screenShare: isScreenShareMode,
291
+ tier: userTier,
467
292
  });
468
293
  if (options?.resume) {
469
294
  const loaded = agentLoop.getStateManager().loadTaskState(options.resume);
@@ -480,14 +305,17 @@ export async function handleAgent(goalInput, options) {
480
305
  }
481
306
  const modelInfo = getActiveModelInfo();
482
307
  const fallbackPipeline = modelInfo.fallbackChain.slice(1).join(' ➔ ');
308
+ const tierBadge = isPro
309
+ ? chalk.bold.magenta(`[Plan: ${userTier.toUpperCase()} - Autonomous & Scratchpad Enabled]`)
310
+ : chalk.bold.yellow(`[Plan: FREE - Basic Dev Ops (Edit/Create/Run)]`);
483
311
  const welcomeBanner = `
484
- ${chalk.bold.cyan('Scout Autonomous AI Agent')} ${targetLang ? `(${targetLang})` : ''} [${isScreenShareMode ? 'Live Screen Share Mode' : isAudioMode ? '🎤 Audio Mode' : '📝 Text Mode'}]
312
+ ${chalk.bold.cyan('Scout Autonomous AI Agent')} ${targetLang ? `(${targetLang})` : ''} [${isAudioMode ? '🎤 Audio Mode' : '📝 Text Mode'}] ${tierBadge}
485
313
  ${chalk.bold('Active Model:')} ${chalk.bold.green(modelInfo.currentActiveModel)}
314
+ ${chalk.bold('Capabilities:')} ${isPro ? chalk.green('Autonomous Computer/Browser Control + AI Scratchpad Working Memory') : chalk.dim('Basic Dev Ops (Code editing, creating files/folders, running commands - Max 5 steps)')}
486
315
  ${chalk.bold('Fallback Pipeline:')} ${chalk.dim(fallbackPipeline)}
487
316
 
488
317
  ${chalk.dim('Type your goal, or use slash commands:')}
489
318
  ${chalk.cyan('/help')} - Show agent tools & commands (${AGENT_TOOLS.length} tools)
490
- ${chalk.cyan('/screenshare')} - Toggle real-time live screen share stream with model
491
319
  ${chalk.cyan('/tree')} - View workspace directory tree
492
320
  ${chalk.cyan('/stats')} - View real-time session & model telemetry
493
321
  ${chalk.cyan('/test')} - Run automated project test suite
@@ -532,8 +360,8 @@ ${chalk.cyan('/exit')} - Exit session
532
360
  const KNOWN_SLASH_COMMANDS = [
533
361
  '/help', '/tree', '/status', '/stats', '/test', '/explain',
534
362
  '/export', '/save-session', '/diff', '/clear', '/compact',
535
- '/undo', '/history', '/scan', '/plan', '/scratchpad', '/tasks', '/resume', '/voice', '/speak',
536
- '/screenshare', '/livescreen', '/live', '/exit', '/quit'
363
+ '/undo', '/history', '/scan', '/plan', '/tasks', '/resume', '/voice', '/speak',
364
+ '/exit', '/quit'
537
365
  ];
538
366
  if (trimmedInput.startsWith('/')) {
539
367
  const cmdName = trimmedInput.split(/\s+/)[0].toLowerCase();
@@ -543,8 +371,6 @@ ${chalk.cyan('/exit')} - Exit session
543
371
  { value: '/help', label: '/help', hint: 'Show agent tools & commands guide' },
544
372
  { value: '/tasks', label: '/tasks', hint: 'List saved autonomous tasks in .ft/tasks/' },
545
373
  { value: '/resume', label: '/resume', hint: 'Resume saved autonomous task by task ID' },
546
- { value: '/scratchpad', label: '/scratchpad', hint: 'View current agent working memory & plan (.ft/scratchpad.md)' },
547
- { value: '/screenshare', label: '/screenshare', hint: 'Toggle real-time live screen share stream with model' },
548
374
  { value: '/voice', label: '/voice', hint: 'Activate microphone STT speech input' },
549
375
  { value: '/speak', label: '/speak', hint: 'Speak text out loud via TTS' },
550
376
  { value: '/tree', label: '/tree', hint: 'Display workspace directory tree' },
@@ -621,24 +447,28 @@ ${chalk.cyan('/exit')} - Exit session
621
447
  }
622
448
  if (trimmedInput.toLowerCase() === '/help') {
623
449
  const helpText = `
624
- ### 🛠️ Scout Autonomous Agent Tools (14 Available)
450
+ ### 🛠️ Basic Developer Tools (Available on All Plans)
625
451
  - **read_file**: Read content & line ranges of workspace files.
626
- - **write_file**: Create new files or overwrite code directly.
452
+ - **write_file**: Create new files and directories.
627
453
  - **edit_file**: Search & replace exact target code snippets.
628
454
  - **multi_edit_file**: Apply batch snippet replacements in a single step.
629
- - **run_command**: Execute live terminal commands (\`npm test\`, \`build\`).
455
+ - **run_command**: Execute terminal commands (\`npm test\`, \`npm run build\`).
630
456
  - **tree_view**: Generate visual ASCII directory tree structures.
631
457
  - **file_info**: Get file statistics, size, lines, & modification time.
632
458
  - **grep_search**: String/regex pattern search across codebase.
633
459
  - **glob_search**: Filter workspace files by file pattern.
634
- - **fetch_url**: Fetch web API documentation or URL content.
635
460
  - **git_diff**: Retrieve uncommitted workspace git diff.
636
461
  - **ask_user**: Request missing secret credentials or API keys.
637
- - **task_completed**: Conclude autonomous goal execution with teardown.
462
+ - **task_completed**: Conclude task execution with teardown summary.
463
+
464
+ ### ⚡ Pro & Enterprise Exclusive Features
465
+ - **scratchpad**: Persistent working memory & reasoning scratchpad for multi-phase tasks.
466
+ - **computer_***: Autonomous desktop & GUI app control (screenshot, click, type, open app).
467
+ - **browser_***: Autonomous browser automation (navigate, scrape, interact).
468
+ - **Autonomous Loops**: Extended multi-step execution loops (30+ steps).
638
469
 
639
470
  ### 🚀 Interactive Slash Commands
640
471
  - \`/help\`: Show this tools & commands guide.
641
- - \`/screenshare\` or \`/live\`: Toggle real-time live screen share stream with model.
642
472
  - \`/tree [dir]\`: Display workspace directory tree structure.
643
473
  - \`/status\` or \`/stats\`: Show session telemetry & statistics.
644
474
  - \`/test [cmd]\`: Run project verification test suite.
@@ -649,7 +479,6 @@ ${chalk.cyan('/exit')} - Exit session
649
479
  - \`/undo\`: Revert last file modifications.
650
480
  - \`/history\`: View recent Scout action logs.
651
481
  - \`/plan\`: Generate implementation roadmap.
652
- - \`/scratchpad\`: View current working memory plan & checklist (\`.ft/scratchpad.md\`).
653
482
  - \`/voice\`: Speak goal into microphone (STT).
654
483
  - \`/speak <text>\`: Speak text out loud (TTS).
655
484
  - \`/exit\`: End Scout Agent session.
@@ -657,19 +486,6 @@ ${chalk.cyan('/exit')} - Exit session
657
486
  safeNote(renderMarkdown(helpText), ' Scout Slash Commands & Tools');
658
487
  continue;
659
488
  }
660
- if (trimmedInput.toLowerCase() === '/screenshare' || trimmedInput.toLowerCase() === '/livescreen' || trimmedInput.toLowerCase() === '/live') {
661
- if (isLiveScreenShareActive()) {
662
- const stopRes = stopLiveScreenShare();
663
- isScreenShareMode = false;
664
- safeNote(chalk.yellow(stopRes.summary), ' Live Screen Share Stopped');
665
- }
666
- else {
667
- const startRes = await startLiveScreenShare();
668
- isScreenShareMode = true;
669
- safeNote(chalk.green(startRes.message), ' Live Screen Share Active');
670
- }
671
- continue;
672
- }
673
489
  if (trimmedInput.toLowerCase().startsWith('/speak')) {
674
490
  const phrase = trimmedInput.slice(6).trim();
675
491
  if (phrase) {
@@ -700,17 +516,6 @@ ${chalk.cyan('/exit')} - Exit session
700
516
  continue;
701
517
  }
702
518
  }
703
- if (trimmedInput.toLowerCase() === '/scratchpad') {
704
- const scratchpadPath = path.join(process.cwd(), '.ft', 'scratchpad.md');
705
- if (fs.existsSync(scratchpadPath)) {
706
- const content = fs.readFileSync(scratchpadPath, 'utf-8');
707
- safeNote(renderMarkdown(content), ' Active Agent Scratchpad (.ft/scratchpad.md)');
708
- }
709
- else {
710
- safeNote('No active scratchpad found (.ft/scratchpad.md). The agent will create one during multi-step goal execution.', ' Agent Scratchpad');
711
- }
712
- continue;
713
- }
714
519
  if (trimmedInput.toLowerCase() === '/tasks') {
715
520
  const tasks = agentLoop.getStateManager().listSavedTasks();
716
521
  if (tasks.length === 0) {
@@ -1242,12 +1047,10 @@ ${filePreviews}
1242
1047
  }
1243
1048
  // Standard Agent Goal Execution: Pre-scan & identify target files
1244
1049
  let targetFiles = [];
1245
- if (parsedIntent.intentType !== 'app') {
1246
- const idSpinner = spinner();
1247
- idSpinner.start('Scout Agent: Thinking');
1248
- targetFiles = await identifyTargetFiles(finalGoal, projectName, filesList, targetLang, options?.native);
1249
- idSpinner.stop(targetFiles.length > 0 ? `Target files resolved: ${targetFiles.map(f => `\`${f}\``).join(', ')}` : 'Analysis complete.');
1250
- }
1050
+ const idSpinner = spinner();
1051
+ idSpinner.start('Scout Agent: Thinking');
1052
+ targetFiles = await identifyTargetFiles(finalGoal, projectName, filesList, targetLang, options?.native);
1053
+ idSpinner.stop(targetFiles.length > 0 ? `Target files resolved: ${targetFiles.map(f => `\`${f}\``).join(', ')}` : 'Analysis complete.');
1251
1054
  safeNote(`${chalk.bold.cyan(' Scout Autonomous Execution Initialized')}\n` +
1252
1055
  `${chalk.dim('Goal:')} ${finalGoal}` +
1253
1056
  (targetFiles.length > 0 ? `\n${chalk.dim('Target Files:')} ${targetFiles.map(f => `\`${f}\``).join(', ')}` : ''), ' Scout Agent Execution');