ft-scout 9.4.6 ā 9.4.7
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 +2 -2
- package/bin/src/commands/agent.d.ts.map +1 -1
- package/bin/src/commands/agent.js +62 -1
- package/bin/src/commands/agent.js.map +1 -1
- package/bin/src/commands/checkpoint.d.ts.map +1 -0
- package/bin/src/commands/checkpoint.js +49 -0
- package/bin/src/commands/checkpoint.js.map +1 -0
- package/bin/src/commands/pr.d.ts.map +1 -0
- package/bin/src/commands/pr.js +191 -0
- package/bin/src/commands/pr.js.map +1 -0
- package/bin/src/commands/watch.d.ts.map +1 -0
- package/bin/src/commands/watch.js +149 -0
- package/bin/src/commands/watch.js.map +1 -0
- package/bin/src/engine/agentEngine.d.ts.map +1 -1
- package/bin/src/engine/agentEngine.js +102 -29
- package/bin/src/engine/agentEngine.js.map +1 -1
- package/bin/src/engine/checkpoints/checkpointManager.d.ts.map +1 -0
- package/bin/src/engine/checkpoints/checkpointManager.js +171 -0
- package/bin/src/engine/checkpoints/checkpointManager.js.map +1 -0
- package/bin/src/engine/computer/computerController.d.ts.map +1 -1
- package/bin/src/engine/computer/computerController.js +3 -0
- package/bin/src/engine/computer/computerController.js.map +1 -1
- package/bin/src/engine/computer/operatorHud.d.ts.map +1 -0
- package/bin/src/engine/computer/operatorHud.js +126 -0
- package/bin/src/engine/computer/operatorHud.js.map +1 -0
- package/bin/src/engine/runtime/agentRuntime.d.ts.map +1 -1
- package/bin/src/engine/runtime/agentRuntime.js +12 -5
- package/bin/src/engine/runtime/agentRuntime.js.map +1 -1
- package/bin/src/engine/subagents/subagentManager.d.ts.map +1 -0
- package/bin/src/engine/subagents/subagentManager.js +96 -0
- package/bin/src/engine/subagents/subagentManager.js.map +1 -0
- package/bin/src/index.js +50 -4
- package/bin/src/index.js.map +1 -1
- package/bin/src/mcp/client.js +1 -1
- package/bin/src/server/server.js +2 -2
- package/bin/src/server/server.js.map +1 -1
- package/bin/src/utils/branding.js +1 -1
- package/bin/src/utils/qrBridge.js +1 -1
- package/package.json +1 -1
- package/web/app.js +4 -3
- package/web/styles.css +2 -2
|
@@ -0,0 +1,191 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Scout Autonomous GitHub PR Creator
|
|
3
|
+
* Cuts clean feature branches, analyzes git diff, generates architectural summaries, and creates GitHub PRs.
|
|
4
|
+
*/
|
|
5
|
+
import fs from 'fs';
|
|
6
|
+
import path from 'path';
|
|
7
|
+
import { exec } from 'child_process';
|
|
8
|
+
import { promisify } from 'util';
|
|
9
|
+
import chalk from 'chalk';
|
|
10
|
+
import { spinner, confirm, text, isCancel } from '@clack/prompts';
|
|
11
|
+
import { openai, callOpenAIWithRetry } from '../engine/llm.js';
|
|
12
|
+
const execAsync = promisify(exec);
|
|
13
|
+
export async function handlePrCommand(titleInput, options = {}) {
|
|
14
|
+
const cwd = process.cwd();
|
|
15
|
+
const baseBranch = options.base || 'main';
|
|
16
|
+
console.log(chalk.bold.cyan(`\nš Scout Autonomous GitHub PR Creator\n`));
|
|
17
|
+
// 1. Verify Git Repository
|
|
18
|
+
try {
|
|
19
|
+
await execAsync('git rev-parse --is-inside-work-tree', { cwd });
|
|
20
|
+
}
|
|
21
|
+
catch {
|
|
22
|
+
console.log(chalk.red('ā Error: Current directory is not a git repository.'));
|
|
23
|
+
return;
|
|
24
|
+
}
|
|
25
|
+
// 2. Check current branch & git status
|
|
26
|
+
let currentBranch = 'main';
|
|
27
|
+
try {
|
|
28
|
+
const { stdout } = await execAsync('git rev-parse --abbrev-ref HEAD', { cwd });
|
|
29
|
+
currentBranch = stdout.trim();
|
|
30
|
+
}
|
|
31
|
+
catch { }
|
|
32
|
+
let statusOutput = '';
|
|
33
|
+
try {
|
|
34
|
+
const { stdout } = await execAsync('git status --porcelain', { cwd });
|
|
35
|
+
statusOutput = stdout.trim();
|
|
36
|
+
}
|
|
37
|
+
catch { }
|
|
38
|
+
// If there are uncommitted changes, commit them
|
|
39
|
+
if (statusOutput) {
|
|
40
|
+
console.log(chalk.yellow(`Found uncommitted changes in working directory:`));
|
|
41
|
+
const statusLines = statusOutput.split('\n').slice(0, 5);
|
|
42
|
+
statusLines.forEach(l => console.log(chalk.dim(` ${l}`)));
|
|
43
|
+
if (statusOutput.split('\n').length > 5) {
|
|
44
|
+
console.log(chalk.dim(` ...and ${statusOutput.split('\n').length - 5} more files`));
|
|
45
|
+
}
|
|
46
|
+
const shouldCommit = await confirm({
|
|
47
|
+
message: 'Commit these changes before creating the Pull Request?',
|
|
48
|
+
initialValue: true,
|
|
49
|
+
});
|
|
50
|
+
if (isCancel(shouldCommit))
|
|
51
|
+
return;
|
|
52
|
+
if (shouldCommit) {
|
|
53
|
+
const commitMsg = titleInput || `feat: autonomous updates by Scout AI`;
|
|
54
|
+
const spin = spinner();
|
|
55
|
+
spin.start(chalk.cyan('Committing changes...'));
|
|
56
|
+
try {
|
|
57
|
+
await execAsync('git add -A', { cwd });
|
|
58
|
+
await execAsync(`git commit -m "${commitMsg.replace(/"/g, '\\"')}"`, { cwd });
|
|
59
|
+
spin.stop(chalk.green('ā Changes committed cleanly.'));
|
|
60
|
+
}
|
|
61
|
+
catch (err) {
|
|
62
|
+
spin.stop(chalk.red(`Failed to commit: ${err?.message || String(err)}`));
|
|
63
|
+
return;
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
// If currently on main or master, create and checkout feature branch
|
|
68
|
+
if (currentBranch === 'main' || currentBranch === 'master') {
|
|
69
|
+
const branchSlug = (titleInput || 'feature')
|
|
70
|
+
.toLowerCase()
|
|
71
|
+
.replace(/[^a-z0-9]+/g, '-')
|
|
72
|
+
.replace(/^-|-$/g, '')
|
|
73
|
+
.slice(0, 30);
|
|
74
|
+
const newBranch = `feat/scout-${branchSlug || 'update'}-${Date.now().toString(36)}`;
|
|
75
|
+
console.log(chalk.cyan(`Currently on ${chalk.bold(currentBranch)}. Creating feature branch ${chalk.bold.yellow(newBranch)}...`));
|
|
76
|
+
try {
|
|
77
|
+
await execAsync(`git checkout -b "${newBranch}"`, { cwd });
|
|
78
|
+
currentBranch = newBranch;
|
|
79
|
+
}
|
|
80
|
+
catch (err) {
|
|
81
|
+
console.log(chalk.red(`Failed to create feature branch: ${err?.message || String(err)}`));
|
|
82
|
+
return;
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
// 3. Compute Diff against base branch
|
|
86
|
+
const diffSpin = spinner();
|
|
87
|
+
diffSpin.start(chalk.cyan(`Analyzing diff against ${baseBranch}...`));
|
|
88
|
+
let diffText = '';
|
|
89
|
+
try {
|
|
90
|
+
const { stdout } = await execAsync(`git diff ${baseBranch}...HEAD`, { cwd });
|
|
91
|
+
diffText = stdout.trim();
|
|
92
|
+
if (!diffText) {
|
|
93
|
+
// Fallback to diff against previous commit
|
|
94
|
+
const { stdout: headDiff } = await execAsync(`git diff HEAD~1..HEAD`, { cwd });
|
|
95
|
+
diffText = headDiff.trim();
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
catch {
|
|
99
|
+
try {
|
|
100
|
+
const { stdout } = await execAsync(`git diff HEAD~1`, { cwd });
|
|
101
|
+
diffText = stdout.trim();
|
|
102
|
+
}
|
|
103
|
+
catch { }
|
|
104
|
+
}
|
|
105
|
+
diffSpin.stop(chalk.green(`ā Git diff captured (${diffText.length} characters).`));
|
|
106
|
+
// 4. Generate PR Description with AI
|
|
107
|
+
const prSpin = spinner();
|
|
108
|
+
prSpin.start(chalk.cyan('Synthesizing PR title, architectural breakdown, and risk analysis...'));
|
|
109
|
+
let prTitle = titleInput || 'feat: codebase improvements and updates';
|
|
110
|
+
let prBody = '';
|
|
111
|
+
try {
|
|
112
|
+
const prompt = `You are a Principal Software Engineer. Write a comprehensive GitHub Pull Request description based on this git diff.
|
|
113
|
+
DIFF:
|
|
114
|
+
${diffText.slice(0, 15000)}
|
|
115
|
+
|
|
116
|
+
Generate the response in JSON format:
|
|
117
|
+
{
|
|
118
|
+
"title": "Conventional commit style PR title (e.g. feat(engine): add auto-healer and visual HUD)",
|
|
119
|
+
"body": "Markdown formatted PR body with sections: ## š Summary of Changes, ## š§± Architectural Impact, ## š”ļø Risk & Verification Checklist, ## š§Ŗ How Was This Tested"
|
|
120
|
+
}`;
|
|
121
|
+
const res = await callOpenAIWithRetry((model) => openai.chat.completions.create({
|
|
122
|
+
model,
|
|
123
|
+
messages: [{ role: 'user', content: prompt }],
|
|
124
|
+
response_format: { type: 'json_object' },
|
|
125
|
+
}));
|
|
126
|
+
const parsed = JSON.parse(res?.choices?.[0]?.message?.content || '{}');
|
|
127
|
+
if (parsed.title && !titleInput)
|
|
128
|
+
prTitle = parsed.title;
|
|
129
|
+
prBody = parsed.body || `## Summary\nAutonomous updates generated by FrontTerrain Scout.`;
|
|
130
|
+
}
|
|
131
|
+
catch {
|
|
132
|
+
prBody = `## š Summary of Changes\n- Autonomous updates and refinements applied by Scout AI.\n\n## š§Ŗ Verification\n- Local build and test suites validated.`;
|
|
133
|
+
}
|
|
134
|
+
prSpin.stop(chalk.green('ā PR metadata generated!'));
|
|
135
|
+
// 5. Save PR markdown artifact
|
|
136
|
+
const ftDir = path.join(cwd, '.ft');
|
|
137
|
+
if (!fs.existsSync(ftDir))
|
|
138
|
+
fs.mkdirSync(ftDir, { recursive: true });
|
|
139
|
+
fs.writeFileSync(path.join(ftDir, 'PULL_REQUEST.md'), `# ${prTitle}\n\n${prBody}`, 'utf-8');
|
|
140
|
+
console.log(`\n${chalk.bold('Title:')} ${chalk.green(prTitle)}`);
|
|
141
|
+
console.log(`${chalk.bold('Branch:')} ${chalk.cyan(currentBranch)} -> ${chalk.cyan(baseBranch)}\n`);
|
|
142
|
+
// 6. Push to Remote unless --no-push
|
|
143
|
+
if (!options.noPush) {
|
|
144
|
+
const pushSpin = spinner();
|
|
145
|
+
pushSpin.start(chalk.cyan(`Pushing branch ${currentBranch} to origin...`));
|
|
146
|
+
try {
|
|
147
|
+
await execAsync(`git push -u origin "${currentBranch}"`, { cwd });
|
|
148
|
+
pushSpin.stop(chalk.green('ā Pushed branch to remote origin.'));
|
|
149
|
+
}
|
|
150
|
+
catch (err) {
|
|
151
|
+
pushSpin.stop(chalk.yellow(`Warning: Remote push notice: ${err?.message || String(err)}`));
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
// 7. Check for GitHub CLI (gh)
|
|
155
|
+
let ghAvailable = false;
|
|
156
|
+
try {
|
|
157
|
+
await execAsync('gh --version', { cwd });
|
|
158
|
+
ghAvailable = true;
|
|
159
|
+
}
|
|
160
|
+
catch { }
|
|
161
|
+
if (ghAvailable && !options.noPush) {
|
|
162
|
+
const createPrSpin = spinner();
|
|
163
|
+
createPrSpin.start(chalk.cyan('Creating Pull Request on GitHub via gh CLI...'));
|
|
164
|
+
try {
|
|
165
|
+
const draftFlag = options.draft ? '--draft' : '';
|
|
166
|
+
const { stdout } = await execAsync(`gh pr create --title "${prTitle.replace(/"/g, '\\"')}" --body-file "${path.join(ftDir, 'PULL_REQUEST.md').replace(/\\/g, '/')}" --base "${baseBranch}" ${draftFlag}`, { cwd });
|
|
167
|
+
createPrSpin.stop(chalk.green(`ā GitHub Pull Request Created Successfully!`));
|
|
168
|
+
console.log(chalk.bold.green(`\nš PR URL: ${stdout.trim()}\n`));
|
|
169
|
+
return;
|
|
170
|
+
}
|
|
171
|
+
catch (err) {
|
|
172
|
+
createPrSpin.stop(chalk.yellow(`Notice: gh CLI could not complete: ${err?.message || String(err)}`));
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
// Fallback: Get remote URL and print web compare link
|
|
176
|
+
let originUrl = '';
|
|
177
|
+
try {
|
|
178
|
+
const { stdout } = await execAsync('git config --get remote.origin.url', { cwd });
|
|
179
|
+
originUrl = stdout.trim();
|
|
180
|
+
}
|
|
181
|
+
catch { }
|
|
182
|
+
if (originUrl) {
|
|
183
|
+
// Convert git@github.com:owner/repo.git or https://github.com/owner/repo.git to web URL
|
|
184
|
+
let webUrl = originUrl.replace(/^git@github\.com:/, 'https://github.com/').replace(/\.git$/, '');
|
|
185
|
+
const compareUrl = `${webUrl}/compare/${baseBranch}...${currentBranch}?expand=1`;
|
|
186
|
+
console.log(chalk.bold.green(`\nā Branch pushed! Create your PR online at:`));
|
|
187
|
+
console.log(` š ${chalk.cyan.underline(compareUrl)}\n`);
|
|
188
|
+
console.log(chalk.dim(`PR description saved locally to .ft/PULL_REQUEST.md`));
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
//# sourceMappingURL=pr.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pr.js","sourceRoot":"","sources":["pr.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"watch.d.ts","sourceRoot":"","sources":["watch.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAaH,MAAM,WAAW,YAAY;IACzB,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,GAAG,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,wBAAgB,iBAAiB,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAyBrD;AAED,wBAAsB,WAAW,CAAC,aAAa,CAAC,EAAE,MAAM,EAAE,OAAO,GAAE,YAAiB,iBAwHnF"}
|
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Scout Smart Terminal Auto-Healer & Test Watcher
|
|
3
|
+
* Background watch daemon that auto-runs tests on save, captures tracebacks, and self-heals failures.
|
|
4
|
+
*/
|
|
5
|
+
import fs from 'fs';
|
|
6
|
+
import path from 'path';
|
|
7
|
+
import { exec } from 'child_process';
|
|
8
|
+
import { promisify } from 'util';
|
|
9
|
+
import chalk from 'chalk';
|
|
10
|
+
import { spinner, select, isCancel } from '@clack/prompts';
|
|
11
|
+
import { AgentExecutionLoop } from '../engine/agentEngine.js';
|
|
12
|
+
import { extractErrorDiagnostics } from '../engine/verifier.js';
|
|
13
|
+
const execAsync = promisify(exec);
|
|
14
|
+
export function detectTestCommand(cwd) {
|
|
15
|
+
const pkgJson = path.join(cwd, 'package.json');
|
|
16
|
+
if (fs.existsSync(pkgJson)) {
|
|
17
|
+
try {
|
|
18
|
+
const pkg = JSON.parse(fs.readFileSync(pkgJson, 'utf-8'));
|
|
19
|
+
if (pkg.scripts?.test && pkg.scripts.test !== 'echo "Error: no test specified" && exit 1') {
|
|
20
|
+
return 'npm test';
|
|
21
|
+
}
|
|
22
|
+
if (pkg.scripts?.build) {
|
|
23
|
+
return 'npm run build';
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
catch { }
|
|
27
|
+
}
|
|
28
|
+
if (fs.existsSync(path.join(cwd, 'pytest.ini')) || fs.existsSync(path.join(cwd, 'pyproject.toml'))) {
|
|
29
|
+
return 'pytest';
|
|
30
|
+
}
|
|
31
|
+
if (fs.existsSync(path.join(cwd, 'Cargo.toml'))) {
|
|
32
|
+
return 'cargo test';
|
|
33
|
+
}
|
|
34
|
+
if (fs.existsSync(path.join(cwd, 'go.mod'))) {
|
|
35
|
+
return 'go test ./...';
|
|
36
|
+
}
|
|
37
|
+
return 'npm test';
|
|
38
|
+
}
|
|
39
|
+
export async function handleWatch(customCommand, options = {}) {
|
|
40
|
+
const cwd = options.dir ? path.resolve(process.cwd(), options.dir) : process.cwd();
|
|
41
|
+
const testCmd = customCommand || detectTestCommand(cwd);
|
|
42
|
+
console.log(chalk.bold.cyan(`\nšļø Scout Smart Watch Daemon Active`));
|
|
43
|
+
console.log(` ${chalk.bold('Workspace:')} ${chalk.gray(cwd)}`);
|
|
44
|
+
console.log(` ${chalk.bold('Command:')} ${chalk.yellow(testCmd)}`);
|
|
45
|
+
console.log(` ${chalk.bold('Mode:')} ${options.auto ? chalk.green('Auto-Heal ON') : chalk.cyan('Interactive Prompt')}`);
|
|
46
|
+
console.log(chalk.dim(`\nWatching for file changes... Press Ctrl+C to stop.\n`));
|
|
47
|
+
let isRunning = false;
|
|
48
|
+
let pendingRun = false;
|
|
49
|
+
let debounceTimer = null;
|
|
50
|
+
const runCheck = async () => {
|
|
51
|
+
if (isRunning) {
|
|
52
|
+
pendingRun = true;
|
|
53
|
+
return;
|
|
54
|
+
}
|
|
55
|
+
isRunning = true;
|
|
56
|
+
pendingRun = false;
|
|
57
|
+
if (options.clear) {
|
|
58
|
+
console.clear();
|
|
59
|
+
}
|
|
60
|
+
console.log(chalk.gray(`\n[${new Date().toLocaleTimeString()}] Running: ${testCmd}...`));
|
|
61
|
+
const runSpin = spinner();
|
|
62
|
+
runSpin.start(chalk.cyan(`Executing ${testCmd}...`));
|
|
63
|
+
try {
|
|
64
|
+
const { stdout, stderr } = await execAsync(testCmd, { cwd });
|
|
65
|
+
runSpin.stop(chalk.green(`ā All checks passed cleanly!`));
|
|
66
|
+
if (stdout && stdout.length < 500) {
|
|
67
|
+
console.log(chalk.dim(stdout.trim()));
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
catch (err) {
|
|
71
|
+
runSpin.stop(chalk.red(`ā Command failed with error:`));
|
|
72
|
+
const errorOutput = `${err?.stdout || ''}\n${err?.stderr || ''}\n${err?.message || ''}`.trim();
|
|
73
|
+
console.log(chalk.red.dim(errorOutput.slice(-1200)));
|
|
74
|
+
const diagnostics = extractErrorDiagnostics(errorOutput);
|
|
75
|
+
const errorSummary = diagnostics.keyErrors[0] || 'Build or test execution failure';
|
|
76
|
+
const brokenFile = diagnostics.referencedFiles[0] || '';
|
|
77
|
+
console.log(chalk.bold.yellow(`\nDetected issue: ${errorSummary}`));
|
|
78
|
+
if (brokenFile) {
|
|
79
|
+
console.log(` ${chalk.bold('Target file:')} ${chalk.cyan(brokenFile)}`);
|
|
80
|
+
}
|
|
81
|
+
let shouldHeal = Boolean(options.auto);
|
|
82
|
+
if (!shouldHeal) {
|
|
83
|
+
const choice = await select({
|
|
84
|
+
message: 'How would you like to proceed?',
|
|
85
|
+
options: [
|
|
86
|
+
{ label: 'ā” Auto-heal with Scout Agent', value: 'heal' },
|
|
87
|
+
{ label: 'š Re-run command', value: 'rerun' },
|
|
88
|
+
{ label: 'šļø Continue watching', value: 'ignore' },
|
|
89
|
+
],
|
|
90
|
+
});
|
|
91
|
+
if (isCancel(choice)) {
|
|
92
|
+
process.exit(0);
|
|
93
|
+
}
|
|
94
|
+
if (choice === 'heal') {
|
|
95
|
+
shouldHeal = true;
|
|
96
|
+
}
|
|
97
|
+
else if (choice === 'rerun') {
|
|
98
|
+
isRunning = false;
|
|
99
|
+
runCheck();
|
|
100
|
+
return;
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
if (shouldHeal) {
|
|
104
|
+
console.log(chalk.cyan.bold(`\nš ļø Scout Auto-Healer Dispatching...`));
|
|
105
|
+
const goal = `Fix the test/build failure caused by: ${errorSummary}. The broken file is ${brokenFile || 'in the project'}. Verify the solution by ensuring '${testCmd}' executes without errors.`;
|
|
106
|
+
const agent = new AgentExecutionLoop({
|
|
107
|
+
autoApprove: true,
|
|
108
|
+
});
|
|
109
|
+
const result = await agent.executeGoal(goal);
|
|
110
|
+
if (result.success) {
|
|
111
|
+
console.log(chalk.green.bold(`\nā Auto-heal succeeded! Re-running verification...`));
|
|
112
|
+
}
|
|
113
|
+
else {
|
|
114
|
+
console.log(chalk.yellow(`\nā Auto-heal finished with notice: ${result.summary}`));
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
finally {
|
|
119
|
+
isRunning = false;
|
|
120
|
+
if (pendingRun) {
|
|
121
|
+
runCheck();
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
};
|
|
125
|
+
// Run once on launch
|
|
126
|
+
await runCheck();
|
|
127
|
+
// Setup recursive filesystem watcher
|
|
128
|
+
const ignoreDirs = ['node_modules', '.git', '.ft', 'dist', 'bin', 'coverage', '.cache'];
|
|
129
|
+
const watcher = fs.watch(cwd, { recursive: true }, (_eventType, filename) => {
|
|
130
|
+
if (!filename)
|
|
131
|
+
return;
|
|
132
|
+
const norm = filename.replace(/\\/g, '/');
|
|
133
|
+
if (ignoreDirs.some(dir => norm.startsWith(dir + '/') || norm === dir))
|
|
134
|
+
return;
|
|
135
|
+
if (norm.endsWith('.tmp') || norm.endsWith('.log'))
|
|
136
|
+
return;
|
|
137
|
+
if (debounceTimer)
|
|
138
|
+
clearTimeout(debounceTimer);
|
|
139
|
+
debounceTimer = setTimeout(() => {
|
|
140
|
+
runCheck();
|
|
141
|
+
}, 350);
|
|
142
|
+
});
|
|
143
|
+
process.on('SIGINT', () => {
|
|
144
|
+
watcher.close();
|
|
145
|
+
console.log(chalk.cyan('\nWatcher stopped. Goodbye!\n'));
|
|
146
|
+
process.exit(0);
|
|
147
|
+
});
|
|
148
|
+
}
|
|
149
|
+
//# sourceMappingURL=watch.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"watch.js","sourceRoot":"","sources":["watch.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"agentEngine.d.ts","sourceRoot":"","sources":["agentEngine.ts"],"names":[],"mappings":"AAMA,OAAO,EAA0C,KAAK,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAM7F,OAAO,EAAE,gBAAgB,EAA4B,MAAM,iBAAiB,CAAC;AAC7E,OAAO,EAAE,KAAK,kBAAkB,EAA6B,MAAM,oBAAoB,CAAC;AACxF,OAAO,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AACrD,OAAO,EAAE,eAAe,EAAkB,MAAM,aAAa,CAAC;AAC9D,OAAO,EAAE,WAAW,EAAwB,MAAM,cAAc,CAAC;AACjE,OAAO,EAAE,mBAAmB,EAAE,MAAM,mBAAmB,CAAC;AACxD,OAAO,EAAE,KAAK,mBAAmB,EAAE,wBAAwB,EAAE,sBAAsB,EAAE,MAAM,qBAAqB,CAAC;AACjH,OAAO,EAAE,cAAc,EAAE,oBAAoB,EAAE,kBAAkB,EAAE,KAAK,eAAe,EAAE,MAAM,sBAAsB,CAAC;AACtH,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;
|
|
1
|
+
{"version":3,"file":"agentEngine.d.ts","sourceRoot":"","sources":["agentEngine.ts"],"names":[],"mappings":"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"}
|
|
@@ -23,6 +23,7 @@ import { loadAuthConfig, isProOrHigher } from '../utils/auth.js';
|
|
|
23
23
|
import { getMCPManager } from '../mcp/index.js';
|
|
24
24
|
import { writeTelemetry } from '../utils/qrBridge.js';
|
|
25
25
|
import { compress, LEVEL_FAST } from 'codrop';
|
|
26
|
+
import { CheckpointManager } from './checkpoints/checkpointManager.js';
|
|
26
27
|
export { AgentRuntime, AgentWorkspace, inferExecutionIntent, resolveDesktopPath, SystemComputerController, MockComputerController };
|
|
27
28
|
const execAsync = promisify(exec);
|
|
28
29
|
export function robustSnippetReplace(origContent, target, replacement) {
|
|
@@ -293,6 +294,29 @@ export const AGENT_TOOLS = [
|
|
|
293
294
|
required: ['text'],
|
|
294
295
|
},
|
|
295
296
|
},
|
|
297
|
+
{
|
|
298
|
+
name: 'delegate_subtask',
|
|
299
|
+
description: 'Delegate a specialized subtask to an autonomous specialist subagent (architect, coder, tester, reviewer, general). Useful for delegating code reviews, test generation, architectural breakdowns, or isolated module implementations to an autonomous worker agent.',
|
|
300
|
+
parameters: {
|
|
301
|
+
type: 'object',
|
|
302
|
+
properties: {
|
|
303
|
+
role: {
|
|
304
|
+
type: 'string',
|
|
305
|
+
enum: ['architect', 'coder', 'tester', 'reviewer', 'general'],
|
|
306
|
+
description: 'Specialist role for the subagent (architect, coder, tester, reviewer, general)',
|
|
307
|
+
},
|
|
308
|
+
task: {
|
|
309
|
+
type: 'string',
|
|
310
|
+
description: 'The specific subtask instruction or goal for the subagent to complete',
|
|
311
|
+
},
|
|
312
|
+
context: {
|
|
313
|
+
type: 'string',
|
|
314
|
+
description: 'Relevant file paths, error messages, or architectural context to provide to the subagent',
|
|
315
|
+
},
|
|
316
|
+
},
|
|
317
|
+
required: ['role', 'task'],
|
|
318
|
+
},
|
|
319
|
+
},
|
|
296
320
|
{
|
|
297
321
|
name: 'task_completed',
|
|
298
322
|
description: 'Signal that the user goal has been fully completed with the full answer, results, and summary.',
|
|
@@ -403,10 +427,10 @@ export class AgentExecutionLoop {
|
|
|
403
427
|
this.mockMode = Boolean(options?.mockMode);
|
|
404
428
|
this.isAudioMode = Boolean(options?.isAudioMode);
|
|
405
429
|
this.userTier = (options?.tier || loadAuthConfig().currentTier || 'free').toLowerCase();
|
|
406
|
-
// Free tier is bounded to basic direct actions (max 5 steps). Full autonomous multi-step loops require Pro/Enterprise.
|
|
430
|
+
// Free tier is bounded to basic direct actions (max 5 steps). Full autonomous multi-step loops require Pro/Enterprise (unlimited steps).
|
|
407
431
|
const isPaid = this.mockMode || this.userTier === 'pro' || this.userTier === 'enterprise';
|
|
408
|
-
const requestedSteps = options?.maxSteps
|
|
409
|
-
this.maxSteps = isPaid ? requestedSteps : Math.min(requestedSteps, 5);
|
|
432
|
+
const requestedSteps = options?.maxSteps;
|
|
433
|
+
this.maxSteps = isPaid ? (requestedSteps || Infinity) : Math.min(requestedSteps || 5, 5);
|
|
410
434
|
this.taskStateManager = new TaskStateManager(options?.taskId, '', this.cwd);
|
|
411
435
|
this.computerController = options?.computerController || (this.mockMode ? new MockComputerController() : new SystemComputerController(this.cwd));
|
|
412
436
|
this.browserController = options?.browserController || new SemanticBrowserController(this.cwd);
|
|
@@ -418,6 +442,9 @@ export class AgentExecutionLoop {
|
|
|
418
442
|
getUserTier() {
|
|
419
443
|
return this.userTier;
|
|
420
444
|
}
|
|
445
|
+
isPaidTier() {
|
|
446
|
+
return this.mockMode || this.userTier === 'pro' || this.userTier === 'enterprise';
|
|
447
|
+
}
|
|
421
448
|
getExecutionIntent() {
|
|
422
449
|
return this.executionIntent;
|
|
423
450
|
}
|
|
@@ -591,9 +618,10 @@ Task Execution Intent & Constraints:
|
|
|
591
618
|
⢠Target Destination: ${this.executionIntent.targetDestination || 'Default'}
|
|
592
619
|
⢠Target Artifact: ${this.executionIntent.targetArtifactName || 'None'}
|
|
593
620
|
` : '';
|
|
594
|
-
const isPaid = this.
|
|
621
|
+
const isPaid = this.isPaidTier();
|
|
595
622
|
const tierDirective = isPaid ? `
|
|
596
623
|
PLAN TIER & CAPABILITIES: ${this.userTier.toUpperCase()} (FULL ACCESS UNLOCKED)
|
|
624
|
+
⢠Unlimited autonomous multi-step loops with no step limits.
|
|
597
625
|
⢠Autonomous Computer-Use, Browser Automation, and AI Scratchpad Reasoning are fully ENABLED.
|
|
598
626
|
⢠Use the 'scratchpad' tool to organize multi-step reasoning, break down complex goals, draft hypotheses, and track working memory across turns.
|
|
599
627
|
` : `
|
|
@@ -821,9 +849,15 @@ When returning tool calls, use standard OpenAI function calling format or JSON t
|
|
|
821
849
|
content: promptContent,
|
|
822
850
|
});
|
|
823
851
|
}
|
|
824
|
-
const
|
|
825
|
-
|
|
826
|
-
|
|
852
|
+
const isPaid = this.mockMode || this.userTier === 'pro' || this.userTier === 'enterprise';
|
|
853
|
+
if (!isPaid && Number.isFinite(this.maxSteps)) {
|
|
854
|
+
const estTotalSecs = Math.round(this.maxSteps * 12);
|
|
855
|
+
const estTimeText = estTotalSecs >= 60 ? `~${(estTotalSecs / 60).toFixed(1)}m` : `~${estTotalSecs}s`;
|
|
856
|
+
console.log(chalk.gray(`Estimated completion time: ${estTimeText} (Free Tier Max ${this.maxSteps} steps)`));
|
|
857
|
+
}
|
|
858
|
+
else {
|
|
859
|
+
console.log(chalk.gray(`ā” Autonomous execution loop: Unlimited steps active (${this.userTier.toUpperCase()} plan)`));
|
|
860
|
+
}
|
|
827
861
|
let step = 0;
|
|
828
862
|
let finalSummary = '';
|
|
829
863
|
const stepDurations = [];
|
|
@@ -838,16 +872,21 @@ When returning tool calls, use standard OpenAI function calling format or JSON t
|
|
|
838
872
|
this.currentStep = step;
|
|
839
873
|
this.taskStateManager.startStep(step);
|
|
840
874
|
const stepStartTime = Date.now();
|
|
841
|
-
const avgStepMs = stepDurations.length > 0
|
|
842
|
-
? stepDurations.reduce((a, b) => a + b, 0) / stepDurations.length
|
|
843
|
-
: 12000;
|
|
844
|
-
const remainingSteps = (this.maxSteps - step + 1);
|
|
845
|
-
const estSecsLeft = Math.max(5, Math.round((remainingSteps * avgStepMs) / 1000));
|
|
846
|
-
const estLeftStr = estSecsLeft >= 60
|
|
847
|
-
? `${Math.floor(estSecsLeft / 60)}m ${estSecsLeft % 60}s`
|
|
848
|
-
: `${estSecsLeft}s`;
|
|
849
875
|
const stepSpinner = spinner();
|
|
850
|
-
|
|
876
|
+
if (isPaid && !Number.isFinite(this.maxSteps)) {
|
|
877
|
+
stepSpinner.start(chalk.cyan(`Scout is Working (Step ${step})`));
|
|
878
|
+
}
|
|
879
|
+
else {
|
|
880
|
+
const avgStepMs = stepDurations.length > 0
|
|
881
|
+
? stepDurations.reduce((a, b) => a + b, 0) / stepDurations.length
|
|
882
|
+
: 12000;
|
|
883
|
+
const remainingSteps = (this.maxSteps - step + 1);
|
|
884
|
+
const estSecsLeft = Math.max(5, Math.round((remainingSteps * avgStepMs) / 1000));
|
|
885
|
+
const estLeftStr = estSecsLeft >= 60
|
|
886
|
+
? `${Math.floor(estSecsLeft / 60)}m ${estSecsLeft % 60}s`
|
|
887
|
+
: `${estSecsLeft}s`;
|
|
888
|
+
stepSpinner.start(chalk.cyan(`Scout is Working (Step ${step}/${this.maxSteps} ⢠Est. completion: ~${estLeftStr} left)`));
|
|
889
|
+
}
|
|
851
890
|
try {
|
|
852
891
|
let response;
|
|
853
892
|
const mcpRouting = getMCPManager().routeTools(userGoal);
|
|
@@ -1169,22 +1208,17 @@ You MUST output exactly ONE JSON code block per tool call. Do NOT describe what
|
|
|
1169
1208
|
content: `Error in previous turn: ${err?.message || String(err)}. Please try alternative steps or call tools.`,
|
|
1170
1209
|
});
|
|
1171
1210
|
}
|
|
1172
|
-
// Step limit check:
|
|
1173
|
-
|
|
1174
|
-
|
|
1175
|
-
|
|
1176
|
-
this.maxSteps += 15;
|
|
1177
|
-
safeNote(chalk.bold.yellow(`ā” Step limit reached while task is in progress. Automatically extending execution by +15 extra steps (New Max Limit: ${this.maxSteps})...`), ' Auto Extra Steps Extension');
|
|
1178
|
-
}
|
|
1179
|
-
else if (!isPaid) {
|
|
1180
|
-
safeNote(chalk.bold.yellow(`ā” Free Tier limit reached (${this.maxSteps} steps).\nFree developers can perform basic code editing, creating files/folders, and running commands.\nTo unlock unlimited autonomous multi-step loops and scratchpad reasoning, upgrade to Pro at https://scout.frontterrain.com/plans or run 'scout dashboard'.`), ' Free Tier Step Limit');
|
|
1181
|
-
break;
|
|
1182
|
-
}
|
|
1211
|
+
// Step limit check: Free tier only. Pro and Enterprise have unlimited steps.
|
|
1212
|
+
if (!isPaid && step >= this.maxSteps) {
|
|
1213
|
+
safeNote(chalk.bold.yellow(`ā” Free Tier limit reached (${this.maxSteps} steps).\nFree developers can perform basic code editing, creating files/folders, and running commands.\nTo unlock unlimited autonomous multi-step loops and scratchpad reasoning, upgrade to Pro at https://scout.frontterrain.com/plans or run 'scout dashboard'.`), ' Free Tier Step Limit');
|
|
1214
|
+
break;
|
|
1183
1215
|
}
|
|
1184
1216
|
}
|
|
1185
1217
|
return {
|
|
1186
1218
|
success: false,
|
|
1187
|
-
summary:
|
|
1219
|
+
summary: isPaid
|
|
1220
|
+
? `Task ended after ${step} iteration steps. Modified files: ${Array.from(this.modifiedFiles).join(', ')}`
|
|
1221
|
+
: `Reached max iteration steps limit (${this.maxSteps}). Modified files: ${Array.from(this.modifiedFiles).join(', ')}`,
|
|
1188
1222
|
};
|
|
1189
1223
|
}
|
|
1190
1224
|
extractJsonToolCall(content) {
|
|
@@ -1206,7 +1240,7 @@ You MUST output exactly ONE JSON code block per tool call. Do NOT describe what
|
|
|
1206
1240
|
'read_file', 'write_file', 'edit_file', 'run_command', 'list_dir',
|
|
1207
1241
|
'grep_search', 'glob_search', 'tree_view', 'file_info', 'multi_edit_file',
|
|
1208
1242
|
'fetch_url', 'git_diff',
|
|
1209
|
-
'ask_user', 'speak_text', 'task_completed', 'scratchpad',
|
|
1243
|
+
'ask_user', 'speak_text', 'delegate_subtask', 'task_completed', 'scratchpad',
|
|
1210
1244
|
];
|
|
1211
1245
|
for (const toolName of knownTools) {
|
|
1212
1246
|
const tagRegex = new RegExp(`<${toolName}>([\\s\\S]*?)<\\/${toolName}>`, 'i');
|
|
@@ -1306,6 +1340,8 @@ You MUST output exactly ONE JSON code block per tool call. Do NOT describe what
|
|
|
1306
1340
|
actionDesc = `Inspecting visible desktop UI`;
|
|
1307
1341
|
else if (name === 'computer_diagnostic')
|
|
1308
1342
|
actionDesc = `Running computer control diagnostics`;
|
|
1343
|
+
else if (name === 'delegate_subtask')
|
|
1344
|
+
actionDesc = `Delegating subtask to [${args.role || 'subagent'}]: ${String(args.task || '').slice(0, 40)}`;
|
|
1309
1345
|
else if (name === 'computer')
|
|
1310
1346
|
actionDesc = `Computer action: ${args.action || 'action'}`;
|
|
1311
1347
|
else if (name === 'scratchpad')
|
|
@@ -1504,6 +1540,11 @@ You MUST output exactly ONE JSON code block per tool call. Do NOT describe what
|
|
|
1504
1540
|
this.taskStateManager.addObservation(name, upgradeMsg, false);
|
|
1505
1541
|
return { result: upgradeMsg };
|
|
1506
1542
|
}
|
|
1543
|
+
if (name === 'delegate_subtask') {
|
|
1544
|
+
const upgradeMsg = `[PLAN RESTRICTION]: Autonomous Multi-Agent Swarm Delegation is exclusively available to Pro and Enterprise plan subscribers. Free tier developers can perform code editing, creating files/folders, and running commands. Upgrade to Pro at https://scout.frontterrain.com to unlock autonomous subagents.`;
|
|
1545
|
+
this.taskStateManager.addObservation(name, upgradeMsg, false);
|
|
1546
|
+
return { result: upgradeMsg };
|
|
1547
|
+
}
|
|
1507
1548
|
}
|
|
1508
1549
|
switch (name) {
|
|
1509
1550
|
case 'read_file': {
|
|
@@ -1563,6 +1604,10 @@ You MUST output exactly ONE JSON code block per tool call. Do NOT describe what
|
|
|
1563
1604
|
this.backups.push({ filePath: targetPath, originalContent: '__FT_WAS_NEW__' });
|
|
1564
1605
|
fs.mkdirSync(path.dirname(fullPath), { recursive: true });
|
|
1565
1606
|
}
|
|
1607
|
+
try {
|
|
1608
|
+
CheckpointManager.getInstance(this.cwd).createCheckpoint(`Step ${this.currentStep}: write_file ${targetPath}`, [targetPath], this.currentStep, this.taskStateManager.getCurrentState().taskId);
|
|
1609
|
+
}
|
|
1610
|
+
catch { }
|
|
1566
1611
|
fs.writeFileSync(fullPath, content, 'utf-8');
|
|
1567
1612
|
this.modifiedFiles.add(targetPath);
|
|
1568
1613
|
const oldLineCount = origContent !== '__FT_WAS_NEW__' ? origContent.split('\n').length : 0;
|
|
@@ -1618,6 +1663,10 @@ You MUST output exactly ONE JSON code block per tool call. Do NOT describe what
|
|
|
1618
1663
|
return { result: `Error editing "${targetPath}": ${replaceRes.error}` };
|
|
1619
1664
|
}
|
|
1620
1665
|
this.backups.push({ filePath: targetPath, originalContent: origContent });
|
|
1666
|
+
try {
|
|
1667
|
+
CheckpointManager.getInstance(this.cwd).createCheckpoint(`Step ${this.currentStep}: edit_file ${targetPath}`, [targetPath], this.currentStep, this.taskStateManager.getCurrentState().taskId);
|
|
1668
|
+
}
|
|
1669
|
+
catch { }
|
|
1621
1670
|
fs.writeFileSync(fullPath, replaceRes.updatedContent, 'utf-8');
|
|
1622
1671
|
this.modifiedFiles.add(targetPath);
|
|
1623
1672
|
const targetLines = target.split('\n').length;
|
|
@@ -2244,6 +2293,30 @@ You MUST output exactly ONE JSON code block per tool call. Do NOT describe what
|
|
|
2244
2293
|
};
|
|
2245
2294
|
return { result: JSON.stringify(structuredRes, null, 2) };
|
|
2246
2295
|
}
|
|
2296
|
+
case 'delegate_subtask': {
|
|
2297
|
+
const role = (args.role || 'general');
|
|
2298
|
+
const task = String(args.task || '').trim();
|
|
2299
|
+
const context = args.context ? String(args.context) : undefined;
|
|
2300
|
+
if (!task) {
|
|
2301
|
+
return { result: JSON.stringify({ success: false, error: 'No task specified for subagent delegation.' }) };
|
|
2302
|
+
}
|
|
2303
|
+
const { SubagentManager } = await import('./subagents/subagentManager.js');
|
|
2304
|
+
const subagentMgr = SubagentManager.getInstance();
|
|
2305
|
+
const subRes = await subagentMgr.delegate({
|
|
2306
|
+
role,
|
|
2307
|
+
task,
|
|
2308
|
+
context,
|
|
2309
|
+
cwd: this.cwd,
|
|
2310
|
+
tier: this.userTier,
|
|
2311
|
+
});
|
|
2312
|
+
if (subRes.modifiedFiles && subRes.modifiedFiles.length > 0) {
|
|
2313
|
+
for (const f of subRes.modifiedFiles) {
|
|
2314
|
+
this.modifiedFiles.add(f);
|
|
2315
|
+
}
|
|
2316
|
+
}
|
|
2317
|
+
this.taskStateManager.addObservation('delegate_subtask', `[Subagent ${role.toUpperCase()} Result]: ${subRes.summary}`, subRes.success);
|
|
2318
|
+
return { result: JSON.stringify(subRes, null, 2) };
|
|
2319
|
+
}
|
|
2247
2320
|
case 'task_completed': {
|
|
2248
2321
|
const summaryStr = String(args.summary || 'Task completed successfully.');
|
|
2249
2322
|
if (this.executionIntent?.targetDestination === 'Desktop' && this.executionIntent?.targetArtifactName) {
|