@xagent/x-cli 1.2.11 → 1.2.13
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 +15 -1
- package/dist/index.js +2708 -318
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import OpenAI from 'openai';
|
|
3
|
-
import * as
|
|
4
|
-
import
|
|
3
|
+
import * as fs9 from 'fs';
|
|
4
|
+
import fs9__default, { existsSync, promises } from 'fs';
|
|
5
5
|
import * as path8 from 'path';
|
|
6
6
|
import path8__default from 'path';
|
|
7
7
|
import { StdioClientTransport } from '@modelcontextprotocol/sdk/client/stdio.js';
|
|
@@ -12,7 +12,9 @@ import os__default from 'os';
|
|
|
12
12
|
import { Client } from '@modelcontextprotocol/sdk/client/index.js';
|
|
13
13
|
import { exec, execSync, spawn } from 'child_process';
|
|
14
14
|
import { promisify } from 'util';
|
|
15
|
-
import
|
|
15
|
+
import { createTwoFilesPatch } from 'diff';
|
|
16
|
+
import * as fs6 from 'fs/promises';
|
|
17
|
+
import fs6__default, { writeFile } from 'fs/promises';
|
|
16
18
|
import * as ops6 from 'fs-extra';
|
|
17
19
|
import { parse } from '@typescript-eslint/typescript-estree';
|
|
18
20
|
import Fuse from 'fuse.js';
|
|
@@ -168,11 +170,11 @@ var init_client = __esm({
|
|
|
168
170
|
};
|
|
169
171
|
const logPath = process.env.XCLI_TOKEN_LOG || `${process.env.HOME}/.grok/token-usage.jsonl`;
|
|
170
172
|
const dir = path8__default.dirname(logPath);
|
|
171
|
-
if (!
|
|
172
|
-
|
|
173
|
+
if (!fs9__default.existsSync(dir)) {
|
|
174
|
+
fs9__default.mkdirSync(dir, { recursive: true });
|
|
173
175
|
}
|
|
174
176
|
const logLine = JSON.stringify(tokenData) + "\n";
|
|
175
|
-
|
|
177
|
+
fs9__default.appendFileSync(logPath, logLine);
|
|
176
178
|
} catch (error) {
|
|
177
179
|
console.warn("Failed to log token usage:", error);
|
|
178
180
|
}
|
|
@@ -433,8 +435,8 @@ var init_settings_manager = __esm({
|
|
|
433
435
|
*/
|
|
434
436
|
ensureDirectoryExists(filePath) {
|
|
435
437
|
const dir = path8.dirname(filePath);
|
|
436
|
-
if (!
|
|
437
|
-
|
|
438
|
+
if (!fs9.existsSync(dir)) {
|
|
439
|
+
fs9.mkdirSync(dir, { recursive: true, mode: 448 });
|
|
438
440
|
}
|
|
439
441
|
}
|
|
440
442
|
/**
|
|
@@ -442,11 +444,11 @@ var init_settings_manager = __esm({
|
|
|
442
444
|
*/
|
|
443
445
|
loadUserSettings() {
|
|
444
446
|
try {
|
|
445
|
-
if (!
|
|
447
|
+
if (!fs9.existsSync(this.userSettingsPath)) {
|
|
446
448
|
this.saveUserSettings(DEFAULT_USER_SETTINGS);
|
|
447
449
|
return { ...DEFAULT_USER_SETTINGS };
|
|
448
450
|
}
|
|
449
|
-
const content =
|
|
451
|
+
const content = fs9.readFileSync(this.userSettingsPath, "utf-8");
|
|
450
452
|
const settings = JSON.parse(content);
|
|
451
453
|
return { ...DEFAULT_USER_SETTINGS, ...settings };
|
|
452
454
|
} catch (error) {
|
|
@@ -464,9 +466,9 @@ var init_settings_manager = __esm({
|
|
|
464
466
|
try {
|
|
465
467
|
this.ensureDirectoryExists(this.userSettingsPath);
|
|
466
468
|
let existingSettings = { ...DEFAULT_USER_SETTINGS };
|
|
467
|
-
if (
|
|
469
|
+
if (fs9.existsSync(this.userSettingsPath)) {
|
|
468
470
|
try {
|
|
469
|
-
const content =
|
|
471
|
+
const content = fs9.readFileSync(this.userSettingsPath, "utf-8");
|
|
470
472
|
const parsed = JSON.parse(content);
|
|
471
473
|
existingSettings = { ...DEFAULT_USER_SETTINGS, ...parsed };
|
|
472
474
|
} catch (_error) {
|
|
@@ -474,7 +476,7 @@ var init_settings_manager = __esm({
|
|
|
474
476
|
}
|
|
475
477
|
}
|
|
476
478
|
const mergedSettings = { ...existingSettings, ...settings };
|
|
477
|
-
|
|
479
|
+
fs9.writeFileSync(
|
|
478
480
|
this.userSettingsPath,
|
|
479
481
|
JSON.stringify(mergedSettings, null, 2),
|
|
480
482
|
{ mode: 384 }
|
|
@@ -507,11 +509,11 @@ var init_settings_manager = __esm({
|
|
|
507
509
|
*/
|
|
508
510
|
loadProjectSettings() {
|
|
509
511
|
try {
|
|
510
|
-
if (!
|
|
512
|
+
if (!fs9.existsSync(this.projectSettingsPath)) {
|
|
511
513
|
this.saveProjectSettings(DEFAULT_PROJECT_SETTINGS);
|
|
512
514
|
return { ...DEFAULT_PROJECT_SETTINGS };
|
|
513
515
|
}
|
|
514
|
-
const content =
|
|
516
|
+
const content = fs9.readFileSync(this.projectSettingsPath, "utf-8");
|
|
515
517
|
const settings = JSON.parse(content);
|
|
516
518
|
return { ...DEFAULT_PROJECT_SETTINGS, ...settings };
|
|
517
519
|
} catch (error) {
|
|
@@ -529,9 +531,9 @@ var init_settings_manager = __esm({
|
|
|
529
531
|
try {
|
|
530
532
|
this.ensureDirectoryExists(this.projectSettingsPath);
|
|
531
533
|
let existingSettings = { ...DEFAULT_PROJECT_SETTINGS };
|
|
532
|
-
if (
|
|
534
|
+
if (fs9.existsSync(this.projectSettingsPath)) {
|
|
533
535
|
try {
|
|
534
|
-
const content =
|
|
536
|
+
const content = fs9.readFileSync(this.projectSettingsPath, "utf-8");
|
|
535
537
|
const parsed = JSON.parse(content);
|
|
536
538
|
existingSettings = { ...DEFAULT_PROJECT_SETTINGS, ...parsed };
|
|
537
539
|
} catch (_error) {
|
|
@@ -539,7 +541,7 @@ var init_settings_manager = __esm({
|
|
|
539
541
|
}
|
|
540
542
|
}
|
|
541
543
|
const mergedSettings = { ...existingSettings, ...settings };
|
|
542
|
-
|
|
544
|
+
fs9.writeFileSync(
|
|
543
545
|
this.projectSettingsPath,
|
|
544
546
|
JSON.stringify(mergedSettings, null, 2)
|
|
545
547
|
);
|
|
@@ -1913,13 +1915,36 @@ STDERR: ${stderr}` : "");
|
|
|
1913
1915
|
};
|
|
1914
1916
|
}
|
|
1915
1917
|
});
|
|
1918
|
+
function logToSession(message, data) {
|
|
1919
|
+
try {
|
|
1920
|
+
const timestamp = (/* @__PURE__ */ new Date()).toISOString();
|
|
1921
|
+
const logEntry = `
|
|
1922
|
+
[${timestamp}] \u{1F527} TEXT EDITOR TOOL - ${message}
|
|
1923
|
+
=====================================
|
|
1924
|
+
${data ? JSON.stringify(data, null, 2) : "No additional data"}
|
|
1925
|
+
=====================================
|
|
1926
|
+
`;
|
|
1927
|
+
const workingDir = process.cwd();
|
|
1928
|
+
const logsDir = path8.join(workingDir, "logs");
|
|
1929
|
+
const fs21 = fs9;
|
|
1930
|
+
if (fs21.existsSync(logsDir)) {
|
|
1931
|
+
const sessionFiles = fs21.readdirSync(logsDir).filter((f) => f.startsWith("session-") && f.endsWith(".log"));
|
|
1932
|
+
if (sessionFiles.length > 0) {
|
|
1933
|
+
const sessionFile = path8.join(logsDir, sessionFiles[sessionFiles.length - 1]);
|
|
1934
|
+
fs21.appendFileSync(sessionFile, logEntry);
|
|
1935
|
+
}
|
|
1936
|
+
}
|
|
1937
|
+
} catch (error) {
|
|
1938
|
+
console.log(`[TextEditorTool] ${message}`, data);
|
|
1939
|
+
}
|
|
1940
|
+
}
|
|
1916
1941
|
var pathExists, TextEditorTool;
|
|
1917
1942
|
var init_text_editor = __esm({
|
|
1918
1943
|
"src/tools/text-editor.ts"() {
|
|
1919
1944
|
init_confirmation_service();
|
|
1920
1945
|
pathExists = async (filePath) => {
|
|
1921
1946
|
try {
|
|
1922
|
-
await
|
|
1947
|
+
await fs9.promises.access(filePath, fs9.constants.F_OK);
|
|
1923
1948
|
return true;
|
|
1924
1949
|
} catch {
|
|
1925
1950
|
return false;
|
|
@@ -1934,16 +1959,16 @@ var init_text_editor = __esm({
|
|
|
1934
1959
|
try {
|
|
1935
1960
|
const resolvedPath = path8.resolve(filePath);
|
|
1936
1961
|
if (await pathExists(resolvedPath)) {
|
|
1937
|
-
const stats = await
|
|
1962
|
+
const stats = await fs9.promises.stat(resolvedPath);
|
|
1938
1963
|
if (stats.isDirectory()) {
|
|
1939
|
-
const files = await
|
|
1964
|
+
const files = await fs9.promises.readdir(resolvedPath);
|
|
1940
1965
|
return {
|
|
1941
1966
|
success: true,
|
|
1942
1967
|
output: `Directory contents of ${filePath}:
|
|
1943
1968
|
${files.join("\n")}`
|
|
1944
1969
|
};
|
|
1945
1970
|
}
|
|
1946
|
-
const content = await
|
|
1971
|
+
const content = await fs9.promises.readFile(resolvedPath, "utf-8");
|
|
1947
1972
|
const lines = content.split("\n");
|
|
1948
1973
|
if (viewRange) {
|
|
1949
1974
|
const [start, end] = viewRange;
|
|
@@ -1993,7 +2018,7 @@ ${numberedLines}${additionalLinesMessage}`
|
|
|
1993
2018
|
error: `File not found: ${filePath}`
|
|
1994
2019
|
};
|
|
1995
2020
|
}
|
|
1996
|
-
const content = await
|
|
2021
|
+
const content = await fs9.promises.readFile(resolvedPath, "utf-8");
|
|
1997
2022
|
if (!content.includes(oldStr)) {
|
|
1998
2023
|
if (oldStr.includes("\n")) {
|
|
1999
2024
|
const fuzzyResult = this.findFuzzyMatch(content, oldStr);
|
|
@@ -2045,7 +2070,7 @@ ${numberedLines}${additionalLinesMessage}`
|
|
|
2045
2070
|
});
|
|
2046
2071
|
const oldLines = content.split("\n");
|
|
2047
2072
|
const newLines = newContent.split("\n");
|
|
2048
|
-
const diff = this.
|
|
2073
|
+
const diff = this.generateColoredDiff(oldLines, newLines, filePath);
|
|
2049
2074
|
return {
|
|
2050
2075
|
success: true,
|
|
2051
2076
|
output: diff
|
|
@@ -2093,7 +2118,7 @@ ${numberedLines}${additionalLinesMessage}`
|
|
|
2093
2118
|
}
|
|
2094
2119
|
}
|
|
2095
2120
|
const dir = path8.dirname(resolvedPath);
|
|
2096
|
-
await
|
|
2121
|
+
await fs9.promises.mkdir(dir, { recursive: true });
|
|
2097
2122
|
await writeFile(resolvedPath, content, "utf-8");
|
|
2098
2123
|
this.editHistory.push({
|
|
2099
2124
|
command: "create",
|
|
@@ -2123,7 +2148,7 @@ ${numberedLines}${additionalLinesMessage}`
|
|
|
2123
2148
|
error: `File not found: ${filePath}`
|
|
2124
2149
|
};
|
|
2125
2150
|
}
|
|
2126
|
-
const fileContent = await
|
|
2151
|
+
const fileContent = await fs9.promises.readFile(resolvedPath, "utf-8");
|
|
2127
2152
|
const lines = fileContent.split("\n");
|
|
2128
2153
|
if (startLine < 1 || startLine > lines.length) {
|
|
2129
2154
|
return {
|
|
@@ -2191,7 +2216,7 @@ ${numberedLines}${additionalLinesMessage}`
|
|
|
2191
2216
|
error: `File not found: ${filePath}`
|
|
2192
2217
|
};
|
|
2193
2218
|
}
|
|
2194
|
-
const fileContent = await
|
|
2219
|
+
const fileContent = await fs9.promises.readFile(resolvedPath, "utf-8");
|
|
2195
2220
|
const lines = fileContent.split("\n");
|
|
2196
2221
|
lines.splice(insertLine - 1, 0, content);
|
|
2197
2222
|
const newContent = lines.join("\n");
|
|
@@ -2225,7 +2250,7 @@ ${numberedLines}${additionalLinesMessage}`
|
|
|
2225
2250
|
switch (lastEdit.command) {
|
|
2226
2251
|
case "str_replace":
|
|
2227
2252
|
if (lastEdit.path && lastEdit.old_str && lastEdit.new_str) {
|
|
2228
|
-
const content = await
|
|
2253
|
+
const content = await fs9.promises.readFile(lastEdit.path, "utf-8");
|
|
2229
2254
|
const revertedContent = content.replace(
|
|
2230
2255
|
lastEdit.new_str,
|
|
2231
2256
|
lastEdit.old_str
|
|
@@ -2235,12 +2260,12 @@ ${numberedLines}${additionalLinesMessage}`
|
|
|
2235
2260
|
break;
|
|
2236
2261
|
case "create":
|
|
2237
2262
|
if (lastEdit.path) {
|
|
2238
|
-
await
|
|
2263
|
+
await fs9.promises.rm(lastEdit.path);
|
|
2239
2264
|
}
|
|
2240
2265
|
break;
|
|
2241
2266
|
case "insert":
|
|
2242
2267
|
if (lastEdit.path && lastEdit.insert_line) {
|
|
2243
|
-
const content = await
|
|
2268
|
+
const content = await fs9.promises.readFile(lastEdit.path, "utf-8");
|
|
2244
2269
|
const lines = content.split("\n");
|
|
2245
2270
|
lines.splice(lastEdit.insert_line - 1, 1);
|
|
2246
2271
|
await writeFile(lastEdit.path, lines.join("\n"), "utf-8");
|
|
@@ -2434,6 +2459,134 @@ ${numberedLines}${additionalLinesMessage}`
|
|
|
2434
2459
|
}
|
|
2435
2460
|
return diff.trim();
|
|
2436
2461
|
}
|
|
2462
|
+
/**
|
|
2463
|
+
* Generate colored diff with ANSI color codes for terminal display
|
|
2464
|
+
*/
|
|
2465
|
+
generateColoredDiff(oldLines, newLines, filePath) {
|
|
2466
|
+
logToSession("generateColoredDiff called", { filePath, oldLinesCount: oldLines.length, newLinesCount: newLines.length });
|
|
2467
|
+
if (oldLines.length === 0 && newLines.length === 0) {
|
|
2468
|
+
return `No changes in ${filePath}`;
|
|
2469
|
+
}
|
|
2470
|
+
if (oldLines.length === 0 && newLines.length > 0) {
|
|
2471
|
+
logToSession("Handling new file creation");
|
|
2472
|
+
const addedCount = newLines.length;
|
|
2473
|
+
let diff = `\x1B[32m\u2705 Created ${filePath} with ${addedCount} line${addedCount !== 1 ? "s" : ""}\x1B[0m
|
|
2474
|
+
|
|
2475
|
+
`;
|
|
2476
|
+
diff += `\x1B[36m--- /dev/null\x1B[0m
|
|
2477
|
+
`;
|
|
2478
|
+
diff += `\x1B[36m+++ b/${filePath}\x1B[0m
|
|
2479
|
+
`;
|
|
2480
|
+
diff += `\x1B[36m@@ -0,0 +1,${addedCount} @@\x1B[0m
|
|
2481
|
+
`;
|
|
2482
|
+
newLines.forEach((line) => {
|
|
2483
|
+
diff += `\x1B[32m+${line}\x1B[0m
|
|
2484
|
+
`;
|
|
2485
|
+
});
|
|
2486
|
+
return diff.trim();
|
|
2487
|
+
}
|
|
2488
|
+
try {
|
|
2489
|
+
logToSession("Generating unified diff with createTwoFilesPatch");
|
|
2490
|
+
const patch = createTwoFilesPatch(
|
|
2491
|
+
`a/${filePath}`,
|
|
2492
|
+
`b/${filePath}`,
|
|
2493
|
+
oldLines.join("\n"),
|
|
2494
|
+
newLines.join("\n"),
|
|
2495
|
+
"",
|
|
2496
|
+
// old header
|
|
2497
|
+
"",
|
|
2498
|
+
// new header
|
|
2499
|
+
{ context: 3 }
|
|
2500
|
+
);
|
|
2501
|
+
logToSession("createTwoFilesPatch completed", { patchLength: patch.length });
|
|
2502
|
+
return this.colorizeUnifiedDiff(patch, filePath);
|
|
2503
|
+
} catch (error) {
|
|
2504
|
+
logToSession("CRITICAL: createTwoFilesPatch failed", {
|
|
2505
|
+
error: error.message,
|
|
2506
|
+
errorName: error.name,
|
|
2507
|
+
errorStack: error.stack?.substring(0, 500),
|
|
2508
|
+
filePath
|
|
2509
|
+
});
|
|
2510
|
+
return `\x1B[32m\u2705 Updated ${filePath}\x1B[0m
|
|
2511
|
+
\x1B[32m+ (diff generation failed - ${error.message})\x1B[0m`;
|
|
2512
|
+
}
|
|
2513
|
+
}
|
|
2514
|
+
/**
|
|
2515
|
+
* Colorize unified diff output with ANSI color codes
|
|
2516
|
+
*/
|
|
2517
|
+
colorizeUnifiedDiff(diff, filePath) {
|
|
2518
|
+
logToSession("colorizeUnifiedDiff called", { diffLength: diff.length });
|
|
2519
|
+
try {
|
|
2520
|
+
const lines = diff.split("\n");
|
|
2521
|
+
logToSession("Split into lines", { lineCount: lines.length });
|
|
2522
|
+
let colorizedLines = [];
|
|
2523
|
+
let addedLines = 0;
|
|
2524
|
+
let removedLines = 0;
|
|
2525
|
+
for (const line of lines) {
|
|
2526
|
+
if (line.startsWith("+") && !line.startsWith("+++")) addedLines++;
|
|
2527
|
+
if (line.startsWith("-") && !line.startsWith("---")) removedLines++;
|
|
2528
|
+
}
|
|
2529
|
+
logToSession("Change counts", { added: addedLines, removed: removedLines });
|
|
2530
|
+
if (addedLines > 0 || removedLines > 0) {
|
|
2531
|
+
let summary = `\x1B[32m\u2705 Updated ${filePath}\x1B[0m`;
|
|
2532
|
+
if (addedLines > 0 && removedLines > 0) {
|
|
2533
|
+
summary += ` with \x1B[32m${addedLines} addition${addedLines !== 1 ? "s" : ""}\x1B[0m and \x1B[31m${removedLines} removal${removedLines !== 1 ? "s" : ""}\x1B[0m`;
|
|
2534
|
+
} else if (addedLines > 0) {
|
|
2535
|
+
summary += ` with \x1B[32m${addedLines} addition${addedLines !== 1 ? "s" : ""}\x1B[0m`;
|
|
2536
|
+
} else if (removedLines > 0) {
|
|
2537
|
+
summary += ` with \x1B[31m${removedLines} removal${removedLines !== 1 ? "s" : ""}\x1B[0m`;
|
|
2538
|
+
}
|
|
2539
|
+
colorizedLines.push(summary);
|
|
2540
|
+
colorizedLines.push("");
|
|
2541
|
+
}
|
|
2542
|
+
let oldLineNum = 1;
|
|
2543
|
+
let newLineNum = 1;
|
|
2544
|
+
for (const line of lines) {
|
|
2545
|
+
if (line.startsWith("---") || line.startsWith("+++")) {
|
|
2546
|
+
continue;
|
|
2547
|
+
} else if (line.startsWith("@@")) {
|
|
2548
|
+
logToSession("Processing hunk header", { header: line });
|
|
2549
|
+
const hunkMatch = line.match(/@@ -(\d+),?\d* \+(\d+),?\d* @@/);
|
|
2550
|
+
if (hunkMatch) {
|
|
2551
|
+
oldLineNum = parseInt(hunkMatch[1]);
|
|
2552
|
+
newLineNum = parseInt(hunkMatch[2]);
|
|
2553
|
+
logToSession("Parsed line numbers", { old: oldLineNum, new: newLineNum });
|
|
2554
|
+
} else {
|
|
2555
|
+
logToSession("Failed to parse hunk header", { header: line });
|
|
2556
|
+
}
|
|
2557
|
+
continue;
|
|
2558
|
+
} else if (line.startsWith("+")) {
|
|
2559
|
+
const content = line.substring(1);
|
|
2560
|
+
colorizedLines.push(` \x1B[32m${newLineNum.toString().padStart(3)} +\x1B[0m ${content}`);
|
|
2561
|
+
newLineNum++;
|
|
2562
|
+
} else if (line.startsWith("-")) {
|
|
2563
|
+
const content = line.substring(1);
|
|
2564
|
+
colorizedLines.push(` \x1B[31m${oldLineNum.toString().padStart(3)} -\x1B[0m ${content}`);
|
|
2565
|
+
oldLineNum++;
|
|
2566
|
+
} else if (line.startsWith(" ")) {
|
|
2567
|
+
const content = line.substring(1);
|
|
2568
|
+
colorizedLines.push(` ${oldLineNum.toString().padStart(3)} ${content}`);
|
|
2569
|
+
oldLineNum++;
|
|
2570
|
+
newLineNum++;
|
|
2571
|
+
} else if (line.trim() === "") {
|
|
2572
|
+
continue;
|
|
2573
|
+
}
|
|
2574
|
+
}
|
|
2575
|
+
const result = colorizedLines.join("\n");
|
|
2576
|
+
logToSession("colorizeUnifiedDiff completed", { resultLength: result.length });
|
|
2577
|
+
return result;
|
|
2578
|
+
} catch (error) {
|
|
2579
|
+
logToSession("CRITICAL: colorizeUnifiedDiff failed", {
|
|
2580
|
+
error: error.message,
|
|
2581
|
+
errorName: error.name,
|
|
2582
|
+
errorStack: error.stack?.substring(0, 500),
|
|
2583
|
+
filePath,
|
|
2584
|
+
diffPreview: diff.substring(0, 500)
|
|
2585
|
+
});
|
|
2586
|
+
return `\x1B[32m\u2705 Updated ${filePath}\x1B[0m
|
|
2587
|
+
\x1B[32m+ (diff colorization failed - ${error.message})\x1B[0m`;
|
|
2588
|
+
}
|
|
2589
|
+
}
|
|
2437
2590
|
getEditHistory() {
|
|
2438
2591
|
return [...this.editHistory];
|
|
2439
2592
|
}
|
|
@@ -2446,7 +2599,7 @@ var init_morph_editor = __esm({
|
|
|
2446
2599
|
init_confirmation_service();
|
|
2447
2600
|
pathExists2 = async (filePath) => {
|
|
2448
2601
|
try {
|
|
2449
|
-
await
|
|
2602
|
+
await fs9.promises.access(filePath, fs9.constants.F_OK);
|
|
2450
2603
|
return true;
|
|
2451
2604
|
} catch {
|
|
2452
2605
|
return false;
|
|
@@ -2499,7 +2652,7 @@ var init_morph_editor = __esm({
|
|
|
2499
2652
|
error: "MORPH_API_KEY not configured. Please set your Morph API key."
|
|
2500
2653
|
};
|
|
2501
2654
|
}
|
|
2502
|
-
const initialCode = await
|
|
2655
|
+
const initialCode = await fs9.promises.readFile(resolvedPath, "utf-8");
|
|
2503
2656
|
const sessionFlags = this.confirmationService.getSessionFlags();
|
|
2504
2657
|
if (!sessionFlags.fileOperations && !sessionFlags.allOperations) {
|
|
2505
2658
|
const confirmationResult = await this.confirmationService.requestConfirmation(
|
|
@@ -2522,7 +2675,7 @@ ${codeEdit}`
|
|
|
2522
2675
|
}
|
|
2523
2676
|
}
|
|
2524
2677
|
const mergedCode = await this.callMorphApply(instructions, initialCode, codeEdit);
|
|
2525
|
-
await
|
|
2678
|
+
await fs9.promises.writeFile(resolvedPath, mergedCode, "utf-8");
|
|
2526
2679
|
const oldLines = initialCode.split("\n");
|
|
2527
2680
|
const newLines = mergedCode.split("\n");
|
|
2528
2681
|
const diff = this.generateDiff(oldLines, newLines, targetFile);
|
|
@@ -2696,16 +2849,16 @@ ${codeEdit}`
|
|
|
2696
2849
|
try {
|
|
2697
2850
|
const resolvedPath = path8.resolve(filePath);
|
|
2698
2851
|
if (await pathExists2(resolvedPath)) {
|
|
2699
|
-
const stats = await
|
|
2852
|
+
const stats = await fs9.promises.stat(resolvedPath);
|
|
2700
2853
|
if (stats.isDirectory()) {
|
|
2701
|
-
const files = await
|
|
2854
|
+
const files = await fs9.promises.readdir(resolvedPath);
|
|
2702
2855
|
return {
|
|
2703
2856
|
success: true,
|
|
2704
2857
|
output: `Directory contents of ${filePath}:
|
|
2705
2858
|
${files.join("\n")}`
|
|
2706
2859
|
};
|
|
2707
2860
|
}
|
|
2708
|
-
const content = await
|
|
2861
|
+
const content = await fs9.promises.readFile(resolvedPath, "utf-8");
|
|
2709
2862
|
const lines = content.split("\n");
|
|
2710
2863
|
if (viewRange) {
|
|
2711
2864
|
const [start, end] = viewRange;
|
|
@@ -3133,7 +3286,7 @@ var init_search = __esm({
|
|
|
3133
3286
|
const walkDir = async (dir, depth = 0) => {
|
|
3134
3287
|
if (depth > 10 || files.length >= maxResults) return;
|
|
3135
3288
|
try {
|
|
3136
|
-
const entries = await
|
|
3289
|
+
const entries = await fs9.promises.readdir(dir, { withFileTypes: true });
|
|
3137
3290
|
for (const entry of entries) {
|
|
3138
3291
|
if (files.length >= maxResults) break;
|
|
3139
3292
|
const fullPath = path8.join(dir, entry.name);
|
|
@@ -3773,7 +3926,7 @@ var init_advanced_search = __esm({
|
|
|
3773
3926
|
init_confirmation_service();
|
|
3774
3927
|
pathExists4 = async (filePath) => {
|
|
3775
3928
|
try {
|
|
3776
|
-
await
|
|
3929
|
+
await fs9.promises.access(filePath, fs9.constants.F_OK);
|
|
3777
3930
|
return true;
|
|
3778
3931
|
} catch {
|
|
3779
3932
|
return false;
|
|
@@ -3795,7 +3948,7 @@ var init_advanced_search = __esm({
|
|
|
3795
3948
|
error: `Path not found: ${searchPath}`
|
|
3796
3949
|
};
|
|
3797
3950
|
}
|
|
3798
|
-
const stats = await
|
|
3951
|
+
const stats = await fs9.promises.stat(resolvedPath);
|
|
3799
3952
|
const filesToSearch = [];
|
|
3800
3953
|
if (stats.isFile()) {
|
|
3801
3954
|
filesToSearch.push(resolvedPath);
|
|
@@ -3838,7 +3991,7 @@ var init_advanced_search = __esm({
|
|
|
3838
3991
|
error: `Path not found: ${searchPath}`
|
|
3839
3992
|
};
|
|
3840
3993
|
}
|
|
3841
|
-
const stats = await
|
|
3994
|
+
const stats = await fs9.promises.stat(resolvedPath);
|
|
3842
3995
|
const filesToProcess = [];
|
|
3843
3996
|
if (stats.isFile()) {
|
|
3844
3997
|
filesToProcess.push(resolvedPath);
|
|
@@ -3883,7 +4036,7 @@ var init_advanced_search = __esm({
|
|
|
3883
4036
|
}
|
|
3884
4037
|
for (const result of results) {
|
|
3885
4038
|
if (result.success && result.preview) {
|
|
3886
|
-
await
|
|
4039
|
+
await fs9.promises.writeFile(result.filePath, result.preview, "utf-8");
|
|
3887
4040
|
}
|
|
3888
4041
|
}
|
|
3889
4042
|
}
|
|
@@ -3945,7 +4098,7 @@ ${matchingFiles.join("\n")}` : "No matching files found"
|
|
|
3945
4098
|
* Search in a single file
|
|
3946
4099
|
*/
|
|
3947
4100
|
async searchInFile(filePath, options) {
|
|
3948
|
-
const content = await
|
|
4101
|
+
const content = await fs9.promises.readFile(filePath, "utf-8");
|
|
3949
4102
|
const lines = content.split("\n");
|
|
3950
4103
|
const matches = [];
|
|
3951
4104
|
let pattern;
|
|
@@ -3996,7 +4149,7 @@ ${matchingFiles.join("\n")}` : "No matching files found"
|
|
|
3996
4149
|
*/
|
|
3997
4150
|
async replaceInFile(filePath, options) {
|
|
3998
4151
|
try {
|
|
3999
|
-
const content = await
|
|
4152
|
+
const content = await fs9.promises.readFile(filePath, "utf-8");
|
|
4000
4153
|
let pattern;
|
|
4001
4154
|
try {
|
|
4002
4155
|
if (options.isRegex) {
|
|
@@ -4047,7 +4200,7 @@ ${matchingFiles.join("\n")}` : "No matching files found"
|
|
|
4047
4200
|
async getFilesRecursively(dirPath, options) {
|
|
4048
4201
|
const files = [];
|
|
4049
4202
|
const walk = async (currentPath) => {
|
|
4050
|
-
const entries = await
|
|
4203
|
+
const entries = await fs9.promises.readdir(currentPath, { withFileTypes: true });
|
|
4051
4204
|
for (const entry of entries) {
|
|
4052
4205
|
const fullPath = path8.join(currentPath, entry.name);
|
|
4053
4206
|
if (entry.isDirectory()) {
|
|
@@ -4805,7 +4958,7 @@ var init_code_aware_editor = __esm({
|
|
|
4805
4958
|
init_confirmation_service();
|
|
4806
4959
|
pathExists6 = async (filePath) => {
|
|
4807
4960
|
try {
|
|
4808
|
-
await
|
|
4961
|
+
await fs9.promises.access(filePath, fs9.constants.F_OK);
|
|
4809
4962
|
return true;
|
|
4810
4963
|
} catch {
|
|
4811
4964
|
return false;
|
|
@@ -4827,7 +4980,7 @@ var init_code_aware_editor = __esm({
|
|
|
4827
4980
|
error: `File not found: ${filePath}`
|
|
4828
4981
|
};
|
|
4829
4982
|
}
|
|
4830
|
-
const content = await
|
|
4983
|
+
const content = await fs9.promises.readFile(resolvedPath, "utf-8");
|
|
4831
4984
|
const language = this.detectLanguage(filePath);
|
|
4832
4985
|
const context = await this.parseCodeContext(content, language);
|
|
4833
4986
|
const output = this.formatCodeAnalysis(context, filePath);
|
|
@@ -4854,7 +5007,7 @@ var init_code_aware_editor = __esm({
|
|
|
4854
5007
|
error: `File not found: ${filePath}`
|
|
4855
5008
|
};
|
|
4856
5009
|
}
|
|
4857
|
-
const content = await
|
|
5010
|
+
const content = await fs9.promises.readFile(resolvedPath, "utf-8");
|
|
4858
5011
|
const language = this.detectLanguage(filePath);
|
|
4859
5012
|
const context = await this.parseCodeContext(content, language);
|
|
4860
5013
|
const result = await this.performRefactoring(content, context, operation, language);
|
|
@@ -4880,7 +5033,7 @@ var init_code_aware_editor = __esm({
|
|
|
4880
5033
|
};
|
|
4881
5034
|
}
|
|
4882
5035
|
}
|
|
4883
|
-
await
|
|
5036
|
+
await fs9.promises.writeFile(resolvedPath, result.newContent, "utf-8");
|
|
4884
5037
|
return {
|
|
4885
5038
|
success: true,
|
|
4886
5039
|
output: result.output
|
|
@@ -4904,7 +5057,7 @@ var init_code_aware_editor = __esm({
|
|
|
4904
5057
|
error: `File not found: ${filePath}`
|
|
4905
5058
|
};
|
|
4906
5059
|
}
|
|
4907
|
-
const content = await
|
|
5060
|
+
const content = await fs9.promises.readFile(resolvedPath, "utf-8");
|
|
4908
5061
|
const language = this.detectLanguage(filePath);
|
|
4909
5062
|
const context = await this.parseCodeContext(content, language);
|
|
4910
5063
|
const insertionPoint = this.findInsertionPoint(content, context, location, target);
|
|
@@ -4934,7 +5087,7 @@ var init_code_aware_editor = __esm({
|
|
|
4934
5087
|
};
|
|
4935
5088
|
}
|
|
4936
5089
|
}
|
|
4937
|
-
await
|
|
5090
|
+
await fs9.promises.writeFile(resolvedPath, newContent, "utf-8");
|
|
4938
5091
|
return {
|
|
4939
5092
|
success: true,
|
|
4940
5093
|
output: `Code inserted at line ${insertionPoint.line + 1} in ${filePath}`
|
|
@@ -4958,7 +5111,7 @@ var init_code_aware_editor = __esm({
|
|
|
4958
5111
|
error: `File not found: ${filePath}`
|
|
4959
5112
|
};
|
|
4960
5113
|
}
|
|
4961
|
-
const content = await
|
|
5114
|
+
const content = await fs9.promises.readFile(resolvedPath, "utf-8");
|
|
4962
5115
|
const language = this.detectLanguage(filePath);
|
|
4963
5116
|
const formattedContent = await this.formatCodeContent(content, language, options);
|
|
4964
5117
|
if (formattedContent === content) {
|
|
@@ -4986,7 +5139,7 @@ var init_code_aware_editor = __esm({
|
|
|
4986
5139
|
};
|
|
4987
5140
|
}
|
|
4988
5141
|
}
|
|
4989
|
-
await
|
|
5142
|
+
await fs9.promises.writeFile(resolvedPath, formattedContent, "utf-8");
|
|
4990
5143
|
return {
|
|
4991
5144
|
success: true,
|
|
4992
5145
|
output: `Code formatted in ${filePath}`
|
|
@@ -5010,7 +5163,7 @@ var init_code_aware_editor = __esm({
|
|
|
5010
5163
|
error: `File not found: ${filePath}`
|
|
5011
5164
|
};
|
|
5012
5165
|
}
|
|
5013
|
-
const content = await
|
|
5166
|
+
const content = await fs9.promises.readFile(resolvedPath, "utf-8");
|
|
5014
5167
|
const language = this.detectLanguage(filePath);
|
|
5015
5168
|
const context = await this.parseCodeContext(content, language);
|
|
5016
5169
|
const missingImports = symbols.filter(
|
|
@@ -5051,7 +5204,7 @@ ${importsToAdd.join("\n")}`;
|
|
|
5051
5204
|
};
|
|
5052
5205
|
}
|
|
5053
5206
|
}
|
|
5054
|
-
await
|
|
5207
|
+
await fs9.promises.writeFile(resolvedPath, newContent, "utf-8");
|
|
5055
5208
|
return {
|
|
5056
5209
|
success: true,
|
|
5057
5210
|
output: `Added ${missingImports.length} missing imports to ${filePath}`
|
|
@@ -6410,7 +6563,7 @@ var init_ast_parser = __esm({
|
|
|
6410
6563
|
}
|
|
6411
6564
|
pathExists8 = async (filePath) => {
|
|
6412
6565
|
try {
|
|
6413
|
-
await
|
|
6566
|
+
await fs9.promises.access(filePath, fs9.constants.F_OK);
|
|
6414
6567
|
return true;
|
|
6415
6568
|
} catch {
|
|
6416
6569
|
return false;
|
|
@@ -6486,7 +6639,7 @@ var init_ast_parser = __esm({
|
|
|
6486
6639
|
if (!await pathExists8(filePath)) {
|
|
6487
6640
|
throw new Error(`File not found: ${filePath}`);
|
|
6488
6641
|
}
|
|
6489
|
-
const content = await
|
|
6642
|
+
const content = await fs9.promises.readFile(filePath, "utf-8");
|
|
6490
6643
|
const language = this.detectLanguage(filePath);
|
|
6491
6644
|
let result;
|
|
6492
6645
|
if (language === "typescript" || language === "tsx") {
|
|
@@ -7180,7 +7333,7 @@ var init_symbol_search = __esm({
|
|
|
7180
7333
|
async findSymbolUsages(symbolRef) {
|
|
7181
7334
|
const usages = [];
|
|
7182
7335
|
try {
|
|
7183
|
-
const content = await
|
|
7336
|
+
const content = await fs9.promises.readFile(symbolRef.filePath, "utf-8");
|
|
7184
7337
|
const lines = content.split("\n");
|
|
7185
7338
|
for (let i = 0; i < lines.length; i++) {
|
|
7186
7339
|
const line = lines[i];
|
|
@@ -7360,7 +7513,7 @@ var init_dependency_analyzer = __esm({
|
|
|
7360
7513
|
init_ast_parser();
|
|
7361
7514
|
pathExists9 = async (filePath) => {
|
|
7362
7515
|
try {
|
|
7363
|
-
await
|
|
7516
|
+
await fs9.promises.access(filePath, fs9.constants.F_OK);
|
|
7364
7517
|
return true;
|
|
7365
7518
|
} catch {
|
|
7366
7519
|
return false;
|
|
@@ -7562,10 +7715,10 @@ var init_dependency_analyzer = __esm({
|
|
|
7562
7715
|
const circularDeps = [];
|
|
7563
7716
|
const visited = /* @__PURE__ */ new Set();
|
|
7564
7717
|
const visiting = /* @__PURE__ */ new Set();
|
|
7565
|
-
const dfs = (filePath,
|
|
7718
|
+
const dfs = (filePath, path43) => {
|
|
7566
7719
|
if (visiting.has(filePath)) {
|
|
7567
|
-
const cycleStart =
|
|
7568
|
-
const cycle =
|
|
7720
|
+
const cycleStart = path43.indexOf(filePath);
|
|
7721
|
+
const cycle = path43.slice(cycleStart).concat([filePath]);
|
|
7569
7722
|
circularDeps.push({
|
|
7570
7723
|
cycle: cycle.map((fp) => graph.nodes.get(fp)?.filePath || fp),
|
|
7571
7724
|
severity: cycle.length <= 2 ? "error" : "warning",
|
|
@@ -7581,7 +7734,7 @@ var init_dependency_analyzer = __esm({
|
|
|
7581
7734
|
if (node) {
|
|
7582
7735
|
for (const dependency of node.dependencies) {
|
|
7583
7736
|
if (graph.nodes.has(dependency)) {
|
|
7584
|
-
dfs(dependency, [...
|
|
7737
|
+
dfs(dependency, [...path43, filePath]);
|
|
7585
7738
|
}
|
|
7586
7739
|
}
|
|
7587
7740
|
}
|
|
@@ -7838,7 +7991,7 @@ var init_code_context = __esm({
|
|
|
7838
7991
|
init_dependency_analyzer();
|
|
7839
7992
|
pathExists10 = async (filePath) => {
|
|
7840
7993
|
try {
|
|
7841
|
-
await
|
|
7994
|
+
await fs9.promises.access(filePath, fs9.constants.F_OK);
|
|
7842
7995
|
return true;
|
|
7843
7996
|
} catch {
|
|
7844
7997
|
return false;
|
|
@@ -7983,7 +8136,7 @@ var init_code_context = __esm({
|
|
|
7983
8136
|
async analyzeUsagePatterns(symbol, filePath) {
|
|
7984
8137
|
const patterns = [];
|
|
7985
8138
|
try {
|
|
7986
|
-
const content = await
|
|
8139
|
+
const content = await fs9.promises.readFile(filePath, "utf-8");
|
|
7987
8140
|
const lines = content.split("\n");
|
|
7988
8141
|
let callCount = 0;
|
|
7989
8142
|
let assignmentCount = 0;
|
|
@@ -8136,7 +8289,7 @@ var init_code_context = __esm({
|
|
|
8136
8289
|
}
|
|
8137
8290
|
async analyzeSemanticContext(filePath, symbols, dependencies) {
|
|
8138
8291
|
const fileName = path8__default.basename(filePath);
|
|
8139
|
-
const content = await
|
|
8292
|
+
const content = await fs9.promises.readFile(filePath, "utf-8");
|
|
8140
8293
|
const purpose = this.inferPurpose(fileName, symbols, content);
|
|
8141
8294
|
const domain = this.extractDomain(filePath, symbols, dependencies);
|
|
8142
8295
|
const patterns = this.detectDesignPatterns(content, symbols);
|
|
@@ -8265,7 +8418,7 @@ var init_code_context = __esm({
|
|
|
8265
8418
|
};
|
|
8266
8419
|
}
|
|
8267
8420
|
async calculateCodeMetrics(filePath, symbols) {
|
|
8268
|
-
const content = await
|
|
8421
|
+
const content = await fs9.promises.readFile(filePath, "utf-8");
|
|
8269
8422
|
const lines = content.split("\n");
|
|
8270
8423
|
const codeLines = lines.filter((line) => line.trim().length > 0 && !line.trim().startsWith("//"));
|
|
8271
8424
|
const linesOfCode = codeLines.length;
|
|
@@ -8374,7 +8527,7 @@ var init_refactoring_assistant = __esm({
|
|
|
8374
8527
|
init_operation_history();
|
|
8375
8528
|
pathExists11 = async (filePath) => {
|
|
8376
8529
|
try {
|
|
8377
|
-
await
|
|
8530
|
+
await fs9.promises.access(filePath, fs9.constants.F_OK);
|
|
8378
8531
|
return true;
|
|
8379
8532
|
} catch {
|
|
8380
8533
|
return false;
|
|
@@ -8494,7 +8647,7 @@ var init_refactoring_assistant = __esm({
|
|
|
8494
8647
|
if (!await pathExists11(filePath)) {
|
|
8495
8648
|
throw new Error(`File not found: ${filePath}`);
|
|
8496
8649
|
}
|
|
8497
|
-
const content = await
|
|
8650
|
+
const content = await fs9.promises.readFile(filePath, "utf-8");
|
|
8498
8651
|
const lines = content.split("\n");
|
|
8499
8652
|
if (startLine < 0 || endLine >= lines.length || startLine > endLine) {
|
|
8500
8653
|
throw new Error("Invalid line range");
|
|
@@ -8569,7 +8722,7 @@ var init_refactoring_assistant = __esm({
|
|
|
8569
8722
|
if (!filePath || !variableName) {
|
|
8570
8723
|
throw new Error("File path and variable name are required");
|
|
8571
8724
|
}
|
|
8572
|
-
const content = await
|
|
8725
|
+
const content = await fs9.promises.readFile(filePath, "utf-8");
|
|
8573
8726
|
const lines = content.split("\n");
|
|
8574
8727
|
const startLineContent = lines[startLine];
|
|
8575
8728
|
const endLineContent = lines[endLine];
|
|
@@ -8644,7 +8797,7 @@ var init_refactoring_assistant = __esm({
|
|
|
8644
8797
|
if (!functionSymbol) {
|
|
8645
8798
|
throw new Error(`Function '${symbolName}' not found`);
|
|
8646
8799
|
}
|
|
8647
|
-
const content = await
|
|
8800
|
+
const content = await fs9.promises.readFile(filePath, "utf-8");
|
|
8648
8801
|
const lines = content.split("\n");
|
|
8649
8802
|
const functionLines = lines.slice(functionSymbol.startPosition.row, functionSymbol.endPosition.row + 1);
|
|
8650
8803
|
const functionBody = this.extractFunctionBody(functionLines.join("\n"));
|
|
@@ -8754,7 +8907,7 @@ var init_refactoring_assistant = __esm({
|
|
|
8754
8907
|
}
|
|
8755
8908
|
async generateRenameChanges(ref, oldName, newName, includeComments, includeStrings) {
|
|
8756
8909
|
const changes = [];
|
|
8757
|
-
const content = await
|
|
8910
|
+
const content = await fs9.promises.readFile(ref.filePath, "utf-8");
|
|
8758
8911
|
const lines = content.split("\n");
|
|
8759
8912
|
for (let i = 0; i < lines.length; i++) {
|
|
8760
8913
|
const line = lines[i];
|
|
@@ -9129,7 +9282,7 @@ var init_codebase_explorer = __esm({
|
|
|
9129
9282
|
return files;
|
|
9130
9283
|
}
|
|
9131
9284
|
try {
|
|
9132
|
-
const entries = await
|
|
9285
|
+
const entries = await fs6__default.readdir(dirPath, { withFileTypes: true });
|
|
9133
9286
|
for (const entry of entries) {
|
|
9134
9287
|
const fullPath = path8__default.join(dirPath, entry.name);
|
|
9135
9288
|
const relativePath = path8__default.relative(options.rootPath, fullPath);
|
|
@@ -9152,7 +9305,7 @@ var init_codebase_explorer = __esm({
|
|
|
9152
9305
|
files.push(...subFiles);
|
|
9153
9306
|
} else {
|
|
9154
9307
|
try {
|
|
9155
|
-
const stats = await
|
|
9308
|
+
const stats = await fs6__default.stat(fullPath);
|
|
9156
9309
|
fileInfo.size = stats.size;
|
|
9157
9310
|
fileInfo.lastModified = stats.mtimeMs;
|
|
9158
9311
|
if (fileInfo.size > this.settings.maxFileSize) {
|
|
@@ -9425,7 +9578,7 @@ var init_codebase_explorer = __esm({
|
|
|
9425
9578
|
async detectProjectType(rootPath, files) {
|
|
9426
9579
|
const packageJsonPath = path8__default.join(rootPath, "package.json");
|
|
9427
9580
|
try {
|
|
9428
|
-
const packageJson = await
|
|
9581
|
+
const packageJson = await fs6__default.readFile(packageJsonPath, "utf-8");
|
|
9429
9582
|
const pkg = JSON.parse(packageJson);
|
|
9430
9583
|
if (pkg.dependencies?.react || pkg.devDependencies?.react) return "react";
|
|
9431
9584
|
if (pkg.dependencies?.vue || pkg.devDependencies?.vue) return "vue";
|
|
@@ -9621,7 +9774,7 @@ var init_codebase_explorer = __esm({
|
|
|
9621
9774
|
*/
|
|
9622
9775
|
async calculateFileChecksum(filePath) {
|
|
9623
9776
|
try {
|
|
9624
|
-
const content = await
|
|
9777
|
+
const content = await fs6__default.readFile(filePath);
|
|
9625
9778
|
return crypto2.createHash("sha256").update(content).digest("hex");
|
|
9626
9779
|
} catch {
|
|
9627
9780
|
return "";
|
|
@@ -9805,7 +9958,7 @@ var init_incremental_indexer = __esm({
|
|
|
9805
9958
|
async scanDirectory(dirPath, options, files, depth = 0) {
|
|
9806
9959
|
if (depth > 10) return;
|
|
9807
9960
|
try {
|
|
9808
|
-
const entries = await
|
|
9961
|
+
const entries = await fs6__default.readdir(dirPath, { withFileTypes: true });
|
|
9809
9962
|
for (const entry of entries) {
|
|
9810
9963
|
const fullPath = path8__default.join(dirPath, entry.name);
|
|
9811
9964
|
if (!this.shouldTrackFile(fullPath, options)) {
|
|
@@ -9815,7 +9968,7 @@ var init_incremental_indexer = __esm({
|
|
|
9815
9968
|
await this.scanDirectory(fullPath, options, files, depth + 1);
|
|
9816
9969
|
} else {
|
|
9817
9970
|
try {
|
|
9818
|
-
const stats = await
|
|
9971
|
+
const stats = await fs6__default.stat(fullPath);
|
|
9819
9972
|
if (options.maxFileSize && stats.size > options.maxFileSize) {
|
|
9820
9973
|
continue;
|
|
9821
9974
|
}
|
|
@@ -9855,7 +10008,7 @@ var init_incremental_indexer = __esm({
|
|
|
9855
10008
|
}
|
|
9856
10009
|
async calculateChecksum(filePath) {
|
|
9857
10010
|
try {
|
|
9858
|
-
const content = await
|
|
10011
|
+
const content = await fs6__default.readFile(filePath);
|
|
9859
10012
|
return crypto2.createHash("sha256").update(content).digest("hex");
|
|
9860
10013
|
} catch {
|
|
9861
10014
|
return "";
|
|
@@ -10542,8 +10695,936 @@ Use \`--action=incremental\` for faster subsequent updates.`
|
|
|
10542
10695
|
}
|
|
10543
10696
|
});
|
|
10544
10697
|
|
|
10545
|
-
// src/services/
|
|
10546
|
-
var
|
|
10698
|
+
// src/services/semantic-planner.ts
|
|
10699
|
+
var SemanticPlanner;
|
|
10700
|
+
var init_semantic_planner = __esm({
|
|
10701
|
+
"src/services/semantic-planner.ts"() {
|
|
10702
|
+
SemanticPlanner = class {
|
|
10703
|
+
constructor(vectorSearch) {
|
|
10704
|
+
this.intentPatterns = /* @__PURE__ */ new Map();
|
|
10705
|
+
this.operationMappings = /* @__PURE__ */ new Map();
|
|
10706
|
+
this.contextHistory = [];
|
|
10707
|
+
this.vectorSearch = vectorSearch;
|
|
10708
|
+
this.initializeIntentPatterns();
|
|
10709
|
+
this.initializeOperationMappings();
|
|
10710
|
+
}
|
|
10711
|
+
/**
|
|
10712
|
+
* Parse natural language intent and create executable operations
|
|
10713
|
+
*/
|
|
10714
|
+
async parseIntent(goal, description = "", context) {
|
|
10715
|
+
console.log(`\u{1F9E0} Analyzing intent: ${goal}`);
|
|
10716
|
+
const searchResults = await this.vectorSearch.semanticSearch(goal, 5);
|
|
10717
|
+
const analysis = await this.analyzeGoalIntent(goal, description, searchResults);
|
|
10718
|
+
analysis.decompositionNeeded = this.shouldDecompose(analysis, context);
|
|
10719
|
+
analysis.suggestedTools = this.suggestTools(analysis);
|
|
10720
|
+
if (context) {
|
|
10721
|
+
this.contextHistory.push(context);
|
|
10722
|
+
this.learnFromContext(context, analysis);
|
|
10723
|
+
}
|
|
10724
|
+
return analysis;
|
|
10725
|
+
}
|
|
10726
|
+
/**
|
|
10727
|
+
* Map declarative intent to executable tool sequences
|
|
10728
|
+
*/
|
|
10729
|
+
async mapToOperations(analysis, context) {
|
|
10730
|
+
const operations = [];
|
|
10731
|
+
if (analysis.decompositionNeeded) {
|
|
10732
|
+
const decomposed = await this.decomposeIntent(analysis, context);
|
|
10733
|
+
operations.push(...decomposed);
|
|
10734
|
+
} else {
|
|
10735
|
+
const operation = this.mapSimpleIntent(analysis);
|
|
10736
|
+
if (operation) {
|
|
10737
|
+
operations.push(operation);
|
|
10738
|
+
}
|
|
10739
|
+
}
|
|
10740
|
+
return this.optimizeOperationSequence(operations, context);
|
|
10741
|
+
}
|
|
10742
|
+
/**
|
|
10743
|
+
* Convert operations to executable task steps
|
|
10744
|
+
*/
|
|
10745
|
+
async operationsToSteps(operations, context) {
|
|
10746
|
+
const steps = [];
|
|
10747
|
+
for (const operation of operations) {
|
|
10748
|
+
const step = await this.operationToStep(operation, context);
|
|
10749
|
+
steps.push(step);
|
|
10750
|
+
}
|
|
10751
|
+
return steps;
|
|
10752
|
+
}
|
|
10753
|
+
/**
|
|
10754
|
+
* Initialize intent pattern recognition
|
|
10755
|
+
*/
|
|
10756
|
+
initializeIntentPatterns() {
|
|
10757
|
+
this.intentPatterns.set("refactor", /refactor|redesign|restructure|reorganize/i);
|
|
10758
|
+
this.intentPatterns.set("implement", /implement|add|create|build|develop|feature/i);
|
|
10759
|
+
this.intentPatterns.set("fix", /fix|bug|issue|error|problem|resolve/i);
|
|
10760
|
+
this.intentPatterns.set("test", /test|validate|verify|check/i);
|
|
10761
|
+
this.intentPatterns.set("optimize", /optimize|improve|performance|efficiency/i);
|
|
10762
|
+
this.intentPatterns.set("document", /document|docs|readme|comment/i);
|
|
10763
|
+
this.intentPatterns.set("configure", /config|setup|initialize|install/i);
|
|
10764
|
+
}
|
|
10765
|
+
/**
|
|
10766
|
+
* Initialize operation mappings
|
|
10767
|
+
*/
|
|
10768
|
+
initializeOperationMappings() {
|
|
10769
|
+
this.operationMappings.set("refactor_component", {
|
|
10770
|
+
operation: "refactor_component",
|
|
10771
|
+
tools: ["autonomous_task", "multi_file_editor", "ast_parser"],
|
|
10772
|
+
parameters: /* @__PURE__ */ new Map([["component", "target"], ["approach", "strategy"]]),
|
|
10773
|
+
dependencies: [],
|
|
10774
|
+
estimatedEffort: 5
|
|
10775
|
+
});
|
|
10776
|
+
this.operationMappings.set("implement_feature", {
|
|
10777
|
+
operation: "implement_feature",
|
|
10778
|
+
tools: ["autonomous_task", "search", "code_context"],
|
|
10779
|
+
parameters: /* @__PURE__ */ new Map([["feature", "description"], ["location", "path"]]),
|
|
10780
|
+
dependencies: ["analysis"],
|
|
10781
|
+
estimatedEffort: 4
|
|
10782
|
+
});
|
|
10783
|
+
this.operationMappings.set("fix_bug", {
|
|
10784
|
+
operation: "fix_bug",
|
|
10785
|
+
tools: ["search", "symbol_search", "autonomous_task"],
|
|
10786
|
+
parameters: /* @__PURE__ */ new Map([["bug", "description"], ["location", "file"]]),
|
|
10787
|
+
dependencies: ["locate"],
|
|
10788
|
+
estimatedEffort: 3
|
|
10789
|
+
});
|
|
10790
|
+
}
|
|
10791
|
+
/**
|
|
10792
|
+
* Analyze goal intent using NLP patterns
|
|
10793
|
+
*/
|
|
10794
|
+
async analyzeGoalIntent(goal, description, searchResults) {
|
|
10795
|
+
const fullText = `${goal} ${description}`.toLowerCase();
|
|
10796
|
+
let bestIntent = "general";
|
|
10797
|
+
let highestConfidence = 0;
|
|
10798
|
+
for (const [intent, pattern] of this.intentPatterns) {
|
|
10799
|
+
const matches = fullText.match(pattern);
|
|
10800
|
+
if (matches) {
|
|
10801
|
+
const confidence = this.calculateConfidence(fullText, pattern);
|
|
10802
|
+
if (confidence > highestConfidence) {
|
|
10803
|
+
highestConfidence = confidence;
|
|
10804
|
+
bestIntent = intent;
|
|
10805
|
+
}
|
|
10806
|
+
}
|
|
10807
|
+
}
|
|
10808
|
+
const entities = this.extractEntities(fullText, searchResults);
|
|
10809
|
+
const complexity = this.determineComplexity(fullText, entities);
|
|
10810
|
+
return {
|
|
10811
|
+
intent: bestIntent,
|
|
10812
|
+
confidence: highestConfidence,
|
|
10813
|
+
entities,
|
|
10814
|
+
complexity,
|
|
10815
|
+
suggestedTools: [],
|
|
10816
|
+
decompositionNeeded: false
|
|
10817
|
+
};
|
|
10818
|
+
}
|
|
10819
|
+
/**
|
|
10820
|
+
* Calculate confidence score for intent matching
|
|
10821
|
+
*/
|
|
10822
|
+
calculateConfidence(text, pattern) {
|
|
10823
|
+
const matches = text.match(pattern);
|
|
10824
|
+
if (!matches) return 0;
|
|
10825
|
+
const matchLength = matches[0].length;
|
|
10826
|
+
const textLength = text.length;
|
|
10827
|
+
const positionBonus = matches.index === 0 ? 0.2 : 0;
|
|
10828
|
+
return Math.min(1, matchLength / textLength + positionBonus);
|
|
10829
|
+
}
|
|
10830
|
+
/**
|
|
10831
|
+
* Extract entities from goal text
|
|
10832
|
+
*/
|
|
10833
|
+
extractEntities(text, searchResults) {
|
|
10834
|
+
const entities = /* @__PURE__ */ new Map();
|
|
10835
|
+
const filePatterns = [
|
|
10836
|
+
/\b(?:\.\/|\.\.\/)?(?:src|lib|app|components?)\/[^\s]+\.[jt]sx?\b/g,
|
|
10837
|
+
/\b[a-zA-Z0-9_\-\/]+\.[jt]sx?\b/g
|
|
10838
|
+
];
|
|
10839
|
+
for (const pattern of filePatterns) {
|
|
10840
|
+
const matches = text.match(pattern);
|
|
10841
|
+
if (matches) {
|
|
10842
|
+
entities.set("files", matches);
|
|
10843
|
+
break;
|
|
10844
|
+
}
|
|
10845
|
+
}
|
|
10846
|
+
const namePatterns = [
|
|
10847
|
+
/\b[A-Z][a-zA-Z0-9]*\b/g,
|
|
10848
|
+
// PascalCase
|
|
10849
|
+
/\b[a-z][a-zA-Z0-9]*\b/g
|
|
10850
|
+
// camelCase
|
|
10851
|
+
];
|
|
10852
|
+
for (const pattern of namePatterns) {
|
|
10853
|
+
const matches = text.match(pattern);
|
|
10854
|
+
if (matches && matches.length > 0) {
|
|
10855
|
+
entities.set("names", matches.slice(0, 5));
|
|
10856
|
+
break;
|
|
10857
|
+
}
|
|
10858
|
+
}
|
|
10859
|
+
if (searchResults.length > 0) {
|
|
10860
|
+
entities.set("related_symbols", searchResults.map((r) => r.symbol?.name).filter(Boolean));
|
|
10861
|
+
entities.set("affected_files", searchResults.map((r) => r.filePath));
|
|
10862
|
+
}
|
|
10863
|
+
return entities;
|
|
10864
|
+
}
|
|
10865
|
+
/**
|
|
10866
|
+
* Determine complexity of the goal
|
|
10867
|
+
*/
|
|
10868
|
+
determineComplexity(text, entities) {
|
|
10869
|
+
let complexityScore = 0;
|
|
10870
|
+
if (text.length > 200) complexityScore += 2;
|
|
10871
|
+
else if (text.length > 100) complexityScore += 1;
|
|
10872
|
+
const fileCount = entities.get("files")?.length || 0;
|
|
10873
|
+
const nameCount = entities.get("names")?.length || 0;
|
|
10874
|
+
complexityScore += Math.min(2, fileCount);
|
|
10875
|
+
complexityScore += Math.min(2, nameCount / 2);
|
|
10876
|
+
const complexKeywords = ["system", "architecture", "framework", "multiple", "all", "entire"];
|
|
10877
|
+
for (const keyword of complexKeywords) {
|
|
10878
|
+
if (text.includes(keyword)) complexityScore += 1;
|
|
10879
|
+
}
|
|
10880
|
+
if (complexityScore >= 4) return "high";
|
|
10881
|
+
if (complexityScore >= 2) return "medium";
|
|
10882
|
+
return "low";
|
|
10883
|
+
}
|
|
10884
|
+
/**
|
|
10885
|
+
* Determine if intent should be decomposed
|
|
10886
|
+
*/
|
|
10887
|
+
shouldDecompose(analysis, context) {
|
|
10888
|
+
if (analysis.complexity === "high") return true;
|
|
10889
|
+
if (analysis.entities.get("files")?.length > 3) return true;
|
|
10890
|
+
if (context?.previousOperations && context.previousOperations.length > 5) return true;
|
|
10891
|
+
return false;
|
|
10892
|
+
}
|
|
10893
|
+
/**
|
|
10894
|
+
* Suggest appropriate tools for the intent
|
|
10895
|
+
*/
|
|
10896
|
+
suggestTools(analysis) {
|
|
10897
|
+
const toolSuggestions = {
|
|
10898
|
+
refactor: ["autonomous_task", "multi_file_editor", "ast_parser", "dependency_analyzer"],
|
|
10899
|
+
implement: ["autonomous_task", "search", "code_context", "symbol_search"],
|
|
10900
|
+
fix: ["search", "symbol_search", "autonomous_task", "run_terminal_cmd"],
|
|
10901
|
+
test: ["run_terminal_cmd", "autonomous_task", "search"],
|
|
10902
|
+
optimize: ["code_context", "autonomous_task", "performance_analyzer"],
|
|
10903
|
+
document: ["autonomous_task", "search", "read_file"],
|
|
10904
|
+
configure: ["run_terminal_cmd", "autonomous_task", "search"]
|
|
10905
|
+
};
|
|
10906
|
+
return toolSuggestions[analysis.intent] || ["autonomous_task", "search"];
|
|
10907
|
+
}
|
|
10908
|
+
/**
|
|
10909
|
+
* Decompose complex intent into multiple operations
|
|
10910
|
+
*/
|
|
10911
|
+
async decomposeIntent(analysis, context) {
|
|
10912
|
+
const operations = [];
|
|
10913
|
+
operations.push({
|
|
10914
|
+
operation: "analyze_context",
|
|
10915
|
+
tools: ["search", "code_context"],
|
|
10916
|
+
parameters: /* @__PURE__ */ new Map([["query", analysis.entities.get("files")?.[0] || ""]]),
|
|
10917
|
+
dependencies: [],
|
|
10918
|
+
estimatedEffort: 1
|
|
10919
|
+
});
|
|
10920
|
+
const mainOperation = this.operationMappings.get(`${analysis.intent}_${analysis.intent === "implement" ? "feature" : analysis.intent === "fix" ? "bug" : "component"}`);
|
|
10921
|
+
if (mainOperation) {
|
|
10922
|
+
operations.push({
|
|
10923
|
+
...mainOperation,
|
|
10924
|
+
parameters: new Map([...mainOperation.parameters, ...analysis.entities])
|
|
10925
|
+
});
|
|
10926
|
+
}
|
|
10927
|
+
operations.push({
|
|
10928
|
+
operation: "validate_changes",
|
|
10929
|
+
tools: ["run_terminal_cmd", "autonomous_task"],
|
|
10930
|
+
parameters: /* @__PURE__ */ new Map([["type", "syntax_check"]]),
|
|
10931
|
+
dependencies: ["main_operation"],
|
|
10932
|
+
estimatedEffort: 1
|
|
10933
|
+
});
|
|
10934
|
+
return operations;
|
|
10935
|
+
}
|
|
10936
|
+
/**
|
|
10937
|
+
* Map simple intent to single operation
|
|
10938
|
+
*/
|
|
10939
|
+
mapSimpleIntent(analysis) {
|
|
10940
|
+
const mappingKey = `${analysis.intent}_${analysis.intent === "implement" ? "feature" : analysis.intent === "fix" ? "bug" : "component"}`;
|
|
10941
|
+
return this.operationMappings.get(mappingKey) || null;
|
|
10942
|
+
}
|
|
10943
|
+
/**
|
|
10944
|
+
* Optimize operation sequence for efficiency
|
|
10945
|
+
*/
|
|
10946
|
+
optimizeOperationSequence(operations, context) {
|
|
10947
|
+
const sorted = this.topologicalSort(operations);
|
|
10948
|
+
const merged = this.mergeSimilarOperations(sorted);
|
|
10949
|
+
if (context?.learnedPatterns) {
|
|
10950
|
+
return this.applyLearnedOptimizations(merged, context);
|
|
10951
|
+
}
|
|
10952
|
+
return merged;
|
|
10953
|
+
}
|
|
10954
|
+
/**
|
|
10955
|
+
* Convert operation to executable task step
|
|
10956
|
+
*/
|
|
10957
|
+
async operationToStep(operation, context) {
|
|
10958
|
+
return {
|
|
10959
|
+
id: `step_${operation.operation}_${Date.now()}`,
|
|
10960
|
+
type: this.inferStepType(operation),
|
|
10961
|
+
description: `Execute ${operation.operation}`,
|
|
10962
|
+
inputs: Object.fromEntries(operation.parameters),
|
|
10963
|
+
status: "pending"
|
|
10964
|
+
};
|
|
10965
|
+
}
|
|
10966
|
+
/**
|
|
10967
|
+
* Infer step type from operation
|
|
10968
|
+
*/
|
|
10969
|
+
inferStepType(operation) {
|
|
10970
|
+
if (operation.tools.includes("search")) return "search";
|
|
10971
|
+
if (operation.tools.includes("multi_file_editor")) return "edit";
|
|
10972
|
+
if (operation.tools.includes("run_terminal_cmd")) return "test";
|
|
10973
|
+
return "analyze";
|
|
10974
|
+
}
|
|
10975
|
+
/**
|
|
10976
|
+
* Topological sort operations by dependencies
|
|
10977
|
+
*/
|
|
10978
|
+
topologicalSort(operations) {
|
|
10979
|
+
const sorted = [];
|
|
10980
|
+
const visited = /* @__PURE__ */ new Set();
|
|
10981
|
+
const visit = (op) => {
|
|
10982
|
+
if (visited.has(op.operation)) return;
|
|
10983
|
+
visited.add(op.operation);
|
|
10984
|
+
for (const dep of op.dependencies) {
|
|
10985
|
+
const depOp = operations.find((o) => o.operation === dep);
|
|
10986
|
+
if (depOp) visit(depOp);
|
|
10987
|
+
}
|
|
10988
|
+
sorted.push(op);
|
|
10989
|
+
};
|
|
10990
|
+
for (const op of operations) {
|
|
10991
|
+
visit(op);
|
|
10992
|
+
}
|
|
10993
|
+
return sorted;
|
|
10994
|
+
}
|
|
10995
|
+
/**
|
|
10996
|
+
* Merge similar operations to reduce redundancy
|
|
10997
|
+
*/
|
|
10998
|
+
mergeSimilarOperations(operations) {
|
|
10999
|
+
const operationMap = /* @__PURE__ */ new Map();
|
|
11000
|
+
for (const op of operations) {
|
|
11001
|
+
const key = `${op.operation}_${Array.from(op.parameters.keys()).sort().join("_")}`;
|
|
11002
|
+
if (operationMap.has(key)) {
|
|
11003
|
+
const existing = operationMap.get(key);
|
|
11004
|
+
existing.tools = [.../* @__PURE__ */ new Set([...existing.tools, ...op.tools])];
|
|
11005
|
+
existing.estimatedEffort = Math.max(existing.estimatedEffort, op.estimatedEffort);
|
|
11006
|
+
} else {
|
|
11007
|
+
operationMap.set(key, { ...op });
|
|
11008
|
+
}
|
|
11009
|
+
}
|
|
11010
|
+
return Array.from(operationMap.values());
|
|
11011
|
+
}
|
|
11012
|
+
/**
|
|
11013
|
+
* Apply learned optimizations from context
|
|
11014
|
+
*/
|
|
11015
|
+
applyLearnedOptimizations(operations, context) {
|
|
11016
|
+
const optimizations = context.learnedPatterns.get("operation_optimizations") || [];
|
|
11017
|
+
for (const optimization of optimizations) {
|
|
11018
|
+
if (optimization.type === "merge_operations") {
|
|
11019
|
+
const searchOps = operations.filter((op) => op.tools.includes("search"));
|
|
11020
|
+
const analyzeOps = operations.filter((op) => op.tools.includes("code_context"));
|
|
11021
|
+
if (searchOps.length > 0 && analyzeOps.length > 0) {
|
|
11022
|
+
const mergedOp = {
|
|
11023
|
+
...searchOps[0],
|
|
11024
|
+
tools: [.../* @__PURE__ */ new Set([...searchOps[0].tools, ...analyzeOps[0].tools])],
|
|
11025
|
+
operation: "search_and_analyze",
|
|
11026
|
+
estimatedEffort: searchOps[0].estimatedEffort + analyzeOps[0].estimatedEffort - 1
|
|
11027
|
+
};
|
|
11028
|
+
const searchIndex = operations.indexOf(searchOps[0]);
|
|
11029
|
+
const analyzeIndex = operations.indexOf(analyzeOps[0]);
|
|
11030
|
+
operations.splice(Math.max(searchIndex, analyzeIndex), 1);
|
|
11031
|
+
operations.splice(Math.min(searchIndex, analyzeIndex), 1, mergedOp);
|
|
11032
|
+
}
|
|
11033
|
+
}
|
|
11034
|
+
}
|
|
11035
|
+
return operations;
|
|
11036
|
+
}
|
|
11037
|
+
/**
|
|
11038
|
+
* Learn patterns from successful operations
|
|
11039
|
+
*/
|
|
11040
|
+
learnFromContext(context, analysis) {
|
|
11041
|
+
if (!context.learnedPatterns.has("intent_patterns")) {
|
|
11042
|
+
context.learnedPatterns.set("intent_patterns", /* @__PURE__ */ new Map());
|
|
11043
|
+
}
|
|
11044
|
+
const patterns = context.learnedPatterns.get("intent_patterns");
|
|
11045
|
+
patterns.set(analysis.intent, (patterns.get(analysis.intent) || 0) + 1);
|
|
11046
|
+
if (context.previousOperations.length > 1) {
|
|
11047
|
+
const sequence = context.previousOperations.map((op) => op.operation);
|
|
11048
|
+
context.learnedPatterns.set("successful_sequences", sequence);
|
|
11049
|
+
}
|
|
11050
|
+
}
|
|
11051
|
+
};
|
|
11052
|
+
}
|
|
11053
|
+
});
|
|
11054
|
+
|
|
11055
|
+
// src/services/enhanced-error-handler.ts
|
|
11056
|
+
var EnhancedErrorHandler;
|
|
11057
|
+
var init_enhanced_error_handler = __esm({
|
|
11058
|
+
"src/services/enhanced-error-handler.ts"() {
|
|
11059
|
+
EnhancedErrorHandler = class {
|
|
11060
|
+
constructor() {
|
|
11061
|
+
this.errorPatterns = /* @__PURE__ */ new Map();
|
|
11062
|
+
this.recoveryStrategies = /* @__PURE__ */ new Map();
|
|
11063
|
+
this.errorHistory = /* @__PURE__ */ new Map();
|
|
11064
|
+
this.retryConfigs = /* @__PURE__ */ new Map();
|
|
11065
|
+
this.initializeErrorPatterns();
|
|
11066
|
+
this.initializeRecoveryStrategies();
|
|
11067
|
+
this.initializeRetryConfigurations();
|
|
11068
|
+
}
|
|
11069
|
+
/**
|
|
11070
|
+
* Analyze an error and provide comprehensive handling information
|
|
11071
|
+
*/
|
|
11072
|
+
async analyzeError(error, context = {}) {
|
|
11073
|
+
console.log(`\u{1F50D} Analyzing error: ${error.message}`);
|
|
11074
|
+
const classification = this.classifyError(error, context);
|
|
11075
|
+
const rootCause = await this.identifyRootCause(error, classification, context);
|
|
11076
|
+
const recoveryStrategies = this.generateRecoveryStrategies(classification, context);
|
|
11077
|
+
const userExplanation = this.generateUserExplanation(error, classification, rootCause);
|
|
11078
|
+
const suggestedActions = this.generateSuggestedActions(classification, recoveryStrategies);
|
|
11079
|
+
const preventionTips = this.generatePreventionTips(classification);
|
|
11080
|
+
const analysis = {
|
|
11081
|
+
originalError: error,
|
|
11082
|
+
classification,
|
|
11083
|
+
rootCause,
|
|
11084
|
+
context,
|
|
11085
|
+
recoveryStrategies,
|
|
11086
|
+
userExplanation,
|
|
11087
|
+
suggestedActions,
|
|
11088
|
+
preventionTips
|
|
11089
|
+
};
|
|
11090
|
+
this.storeErrorAnalysis(analysis);
|
|
11091
|
+
return analysis;
|
|
11092
|
+
}
|
|
11093
|
+
/**
|
|
11094
|
+
* Attempt automatic error recovery
|
|
11095
|
+
*/
|
|
11096
|
+
async attemptRecovery(errorAnalysis, context = {}) {
|
|
11097
|
+
const automaticStrategies = errorAnalysis.recoveryStrategies.filter((strategy) => strategy.type === "automatic").sort((a, b) => b.successRate - a.successRate);
|
|
11098
|
+
for (const strategy of automaticStrategies) {
|
|
11099
|
+
try {
|
|
11100
|
+
console.log(`\u{1F527} Attempting recovery strategy: ${strategy.name}`);
|
|
11101
|
+
const result = await this.executeRecoveryStrategy(strategy, errorAnalysis, context);
|
|
11102
|
+
if (result.success) {
|
|
11103
|
+
return {
|
|
11104
|
+
success: true,
|
|
11105
|
+
strategy,
|
|
11106
|
+
result: result.output,
|
|
11107
|
+
explanation: `Successfully recovered using: ${strategy.name}`
|
|
11108
|
+
};
|
|
11109
|
+
}
|
|
11110
|
+
} catch (recoveryError) {
|
|
11111
|
+
console.warn(`Recovery strategy ${strategy.name} failed:`, recoveryError);
|
|
11112
|
+
}
|
|
11113
|
+
}
|
|
11114
|
+
return {
|
|
11115
|
+
success: false,
|
|
11116
|
+
explanation: "No automatic recovery strategy succeeded. Manual intervention required."
|
|
11117
|
+
};
|
|
11118
|
+
}
|
|
11119
|
+
/**
|
|
11120
|
+
* Execute retry with intelligent backoff
|
|
11121
|
+
*/
|
|
11122
|
+
async executeWithRetry(operation, operationName, customConfig) {
|
|
11123
|
+
const config2 = { ...this.retryConfigs.get("default"), ...customConfig };
|
|
11124
|
+
let lastError = null;
|
|
11125
|
+
let attempt = 0;
|
|
11126
|
+
while (attempt < config2.maxAttempts) {
|
|
11127
|
+
attempt++;
|
|
11128
|
+
try {
|
|
11129
|
+
console.log(`\u{1F504} Attempt ${attempt}/${config2.maxAttempts} for ${operationName}`);
|
|
11130
|
+
const result = await operation();
|
|
11131
|
+
return { success: true, result, attempts: attempt };
|
|
11132
|
+
} catch (error) {
|
|
11133
|
+
lastError = error;
|
|
11134
|
+
console.warn(`Attempt ${attempt} failed:`, error);
|
|
11135
|
+
if (!this.isRetryableError(lastError, config2.retryableErrors)) {
|
|
11136
|
+
break;
|
|
11137
|
+
}
|
|
11138
|
+
if (attempt < config2.maxAttempts) {
|
|
11139
|
+
const delay = this.calculateBackoffDelay(config2, attempt);
|
|
11140
|
+
console.log(`\u23F3 Waiting ${delay}ms before retry...`);
|
|
11141
|
+
await this.delay(delay);
|
|
11142
|
+
}
|
|
11143
|
+
}
|
|
11144
|
+
}
|
|
11145
|
+
return { success: false, error: lastError, attempts: attempt };
|
|
11146
|
+
}
|
|
11147
|
+
/**
|
|
11148
|
+
* Classify error based on patterns and context
|
|
11149
|
+
*/
|
|
11150
|
+
classifyError(error, context) {
|
|
11151
|
+
const errorMessage = error.message.toLowerCase();
|
|
11152
|
+
const errorStack = error.stack?.toLowerCase() || "";
|
|
11153
|
+
for (const [pattern, classification] of this.errorPatterns) {
|
|
11154
|
+
if (pattern.test(errorMessage) || pattern.test(errorStack)) {
|
|
11155
|
+
return {
|
|
11156
|
+
...classification,
|
|
11157
|
+
confidence: this.calculatePatternConfidence(pattern, errorMessage)
|
|
11158
|
+
};
|
|
11159
|
+
}
|
|
11160
|
+
}
|
|
11161
|
+
return this.fallbackClassification(error, context);
|
|
11162
|
+
}
|
|
11163
|
+
/**
|
|
11164
|
+
* Identify the root cause of an error
|
|
11165
|
+
*/
|
|
11166
|
+
async identifyRootCause(error, classification, context) {
|
|
11167
|
+
const message = error.message.toLowerCase();
|
|
11168
|
+
switch (classification.type) {
|
|
11169
|
+
case "syntax":
|
|
11170
|
+
if (message.includes("unexpected token") || message.includes("syntax error")) {
|
|
11171
|
+
return "Invalid syntax in code file";
|
|
11172
|
+
}
|
|
11173
|
+
if (message.includes("cannot find module") || message.includes("module not found")) {
|
|
11174
|
+
return "Missing or incorrect module import";
|
|
11175
|
+
}
|
|
11176
|
+
break;
|
|
11177
|
+
case "dependency":
|
|
11178
|
+
if (message.includes("cannot resolve dependency")) {
|
|
11179
|
+
return "Unresolved package dependency";
|
|
11180
|
+
}
|
|
11181
|
+
if (message.includes("version conflict") || message.includes("incompatible")) {
|
|
11182
|
+
return "Package version incompatibility";
|
|
11183
|
+
}
|
|
11184
|
+
break;
|
|
11185
|
+
case "permission":
|
|
11186
|
+
if (message.includes("permission denied") || message.includes("access denied")) {
|
|
11187
|
+
return "Insufficient file system permissions";
|
|
11188
|
+
}
|
|
11189
|
+
break;
|
|
11190
|
+
case "network":
|
|
11191
|
+
if (message.includes("timeout") || message.includes("connection refused")) {
|
|
11192
|
+
return "Network connectivity issue";
|
|
11193
|
+
}
|
|
11194
|
+
break;
|
|
11195
|
+
}
|
|
11196
|
+
return `Unspecified ${classification.type} error`;
|
|
11197
|
+
}
|
|
11198
|
+
/**
|
|
11199
|
+
* Generate recovery strategies for an error
|
|
11200
|
+
*/
|
|
11201
|
+
generateRecoveryStrategies(classification, context) {
|
|
11202
|
+
const strategies = this.recoveryStrategies.get(classification.category) || [];
|
|
11203
|
+
return strategies.filter((strategy) => {
|
|
11204
|
+
return strategy.prerequisites.every((prereq) => {
|
|
11205
|
+
switch (prereq) {
|
|
11206
|
+
case "git_available":
|
|
11207
|
+
return context.hasGit !== false;
|
|
11208
|
+
case "package_manager_available":
|
|
11209
|
+
return context.hasPackageManager !== false;
|
|
11210
|
+
case "write_permissions":
|
|
11211
|
+
return context.hasWritePermissions !== false;
|
|
11212
|
+
default:
|
|
11213
|
+
return true;
|
|
11214
|
+
}
|
|
11215
|
+
});
|
|
11216
|
+
});
|
|
11217
|
+
}
|
|
11218
|
+
/**
|
|
11219
|
+
* Generate user-friendly explanation
|
|
11220
|
+
*/
|
|
11221
|
+
generateUserExplanation(error, classification, rootCause) {
|
|
11222
|
+
let explanation = `**${classification.severity.toUpperCase()} ${classification.type.toUpperCase()} ERROR**
|
|
11223
|
+
|
|
11224
|
+
`;
|
|
11225
|
+
explanation += `**What happened:** ${error.message}
|
|
11226
|
+
|
|
11227
|
+
`;
|
|
11228
|
+
explanation += `**Root cause:** ${rootCause}
|
|
11229
|
+
|
|
11230
|
+
`;
|
|
11231
|
+
switch (classification.type) {
|
|
11232
|
+
case "syntax":
|
|
11233
|
+
explanation += `**What to check:**
|
|
11234
|
+
`;
|
|
11235
|
+
explanation += `- Verify code syntax and formatting
|
|
11236
|
+
`;
|
|
11237
|
+
explanation += `- Check for missing semicolons, brackets, or quotes
|
|
11238
|
+
`;
|
|
11239
|
+
explanation += `- Ensure all imports are correct
|
|
11240
|
+
`;
|
|
11241
|
+
break;
|
|
11242
|
+
case "dependency":
|
|
11243
|
+
explanation += `**What to check:**
|
|
11244
|
+
`;
|
|
11245
|
+
explanation += `- Verify package.json dependencies
|
|
11246
|
+
`;
|
|
11247
|
+
explanation += `- Check if packages are installed: \`npm install\` or \`yarn install\`
|
|
11248
|
+
`;
|
|
11249
|
+
explanation += `- Update packages if needed: \`npm update\`
|
|
11250
|
+
`;
|
|
11251
|
+
break;
|
|
11252
|
+
case "permission":
|
|
11253
|
+
explanation += `**What to check:**
|
|
11254
|
+
`;
|
|
11255
|
+
explanation += `- Verify file permissions
|
|
11256
|
+
`;
|
|
11257
|
+
explanation += `- Check if files are read-only
|
|
11258
|
+
`;
|
|
11259
|
+
explanation += `- Ensure write access to target directory
|
|
11260
|
+
`;
|
|
11261
|
+
break;
|
|
11262
|
+
}
|
|
11263
|
+
return explanation;
|
|
11264
|
+
}
|
|
11265
|
+
/**
|
|
11266
|
+
* Generate suggested immediate actions
|
|
11267
|
+
*/
|
|
11268
|
+
generateSuggestedActions(classification, recoveryStrategies) {
|
|
11269
|
+
const actions = [];
|
|
11270
|
+
const autoStrategies = recoveryStrategies.filter((s) => s.type === "automatic");
|
|
11271
|
+
if (autoStrategies.length > 0) {
|
|
11272
|
+
actions.push(`\u{1F527} Try automatic recovery: ${autoStrategies[0].name}`);
|
|
11273
|
+
}
|
|
11274
|
+
const manualStrategies = recoveryStrategies.filter((s) => s.type === "manual");
|
|
11275
|
+
if (manualStrategies.length > 0) {
|
|
11276
|
+
actions.push(`\u{1F4CB} Manual recovery options available (${manualStrategies.length})`);
|
|
11277
|
+
}
|
|
11278
|
+
switch (classification.type) {
|
|
11279
|
+
case "syntax":
|
|
11280
|
+
actions.push("\u{1F50D} Check recent code changes for syntax errors");
|
|
11281
|
+
actions.push("\u{1F9EA} Run linter: `npm run lint` or similar");
|
|
11282
|
+
break;
|
|
11283
|
+
case "dependency":
|
|
11284
|
+
actions.push("\u{1F4E6} Check package versions: `npm ls`");
|
|
11285
|
+
actions.push("\u{1F504} Clear cache and reinstall: `rm -rf node_modules && npm install`");
|
|
11286
|
+
break;
|
|
11287
|
+
case "runtime":
|
|
11288
|
+
actions.push("\u{1F41B} Add debugging logs to identify issue location");
|
|
11289
|
+
actions.push("\u{1F9EA} Write unit test to reproduce the error");
|
|
11290
|
+
break;
|
|
11291
|
+
}
|
|
11292
|
+
return actions;
|
|
11293
|
+
}
|
|
11294
|
+
/**
|
|
11295
|
+
* Generate prevention tips
|
|
11296
|
+
*/
|
|
11297
|
+
generatePreventionTips(classification) {
|
|
11298
|
+
const tips = [];
|
|
11299
|
+
switch (classification.type) {
|
|
11300
|
+
case "syntax":
|
|
11301
|
+
tips.push("Use a linter (ESLint, Prettier) to catch syntax errors early");
|
|
11302
|
+
tips.push("Enable syntax checking in your IDE");
|
|
11303
|
+
tips.push("Write tests to validate code changes");
|
|
11304
|
+
break;
|
|
11305
|
+
case "dependency":
|
|
11306
|
+
tips.push("Keep dependencies updated regularly");
|
|
11307
|
+
tips.push("Use exact versions in package.json to avoid conflicts");
|
|
11308
|
+
tips.push("Test dependency updates in isolation");
|
|
11309
|
+
break;
|
|
11310
|
+
case "runtime":
|
|
11311
|
+
tips.push("Add comprehensive error handling");
|
|
11312
|
+
tips.push("Write unit and integration tests");
|
|
11313
|
+
tips.push("Use type checking (TypeScript) to catch errors early");
|
|
11314
|
+
break;
|
|
11315
|
+
case "permission":
|
|
11316
|
+
tips.push("Avoid running as root unless necessary");
|
|
11317
|
+
tips.push("Check file permissions before operations");
|
|
11318
|
+
tips.push("Use proper user accounts for different services");
|
|
11319
|
+
break;
|
|
11320
|
+
}
|
|
11321
|
+
return tips;
|
|
11322
|
+
}
|
|
11323
|
+
/**
|
|
11324
|
+
* Initialize error classification patterns
|
|
11325
|
+
*/
|
|
11326
|
+
initializeErrorPatterns() {
|
|
11327
|
+
this.errorPatterns.set(/syntax error|unexpected token|parsing error/i, {
|
|
11328
|
+
type: "syntax",
|
|
11329
|
+
severity: "high",
|
|
11330
|
+
category: "code_quality",
|
|
11331
|
+
confidence: 0.9,
|
|
11332
|
+
recoverable: true
|
|
11333
|
+
});
|
|
11334
|
+
this.errorPatterns.set(/cannot find module|module not found|cannot resolve/i, {
|
|
11335
|
+
type: "dependency",
|
|
11336
|
+
severity: "medium",
|
|
11337
|
+
category: "dependencies",
|
|
11338
|
+
confidence: 0.95,
|
|
11339
|
+
recoverable: true
|
|
11340
|
+
});
|
|
11341
|
+
this.errorPatterns.set(/permission denied|access denied|eacces/i, {
|
|
11342
|
+
type: "permission",
|
|
11343
|
+
severity: "high",
|
|
11344
|
+
category: "filesystem",
|
|
11345
|
+
confidence: 0.9,
|
|
11346
|
+
recoverable: false
|
|
11347
|
+
});
|
|
11348
|
+
this.errorPatterns.set(/timeout|connection refused|network error/i, {
|
|
11349
|
+
type: "network",
|
|
11350
|
+
severity: "medium",
|
|
11351
|
+
category: "connectivity",
|
|
11352
|
+
confidence: 0.8,
|
|
11353
|
+
recoverable: true
|
|
11354
|
+
});
|
|
11355
|
+
this.errorPatterns.set(/type error|reference error|null pointer|undefined/i, {
|
|
11356
|
+
type: "runtime",
|
|
11357
|
+
severity: "high",
|
|
11358
|
+
category: "logic",
|
|
11359
|
+
confidence: 0.7,
|
|
11360
|
+
recoverable: true
|
|
11361
|
+
});
|
|
11362
|
+
}
|
|
11363
|
+
/**
|
|
11364
|
+
* Initialize recovery strategies
|
|
11365
|
+
*/
|
|
11366
|
+
initializeRecoveryStrategies() {
|
|
11367
|
+
this.recoveryStrategies.set("code_quality", [
|
|
11368
|
+
{
|
|
11369
|
+
id: "syntax_check",
|
|
11370
|
+
name: "Run Syntax Validation",
|
|
11371
|
+
description: "Automatically check and fix common syntax issues",
|
|
11372
|
+
type: "automatic",
|
|
11373
|
+
estimatedEffort: 1,
|
|
11374
|
+
successRate: 0.7,
|
|
11375
|
+
prerequisites: ["package_manager_available"],
|
|
11376
|
+
steps: [
|
|
11377
|
+
{
|
|
11378
|
+
id: "run_linter",
|
|
11379
|
+
description: "Execute code linter to identify issues",
|
|
11380
|
+
action: "run_terminal_cmd",
|
|
11381
|
+
parameters: { command: "npm run lint" },
|
|
11382
|
+
timeout: 3e4,
|
|
11383
|
+
rollbackOnFailure: false
|
|
11384
|
+
}
|
|
11385
|
+
]
|
|
11386
|
+
},
|
|
11387
|
+
{
|
|
11388
|
+
id: "format_code",
|
|
11389
|
+
name: "Auto-format Code",
|
|
11390
|
+
description: "Automatically format code to fix indentation and spacing issues",
|
|
11391
|
+
type: "automatic",
|
|
11392
|
+
estimatedEffort: 1,
|
|
11393
|
+
successRate: 0.8,
|
|
11394
|
+
prerequisites: ["package_manager_available"],
|
|
11395
|
+
steps: [
|
|
11396
|
+
{
|
|
11397
|
+
id: "run_formatter",
|
|
11398
|
+
description: "Execute code formatter",
|
|
11399
|
+
action: "run_terminal_cmd",
|
|
11400
|
+
parameters: { command: "npm run format" },
|
|
11401
|
+
timeout: 3e4,
|
|
11402
|
+
rollbackOnFailure: false
|
|
11403
|
+
}
|
|
11404
|
+
]
|
|
11405
|
+
}
|
|
11406
|
+
]);
|
|
11407
|
+
this.recoveryStrategies.set("dependencies", [
|
|
11408
|
+
{
|
|
11409
|
+
id: "install_deps",
|
|
11410
|
+
name: "Install Missing Dependencies",
|
|
11411
|
+
description: "Automatically install missing packages",
|
|
11412
|
+
type: "automatic",
|
|
11413
|
+
estimatedEffort: 2,
|
|
11414
|
+
successRate: 0.9,
|
|
11415
|
+
prerequisites: ["package_manager_available"],
|
|
11416
|
+
steps: [
|
|
11417
|
+
{
|
|
11418
|
+
id: "npm_install",
|
|
11419
|
+
description: "Install npm dependencies",
|
|
11420
|
+
action: "run_terminal_cmd",
|
|
11421
|
+
parameters: { command: "npm install" },
|
|
11422
|
+
timeout: 12e4,
|
|
11423
|
+
rollbackOnFailure: false
|
|
11424
|
+
}
|
|
11425
|
+
]
|
|
11426
|
+
},
|
|
11427
|
+
{
|
|
11428
|
+
id: "clear_cache",
|
|
11429
|
+
name: "Clear Package Cache",
|
|
11430
|
+
description: "Clear package manager cache and reinstall",
|
|
11431
|
+
type: "semi-automatic",
|
|
11432
|
+
estimatedEffort: 3,
|
|
11433
|
+
successRate: 0.75,
|
|
11434
|
+
prerequisites: ["package_manager_available"],
|
|
11435
|
+
steps: [
|
|
11436
|
+
{
|
|
11437
|
+
id: "clear_npm_cache",
|
|
11438
|
+
description: "Clear npm cache",
|
|
11439
|
+
action: "run_terminal_cmd",
|
|
11440
|
+
parameters: { command: "npm cache clean --force" },
|
|
11441
|
+
timeout: 3e4,
|
|
11442
|
+
rollbackOnFailure: false
|
|
11443
|
+
},
|
|
11444
|
+
{
|
|
11445
|
+
id: "reinstall_deps",
|
|
11446
|
+
description: "Reinstall all dependencies",
|
|
11447
|
+
action: "run_terminal_cmd",
|
|
11448
|
+
parameters: { command: "rm -rf node_modules package-lock.json && npm install" },
|
|
11449
|
+
timeout: 18e4,
|
|
11450
|
+
rollbackOnFailure: false
|
|
11451
|
+
}
|
|
11452
|
+
]
|
|
11453
|
+
}
|
|
11454
|
+
]);
|
|
11455
|
+
this.recoveryStrategies.set("filesystem", [
|
|
11456
|
+
{
|
|
11457
|
+
id: "fix_permissions",
|
|
11458
|
+
name: "Fix File Permissions",
|
|
11459
|
+
description: "Automatically fix common file permission issues",
|
|
11460
|
+
type: "automatic",
|
|
11461
|
+
estimatedEffort: 1,
|
|
11462
|
+
successRate: 0.6,
|
|
11463
|
+
prerequisites: ["write_permissions"],
|
|
11464
|
+
steps: [
|
|
11465
|
+
{
|
|
11466
|
+
id: "chmod_files",
|
|
11467
|
+
description: "Set proper permissions on files",
|
|
11468
|
+
action: "run_terminal_cmd",
|
|
11469
|
+
parameters: { command: "chmod -R u+w ." },
|
|
11470
|
+
timeout: 3e4,
|
|
11471
|
+
rollbackOnFailure: false
|
|
11472
|
+
}
|
|
11473
|
+
]
|
|
11474
|
+
}
|
|
11475
|
+
]);
|
|
11476
|
+
}
|
|
11477
|
+
/**
|
|
11478
|
+
* Initialize retry configurations
|
|
11479
|
+
*/
|
|
11480
|
+
initializeRetryConfigurations() {
|
|
11481
|
+
this.retryConfigs.set("default", {
|
|
11482
|
+
maxAttempts: 3,
|
|
11483
|
+
backoffStrategy: "exponential",
|
|
11484
|
+
baseDelay: 1e3,
|
|
11485
|
+
maxDelay: 3e4,
|
|
11486
|
+
jitter: true,
|
|
11487
|
+
retryableErrors: ["timeout", "network", "temporary"]
|
|
11488
|
+
});
|
|
11489
|
+
this.retryConfigs.set("aggressive", {
|
|
11490
|
+
maxAttempts: 5,
|
|
11491
|
+
backoffStrategy: "linear",
|
|
11492
|
+
baseDelay: 500,
|
|
11493
|
+
maxDelay: 1e4,
|
|
11494
|
+
jitter: false,
|
|
11495
|
+
retryableErrors: ["timeout", "network"]
|
|
11496
|
+
});
|
|
11497
|
+
this.retryConfigs.set("conservative", {
|
|
11498
|
+
maxAttempts: 2,
|
|
11499
|
+
backoffStrategy: "fixed",
|
|
11500
|
+
baseDelay: 5e3,
|
|
11501
|
+
maxDelay: 5e3,
|
|
11502
|
+
jitter: false,
|
|
11503
|
+
retryableErrors: ["network"]
|
|
11504
|
+
});
|
|
11505
|
+
}
|
|
11506
|
+
/**
|
|
11507
|
+
* Execute a recovery strategy
|
|
11508
|
+
*/
|
|
11509
|
+
async executeRecoveryStrategy(strategy, errorAnalysis, context) {
|
|
11510
|
+
console.log(`Executing recovery strategy: ${strategy.name}`);
|
|
11511
|
+
for (const step of strategy.steps) {
|
|
11512
|
+
try {
|
|
11513
|
+
console.log(`Step: ${step.description}`);
|
|
11514
|
+
switch (step.action) {
|
|
11515
|
+
case "run_terminal_cmd":
|
|
11516
|
+
const command = step.parameters.command;
|
|
11517
|
+
if (command.includes("npm install")) {
|
|
11518
|
+
await this.delay(2e3);
|
|
11519
|
+
return { success: true, output: "Dependencies installed successfully" };
|
|
11520
|
+
}
|
|
11521
|
+
if (command.includes("lint") || command.includes("format")) {
|
|
11522
|
+
await this.delay(1e3);
|
|
11523
|
+
return { success: true, output: "Code validated/formatted successfully" };
|
|
11524
|
+
}
|
|
11525
|
+
break;
|
|
11526
|
+
default:
|
|
11527
|
+
console.warn(`Unknown recovery action: ${step.action}`);
|
|
11528
|
+
}
|
|
11529
|
+
} catch (stepError) {
|
|
11530
|
+
console.error(`Recovery step failed: ${step.description}`, stepError);
|
|
11531
|
+
if (step.rollbackOnFailure) ;
|
|
11532
|
+
return { success: false };
|
|
11533
|
+
}
|
|
11534
|
+
}
|
|
11535
|
+
return { success: true };
|
|
11536
|
+
}
|
|
11537
|
+
/**
|
|
11538
|
+
* Calculate pattern confidence score
|
|
11539
|
+
*/
|
|
11540
|
+
calculatePatternConfidence(pattern, text) {
|
|
11541
|
+
const matches = text.match(pattern);
|
|
11542
|
+
if (!matches) return 0;
|
|
11543
|
+
const matchLength = matches[0].length;
|
|
11544
|
+
const textLength = text.length;
|
|
11545
|
+
const exactMatch = matches[0].toLowerCase() === text.toLowerCase();
|
|
11546
|
+
let confidence = matchLength / textLength;
|
|
11547
|
+
if (exactMatch) confidence += 0.3;
|
|
11548
|
+
return Math.min(1, confidence);
|
|
11549
|
+
}
|
|
11550
|
+
/**
|
|
11551
|
+
* Fallback error classification
|
|
11552
|
+
*/
|
|
11553
|
+
fallbackClassification(error, context) {
|
|
11554
|
+
const message = error.message.toLowerCase();
|
|
11555
|
+
if (message.includes("cannot") || message.includes("failed") || message.includes("error")) {
|
|
11556
|
+
return {
|
|
11557
|
+
type: "runtime",
|
|
11558
|
+
severity: "medium",
|
|
11559
|
+
category: "execution",
|
|
11560
|
+
confidence: 0.5,
|
|
11561
|
+
recoverable: true
|
|
11562
|
+
};
|
|
11563
|
+
}
|
|
11564
|
+
return {
|
|
11565
|
+
type: "unknown",
|
|
11566
|
+
severity: "medium",
|
|
11567
|
+
category: "general",
|
|
11568
|
+
confidence: 0.1,
|
|
11569
|
+
recoverable: false
|
|
11570
|
+
};
|
|
11571
|
+
}
|
|
11572
|
+
/**
|
|
11573
|
+
* Calculate backoff delay for retries
|
|
11574
|
+
*/
|
|
11575
|
+
calculateBackoffDelay(config2, attempt) {
|
|
11576
|
+
let delay;
|
|
11577
|
+
switch (config2.backoffStrategy) {
|
|
11578
|
+
case "linear":
|
|
11579
|
+
delay = config2.baseDelay * attempt;
|
|
11580
|
+
break;
|
|
11581
|
+
case "exponential":
|
|
11582
|
+
delay = config2.baseDelay * Math.pow(2, attempt - 1);
|
|
11583
|
+
break;
|
|
11584
|
+
case "fixed":
|
|
11585
|
+
default:
|
|
11586
|
+
delay = config2.baseDelay;
|
|
11587
|
+
break;
|
|
11588
|
+
}
|
|
11589
|
+
delay = Math.min(delay, config2.maxDelay);
|
|
11590
|
+
if (config2.jitter) {
|
|
11591
|
+
delay = delay * (0.5 + Math.random() * 0.5);
|
|
11592
|
+
}
|
|
11593
|
+
return Math.floor(delay);
|
|
11594
|
+
}
|
|
11595
|
+
/**
|
|
11596
|
+
* Check if an error is retryable
|
|
11597
|
+
*/
|
|
11598
|
+
isRetryableError(error, retryablePatterns) {
|
|
11599
|
+
const message = error.message.toLowerCase();
|
|
11600
|
+
return retryablePatterns.some(
|
|
11601
|
+
(pattern) => message.includes(pattern.toLowerCase())
|
|
11602
|
+
);
|
|
11603
|
+
}
|
|
11604
|
+
/**
|
|
11605
|
+
* Store error analysis for learning
|
|
11606
|
+
*/
|
|
11607
|
+
storeErrorAnalysis(analysis) {
|
|
11608
|
+
const key = `${analysis.classification.type}_${analysis.classification.category}`;
|
|
11609
|
+
if (!this.errorHistory.has(key)) {
|
|
11610
|
+
this.errorHistory.set(key, []);
|
|
11611
|
+
}
|
|
11612
|
+
const history = this.errorHistory.get(key);
|
|
11613
|
+
history.push(analysis);
|
|
11614
|
+
if (history.length > 100) {
|
|
11615
|
+
history.shift();
|
|
11616
|
+
}
|
|
11617
|
+
}
|
|
11618
|
+
/**
|
|
11619
|
+
* Utility delay function
|
|
11620
|
+
*/
|
|
11621
|
+
delay(ms) {
|
|
11622
|
+
return new Promise((resolve8) => setTimeout(resolve8, ms));
|
|
11623
|
+
}
|
|
11624
|
+
};
|
|
11625
|
+
}
|
|
11626
|
+
});
|
|
11627
|
+
var TransactionManager, AutonomousExecutor;
|
|
10547
11628
|
var init_autonomous_executor = __esm({
|
|
10548
11629
|
"src/services/autonomous-executor.ts"() {
|
|
10549
11630
|
init_vector_search_engine();
|
|
@@ -10552,6 +11633,123 @@ var init_autonomous_executor = __esm({
|
|
|
10552
11633
|
init_ast_parser();
|
|
10553
11634
|
init_symbol_search();
|
|
10554
11635
|
init_dependency_analyzer();
|
|
11636
|
+
init_semantic_planner();
|
|
11637
|
+
init_enhanced_error_handler();
|
|
11638
|
+
TransactionManager = class {
|
|
11639
|
+
constructor(backupDir = "/tmp/autonomous-backups") {
|
|
11640
|
+
this.transactions = /* @__PURE__ */ new Map();
|
|
11641
|
+
this.backupDir = backupDir;
|
|
11642
|
+
}
|
|
11643
|
+
/**
|
|
11644
|
+
* Start a new transaction
|
|
11645
|
+
*/
|
|
11646
|
+
async beginTransaction(transactionId) {
|
|
11647
|
+
const transaction = {
|
|
11648
|
+
id: transactionId,
|
|
11649
|
+
steps: [],
|
|
11650
|
+
status: "active",
|
|
11651
|
+
createdAt: Date.now()
|
|
11652
|
+
};
|
|
11653
|
+
this.transactions.set(transactionId, transaction);
|
|
11654
|
+
}
|
|
11655
|
+
/**
|
|
11656
|
+
* Add a file operation to the transaction
|
|
11657
|
+
*/
|
|
11658
|
+
async addFileOperation(transactionId, filePath, newContent, operation = "update") {
|
|
11659
|
+
const transaction = this.transactions.get(transactionId);
|
|
11660
|
+
if (!transaction || transaction.status !== "active") {
|
|
11661
|
+
throw new Error(`Transaction ${transactionId} not found or not active`);
|
|
11662
|
+
}
|
|
11663
|
+
let originalContent = "";
|
|
11664
|
+
try {
|
|
11665
|
+
if (operation !== "create") {
|
|
11666
|
+
originalContent = await fs6.readFile(filePath, "utf-8");
|
|
11667
|
+
}
|
|
11668
|
+
} catch (error) {
|
|
11669
|
+
if (operation === "update") {
|
|
11670
|
+
throw new Error(`Failed to read original content of ${filePath}: ${error}`);
|
|
11671
|
+
}
|
|
11672
|
+
}
|
|
11673
|
+
const fileTransaction = {
|
|
11674
|
+
filePath,
|
|
11675
|
+
originalContent,
|
|
11676
|
+
newContent,
|
|
11677
|
+
operation,
|
|
11678
|
+
timestamp: Date.now()
|
|
11679
|
+
};
|
|
11680
|
+
transaction.steps.push(fileTransaction);
|
|
11681
|
+
}
|
|
11682
|
+
/**
|
|
11683
|
+
* Commit the transaction (apply all changes)
|
|
11684
|
+
*/
|
|
11685
|
+
async commitTransaction(transactionId) {
|
|
11686
|
+
const transaction = this.transactions.get(transactionId);
|
|
11687
|
+
if (!transaction || transaction.status !== "active") {
|
|
11688
|
+
throw new Error(`Transaction ${transactionId} not found or not active`);
|
|
11689
|
+
}
|
|
11690
|
+
try {
|
|
11691
|
+
for (const step of transaction.steps) {
|
|
11692
|
+
await this.applyFileTransaction(step);
|
|
11693
|
+
}
|
|
11694
|
+
transaction.status = "committed";
|
|
11695
|
+
transaction.committedAt = Date.now();
|
|
11696
|
+
} catch (error) {
|
|
11697
|
+
await this.rollbackTransaction(transactionId);
|
|
11698
|
+
throw error;
|
|
11699
|
+
}
|
|
11700
|
+
}
|
|
11701
|
+
/**
|
|
11702
|
+
* Rollback the transaction (restore original state)
|
|
11703
|
+
*/
|
|
11704
|
+
async rollbackTransaction(transactionId) {
|
|
11705
|
+
const transaction = this.transactions.get(transactionId);
|
|
11706
|
+
if (!transaction) {
|
|
11707
|
+
throw new Error(`Transaction ${transactionId} not found`);
|
|
11708
|
+
}
|
|
11709
|
+
if (transaction.status === "committed") {
|
|
11710
|
+
for (const step of transaction.steps.reverse()) {
|
|
11711
|
+
await this.rollbackFileTransaction(step);
|
|
11712
|
+
}
|
|
11713
|
+
}
|
|
11714
|
+
transaction.status = "rolled_back";
|
|
11715
|
+
transaction.rolledBackAt = Date.now();
|
|
11716
|
+
}
|
|
11717
|
+
/**
|
|
11718
|
+
* Apply a single file transaction
|
|
11719
|
+
*/
|
|
11720
|
+
async applyFileTransaction(step) {
|
|
11721
|
+
const dir = path8.dirname(step.filePath);
|
|
11722
|
+
await fs6.mkdir(dir, { recursive: true });
|
|
11723
|
+
if (step.operation === "delete") {
|
|
11724
|
+
await fs6.unlink(step.filePath);
|
|
11725
|
+
} else {
|
|
11726
|
+
await fs6.writeFile(step.filePath, step.newContent, "utf-8");
|
|
11727
|
+
}
|
|
11728
|
+
}
|
|
11729
|
+
/**
|
|
11730
|
+
* Rollback a single file transaction
|
|
11731
|
+
*/
|
|
11732
|
+
async rollbackFileTransaction(step) {
|
|
11733
|
+
if (step.operation === "create") {
|
|
11734
|
+
try {
|
|
11735
|
+
await fs6.unlink(step.filePath);
|
|
11736
|
+
} catch {
|
|
11737
|
+
}
|
|
11738
|
+
} else if (step.operation === "update") {
|
|
11739
|
+
await fs6.writeFile(step.filePath, step.originalContent, "utf-8");
|
|
11740
|
+
} else if (step.operation === "delete") {
|
|
11741
|
+
const dir = path8.dirname(step.filePath);
|
|
11742
|
+
await fs6.mkdir(dir, { recursive: true });
|
|
11743
|
+
await fs6.writeFile(step.filePath, step.originalContent, "utf-8");
|
|
11744
|
+
}
|
|
11745
|
+
}
|
|
11746
|
+
/**
|
|
11747
|
+
* Get transaction status
|
|
11748
|
+
*/
|
|
11749
|
+
getTransaction(transactionId) {
|
|
11750
|
+
return this.transactions.get(transactionId);
|
|
11751
|
+
}
|
|
11752
|
+
};
|
|
10555
11753
|
AutonomousExecutor = class {
|
|
10556
11754
|
constructor(config2 = {}) {
|
|
10557
11755
|
this.activeTasks = /* @__PURE__ */ new Map();
|
|
@@ -10583,6 +11781,9 @@ var init_autonomous_executor = __esm({
|
|
|
10583
11781
|
this.astParser = new ASTParserTool();
|
|
10584
11782
|
this.symbolSearch = new SymbolSearchTool();
|
|
10585
11783
|
this.dependencyAnalyzer = new DependencyAnalyzerTool();
|
|
11784
|
+
this.transactionManager = new TransactionManager();
|
|
11785
|
+
this.semanticPlanner = new SemanticPlanner(this.vectorSearch);
|
|
11786
|
+
this.errorHandler = new EnhancedErrorHandler();
|
|
10586
11787
|
}
|
|
10587
11788
|
/**
|
|
10588
11789
|
* Plan and execute a complex task autonomously
|
|
@@ -10602,16 +11803,17 @@ var init_autonomous_executor = __esm({
|
|
|
10602
11803
|
console.log(`\u2699\uFE0F Step ${i + 1}/${plan.steps.length}: ${step.description}`);
|
|
10603
11804
|
step.status = "running";
|
|
10604
11805
|
plan.status = "executing";
|
|
10605
|
-
plan.progress = Math.round(i / plan.steps.length * 100);
|
|
10606
11806
|
const stepResult = await this.executeStep(step, context);
|
|
10607
11807
|
step.outputs = stepResult;
|
|
10608
11808
|
step.status = "completed";
|
|
10609
11809
|
step.duration = Date.now() - startTime;
|
|
10610
|
-
console.log(`\u2705 Step ${i + 1} completed`);
|
|
11810
|
+
console.log(`\u2705 Step ${i + 1} completed (${plan.progress}% complete)`);
|
|
10611
11811
|
} catch (error) {
|
|
10612
11812
|
step.status = "failed";
|
|
10613
|
-
|
|
11813
|
+
const stepError = error instanceof Error ? error : new Error(String(error));
|
|
11814
|
+
step.error = stepError.message;
|
|
10614
11815
|
console.error(`\u274C Step ${i + 1} failed:`, step.error);
|
|
11816
|
+
await this.updateTaskProgress(plan, context);
|
|
10615
11817
|
const recovered = await this.attemptRecovery(step, context);
|
|
10616
11818
|
if (!recovered) {
|
|
10617
11819
|
plan.status = "failed";
|
|
@@ -10655,15 +11857,32 @@ var init_autonomous_executor = __esm({
|
|
|
10655
11857
|
}
|
|
10656
11858
|
}
|
|
10657
11859
|
/**
|
|
10658
|
-
* Create an execution plan
|
|
11860
|
+
* Create an execution plan using semantic planning
|
|
10659
11861
|
*/
|
|
10660
11862
|
async createExecutionPlan(taskId, goal, description) {
|
|
10661
|
-
|
|
11863
|
+
console.log(`\u{1F4CB} Creating execution plan for: ${goal}`);
|
|
11864
|
+
const semanticContext = {
|
|
11865
|
+
userGoal: goal,
|
|
11866
|
+
projectContext: /* @__PURE__ */ new Map([
|
|
11867
|
+
["rootPath", this.config.rootPath],
|
|
11868
|
+
["description", description]
|
|
11869
|
+
]),
|
|
11870
|
+
previousOperations: [],
|
|
11871
|
+
learnedPatterns: /* @__PURE__ */ new Map()
|
|
11872
|
+
};
|
|
11873
|
+
const intentAnalysis = await this.semanticPlanner.parseIntent(goal, description, semanticContext);
|
|
11874
|
+
console.log(`\u{1F3AF} Detected intent: ${intentAnalysis.intent} (confidence: ${(intentAnalysis.confidence * 100).toFixed(1)}%)`);
|
|
11875
|
+
console.log(`\u{1F527} Suggested tools: ${intentAnalysis.suggestedTools.join(", ")}`);
|
|
11876
|
+
const operations = await this.semanticPlanner.mapToOperations(intentAnalysis, semanticContext);
|
|
11877
|
+
const steps = await this.semanticPlanner.operationsToSteps(operations, semanticContext);
|
|
10662
11878
|
const context = {
|
|
10663
11879
|
rootPath: this.config.rootPath,
|
|
10664
|
-
affectedFiles:
|
|
10665
|
-
relatedSymbols:
|
|
10666
|
-
dependencies: []
|
|
11880
|
+
affectedFiles: intentAnalysis.entities.get("affected_files") || [],
|
|
11881
|
+
relatedSymbols: intentAnalysis.entities.get("related_symbols") || [],
|
|
11882
|
+
dependencies: [],
|
|
11883
|
+
intent: intentAnalysis.intent,
|
|
11884
|
+
confidence: intentAnalysis.confidence,
|
|
11885
|
+
suggestedTools: intentAnalysis.suggestedTools
|
|
10667
11886
|
};
|
|
10668
11887
|
if (context.affectedFiles.length > 0) {
|
|
10669
11888
|
const depResult = await this.dependencyAnalyzer.execute({
|
|
@@ -10676,7 +11895,6 @@ var init_autonomous_executor = __esm({
|
|
|
10676
11895
|
context.dependencies = parsed.result?.dependencies?.map((d) => d.name) || [];
|
|
10677
11896
|
}
|
|
10678
11897
|
}
|
|
10679
|
-
const steps = await this.generateExecutionSteps(goal, description, context);
|
|
10680
11898
|
return {
|
|
10681
11899
|
id: taskId,
|
|
10682
11900
|
goal,
|
|
@@ -10689,144 +11907,247 @@ var init_autonomous_executor = __esm({
|
|
|
10689
11907
|
};
|
|
10690
11908
|
}
|
|
10691
11909
|
/**
|
|
10692
|
-
* Generate execution steps based on goal analysis
|
|
11910
|
+
* Generate execution steps based on advanced goal analysis and task decomposition
|
|
10693
11911
|
*/
|
|
10694
11912
|
async generateExecutionSteps(goal, description, context) {
|
|
10695
11913
|
const steps = [];
|
|
10696
|
-
|
|
10697
|
-
|
|
10698
|
-
|
|
10699
|
-
|
|
10700
|
-
|
|
10701
|
-
|
|
10702
|
-
|
|
10703
|
-
|
|
10704
|
-
|
|
10705
|
-
|
|
10706
|
-
|
|
10707
|
-
|
|
10708
|
-
|
|
10709
|
-
|
|
10710
|
-
|
|
10711
|
-
|
|
10712
|
-
|
|
10713
|
-
|
|
10714
|
-
|
|
10715
|
-
|
|
10716
|
-
|
|
10717
|
-
|
|
10718
|
-
|
|
10719
|
-
|
|
10720
|
-
|
|
10721
|
-
|
|
10722
|
-
|
|
10723
|
-
|
|
10724
|
-
|
|
10725
|
-
|
|
10726
|
-
);
|
|
10727
|
-
|
|
10728
|
-
|
|
10729
|
-
|
|
10730
|
-
|
|
10731
|
-
|
|
10732
|
-
|
|
10733
|
-
inputs: { query: goal },
|
|
10734
|
-
status: "pending"
|
|
10735
|
-
},
|
|
10736
|
-
{
|
|
10737
|
-
id: "identify_location",
|
|
10738
|
-
type: "analyze",
|
|
10739
|
-
description: "Identify optimal location for new implementation",
|
|
10740
|
-
inputs: { files: context.affectedFiles },
|
|
10741
|
-
status: "pending"
|
|
10742
|
-
},
|
|
10743
|
-
{
|
|
10744
|
-
id: "implement_feature",
|
|
10745
|
-
type: "edit",
|
|
10746
|
-
description: "Implement the new feature or functionality",
|
|
10747
|
-
inputs: {},
|
|
10748
|
-
status: "pending"
|
|
10749
|
-
},
|
|
10750
|
-
{
|
|
10751
|
-
id: "update_dependencies",
|
|
10752
|
-
type: "edit",
|
|
10753
|
-
description: "Update imports, exports, and dependencies",
|
|
10754
|
-
inputs: { dependencies: context.dependencies },
|
|
10755
|
-
status: "pending"
|
|
10756
|
-
},
|
|
10757
|
-
{
|
|
10758
|
-
id: "validate_implementation",
|
|
10759
|
-
type: "validate",
|
|
10760
|
-
description: "Validate implementation works correctly",
|
|
10761
|
-
inputs: {},
|
|
10762
|
-
status: "pending"
|
|
10763
|
-
}
|
|
10764
|
-
);
|
|
10765
|
-
} else if (goal.toLowerCase().includes("fix") || goal.toLowerCase().includes("bug")) {
|
|
10766
|
-
steps.push(
|
|
10767
|
-
{
|
|
10768
|
-
id: "locate_issue",
|
|
10769
|
-
type: "search",
|
|
10770
|
-
description: "Locate the source of the issue",
|
|
10771
|
-
inputs: { query: description },
|
|
10772
|
-
status: "pending"
|
|
10773
|
-
},
|
|
10774
|
-
{
|
|
10775
|
-
id: "analyze_impact",
|
|
10776
|
-
type: "analyze",
|
|
10777
|
-
description: "Analyze impact and related components",
|
|
10778
|
-
inputs: { files: context.affectedFiles },
|
|
10779
|
-
status: "pending"
|
|
10780
|
-
},
|
|
10781
|
-
{
|
|
10782
|
-
id: "apply_fix",
|
|
10783
|
-
type: "edit",
|
|
10784
|
-
description: "Apply fix to resolve the issue",
|
|
10785
|
-
inputs: {},
|
|
10786
|
-
status: "pending"
|
|
10787
|
-
},
|
|
10788
|
-
{
|
|
10789
|
-
id: "test_fix",
|
|
10790
|
-
type: "validate",
|
|
10791
|
-
description: "Test that fix resolves issue without side effects",
|
|
10792
|
-
inputs: {},
|
|
10793
|
-
status: "pending"
|
|
11914
|
+
const decomposedTasks = await this.decomposeGoal(goal, description, context);
|
|
11915
|
+
for (const subTask of decomposedTasks) {
|
|
11916
|
+
const taskSteps = await this.generateStepsForSubTask(subTask, context);
|
|
11917
|
+
steps.push(...taskSteps);
|
|
11918
|
+
}
|
|
11919
|
+
if (steps.length > 0) {
|
|
11920
|
+
steps.push({
|
|
11921
|
+
id: "final_validation",
|
|
11922
|
+
type: "validate",
|
|
11923
|
+
description: "Perform comprehensive validation of all changes",
|
|
11924
|
+
inputs: { allSteps: steps.map((s) => s.id) },
|
|
11925
|
+
status: "pending"
|
|
11926
|
+
});
|
|
11927
|
+
steps.push({
|
|
11928
|
+
id: "run_tests",
|
|
11929
|
+
type: "test",
|
|
11930
|
+
description: "Execute relevant tests to ensure functionality",
|
|
11931
|
+
inputs: { affectedFiles: context.affectedFiles },
|
|
11932
|
+
status: "pending"
|
|
11933
|
+
});
|
|
11934
|
+
}
|
|
11935
|
+
return steps;
|
|
11936
|
+
}
|
|
11937
|
+
/**
|
|
11938
|
+
* Decompose complex goals into manageable subtasks using AI planning
|
|
11939
|
+
*/
|
|
11940
|
+
async decomposeGoal(goal, description, context) {
|
|
11941
|
+
const subTasks = [];
|
|
11942
|
+
const goalAnalysis = await this.analyzeGoalComplexity(goal, description);
|
|
11943
|
+
if (goalAnalysis.complexity === "high") {
|
|
11944
|
+
const initialSubTasks = this.generateInitialSubTasks(goal, description, context);
|
|
11945
|
+
subTasks.push(...initialSubTasks);
|
|
11946
|
+
for (const subTask of subTasks) {
|
|
11947
|
+
const refinedSubTasks = await this.refineSubTask(subTask, context);
|
|
11948
|
+
if (refinedSubTasks.length > 1) {
|
|
11949
|
+
const index = subTasks.indexOf(subTask);
|
|
11950
|
+
subTasks.splice(index, 1, ...refinedSubTasks);
|
|
10794
11951
|
}
|
|
10795
|
-
|
|
11952
|
+
}
|
|
10796
11953
|
} else {
|
|
10797
|
-
|
|
10798
|
-
|
|
10799
|
-
|
|
10800
|
-
|
|
10801
|
-
|
|
10802
|
-
|
|
10803
|
-
|
|
10804
|
-
|
|
10805
|
-
|
|
10806
|
-
|
|
10807
|
-
|
|
10808
|
-
|
|
10809
|
-
|
|
10810
|
-
|
|
10811
|
-
|
|
10812
|
-
|
|
10813
|
-
|
|
10814
|
-
|
|
10815
|
-
|
|
10816
|
-
|
|
10817
|
-
|
|
10818
|
-
|
|
10819
|
-
|
|
10820
|
-
|
|
10821
|
-
|
|
10822
|
-
|
|
10823
|
-
|
|
10824
|
-
|
|
11954
|
+
subTasks.push({
|
|
11955
|
+
id: "main_task",
|
|
11956
|
+
description: goal,
|
|
11957
|
+
type: this.inferTaskType(goal),
|
|
11958
|
+
complexity: goalAnalysis.complexity,
|
|
11959
|
+
dependencies: [],
|
|
11960
|
+
estimatedEffort: goalAnalysis.estimatedSteps
|
|
11961
|
+
});
|
|
11962
|
+
}
|
|
11963
|
+
return subTasks;
|
|
11964
|
+
}
|
|
11965
|
+
/**
|
|
11966
|
+
* Analyze goal complexity to determine planning approach
|
|
11967
|
+
*/
|
|
11968
|
+
async analyzeGoalComplexity(goal, description) {
|
|
11969
|
+
const keywords = {
|
|
11970
|
+
high: ["refactor", "migrate", "redesign", "architect", "system", "framework"],
|
|
11971
|
+
low: ["fix", "update", "change", "modify", "improve", "optimize"]
|
|
11972
|
+
};
|
|
11973
|
+
const goal_lower = goal.toLowerCase();
|
|
11974
|
+
let complexity = "medium";
|
|
11975
|
+
let estimatedSteps = 3;
|
|
11976
|
+
if (keywords.high.some((k) => goal_lower.includes(k))) {
|
|
11977
|
+
complexity = "high";
|
|
11978
|
+
estimatedSteps = 8;
|
|
11979
|
+
} else if (keywords.low.some((k) => goal_lower.includes(k))) {
|
|
11980
|
+
complexity = "low";
|
|
11981
|
+
estimatedSteps = 2;
|
|
11982
|
+
}
|
|
11983
|
+
if (description.length < 50) {
|
|
11984
|
+
complexity = "low";
|
|
11985
|
+
estimatedSteps = Math.max(1, estimatedSteps - 1);
|
|
11986
|
+
} else if (description.length > 200) {
|
|
11987
|
+
complexity = "high";
|
|
11988
|
+
estimatedSteps = Math.min(15, estimatedSteps + 3);
|
|
11989
|
+
}
|
|
11990
|
+
return { complexity, estimatedSteps };
|
|
11991
|
+
}
|
|
11992
|
+
/**
|
|
11993
|
+
* Generate initial subtasks for complex goals
|
|
11994
|
+
*/
|
|
11995
|
+
generateInitialSubTasks(goal, description, context) {
|
|
11996
|
+
const subTasks = [];
|
|
11997
|
+
subTasks.push({
|
|
11998
|
+
id: "analysis",
|
|
11999
|
+
description: "Analyze current codebase and requirements",
|
|
12000
|
+
type: "analysis",
|
|
12001
|
+
complexity: "low",
|
|
12002
|
+
dependencies: [],
|
|
12003
|
+
estimatedEffort: 2
|
|
12004
|
+
});
|
|
12005
|
+
subTasks.push({
|
|
12006
|
+
id: "planning",
|
|
12007
|
+
description: "Create detailed implementation plan",
|
|
12008
|
+
type: "planning",
|
|
12009
|
+
complexity: "medium",
|
|
12010
|
+
dependencies: ["analysis"],
|
|
12011
|
+
estimatedEffort: 3
|
|
12012
|
+
});
|
|
12013
|
+
subTasks.push({
|
|
12014
|
+
id: "implementation",
|
|
12015
|
+
description: "Execute the planned changes",
|
|
12016
|
+
type: "implementation",
|
|
12017
|
+
complexity: "high",
|
|
12018
|
+
dependencies: ["planning"],
|
|
12019
|
+
estimatedEffort: 5
|
|
12020
|
+
});
|
|
12021
|
+
subTasks.push({
|
|
12022
|
+
id: "validation",
|
|
12023
|
+
description: "Validate implementation and test results",
|
|
12024
|
+
type: "validation",
|
|
12025
|
+
complexity: "medium",
|
|
12026
|
+
dependencies: ["implementation"],
|
|
12027
|
+
estimatedEffort: 2
|
|
12028
|
+
});
|
|
12029
|
+
return subTasks;
|
|
12030
|
+
}
|
|
12031
|
+
/**
|
|
12032
|
+
* Refine subtasks based on codebase context
|
|
12033
|
+
*/
|
|
12034
|
+
async refineSubTask(subTask, context) {
|
|
12035
|
+
if (subTask.type === "implementation") {
|
|
12036
|
+
const fileTasks = [];
|
|
12037
|
+
for (const file of context.affectedFiles.slice(0, 5)) {
|
|
12038
|
+
fileTasks.push({
|
|
12039
|
+
id: `implement_${file.replace(/[^a-zA-Z0-9]/g, "_")}`,
|
|
12040
|
+
description: `Implement changes in ${file}`,
|
|
12041
|
+
type: "implementation",
|
|
12042
|
+
complexity: "medium",
|
|
12043
|
+
dependencies: [subTask.id],
|
|
12044
|
+
estimatedEffort: 2,
|
|
12045
|
+
targetFile: file
|
|
12046
|
+
});
|
|
12047
|
+
}
|
|
12048
|
+
return fileTasks.length > 0 ? fileTasks : [subTask];
|
|
12049
|
+
}
|
|
12050
|
+
return [subTask];
|
|
12051
|
+
}
|
|
12052
|
+
/**
|
|
12053
|
+
* Generate execution steps for a specific subtask
|
|
12054
|
+
*/
|
|
12055
|
+
async generateStepsForSubTask(subTask, context) {
|
|
12056
|
+
const steps = [];
|
|
12057
|
+
switch (subTask.type) {
|
|
12058
|
+
case "analysis":
|
|
12059
|
+
steps.push(
|
|
12060
|
+
{
|
|
12061
|
+
id: `${subTask.id}_search`,
|
|
12062
|
+
type: "search",
|
|
12063
|
+
description: "Search for relevant code patterns and examples",
|
|
12064
|
+
inputs: { query: subTask.description },
|
|
12065
|
+
status: "pending"
|
|
12066
|
+
},
|
|
12067
|
+
{
|
|
12068
|
+
id: `${subTask.id}_analyze`,
|
|
12069
|
+
type: "analyze",
|
|
12070
|
+
description: "Analyze code structure and dependencies",
|
|
12071
|
+
inputs: { files: context.affectedFiles },
|
|
12072
|
+
status: "pending"
|
|
12073
|
+
}
|
|
12074
|
+
);
|
|
12075
|
+
break;
|
|
12076
|
+
case "planning":
|
|
12077
|
+
steps.push(
|
|
12078
|
+
{
|
|
12079
|
+
id: `${subTask.id}_design`,
|
|
12080
|
+
type: "analyze",
|
|
12081
|
+
description: "Design the implementation approach",
|
|
12082
|
+
inputs: { symbols: context.relatedSymbols },
|
|
12083
|
+
status: "pending"
|
|
12084
|
+
},
|
|
12085
|
+
{
|
|
12086
|
+
id: `${subTask.id}_dependencies`,
|
|
12087
|
+
type: "analyze",
|
|
12088
|
+
description: "Identify and plan dependency updates",
|
|
12089
|
+
inputs: { dependencies: context.dependencies },
|
|
12090
|
+
status: "pending"
|
|
12091
|
+
}
|
|
12092
|
+
);
|
|
12093
|
+
break;
|
|
12094
|
+
case "implementation":
|
|
12095
|
+
if (subTask.targetFile) {
|
|
12096
|
+
steps.push({
|
|
12097
|
+
id: `${subTask.id}_edit`,
|
|
12098
|
+
type: "edit",
|
|
12099
|
+
description: `Apply changes to ${subTask.targetFile}`,
|
|
12100
|
+
inputs: { file: subTask.targetFile, goal: subTask.description },
|
|
12101
|
+
status: "pending"
|
|
12102
|
+
});
|
|
12103
|
+
} else {
|
|
12104
|
+
steps.push({
|
|
12105
|
+
id: `${subTask.id}_edit`,
|
|
12106
|
+
type: "edit",
|
|
12107
|
+
description: "Apply implementation changes",
|
|
12108
|
+
inputs: { files: context.affectedFiles, goal: subTask.description },
|
|
12109
|
+
status: "pending"
|
|
12110
|
+
});
|
|
10825
12111
|
}
|
|
10826
|
-
|
|
12112
|
+
break;
|
|
12113
|
+
case "validation":
|
|
12114
|
+
steps.push(
|
|
12115
|
+
{
|
|
12116
|
+
id: `${subTask.id}_syntax`,
|
|
12117
|
+
type: "validate",
|
|
12118
|
+
description: "Check syntax and compilation",
|
|
12119
|
+
inputs: { files: context.affectedFiles },
|
|
12120
|
+
status: "pending"
|
|
12121
|
+
},
|
|
12122
|
+
{
|
|
12123
|
+
id: `${subTask.id}_logic`,
|
|
12124
|
+
type: "validate",
|
|
12125
|
+
description: "Validate logic and functionality",
|
|
12126
|
+
inputs: {},
|
|
12127
|
+
status: "pending"
|
|
12128
|
+
}
|
|
12129
|
+
);
|
|
12130
|
+
break;
|
|
10827
12131
|
}
|
|
10828
12132
|
return steps;
|
|
10829
12133
|
}
|
|
12134
|
+
/**
|
|
12135
|
+
* Infer task type from goal description
|
|
12136
|
+
*/
|
|
12137
|
+
inferTaskType(goal) {
|
|
12138
|
+
const goal_lower = goal.toLowerCase();
|
|
12139
|
+
if (goal_lower.includes("refactor") || goal_lower.includes("redesign")) {
|
|
12140
|
+
return "refactoring";
|
|
12141
|
+
} else if (goal_lower.includes("add") || goal_lower.includes("implement") || goal_lower.includes("create")) {
|
|
12142
|
+
return "implementation";
|
|
12143
|
+
} else if (goal_lower.includes("fix") || goal_lower.includes("bug") || goal_lower.includes("issue")) {
|
|
12144
|
+
return "bug_fix";
|
|
12145
|
+
} else if (goal_lower.includes("test") || goal_lower.includes("validate")) {
|
|
12146
|
+
return "testing";
|
|
12147
|
+
} else {
|
|
12148
|
+
return "general";
|
|
12149
|
+
}
|
|
12150
|
+
}
|
|
10830
12151
|
/**
|
|
10831
12152
|
* Initialize execution context with tools and state
|
|
10832
12153
|
*/
|
|
@@ -10840,7 +12161,11 @@ var init_autonomous_executor = __esm({
|
|
|
10840
12161
|
codebaseExplorer: this.codebaseExplorer,
|
|
10841
12162
|
currentFiles: /* @__PURE__ */ new Set(),
|
|
10842
12163
|
symbolCache: /* @__PURE__ */ new Map(),
|
|
10843
|
-
validationResults: /* @__PURE__ */ new Map()
|
|
12164
|
+
validationResults: /* @__PURE__ */ new Map(),
|
|
12165
|
+
stepMemory: /* @__PURE__ */ new Map(),
|
|
12166
|
+
fileSnapshots: /* @__PURE__ */ new Map(),
|
|
12167
|
+
dependencyGraph: /* @__PURE__ */ new Map(),
|
|
12168
|
+
learnedPatterns: /* @__PURE__ */ new Map()
|
|
10844
12169
|
};
|
|
10845
12170
|
}
|
|
10846
12171
|
/**
|
|
@@ -10896,11 +12221,52 @@ var init_autonomous_executor = __esm({
|
|
|
10896
12221
|
return { analyses: analysisResults, fileCount: files.length };
|
|
10897
12222
|
}
|
|
10898
12223
|
async executeEditStep(step, context) {
|
|
10899
|
-
|
|
10900
|
-
|
|
10901
|
-
|
|
10902
|
-
|
|
10903
|
-
|
|
12224
|
+
const transactionId = `txn_${step.id}_${Date.now()}`;
|
|
12225
|
+
try {
|
|
12226
|
+
await this.transactionManager.beginTransaction(transactionId);
|
|
12227
|
+
console.log(`\u{1F4DD} Edit step: ${step.description}`);
|
|
12228
|
+
let filesModified = [];
|
|
12229
|
+
if (step.inputs.file) {
|
|
12230
|
+
const filePath = step.inputs.file;
|
|
12231
|
+
const goal = step.inputs.goal || step.description;
|
|
12232
|
+
const newContent = await this.generateFileChanges(filePath, goal, context);
|
|
12233
|
+
await this.transactionManager.addFileOperation(transactionId, filePath, newContent, "update");
|
|
12234
|
+
filesModified.push(filePath);
|
|
12235
|
+
} else if (step.inputs.files) {
|
|
12236
|
+
const files = step.inputs.files;
|
|
12237
|
+
const goal = step.inputs.goal || step.description;
|
|
12238
|
+
for (const filePath of files) {
|
|
12239
|
+
try {
|
|
12240
|
+
const newContent = await this.generateFileChanges(filePath, goal, context);
|
|
12241
|
+
await this.transactionManager.addFileOperation(transactionId, filePath, newContent, "update");
|
|
12242
|
+
filesModified.push(filePath);
|
|
12243
|
+
} catch (error) {
|
|
12244
|
+
console.warn(`Failed to process ${filePath}:`, error);
|
|
12245
|
+
}
|
|
12246
|
+
}
|
|
12247
|
+
}
|
|
12248
|
+
context.stepMemory.set(step.id, { transactionId, filesModified });
|
|
12249
|
+
await this.transactionManager.commitTransaction(transactionId);
|
|
12250
|
+
for (const file of filesModified) {
|
|
12251
|
+
try {
|
|
12252
|
+
const content = await fs6.readFile(file, "utf-8");
|
|
12253
|
+
context.fileSnapshots.set(file, content);
|
|
12254
|
+
} catch {
|
|
12255
|
+
}
|
|
12256
|
+
}
|
|
12257
|
+
return {
|
|
12258
|
+
message: "Edit step executed successfully",
|
|
12259
|
+
filesModified,
|
|
12260
|
+
transactionId
|
|
12261
|
+
};
|
|
12262
|
+
} catch (error) {
|
|
12263
|
+
try {
|
|
12264
|
+
await this.transactionManager.rollbackTransaction(transactionId);
|
|
12265
|
+
} catch (rollbackError) {
|
|
12266
|
+
console.error("Failed to rollback transaction:", rollbackError);
|
|
12267
|
+
}
|
|
12268
|
+
throw new Error(`Edit step failed: ${error instanceof Error ? error.message : String(error)}`);
|
|
12269
|
+
}
|
|
10904
12270
|
}
|
|
10905
12271
|
async executeValidateStep(step, context) {
|
|
10906
12272
|
console.log(`\u2705 Validation step: ${step.description}`);
|
|
@@ -10921,12 +12287,28 @@ var init_autonomous_executor = __esm({
|
|
|
10921
12287
|
async attemptRecovery(step, context) {
|
|
10922
12288
|
console.log(`\u{1F504} Attempting recovery for failed step: ${step.description}`);
|
|
10923
12289
|
try {
|
|
12290
|
+
const stepMemory = context.stepMemory.get(step.id);
|
|
12291
|
+
if (stepMemory?.transactionId) {
|
|
12292
|
+
console.log(`\u{1F519} Rolling back transaction ${stepMemory.transactionId}`);
|
|
12293
|
+
await this.transactionManager.rollbackTransaction(stepMemory.transactionId);
|
|
12294
|
+
if (stepMemory.filesModified) {
|
|
12295
|
+
for (const file of stepMemory.filesModified) {
|
|
12296
|
+
context.fileSnapshots.delete(file);
|
|
12297
|
+
}
|
|
12298
|
+
}
|
|
12299
|
+
}
|
|
10924
12300
|
step.status = "running";
|
|
12301
|
+
step.inputs.retryAttempt = (step.inputs.retryAttempt || 0) + 1;
|
|
12302
|
+
step.inputs.previousError = step.error;
|
|
12303
|
+
step.inputs.recoveryAttempt = true;
|
|
10925
12304
|
await this.executeStep(step, context);
|
|
10926
12305
|
step.status = "completed";
|
|
12306
|
+
console.log(`\u2705 Recovery successful for step: ${step.description}`);
|
|
10927
12307
|
return true;
|
|
10928
|
-
} catch (
|
|
12308
|
+
} catch (retryError) {
|
|
12309
|
+
console.log(`\u274C Recovery failed for step: ${step.description}`);
|
|
10929
12310
|
step.status = "failed";
|
|
12311
|
+
step.error = `Recovery failed: ${retryError instanceof Error ? retryError.message : String(retryError)}`;
|
|
10930
12312
|
return false;
|
|
10931
12313
|
}
|
|
10932
12314
|
}
|
|
@@ -10961,32 +12343,673 @@ var init_autonomous_executor = __esm({
|
|
|
10961
12343
|
if (task) {
|
|
10962
12344
|
task.status = "failed";
|
|
10963
12345
|
task.endTime = Date.now();
|
|
12346
|
+
for (const step of task.steps) {
|
|
12347
|
+
if (step.status === "running" || step.status === "completed") ;
|
|
12348
|
+
}
|
|
10964
12349
|
this.executionHistory.push(task);
|
|
10965
12350
|
this.activeTasks.delete(taskId);
|
|
10966
12351
|
return true;
|
|
10967
12352
|
}
|
|
10968
12353
|
return false;
|
|
10969
12354
|
}
|
|
12355
|
+
/**
|
|
12356
|
+
* Save task state for persistence and recovery
|
|
12357
|
+
*/
|
|
12358
|
+
async saveTaskState(task) {
|
|
12359
|
+
try {
|
|
12360
|
+
const stateFile = path8.join(this.config.rootPath, ".autonomous", `task_${task.id}.json`);
|
|
12361
|
+
await fs6.mkdir(path8.dirname(stateFile), { recursive: true });
|
|
12362
|
+
const state = {
|
|
12363
|
+
task,
|
|
12364
|
+
timestamp: Date.now(),
|
|
12365
|
+
version: "1.0"
|
|
12366
|
+
};
|
|
12367
|
+
await fs6.writeFile(stateFile, JSON.stringify(state, null, 2), "utf-8");
|
|
12368
|
+
} catch (error) {
|
|
12369
|
+
console.warn("Failed to save task state:", error);
|
|
12370
|
+
}
|
|
12371
|
+
}
|
|
12372
|
+
/**
|
|
12373
|
+
* Load task state for recovery
|
|
12374
|
+
*/
|
|
12375
|
+
async loadTaskState(taskId) {
|
|
12376
|
+
try {
|
|
12377
|
+
const stateFile = path8.join(this.config.rootPath, ".autonomous", `task_${taskId}.json`);
|
|
12378
|
+
const content = await fs6.readFile(stateFile, "utf-8");
|
|
12379
|
+
const state = JSON.parse(content);
|
|
12380
|
+
return state.task;
|
|
12381
|
+
} catch {
|
|
12382
|
+
return null;
|
|
12383
|
+
}
|
|
12384
|
+
}
|
|
12385
|
+
/**
|
|
12386
|
+
* Update task progress with persistence
|
|
12387
|
+
*/
|
|
12388
|
+
async updateTaskProgress(task, context) {
|
|
12389
|
+
const totalSteps = task.steps.length;
|
|
12390
|
+
const completedSteps = task.steps.filter((s) => s.status === "completed").length;
|
|
12391
|
+
const runningSteps = task.steps.filter((s) => s.status === "running").length;
|
|
12392
|
+
task.progress = Math.round((completedSteps + runningSteps * 0.5) / totalSteps * 100);
|
|
12393
|
+
if (task.progress % 10 === 0 || task.status !== "executing") {
|
|
12394
|
+
await this.saveTaskState(task);
|
|
12395
|
+
}
|
|
12396
|
+
context.stepMemory.set("task_progress", {
|
|
12397
|
+
taskId: task.id,
|
|
12398
|
+
progress: task.progress,
|
|
12399
|
+
completedSteps,
|
|
12400
|
+
totalSteps,
|
|
12401
|
+
status: task.status,
|
|
12402
|
+
timestamp: Date.now()
|
|
12403
|
+
});
|
|
12404
|
+
}
|
|
12405
|
+
/**
|
|
12406
|
+
* Generate file changes based on goal and context using AI-powered analysis
|
|
12407
|
+
*/
|
|
12408
|
+
async generateFileChanges(filePath, goal, context) {
|
|
12409
|
+
console.log(`\u{1F916} Generating changes for: "${goal}" in ${filePath}`);
|
|
12410
|
+
let currentContent = "";
|
|
12411
|
+
try {
|
|
12412
|
+
currentContent = await fs6.readFile(filePath, "utf-8");
|
|
12413
|
+
} catch {
|
|
12414
|
+
currentContent = "";
|
|
12415
|
+
}
|
|
12416
|
+
const goalAnalysis = await this.analyzeGoalForChanges(goal, context);
|
|
12417
|
+
const fileStructure = await this.analyzeFileStructure(filePath, currentContent);
|
|
12418
|
+
const similarPatterns = await this.findSimilarPatterns(goal, context);
|
|
12419
|
+
const modifiedContent = await this.applyCodeTransformations(
|
|
12420
|
+
currentContent,
|
|
12421
|
+
fileStructure,
|
|
12422
|
+
goalAnalysis,
|
|
12423
|
+
similarPatterns
|
|
12424
|
+
);
|
|
12425
|
+
const validation = await this.validateCodeChanges(filePath, modifiedContent);
|
|
12426
|
+
if (!validation.isValid) {
|
|
12427
|
+
console.warn(`\u26A0\uFE0F Generated changes may have issues: ${validation.errors.join(", ")}`);
|
|
12428
|
+
}
|
|
12429
|
+
return modifiedContent;
|
|
12430
|
+
}
|
|
12431
|
+
/**
|
|
12432
|
+
* Analyze the goal to understand what type of changes are needed
|
|
12433
|
+
*/
|
|
12434
|
+
async analyzeGoalForChanges(goal, context) {
|
|
12435
|
+
const goal_lower = goal.toLowerCase();
|
|
12436
|
+
let action = "general";
|
|
12437
|
+
if (goal_lower.includes("add") && goal_lower.includes("function")) {
|
|
12438
|
+
action = "add_function";
|
|
12439
|
+
} else if (goal_lower.includes("modify") || goal_lower.includes("update") || goal_lower.includes("change")) {
|
|
12440
|
+
action = "modify_function";
|
|
12441
|
+
} else if (goal_lower.includes("add") && (goal_lower.includes("variable") || goal_lower.includes("const") || goal_lower.includes("let"))) {
|
|
12442
|
+
action = "add_variable";
|
|
12443
|
+
} else if (goal_lower.includes("import")) {
|
|
12444
|
+
action = "add_import";
|
|
12445
|
+
}
|
|
12446
|
+
const target = this.extractTargetFromGoal(goal);
|
|
12447
|
+
const complexity = goal_lower.includes("complex") || goal_lower.includes("system") ? "complex" : goal_lower.includes("simple") || goal.length < 50 ? "simple" : "medium";
|
|
12448
|
+
return {
|
|
12449
|
+
action,
|
|
12450
|
+
target,
|
|
12451
|
+
description: goal,
|
|
12452
|
+
complexity
|
|
12453
|
+
};
|
|
12454
|
+
}
|
|
12455
|
+
/**
|
|
12456
|
+
* Analyze the structure of the current file
|
|
12457
|
+
*/
|
|
12458
|
+
async analyzeFileStructure(filePath, content) {
|
|
12459
|
+
const isTypeScript = filePath.endsWith(".ts") || filePath.endsWith(".tsx");
|
|
12460
|
+
const language = isTypeScript ? "typescript" : "javascript";
|
|
12461
|
+
try {
|
|
12462
|
+
const parseResult = await this.astParser.execute({
|
|
12463
|
+
filePath,
|
|
12464
|
+
includeSymbols: true,
|
|
12465
|
+
includeImports: true
|
|
12466
|
+
});
|
|
12467
|
+
if (parseResult.success && parseResult.output) {
|
|
12468
|
+
const parsed = JSON.parse(parseResult.output);
|
|
12469
|
+
const symbols = parsed.result?.symbols || [];
|
|
12470
|
+
const functions = symbols.filter((s) => s.type === "function").map((s) => s.name);
|
|
12471
|
+
const variables = symbols.filter((s) => ["variable", "const", "let", "var"].includes(s.type)).map((s) => s.name);
|
|
12472
|
+
const classes = symbols.filter((s) => s.type === "class").map((s) => s.name);
|
|
12473
|
+
return {
|
|
12474
|
+
hasExports: content.includes("export"),
|
|
12475
|
+
hasImports: content.includes("import") || content.includes("require"),
|
|
12476
|
+
functions,
|
|
12477
|
+
variables,
|
|
12478
|
+
classes,
|
|
12479
|
+
language,
|
|
12480
|
+
structure: "module"
|
|
12481
|
+
};
|
|
12482
|
+
}
|
|
12483
|
+
} catch (error) {
|
|
12484
|
+
console.warn("AST parsing failed, using fallback analysis:", error);
|
|
12485
|
+
}
|
|
12486
|
+
return {
|
|
12487
|
+
hasExports: content.includes("export"),
|
|
12488
|
+
hasImports: content.includes("import") || content.includes("require"),
|
|
12489
|
+
functions: this.extractFunctionsFromContent(content),
|
|
12490
|
+
variables: this.extractVariablesFromContent(content),
|
|
12491
|
+
classes: [],
|
|
12492
|
+
language,
|
|
12493
|
+
structure: content.includes("import") || content.includes("export") ? "module" : "script"
|
|
12494
|
+
};
|
|
12495
|
+
}
|
|
12496
|
+
/**
|
|
12497
|
+
* Find similar code patterns using vector search
|
|
12498
|
+
*/
|
|
12499
|
+
async findSimilarPatterns(goal, context) {
|
|
12500
|
+
try {
|
|
12501
|
+
const searchResults = await context.searchEngine.semanticSearch(goal, 5);
|
|
12502
|
+
return searchResults;
|
|
12503
|
+
} catch (error) {
|
|
12504
|
+
console.warn("Vector search failed:", error);
|
|
12505
|
+
return [];
|
|
12506
|
+
}
|
|
12507
|
+
}
|
|
12508
|
+
/**
|
|
12509
|
+
* Apply the actual code transformations
|
|
12510
|
+
*/
|
|
12511
|
+
async applyCodeTransformations(content, fileStructure, goalAnalysis, similarPatterns) {
|
|
12512
|
+
console.log(`\u{1F527} Applying ${goalAnalysis.action} transformation: ${goalAnalysis.target}`);
|
|
12513
|
+
switch (goalAnalysis.action) {
|
|
12514
|
+
case "add_function":
|
|
12515
|
+
return this.addFunctionToFile(content, fileStructure, goalAnalysis);
|
|
12516
|
+
case "add_variable":
|
|
12517
|
+
return this.addVariableToFile(content, fileStructure, goalAnalysis);
|
|
12518
|
+
case "modify_function":
|
|
12519
|
+
return this.modifyFunctionInFile(content, fileStructure, goalAnalysis);
|
|
12520
|
+
default:
|
|
12521
|
+
return this.applyPatternBasedChanges(content, fileStructure, goalAnalysis, similarPatterns);
|
|
12522
|
+
}
|
|
12523
|
+
}
|
|
12524
|
+
/**
|
|
12525
|
+
* Add a function to the file
|
|
12526
|
+
*/
|
|
12527
|
+
addFunctionToFile(content, fileStructure, goalAnalysis) {
|
|
12528
|
+
const lines = content.split("\n");
|
|
12529
|
+
let insertIndex = lines.length;
|
|
12530
|
+
for (let i = 0; i < lines.length; i++) {
|
|
12531
|
+
const line = lines[i].trim();
|
|
12532
|
+
if (line.startsWith("console.log(") || line.startsWith("export") || line === "main();" || line === "}") {
|
|
12533
|
+
insertIndex = i;
|
|
12534
|
+
break;
|
|
12535
|
+
}
|
|
12536
|
+
}
|
|
12537
|
+
const functionCode = this.generateFunctionCode(goalAnalysis.target, goalAnalysis.description);
|
|
12538
|
+
lines.splice(insertIndex, 0, "", functionCode, "");
|
|
12539
|
+
return lines.join("\n");
|
|
12540
|
+
}
|
|
12541
|
+
/**
|
|
12542
|
+
* Generate function code based on the target description
|
|
12543
|
+
*/
|
|
12544
|
+
generateFunctionCode(target, description) {
|
|
12545
|
+
const desc_lower = description.toLowerCase();
|
|
12546
|
+
if (desc_lower.includes("timestamp") || desc_lower.includes("time") || desc_lower.includes("current time")) {
|
|
12547
|
+
return `function logCurrentTime(): void {
|
|
12548
|
+
const now = new Date();
|
|
12549
|
+
console.log(\`Current time: \${now.toLocaleString()}\`);
|
|
12550
|
+
}`;
|
|
12551
|
+
}
|
|
12552
|
+
if (desc_lower.includes("random") || desc_lower.includes("number")) {
|
|
12553
|
+
return `function generateRandomNumber(): number {
|
|
12554
|
+
return Math.floor(Math.random() * 100);
|
|
12555
|
+
}`;
|
|
12556
|
+
}
|
|
12557
|
+
const functionName = target.replace(/[^a-zA-Z0-9]/g, "").toLowerCase() || "newFunction";
|
|
12558
|
+
return `function ${functionName}(): void {
|
|
12559
|
+
// TODO: Implement ${description}
|
|
12560
|
+
console.log('${functionName} called');
|
|
12561
|
+
}`;
|
|
12562
|
+
}
|
|
12563
|
+
/**
|
|
12564
|
+
* Add a variable to the file
|
|
12565
|
+
*/
|
|
12566
|
+
addVariableToFile(content, fileStructure, goalAnalysis) {
|
|
12567
|
+
const lines = content.split("\n");
|
|
12568
|
+
let insertIndex = 0;
|
|
12569
|
+
for (let i = 0; i < lines.length; i++) {
|
|
12570
|
+
const line = lines[i].trim();
|
|
12571
|
+
if (line.startsWith("function") || line.startsWith("const") || line.startsWith("let") || line.startsWith("var")) {
|
|
12572
|
+
insertIndex = i;
|
|
12573
|
+
break;
|
|
12574
|
+
}
|
|
12575
|
+
}
|
|
12576
|
+
const variableCode = this.generateVariableCode(goalAnalysis.target, goalAnalysis.description);
|
|
12577
|
+
lines.splice(insertIndex, 0, variableCode, "");
|
|
12578
|
+
return lines.join("\n");
|
|
12579
|
+
}
|
|
12580
|
+
/**
|
|
12581
|
+
* Generate variable code
|
|
12582
|
+
*/
|
|
12583
|
+
generateVariableCode(target, description) {
|
|
12584
|
+
const desc_lower = description.toLowerCase();
|
|
12585
|
+
if (desc_lower.includes("timestamp") || desc_lower.includes("time")) {
|
|
12586
|
+
return "const currentTimestamp: number = Date.now();";
|
|
12587
|
+
}
|
|
12588
|
+
if (desc_lower.includes("version") || desc_lower.includes("v1")) {
|
|
12589
|
+
return 'const version: string = "1.0.0";';
|
|
12590
|
+
}
|
|
12591
|
+
const varName = target.replace(/[^a-zA-Z0-9]/g, "").toLowerCase() || "newVariable";
|
|
12592
|
+
return `const ${varName}: string = "TODO: Initialize ${description}";`;
|
|
12593
|
+
}
|
|
12594
|
+
/**
|
|
12595
|
+
* Modify existing function in the file
|
|
12596
|
+
*/
|
|
12597
|
+
modifyFunctionInFile(content, fileStructure, goalAnalysis) {
|
|
12598
|
+
const modificationComment = `// MODIFIED: ${goalAnalysis.description}
|
|
12599
|
+
`;
|
|
12600
|
+
return modificationComment + content;
|
|
12601
|
+
}
|
|
12602
|
+
/**
|
|
12603
|
+
* Apply pattern-based changes using similar code patterns
|
|
12604
|
+
*/
|
|
12605
|
+
applyPatternBasedChanges(content, fileStructure, goalAnalysis, similarPatterns) {
|
|
12606
|
+
if (similarPatterns.length > 0) {
|
|
12607
|
+
const bestPattern = similarPatterns[0];
|
|
12608
|
+
console.log(`\u{1F4CB} Using pattern from ${bestPattern.filePath} as reference`);
|
|
12609
|
+
}
|
|
12610
|
+
const changeComment = `// AUTONOMOUS CHANGE: ${goalAnalysis.description}
|
|
12611
|
+
// Applied at ${(/* @__PURE__ */ new Date()).toISOString()}
|
|
12612
|
+
|
|
12613
|
+
`;
|
|
12614
|
+
return changeComment + content;
|
|
12615
|
+
}
|
|
12616
|
+
/**
|
|
12617
|
+
* Validate the generated code changes
|
|
12618
|
+
*/
|
|
12619
|
+
async validateCodeChanges(filePath, content) {
|
|
12620
|
+
const errors = [];
|
|
12621
|
+
try {
|
|
12622
|
+
const parseResult = await this.astParser.execute({
|
|
12623
|
+
filePath,
|
|
12624
|
+
includeSymbols: false
|
|
12625
|
+
});
|
|
12626
|
+
if (!parseResult.success) {
|
|
12627
|
+
errors.push("Generated code has syntax errors");
|
|
12628
|
+
}
|
|
12629
|
+
} catch (error) {
|
|
12630
|
+
errors.push(`Validation failed: ${error}`);
|
|
12631
|
+
}
|
|
12632
|
+
return {
|
|
12633
|
+
isValid: errors.length === 0,
|
|
12634
|
+
errors
|
|
12635
|
+
};
|
|
12636
|
+
}
|
|
12637
|
+
/**
|
|
12638
|
+
* Extract target from goal description
|
|
12639
|
+
*/
|
|
12640
|
+
extractTargetFromGoal(goal) {
|
|
12641
|
+
const words = goal.toLowerCase().split(" ");
|
|
12642
|
+
const targetKeywords = ["function", "variable", "class", "method"];
|
|
12643
|
+
for (let i = 0; i < words.length; i++) {
|
|
12644
|
+
if (targetKeywords.includes(words[i])) {
|
|
12645
|
+
const targetWords = [];
|
|
12646
|
+
for (let j = i + 1; j < words.length && j < i + 4; j++) {
|
|
12647
|
+
if (!["to", "that", "with", "for", "in"].includes(words[j])) {
|
|
12648
|
+
targetWords.push(words[j]);
|
|
12649
|
+
} else {
|
|
12650
|
+
break;
|
|
12651
|
+
}
|
|
12652
|
+
}
|
|
12653
|
+
return targetWords.join(" ");
|
|
12654
|
+
}
|
|
12655
|
+
}
|
|
12656
|
+
return goal.split(" ").slice(-3).join(" ");
|
|
12657
|
+
}
|
|
12658
|
+
/**
|
|
12659
|
+
* Extract function names from content (fallback when AST fails)
|
|
12660
|
+
*/
|
|
12661
|
+
extractFunctionsFromContent(content) {
|
|
12662
|
+
const functionRegex = /function\s+(\w+)/g;
|
|
12663
|
+
const matches = [];
|
|
12664
|
+
let match;
|
|
12665
|
+
while ((match = functionRegex.exec(content)) !== null) {
|
|
12666
|
+
matches.push(match[1]);
|
|
12667
|
+
}
|
|
12668
|
+
return matches;
|
|
12669
|
+
}
|
|
12670
|
+
/**
|
|
12671
|
+
* Extract variable names from content (fallback when AST fails)
|
|
12672
|
+
*/
|
|
12673
|
+
extractVariablesFromContent(content) {
|
|
12674
|
+
const varRegex = /(?:const|let|var)\s+(\w+)/g;
|
|
12675
|
+
const matches = [];
|
|
12676
|
+
let match;
|
|
12677
|
+
while ((match = varRegex.exec(content)) !== null) {
|
|
12678
|
+
matches.push(match[1]);
|
|
12679
|
+
}
|
|
12680
|
+
return matches;
|
|
12681
|
+
}
|
|
10970
12682
|
generateTaskId() {
|
|
10971
12683
|
return `task_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`;
|
|
10972
12684
|
}
|
|
10973
12685
|
};
|
|
10974
12686
|
}
|
|
10975
12687
|
});
|
|
12688
|
+
var AgentFramework;
|
|
12689
|
+
var init_agent_framework = __esm({
|
|
12690
|
+
"src/services/agent-framework.ts"() {
|
|
12691
|
+
AgentFramework = class {
|
|
12692
|
+
constructor(autonomousExecutor, memoryPath = "/tmp/agent-memory", pluginPath = "/tmp/agent-plugins") {
|
|
12693
|
+
this.sessions = /* @__PURE__ */ new Map();
|
|
12694
|
+
this.plugins = /* @__PURE__ */ new Map();
|
|
12695
|
+
this.autonomousExecutor = autonomousExecutor;
|
|
12696
|
+
this.memoryPath = memoryPath;
|
|
12697
|
+
this.pluginPath = pluginPath;
|
|
12698
|
+
}
|
|
12699
|
+
/**
|
|
12700
|
+
* Initialize the agent framework
|
|
12701
|
+
*/
|
|
12702
|
+
async initialize() {
|
|
12703
|
+
await this.loadPersistedMemory();
|
|
12704
|
+
await this.loadPlugins();
|
|
12705
|
+
console.log(`\u{1F916} Agent Framework initialized with ${this.plugins.size} plugins`);
|
|
12706
|
+
}
|
|
12707
|
+
/**
|
|
12708
|
+
* Create or resume an agent session
|
|
12709
|
+
*/
|
|
12710
|
+
async createSession(userId, sessionId) {
|
|
12711
|
+
const id = sessionId || `session_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`;
|
|
12712
|
+
let session = this.sessions.get(id);
|
|
12713
|
+
if (!session) {
|
|
12714
|
+
session = {
|
|
12715
|
+
id,
|
|
12716
|
+
userId,
|
|
12717
|
+
startTime: Date.now(),
|
|
12718
|
+
lastActivity: Date.now(),
|
|
12719
|
+
context: /* @__PURE__ */ new Map(),
|
|
12720
|
+
memory: {
|
|
12721
|
+
shortTerm: [],
|
|
12722
|
+
longTerm: /* @__PURE__ */ new Map(),
|
|
12723
|
+
episodic: [],
|
|
12724
|
+
semantic: /* @__PURE__ */ new Map()
|
|
12725
|
+
},
|
|
12726
|
+
activeTasks: [],
|
|
12727
|
+
learnedPatterns: /* @__PURE__ */ new Map()
|
|
12728
|
+
};
|
|
12729
|
+
this.sessions.set(id, session);
|
|
12730
|
+
await this.loadSessionMemory(session);
|
|
12731
|
+
}
|
|
12732
|
+
session.lastActivity = Date.now();
|
|
12733
|
+
return session;
|
|
12734
|
+
}
|
|
12735
|
+
/**
|
|
12736
|
+
* Execute an action within an agent session
|
|
12737
|
+
*/
|
|
12738
|
+
async executeInSession(sessionId, action, parameters = {}) {
|
|
12739
|
+
const session = this.sessions.get(sessionId);
|
|
12740
|
+
if (!session) {
|
|
12741
|
+
throw new Error(`Session ${sessionId} not found`);
|
|
12742
|
+
}
|
|
12743
|
+
session.lastActivity = Date.now();
|
|
12744
|
+
try {
|
|
12745
|
+
const pluginResult = await this.tryExecuteWithPlugin(session, action, parameters);
|
|
12746
|
+
if (pluginResult) {
|
|
12747
|
+
await this.recordExperience(session, action, parameters, pluginResult, pluginResult.success ? 1 : -1);
|
|
12748
|
+
return pluginResult;
|
|
12749
|
+
}
|
|
12750
|
+
const result = await this.autonomousExecutor.executeTask(action, JSON.stringify(parameters));
|
|
12751
|
+
await this.recordExperience(session, action, parameters, result, result.status === "completed" ? 1 : -0.5);
|
|
12752
|
+
return result;
|
|
12753
|
+
} catch (error) {
|
|
12754
|
+
await this.recordExperience(session, action, parameters, error, -1);
|
|
12755
|
+
throw error;
|
|
12756
|
+
}
|
|
12757
|
+
}
|
|
12758
|
+
/**
|
|
12759
|
+
* Learn from interactions and improve performance
|
|
12760
|
+
*/
|
|
12761
|
+
async learnFromInteraction(sessionId, interaction) {
|
|
12762
|
+
const session = this.sessions.get(sessionId);
|
|
12763
|
+
if (!session) return;
|
|
12764
|
+
if (interaction.outcome === "success") {
|
|
12765
|
+
await this.extractPatterns(session, interaction);
|
|
12766
|
+
}
|
|
12767
|
+
await this.consolidateMemory(session);
|
|
12768
|
+
await this.persistSessionMemory(session);
|
|
12769
|
+
}
|
|
12770
|
+
/**
|
|
12771
|
+
* Register a plugin
|
|
12772
|
+
*/
|
|
12773
|
+
async registerPlugin(plugin) {
|
|
12774
|
+
this.plugins.set(plugin.name, plugin);
|
|
12775
|
+
await plugin.initialize(this);
|
|
12776
|
+
console.log(`\u{1F50C} Plugin registered: ${plugin.name} v${plugin.version}`);
|
|
12777
|
+
}
|
|
12778
|
+
/**
|
|
12779
|
+
* Get session memory and context
|
|
12780
|
+
*/
|
|
12781
|
+
getSessionContext(sessionId) {
|
|
12782
|
+
return this.sessions.get(sessionId) || null;
|
|
12783
|
+
}
|
|
12784
|
+
/**
|
|
12785
|
+
* Clean up inactive sessions
|
|
12786
|
+
*/
|
|
12787
|
+
async cleanupInactiveSessions(maxAge = 24 * 60 * 60 * 1e3) {
|
|
12788
|
+
const now = Date.now();
|
|
12789
|
+
const toRemove = [];
|
|
12790
|
+
for (const [id, session] of this.sessions) {
|
|
12791
|
+
if (now - session.lastActivity > maxAge) {
|
|
12792
|
+
await this.persistSessionMemory(session);
|
|
12793
|
+
toRemove.push(id);
|
|
12794
|
+
}
|
|
12795
|
+
}
|
|
12796
|
+
for (const id of toRemove) {
|
|
12797
|
+
this.sessions.delete(id);
|
|
12798
|
+
}
|
|
12799
|
+
console.log(`\u{1F9F9} Cleaned up ${toRemove.length} inactive sessions`);
|
|
12800
|
+
}
|
|
12801
|
+
/**
|
|
12802
|
+
* Try to execute action with registered plugins
|
|
12803
|
+
*/
|
|
12804
|
+
async tryExecuteWithPlugin(session, action, parameters) {
|
|
12805
|
+
for (const plugin of this.plugins.values()) {
|
|
12806
|
+
if (plugin.capabilities.includes(action) || plugin.capabilities.includes("general")) {
|
|
12807
|
+
try {
|
|
12808
|
+
const context = {
|
|
12809
|
+
session,
|
|
12810
|
+
input: { action, parameters },
|
|
12811
|
+
previousResults: this.getRecentResults(session)
|
|
12812
|
+
};
|
|
12813
|
+
const result = await plugin.execute(context);
|
|
12814
|
+
if (result.success) {
|
|
12815
|
+
return result;
|
|
12816
|
+
}
|
|
12817
|
+
} catch (error) {
|
|
12818
|
+
console.warn(`Plugin ${plugin.name} failed:`, error);
|
|
12819
|
+
}
|
|
12820
|
+
}
|
|
12821
|
+
}
|
|
12822
|
+
return null;
|
|
12823
|
+
}
|
|
12824
|
+
/**
|
|
12825
|
+
* Record experience for learning
|
|
12826
|
+
*/
|
|
12827
|
+
async recordExperience(session, action, parameters, result, reward) {
|
|
12828
|
+
const experience = {
|
|
12829
|
+
context: session.context.get("current_context") || "general",
|
|
12830
|
+
action,
|
|
12831
|
+
outcome: result,
|
|
12832
|
+
reward,
|
|
12833
|
+
timestamp: Date.now()
|
|
12834
|
+
};
|
|
12835
|
+
const episodicMemory = {
|
|
12836
|
+
id: `epi_${Date.now()}_${Math.random().toString(36).substr(2, 6)}`,
|
|
12837
|
+
timestamp: experience.timestamp,
|
|
12838
|
+
context: experience.context,
|
|
12839
|
+
action: experience.action,
|
|
12840
|
+
outcome: reward > 0 ? "success" : reward === 0 ? "partial" : "failure",
|
|
12841
|
+
lesson: this.extractLesson(experience),
|
|
12842
|
+
confidence: Math.abs(reward)
|
|
12843
|
+
};
|
|
12844
|
+
session.memory.episodic.push(episodicMemory);
|
|
12845
|
+
const memoryItem = {
|
|
12846
|
+
id: `mem_${Date.now()}`,
|
|
12847
|
+
type: "interaction",
|
|
12848
|
+
content: experience,
|
|
12849
|
+
timestamp: Date.now(),
|
|
12850
|
+
importance: Math.abs(reward),
|
|
12851
|
+
accessCount: 1,
|
|
12852
|
+
lastAccessed: Date.now()
|
|
12853
|
+
};
|
|
12854
|
+
session.memory.shortTerm.push(memoryItem);
|
|
12855
|
+
for (const plugin of this.plugins.values()) {
|
|
12856
|
+
if (plugin.learn) {
|
|
12857
|
+
try {
|
|
12858
|
+
await plugin.learn(experience);
|
|
12859
|
+
} catch (error) {
|
|
12860
|
+
console.warn(`Plugin ${plugin.name} learning failed:`, error);
|
|
12861
|
+
}
|
|
12862
|
+
}
|
|
12863
|
+
}
|
|
12864
|
+
}
|
|
12865
|
+
/**
|
|
12866
|
+
* Extract patterns from successful interactions
|
|
12867
|
+
*/
|
|
12868
|
+
async extractPatterns(session, interaction) {
|
|
12869
|
+
const patterns = session.learnedPatterns;
|
|
12870
|
+
if (interaction.action && interaction.parameters) {
|
|
12871
|
+
const actionKey = interaction.action.toLowerCase();
|
|
12872
|
+
const paramKeys = Object.keys(interaction.parameters);
|
|
12873
|
+
if (!patterns.has(actionKey)) {
|
|
12874
|
+
patterns.set(actionKey, /* @__PURE__ */ new Map());
|
|
12875
|
+
}
|
|
12876
|
+
const actionPatterns = patterns.get(actionKey);
|
|
12877
|
+
const paramHash = paramKeys.sort().join(",");
|
|
12878
|
+
actionPatterns.set(paramHash, (actionPatterns.get(paramHash) || 0) + 1);
|
|
12879
|
+
}
|
|
12880
|
+
}
|
|
12881
|
+
/**
|
|
12882
|
+
* Consolidate memory from short-term to long-term
|
|
12883
|
+
*/
|
|
12884
|
+
async consolidateMemory(session) {
|
|
12885
|
+
const now = Date.now();
|
|
12886
|
+
const consolidationThreshold = 5;
|
|
12887
|
+
const ageThreshold = 60 * 60 * 1e3;
|
|
12888
|
+
const toMove = [];
|
|
12889
|
+
for (const item of session.memory.shortTerm) {
|
|
12890
|
+
if (item.accessCount >= consolidationThreshold || now - item.timestamp > ageThreshold) {
|
|
12891
|
+
toMove.push(item);
|
|
12892
|
+
}
|
|
12893
|
+
}
|
|
12894
|
+
for (const item of toMove) {
|
|
12895
|
+
session.memory.longTerm.set(item.id, item);
|
|
12896
|
+
session.memory.shortTerm = session.memory.shortTerm.filter((i) => i.id !== item.id);
|
|
12897
|
+
}
|
|
12898
|
+
if (session.memory.shortTerm.length > 50) {
|
|
12899
|
+
session.memory.shortTerm = session.memory.shortTerm.slice(-50);
|
|
12900
|
+
}
|
|
12901
|
+
if (session.memory.episodic.length > 100) {
|
|
12902
|
+
session.memory.episodic = session.memory.episodic.slice(-100);
|
|
12903
|
+
}
|
|
12904
|
+
}
|
|
12905
|
+
/**
|
|
12906
|
+
* Load persisted memory
|
|
12907
|
+
*/
|
|
12908
|
+
async loadPersistedMemory() {
|
|
12909
|
+
try {
|
|
12910
|
+
await fs6.mkdir(this.memoryPath, { recursive: true });
|
|
12911
|
+
const files = await fs6.readdir(this.memoryPath);
|
|
12912
|
+
for (const file of files) {
|
|
12913
|
+
if (file.endsWith(".json")) {
|
|
12914
|
+
try {
|
|
12915
|
+
const content = await fs6.readFile(path8.join(this.memoryPath, file), "utf-8");
|
|
12916
|
+
const sessionData = JSON.parse(content);
|
|
12917
|
+
const session = {
|
|
12918
|
+
...sessionData,
|
|
12919
|
+
context: new Map(sessionData.context),
|
|
12920
|
+
memory: {
|
|
12921
|
+
shortTerm: sessionData.memory.shortTerm || [],
|
|
12922
|
+
longTerm: new Map(sessionData.memory.longTerm || []),
|
|
12923
|
+
episodic: sessionData.memory.episodic || [],
|
|
12924
|
+
semantic: new Map(sessionData.memory.semantic || [])
|
|
12925
|
+
},
|
|
12926
|
+
learnedPatterns: new Map(sessionData.learnedPatterns || [])
|
|
12927
|
+
};
|
|
12928
|
+
this.sessions.set(session.id, session);
|
|
12929
|
+
} catch (error) {
|
|
12930
|
+
console.warn(`Failed to load session ${file}:`, error);
|
|
12931
|
+
}
|
|
12932
|
+
}
|
|
12933
|
+
}
|
|
12934
|
+
console.log(`\u{1F4BE} Loaded ${this.sessions.size} persisted sessions`);
|
|
12935
|
+
} catch (error) {
|
|
12936
|
+
console.warn("Failed to load persisted memory:", error);
|
|
12937
|
+
}
|
|
12938
|
+
}
|
|
12939
|
+
/**
|
|
12940
|
+
* Persist session memory
|
|
12941
|
+
*/
|
|
12942
|
+
async persistSessionMemory(session) {
|
|
12943
|
+
try {
|
|
12944
|
+
const fileName = `session_${session.id}.json`;
|
|
12945
|
+
const filePath = path8.join(this.memoryPath, fileName);
|
|
12946
|
+
const serializable = {
|
|
12947
|
+
...session,
|
|
12948
|
+
context: Array.from(session.context.entries()),
|
|
12949
|
+
memory: {
|
|
12950
|
+
...session.memory,
|
|
12951
|
+
longTerm: Array.from(session.memory.longTerm.entries()),
|
|
12952
|
+
semantic: Array.from(session.memory.semantic.entries())
|
|
12953
|
+
},
|
|
12954
|
+
learnedPatterns: Array.from(session.learnedPatterns.entries())
|
|
12955
|
+
};
|
|
12956
|
+
await fs6.writeFile(filePath, JSON.stringify(serializable, null, 2), "utf-8");
|
|
12957
|
+
} catch (error) {
|
|
12958
|
+
console.warn(`Failed to persist session ${session.id}:`, error);
|
|
12959
|
+
}
|
|
12960
|
+
}
|
|
12961
|
+
/**
|
|
12962
|
+
* Load session memory from disk
|
|
12963
|
+
*/
|
|
12964
|
+
async loadSessionMemory(session) {
|
|
12965
|
+
}
|
|
12966
|
+
/**
|
|
12967
|
+
* Load plugins from plugin directory
|
|
12968
|
+
*/
|
|
12969
|
+
async loadPlugins() {
|
|
12970
|
+
try {
|
|
12971
|
+
await fs6.mkdir(this.pluginPath, { recursive: true });
|
|
12972
|
+
} catch (error) {
|
|
12973
|
+
console.warn("Failed to load plugins:", error);
|
|
12974
|
+
}
|
|
12975
|
+
}
|
|
12976
|
+
/**
|
|
12977
|
+
* Extract lesson from experience
|
|
12978
|
+
*/
|
|
12979
|
+
extractLesson(experience) {
|
|
12980
|
+
if (experience.reward > 0) {
|
|
12981
|
+
return `Successful: ${experience.action} with parameters ${JSON.stringify(experience.parameters || {})}`;
|
|
12982
|
+
} else {
|
|
12983
|
+
return `Failed: ${experience.action} - avoid similar approaches`;
|
|
12984
|
+
}
|
|
12985
|
+
}
|
|
12986
|
+
/**
|
|
12987
|
+
* Get recent results from session memory
|
|
12988
|
+
*/
|
|
12989
|
+
getRecentResults(session) {
|
|
12990
|
+
return session.memory.shortTerm.filter((item) => item.type === "interaction").slice(-5).map((item) => item.content.outcome);
|
|
12991
|
+
}
|
|
12992
|
+
};
|
|
12993
|
+
}
|
|
12994
|
+
});
|
|
10976
12995
|
|
|
10977
12996
|
// src/tools/intelligence/autonomous-task-tool.ts
|
|
10978
12997
|
var AutonomousTaskTool;
|
|
10979
12998
|
var init_autonomous_task_tool = __esm({
|
|
10980
12999
|
"src/tools/intelligence/autonomous-task-tool.ts"() {
|
|
10981
13000
|
init_autonomous_executor();
|
|
13001
|
+
init_agent_framework();
|
|
10982
13002
|
AutonomousTaskTool = class {
|
|
10983
13003
|
constructor() {
|
|
10984
13004
|
this.name = "autonomous_task";
|
|
10985
13005
|
this.description = "Execute complex multi-step coding tasks autonomously using AI-powered planning and execution. Handles refactoring, feature implementation, bug fixes, and more.";
|
|
10986
13006
|
this.executor = null;
|
|
13007
|
+
this.agentFramework = null;
|
|
10987
13008
|
this.isExecuting = false;
|
|
13009
|
+
this.currentSession = null;
|
|
10988
13010
|
}
|
|
10989
13011
|
async execute(args) {
|
|
13012
|
+
console.log(`\u{1F527} AutonomousTaskTool.execute called with args:`, JSON.stringify(args, null, 2));
|
|
10990
13013
|
try {
|
|
10991
13014
|
const {
|
|
10992
13015
|
goal,
|
|
@@ -10997,6 +13020,7 @@ var init_autonomous_task_tool = __esm({
|
|
|
10997
13020
|
maxSteps = 50,
|
|
10998
13021
|
timeoutMs = 5 * 60 * 1e3
|
|
10999
13022
|
} = args;
|
|
13023
|
+
console.log(`\u{1F4CB} Parsed args - goal: "${goal}", action: "${action}", rootPath: "${rootPath}"`);
|
|
11000
13024
|
if (!this.executor) {
|
|
11001
13025
|
this.executor = new AutonomousExecutor({
|
|
11002
13026
|
rootPath,
|
|
@@ -11005,6 +13029,14 @@ var init_autonomous_task_tool = __esm({
|
|
|
11005
13029
|
validationEnabled: true,
|
|
11006
13030
|
backupEnabled: true
|
|
11007
13031
|
});
|
|
13032
|
+
this.agentFramework = new AgentFramework(this.executor);
|
|
13033
|
+
await this.agentFramework.initialize();
|
|
13034
|
+
}
|
|
13035
|
+
if (!this.currentSession) {
|
|
13036
|
+
const session = await this.agentFramework.createSession("default_user");
|
|
13037
|
+
if (session) {
|
|
13038
|
+
this.currentSession = session.id;
|
|
13039
|
+
}
|
|
11008
13040
|
}
|
|
11009
13041
|
switch (action) {
|
|
11010
13042
|
case "execute":
|
|
@@ -11014,7 +13046,7 @@ var init_autonomous_task_tool = __esm({
|
|
|
11014
13046
|
error: 'Goal is required for task execution. Example: "refactor the authentication system to use JWT tokens"'
|
|
11015
13047
|
};
|
|
11016
13048
|
}
|
|
11017
|
-
return await this.handleExecute(goal, description);
|
|
13049
|
+
return await this.handleExecute(goal, description, maxSteps, timeoutMs);
|
|
11018
13050
|
case "status":
|
|
11019
13051
|
if (!taskId) {
|
|
11020
13052
|
return {
|
|
@@ -11046,7 +13078,7 @@ var init_autonomous_task_tool = __esm({
|
|
|
11046
13078
|
};
|
|
11047
13079
|
}
|
|
11048
13080
|
}
|
|
11049
|
-
async handleExecute(goal, description) {
|
|
13081
|
+
async handleExecute(goal, description, maxSteps = 50, timeoutMs = 5 * 60 * 1e3) {
|
|
11050
13082
|
if (this.isExecuting) {
|
|
11051
13083
|
return {
|
|
11052
13084
|
success: false,
|
|
@@ -11055,11 +13087,21 @@ var init_autonomous_task_tool = __esm({
|
|
|
11055
13087
|
}
|
|
11056
13088
|
try {
|
|
11057
13089
|
this.isExecuting = true;
|
|
11058
|
-
console.log(`\u{1F916} Starting autonomous task execution...`);
|
|
11059
|
-
const
|
|
11060
|
-
|
|
13090
|
+
console.log(`\u{1F916} Starting autonomous task execution in agent session...`);
|
|
13091
|
+
const result = await this.agentFramework.executeInSession(
|
|
13092
|
+
this.currentSession,
|
|
13093
|
+
goal,
|
|
13094
|
+
{ description, maxSteps, timeoutMs }
|
|
13095
|
+
);
|
|
13096
|
+
await this.agentFramework.learnFromInteraction(this.currentSession, {
|
|
13097
|
+
goal,
|
|
13098
|
+
description,
|
|
13099
|
+
outcome: result.status === "completed" ? "success" : "failure",
|
|
13100
|
+
result
|
|
13101
|
+
});
|
|
13102
|
+
const output = this.formatTaskResult(result);
|
|
11061
13103
|
return {
|
|
11062
|
-
success:
|
|
13104
|
+
success: result.status === "completed",
|
|
11063
13105
|
output
|
|
11064
13106
|
};
|
|
11065
13107
|
} catch (error) {
|
|
@@ -11129,6 +13171,7 @@ var init_autonomous_task_tool = __esm({
|
|
|
11129
13171
|
};
|
|
11130
13172
|
}
|
|
11131
13173
|
async handleCancel(taskId) {
|
|
13174
|
+
if (this.agentFramework && this.currentSession) ;
|
|
11132
13175
|
const cancelled = this.executor.cancelTask(taskId);
|
|
11133
13176
|
if (cancelled) {
|
|
11134
13177
|
this.isExecuting = false;
|
|
@@ -11145,6 +13188,14 @@ All partial changes have been preserved.`
|
|
|
11145
13188
|
error: `Task ${taskId} not found or already completed`
|
|
11146
13189
|
};
|
|
11147
13190
|
}
|
|
13191
|
+
/**
|
|
13192
|
+
* Clean up agent sessions and memory
|
|
13193
|
+
*/
|
|
13194
|
+
async cleanup() {
|
|
13195
|
+
if (this.agentFramework) {
|
|
13196
|
+
await this.agentFramework.cleanupInactiveSessions();
|
|
13197
|
+
}
|
|
13198
|
+
}
|
|
11148
13199
|
formatTaskResult(task) {
|
|
11149
13200
|
const duration = task.endTime && task.startTime ? task.endTime - task.startTime : 0;
|
|
11150
13201
|
const statusIcon = task.status === "completed" ? "\u2705" : "\u274C";
|
|
@@ -11421,10 +13472,10 @@ var init_token_counter = __esm({
|
|
|
11421
13472
|
function loadCustomInstructions(workingDirectory = process.cwd()) {
|
|
11422
13473
|
try {
|
|
11423
13474
|
const instructionsPath = path8.join(workingDirectory, ".grok", "GROK.md");
|
|
11424
|
-
if (!
|
|
13475
|
+
if (!fs9.existsSync(instructionsPath)) {
|
|
11425
13476
|
return null;
|
|
11426
13477
|
}
|
|
11427
|
-
const customInstructions =
|
|
13478
|
+
const customInstructions = fs9.readFileSync(instructionsPath, "utf-8");
|
|
11428
13479
|
return customInstructions.trim();
|
|
11429
13480
|
} catch (error) {
|
|
11430
13481
|
console.warn("Failed to load custom instructions:", error);
|
|
@@ -11540,10 +13591,10 @@ var init_execution_orchestrator = __esm({
|
|
|
11540
13591
|
const state = /* @__PURE__ */ new Map();
|
|
11541
13592
|
try {
|
|
11542
13593
|
const walkDir = (dir) => {
|
|
11543
|
-
const files =
|
|
13594
|
+
const files = fs9.readdirSync(dir);
|
|
11544
13595
|
for (const file of files) {
|
|
11545
13596
|
const filePath = path8.join(dir, file);
|
|
11546
|
-
const stat =
|
|
13597
|
+
const stat = fs9.statSync(filePath);
|
|
11547
13598
|
if (stat.isDirectory() && !file.startsWith(".") && file !== "node_modules") {
|
|
11548
13599
|
walkDir(filePath);
|
|
11549
13600
|
} else if (stat.isFile()) {
|
|
@@ -11591,7 +13642,7 @@ var init_execution_orchestrator = __esm({
|
|
|
11591
13642
|
console.log(`[grok-one-shot] #${step.id} Changes detected:`);
|
|
11592
13643
|
for (const change of step.changes) {
|
|
11593
13644
|
console.log(` ${change.changeType.toUpperCase()}: ${change.filePath}`);
|
|
11594
|
-
if (change.changeType === "modified" &&
|
|
13645
|
+
if (change.changeType === "modified" && fs9.existsSync(change.filePath)) {
|
|
11595
13646
|
try {
|
|
11596
13647
|
if (this.isGitRepository()) {
|
|
11597
13648
|
const diff = execSync(`git diff --no-index /dev/null ${change.filePath} 2>/dev/null || git diff ${change.filePath}`, {
|
|
@@ -11617,8 +13668,8 @@ var init_execution_orchestrator = __esm({
|
|
|
11617
13668
|
}
|
|
11618
13669
|
try {
|
|
11619
13670
|
const patchesDir = path8.join(__require("os").homedir(), ".grok", "patches");
|
|
11620
|
-
if (!
|
|
11621
|
-
|
|
13671
|
+
if (!fs9.existsSync(patchesDir)) {
|
|
13672
|
+
fs9.mkdirSync(patchesDir, { recursive: true });
|
|
11622
13673
|
}
|
|
11623
13674
|
const timestamp = (/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-");
|
|
11624
13675
|
const patchFile = path8.join(patchesDir, `step-${step.id}-${timestamp}.patch`);
|
|
@@ -11628,7 +13679,7 @@ var init_execution_orchestrator = __esm({
|
|
|
11628
13679
|
|
|
11629
13680
|
`;
|
|
11630
13681
|
for (const change of step.changes) {
|
|
11631
|
-
if (change.changeType === "modified" &&
|
|
13682
|
+
if (change.changeType === "modified" && fs9.existsSync(change.filePath)) {
|
|
11632
13683
|
try {
|
|
11633
13684
|
const diff = execSync(`git diff ${change.filePath}`, {
|
|
11634
13685
|
encoding: "utf-8",
|
|
@@ -11642,7 +13693,7 @@ ${diff}
|
|
|
11642
13693
|
}
|
|
11643
13694
|
}
|
|
11644
13695
|
}
|
|
11645
|
-
|
|
13696
|
+
fs9.writeFileSync(patchFile, patchContent);
|
|
11646
13697
|
console.log(`[grok-one-shot] #${step.id} Patch saved: ${patchFile}`);
|
|
11647
13698
|
return patchFile;
|
|
11648
13699
|
} catch (error) {
|
|
@@ -11658,10 +13709,10 @@ ${diff}
|
|
|
11658
13709
|
return;
|
|
11659
13710
|
}
|
|
11660
13711
|
for (const change of step.changes) {
|
|
11661
|
-
if ((change.changeType === "modified" || change.changeType === "created") &&
|
|
13712
|
+
if ((change.changeType === "modified" || change.changeType === "created") && fs9.existsSync(change.filePath)) {
|
|
11662
13713
|
try {
|
|
11663
13714
|
const backupPath = `${change.filePath}.bak`;
|
|
11664
|
-
|
|
13715
|
+
fs9.copyFileSync(change.filePath, backupPath);
|
|
11665
13716
|
change.backupPath = backupPath;
|
|
11666
13717
|
console.log(`[grok-one-shot] #${step.id} Backup created: ${backupPath}`);
|
|
11667
13718
|
} catch (_error) {
|
|
@@ -11753,10 +13804,10 @@ Auto-generated by grok-one-shot execution orchestrator`;
|
|
|
11753
13804
|
try {
|
|
11754
13805
|
const testFiles = [];
|
|
11755
13806
|
const walkDir = (dir) => {
|
|
11756
|
-
const files =
|
|
13807
|
+
const files = fs9.readdirSync(dir);
|
|
11757
13808
|
for (const file of files) {
|
|
11758
13809
|
const filePath = path8.join(dir, file);
|
|
11759
|
-
const stat =
|
|
13810
|
+
const stat = fs9.statSync(filePath);
|
|
11760
13811
|
if (stat.isDirectory() && !file.startsWith(".") && file !== "node_modules") {
|
|
11761
13812
|
walkDir(filePath);
|
|
11762
13813
|
} else if (stat.isFile() && (file.includes("test") || file.includes("spec"))) {
|
|
@@ -11775,7 +13826,7 @@ Auto-generated by grok-one-shot execution orchestrator`;
|
|
|
11775
13826
|
*/
|
|
11776
13827
|
findBuildFiles() {
|
|
11777
13828
|
const buildFiles = ["package.json", "tsconfig.json", "webpack.config.js", "babel.config.js"];
|
|
11778
|
-
return buildFiles.filter((file) =>
|
|
13829
|
+
return buildFiles.filter((file) => fs9.existsSync(file));
|
|
11779
13830
|
}
|
|
11780
13831
|
/**
|
|
11781
13832
|
* Find source files
|
|
@@ -11784,10 +13835,10 @@ Auto-generated by grok-one-shot execution orchestrator`;
|
|
|
11784
13835
|
try {
|
|
11785
13836
|
const sourceFiles = [];
|
|
11786
13837
|
const walkDir = (dir) => {
|
|
11787
|
-
const files =
|
|
13838
|
+
const files = fs9.readdirSync(dir);
|
|
11788
13839
|
for (const file of files) {
|
|
11789
13840
|
const filePath = path8.join(dir, file);
|
|
11790
|
-
const stat =
|
|
13841
|
+
const stat = fs9.statSync(filePath);
|
|
11791
13842
|
if (stat.isDirectory() && !file.startsWith(".") && file !== "node_modules") {
|
|
11792
13843
|
walkDir(filePath);
|
|
11793
13844
|
} else if (stat.isFile() && (file.endsWith(".ts") || file.endsWith(".js") || file.endsWith(".tsx") || file.endsWith(".jsx"))) {
|
|
@@ -12328,6 +14379,184 @@ ${option.id}) ${option.title}`);
|
|
|
12328
14379
|
}
|
|
12329
14380
|
});
|
|
12330
14381
|
|
|
14382
|
+
// src/utils/regex-helper.ts
|
|
14383
|
+
var RegexHelper;
|
|
14384
|
+
var init_regex_helper = __esm({
|
|
14385
|
+
"src/utils/regex-helper.ts"() {
|
|
14386
|
+
RegexHelper = class {
|
|
14387
|
+
/**
|
|
14388
|
+
* Sanitize input strings for safe regex construction
|
|
14389
|
+
* Escapes all regex special characters to prevent pattern errors
|
|
14390
|
+
*/
|
|
14391
|
+
static sanitizeForRegex(input) {
|
|
14392
|
+
if (typeof input !== "string") {
|
|
14393
|
+
console.log("RegexHelper.sanitizeForRegex: input is not a string", { input });
|
|
14394
|
+
return "";
|
|
14395
|
+
}
|
|
14396
|
+
const sanitized = input.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
14397
|
+
console.log("RegexHelper.sanitizeForRegex completed", {
|
|
14398
|
+
originalLength: input.length,
|
|
14399
|
+
sanitizedLength: sanitized.length
|
|
14400
|
+
});
|
|
14401
|
+
return sanitized;
|
|
14402
|
+
}
|
|
14403
|
+
/**
|
|
14404
|
+
* Create a RegExp safely with error handling
|
|
14405
|
+
* Returns null if regex construction fails
|
|
14406
|
+
*/
|
|
14407
|
+
static createSafeRegex(pattern, flags = "i") {
|
|
14408
|
+
try {
|
|
14409
|
+
const regex = new RegExp(pattern, flags);
|
|
14410
|
+
console.log("RegexHelper.createSafeRegex success", {
|
|
14411
|
+
pattern: pattern.substring(0, 50),
|
|
14412
|
+
flags
|
|
14413
|
+
});
|
|
14414
|
+
return regex;
|
|
14415
|
+
} catch (error) {
|
|
14416
|
+
console.log("RegexHelper.createSafeRegex failed", {
|
|
14417
|
+
pattern: pattern.substring(0, 50),
|
|
14418
|
+
flags,
|
|
14419
|
+
error: error.message,
|
|
14420
|
+
errorName: error.name
|
|
14421
|
+
});
|
|
14422
|
+
return null;
|
|
14423
|
+
}
|
|
14424
|
+
}
|
|
14425
|
+
/**
|
|
14426
|
+
* Find fuzzy match with multiple fallback strategies
|
|
14427
|
+
* Progressive fallbacks: exact match -> sanitized regex -> Levenshtein distance
|
|
14428
|
+
*/
|
|
14429
|
+
static findFuzzyMatch(content, searchStr) {
|
|
14430
|
+
if (typeof content !== "string" || typeof searchStr !== "string") {
|
|
14431
|
+
console.log("RegexHelper.findFuzzyMatch: invalid input types", {
|
|
14432
|
+
contentType: typeof content,
|
|
14433
|
+
searchStrType: typeof searchStr
|
|
14434
|
+
});
|
|
14435
|
+
return null;
|
|
14436
|
+
}
|
|
14437
|
+
console.log("RegexHelper.findFuzzyMatch started", {
|
|
14438
|
+
contentLength: content.length,
|
|
14439
|
+
searchStrLength: searchStr.length,
|
|
14440
|
+
searchStrPreview: searchStr.substring(0, 50)
|
|
14441
|
+
});
|
|
14442
|
+
try {
|
|
14443
|
+
if (content.includes(searchStr)) {
|
|
14444
|
+
console.log("RegexHelper.findFuzzyMatch: exact match found");
|
|
14445
|
+
return searchStr;
|
|
14446
|
+
}
|
|
14447
|
+
const sanitized = this.sanitizeForRegex(searchStr);
|
|
14448
|
+
const fuzzyPattern = sanitized.split(/\s+/).map((word) => this.sanitizeForRegex(word)).join("\\s*");
|
|
14449
|
+
const regex = this.createSafeRegex(`\\b${fuzzyPattern}\\b`, "i");
|
|
14450
|
+
if (regex) {
|
|
14451
|
+
const match = content.match(regex);
|
|
14452
|
+
if (match) {
|
|
14453
|
+
console.log("RegexHelper.findFuzzyMatch: fuzzy regex match found", {
|
|
14454
|
+
matched: match[0].substring(0, 50)
|
|
14455
|
+
});
|
|
14456
|
+
return match[0];
|
|
14457
|
+
}
|
|
14458
|
+
}
|
|
14459
|
+
const lines = content.split("\n");
|
|
14460
|
+
let bestMatch = null;
|
|
14461
|
+
let bestDistance = Infinity;
|
|
14462
|
+
const maxDistance = Math.min(searchStr.length / 2, 5);
|
|
14463
|
+
for (const line of lines) {
|
|
14464
|
+
const trimmed = line.trim();
|
|
14465
|
+
if (trimmed.length === 0) continue;
|
|
14466
|
+
const distance = this.levenshteinDistance(trimmed, searchStr);
|
|
14467
|
+
if (distance < bestDistance && distance <= maxDistance) {
|
|
14468
|
+
bestDistance = distance;
|
|
14469
|
+
bestMatch = trimmed;
|
|
14470
|
+
}
|
|
14471
|
+
}
|
|
14472
|
+
if (bestMatch) {
|
|
14473
|
+
console.log("RegexHelper.findFuzzyMatch: Levenshtein match found", {
|
|
14474
|
+
distance: bestDistance,
|
|
14475
|
+
matched: bestMatch.substring(0, 50)
|
|
14476
|
+
});
|
|
14477
|
+
} else {
|
|
14478
|
+
console.log("RegexHelper.findFuzzyMatch: no match found");
|
|
14479
|
+
}
|
|
14480
|
+
return bestMatch;
|
|
14481
|
+
} catch (error) {
|
|
14482
|
+
console.log("RegexHelper.findFuzzyMatch critical error", {
|
|
14483
|
+
error: error.message,
|
|
14484
|
+
errorName: error.name,
|
|
14485
|
+
errorStack: error.stack?.substring(0, 500),
|
|
14486
|
+
searchStrPreview: searchStr.substring(0, 50)
|
|
14487
|
+
});
|
|
14488
|
+
return null;
|
|
14489
|
+
}
|
|
14490
|
+
}
|
|
14491
|
+
/**
|
|
14492
|
+
* Calculate Levenshtein distance between two strings
|
|
14493
|
+
* Used as fallback when regex fails
|
|
14494
|
+
*/
|
|
14495
|
+
static levenshteinDistance(a, b) {
|
|
14496
|
+
if (a.length === 0) return b.length;
|
|
14497
|
+
if (b.length === 0) return a.length;
|
|
14498
|
+
const matrix = [];
|
|
14499
|
+
for (let i = 0; i <= b.length; i++) {
|
|
14500
|
+
matrix[i] = [i];
|
|
14501
|
+
}
|
|
14502
|
+
for (let j = 0; j <= a.length; j++) {
|
|
14503
|
+
matrix[0][j] = j;
|
|
14504
|
+
}
|
|
14505
|
+
for (let i = 1; i <= b.length; i++) {
|
|
14506
|
+
for (let j = 1; j <= a.length; j++) {
|
|
14507
|
+
if (b.charAt(i - 1) === a.charAt(j - 1)) {
|
|
14508
|
+
matrix[i][j] = matrix[i - 1][j - 1];
|
|
14509
|
+
} else {
|
|
14510
|
+
matrix[i][j] = Math.min(
|
|
14511
|
+
matrix[i - 1][j - 1] + 1,
|
|
14512
|
+
// substitution
|
|
14513
|
+
matrix[i][j - 1] + 1,
|
|
14514
|
+
// insertion
|
|
14515
|
+
matrix[i - 1][j] + 1
|
|
14516
|
+
// deletion
|
|
14517
|
+
);
|
|
14518
|
+
}
|
|
14519
|
+
}
|
|
14520
|
+
}
|
|
14521
|
+
return matrix[b.length][a.length];
|
|
14522
|
+
}
|
|
14523
|
+
/**
|
|
14524
|
+
* Validate if a string contains potentially dangerous regex patterns
|
|
14525
|
+
* Useful for input validation before processing
|
|
14526
|
+
*/
|
|
14527
|
+
static hasDangerousPatterns(input) {
|
|
14528
|
+
const openBrackets = (input.match(/\[/g) || []).length;
|
|
14529
|
+
const closeBrackets = (input.match(/\]/g) || []).length;
|
|
14530
|
+
if (openBrackets !== closeBrackets) {
|
|
14531
|
+
console.log("RegexHelper.hasDangerousPatterns: unbalanced brackets detected", {
|
|
14532
|
+
open: openBrackets,
|
|
14533
|
+
close: closeBrackets
|
|
14534
|
+
});
|
|
14535
|
+
return true;
|
|
14536
|
+
}
|
|
14537
|
+
const dangerousPatterns = [
|
|
14538
|
+
/\\[dws]/,
|
|
14539
|
+
// Incomplete escape sequences
|
|
14540
|
+
/\(\?/,
|
|
14541
|
+
// Incomplete lookbehind/lookahead
|
|
14542
|
+
/\{[^}]*$/
|
|
14543
|
+
// Unclosed quantifier
|
|
14544
|
+
];
|
|
14545
|
+
for (const pattern of dangerousPatterns) {
|
|
14546
|
+
if (pattern.test(input)) {
|
|
14547
|
+
console.log("RegexHelper.hasDangerousPatterns: dangerous pattern detected", {
|
|
14548
|
+
pattern: pattern.source,
|
|
14549
|
+
inputPreview: input.substring(0, 50)
|
|
14550
|
+
});
|
|
14551
|
+
return true;
|
|
14552
|
+
}
|
|
14553
|
+
}
|
|
14554
|
+
return false;
|
|
14555
|
+
}
|
|
14556
|
+
};
|
|
14557
|
+
}
|
|
14558
|
+
});
|
|
14559
|
+
|
|
12331
14560
|
// node_modules/zod/v3/helpers/util.js
|
|
12332
14561
|
var util, objectUtil, ZodParsedType, getParsedType;
|
|
12333
14562
|
var init_util = __esm({
|
|
@@ -12740,8 +14969,8 @@ var init_parseUtil = __esm({
|
|
|
12740
14969
|
init_errors();
|
|
12741
14970
|
init_en();
|
|
12742
14971
|
makeIssue = (params) => {
|
|
12743
|
-
const { data, path:
|
|
12744
|
-
const fullPath = [...
|
|
14972
|
+
const { data, path: path43, errorMaps, issueData } = params;
|
|
14973
|
+
const fullPath = [...path43, ...issueData.path || []];
|
|
12745
14974
|
const fullIssue = {
|
|
12746
14975
|
...issueData,
|
|
12747
14976
|
path: fullPath
|
|
@@ -13049,11 +15278,11 @@ var init_types = __esm({
|
|
|
13049
15278
|
init_parseUtil();
|
|
13050
15279
|
init_util();
|
|
13051
15280
|
ParseInputLazyPath = class {
|
|
13052
|
-
constructor(parent, value,
|
|
15281
|
+
constructor(parent, value, path43, key) {
|
|
13053
15282
|
this._cachedPath = [];
|
|
13054
15283
|
this.parent = parent;
|
|
13055
15284
|
this.data = value;
|
|
13056
|
-
this._path =
|
|
15285
|
+
this._path = path43;
|
|
13057
15286
|
this._key = key;
|
|
13058
15287
|
}
|
|
13059
15288
|
get path() {
|
|
@@ -16634,8 +18863,8 @@ var init_codebase_indexer = __esm({
|
|
|
16634
18863
|
};
|
|
16635
18864
|
}
|
|
16636
18865
|
async indexFile(filePath) {
|
|
16637
|
-
const stats = await
|
|
16638
|
-
const content = await
|
|
18866
|
+
const stats = await fs9__default.promises.stat(filePath);
|
|
18867
|
+
const content = await fs9__default.promises.readFile(filePath, "utf8");
|
|
16639
18868
|
const extension = path8__default.extname(filePath);
|
|
16640
18869
|
const language = this.detectLanguage(extension);
|
|
16641
18870
|
return {
|
|
@@ -16650,7 +18879,7 @@ var init_codebase_indexer = __esm({
|
|
|
16650
18879
|
};
|
|
16651
18880
|
}
|
|
16652
18881
|
async extractSymbols(filePath) {
|
|
16653
|
-
const content = await
|
|
18882
|
+
const content = await fs9__default.promises.readFile(filePath, "utf8");
|
|
16654
18883
|
const extension = path8__default.extname(filePath);
|
|
16655
18884
|
const symbols = [];
|
|
16656
18885
|
if (extension === ".ts" || extension === ".js" || extension === ".tsx" || extension === ".jsx") {
|
|
@@ -16800,7 +19029,7 @@ var init_codebase_indexer = __esm({
|
|
|
16800
19029
|
const dirInfo = dirMap.get(dir);
|
|
16801
19030
|
dirInfo.fileCount++;
|
|
16802
19031
|
try {
|
|
16803
|
-
const stats = await
|
|
19032
|
+
const stats = await fs9__default.promises.stat(file);
|
|
16804
19033
|
dirInfo.totalSize += stats.size;
|
|
16805
19034
|
} catch (error) {
|
|
16806
19035
|
}
|
|
@@ -16827,7 +19056,7 @@ var init_codebase_indexer = __esm({
|
|
|
16827
19056
|
const packageJson = configFiles.find((f) => path8__default.basename(f) === "package.json");
|
|
16828
19057
|
if (packageJson) {
|
|
16829
19058
|
try {
|
|
16830
|
-
const pkg = JSON.parse(
|
|
19059
|
+
const pkg = JSON.parse(fs9__default.readFileSync(packageJson, "utf8"));
|
|
16831
19060
|
if (pkg.main) entryPoints.push(path8__default.resolve(path8__default.dirname(packageJson), pkg.main));
|
|
16832
19061
|
if (pkg.types) entryPoints.push(path8__default.resolve(path8__default.dirname(packageJson), pkg.types));
|
|
16833
19062
|
} catch (error) {
|
|
@@ -17609,7 +19838,7 @@ var init_semantic_code_search = __esm({
|
|
|
17609
19838
|
}
|
|
17610
19839
|
async extractContext(symbol) {
|
|
17611
19840
|
try {
|
|
17612
|
-
const content = await
|
|
19841
|
+
const content = await fs6__default.readFile(symbol.filePath, "utf8");
|
|
17613
19842
|
const lines = content.split("\n");
|
|
17614
19843
|
const startLine = Math.max(0, symbol.line - 3);
|
|
17615
19844
|
const endLine = Math.min(lines.length, symbol.line + 3);
|
|
@@ -17650,7 +19879,7 @@ var init_semantic_code_search = __esm({
|
|
|
17650
19879
|
for (const [filePath, fileInfo] of index.files) {
|
|
17651
19880
|
if (fileInfo.language === "unknown" || fileInfo.size > 1e5) continue;
|
|
17652
19881
|
try {
|
|
17653
|
-
const content = await
|
|
19882
|
+
const content = await fs6__default.readFile(filePath, "utf8");
|
|
17654
19883
|
const lines = content.split("\n");
|
|
17655
19884
|
for (let i = 0; i < lines.length; i++) {
|
|
17656
19885
|
const line = lines[i].toLowerCase();
|
|
@@ -18371,6 +20600,7 @@ var init_grok_agent = __esm({
|
|
|
18371
20600
|
init_settings_manager();
|
|
18372
20601
|
init_research_recommend();
|
|
18373
20602
|
init_execution_orchestrator();
|
|
20603
|
+
init_regex_helper();
|
|
18374
20604
|
GrokAgent = class extends EventEmitter {
|
|
18375
20605
|
constructor(apiKey, baseURL, model, maxToolRounds, contextPack, verbosityLevel, explainLevel) {
|
|
18376
20606
|
super();
|
|
@@ -18519,6 +20749,12 @@ IMPORTANT RESPONSE GUIDELINES:
|
|
|
18519
20749
|
- Keep responses concise and focused on the actual work being done
|
|
18520
20750
|
- If a tool execution completes the user's request, you can remain silent or give a brief confirmation
|
|
18521
20751
|
|
|
20752
|
+
\u{1F3A8} COLORED DIFF OUTPUT RULES:
|
|
20753
|
+
- When str_replace_editor returns colored diff output with ANSI escape codes, ALWAYS show the full tool output directly
|
|
20754
|
+
- NEVER summarize or paraphrase tool results that contain colored diffs - show the complete output
|
|
20755
|
+
- If the tool output contains ANSI color codes (\\x1b[), display it exactly as returned by the tool
|
|
20756
|
+
- Show the full colored diff with line numbers, not just a summary like "\u2705 Changed X to Y"
|
|
20757
|
+
|
|
18522
20758
|
Current working directory: ${process.cwd()}`
|
|
18523
20759
|
});
|
|
18524
20760
|
}
|
|
@@ -19098,10 +21334,10 @@ Current working directory: ${process.cwd()}`
|
|
|
19098
21334
|
return await this.textEditor.view(args.path, range);
|
|
19099
21335
|
} catch (error) {
|
|
19100
21336
|
console.warn(`view_file tool failed, falling back to bash: ${error.message}`);
|
|
19101
|
-
const
|
|
19102
|
-
let command = `cat "${
|
|
21337
|
+
const path43 = args.path;
|
|
21338
|
+
let command = `cat "${path43}"`;
|
|
19103
21339
|
if (args.start_line && args.end_line) {
|
|
19104
|
-
command = `sed -n '${args.start_line},${args.end_line}p' "${
|
|
21340
|
+
command = `sed -n '${args.start_line},${args.end_line}p' "${path43}"`;
|
|
19105
21341
|
}
|
|
19106
21342
|
return await this.bash.execute(command);
|
|
19107
21343
|
}
|
|
@@ -19128,8 +21364,8 @@ EOF`;
|
|
|
19128
21364
|
return await this.wrapWithChainValidation(toolCall, result);
|
|
19129
21365
|
} catch (error) {
|
|
19130
21366
|
console.warn(`str_replace_editor tool failed, falling back to bash: ${error.message}`);
|
|
19131
|
-
const escapedOld = args.old_str
|
|
19132
|
-
const escapedNew = args.new_str
|
|
21367
|
+
const escapedOld = RegexHelper.sanitizeForRegex(args.old_str);
|
|
21368
|
+
const escapedNew = RegexHelper.sanitizeForRegex(args.new_str);
|
|
19133
21369
|
const sedCommand = args.replace_all ? `sed -i 's/${escapedOld}/${escapedNew}/g' "${args.path}"` : `sed -i '0,/${escapedOld}/s/${escapedOld}/${escapedNew}/' "${args.path}"`;
|
|
19134
21370
|
const result = await this.bash.execute(sedCommand);
|
|
19135
21371
|
return await this.wrapWithChainValidation(toolCall, result);
|
|
@@ -19386,12 +21622,12 @@ EOF`;
|
|
|
19386
21622
|
saveSessionLog() {
|
|
19387
21623
|
try {
|
|
19388
21624
|
const sessionDir = path8__default.join(__require("os").homedir(), ".grok");
|
|
19389
|
-
if (!
|
|
19390
|
-
|
|
21625
|
+
if (!fs9__default.existsSync(sessionDir)) {
|
|
21626
|
+
fs9__default.mkdirSync(sessionDir, { recursive: true });
|
|
19391
21627
|
}
|
|
19392
21628
|
const sessionFile = path8__default.join(sessionDir, "session.log");
|
|
19393
21629
|
const logLines = this.chatHistory.map((entry) => JSON.stringify(entry)).join("\n") + "\n";
|
|
19394
|
-
|
|
21630
|
+
fs9__default.writeFileSync(sessionFile, logLines);
|
|
19395
21631
|
} catch (error) {
|
|
19396
21632
|
console.warn("Failed to save session log:", error);
|
|
19397
21633
|
}
|
|
@@ -19432,17 +21668,6 @@ EOF`;
|
|
|
19432
21668
|
timestamp: Date.now()
|
|
19433
21669
|
});
|
|
19434
21670
|
}
|
|
19435
|
-
if (!result.success) {
|
|
19436
|
-
console.warn(`[GrokAgent] Tool chain validation failed at ${toolCall.function.name}:`, {
|
|
19437
|
-
operationId: this.toolChainContext.operationId,
|
|
19438
|
-
chainLength: this.toolChainContext.chainedOperations.length,
|
|
19439
|
-
previousOperations: this.toolChainContext.chainedOperations.slice(-3).map((op) => ({
|
|
19440
|
-
tool: op.toolName,
|
|
19441
|
-
success: op.success,
|
|
19442
|
-
ago: Date.now() - op.timestamp
|
|
19443
|
-
}))
|
|
19444
|
-
});
|
|
19445
|
-
}
|
|
19446
21671
|
if (this.toolChainContext.chainedOperations.length > 50) {
|
|
19447
21672
|
this.toolChainContext.chainedOperations = this.toolChainContext.chainedOperations.slice(-25);
|
|
19448
21673
|
this.toolChainContext.rollbackPoints = this.toolChainContext.rollbackPoints.slice(-10);
|
|
@@ -19651,8 +21876,8 @@ EOF`;
|
|
|
19651
21876
|
logEntry(entry) {
|
|
19652
21877
|
try {
|
|
19653
21878
|
const dir = path8__default.dirname(this.sessionLogPath);
|
|
19654
|
-
if (!
|
|
19655
|
-
|
|
21879
|
+
if (!fs9__default.existsSync(dir)) {
|
|
21880
|
+
fs9__default.mkdirSync(dir, { recursive: true });
|
|
19656
21881
|
}
|
|
19657
21882
|
const logLine = JSON.stringify({
|
|
19658
21883
|
type: entry.type,
|
|
@@ -19661,7 +21886,7 @@ EOF`;
|
|
|
19661
21886
|
toolCallId: entry.toolCall?.id,
|
|
19662
21887
|
toolCallsCount: entry.toolCalls?.length
|
|
19663
21888
|
}) + "\n";
|
|
19664
|
-
|
|
21889
|
+
fs9__default.appendFileSync(this.sessionLogPath, logLine);
|
|
19665
21890
|
} catch (error) {
|
|
19666
21891
|
console.warn("Failed to log session entry:", error);
|
|
19667
21892
|
}
|
|
@@ -21851,7 +24076,7 @@ var init_readonly_filesystem_overlay = __esm({
|
|
|
21851
24076
|
};
|
|
21852
24077
|
}
|
|
21853
24078
|
try {
|
|
21854
|
-
const actualContent = await
|
|
24079
|
+
const actualContent = await fs9__default.promises.readFile(resolvedPath, "utf-8");
|
|
21855
24080
|
return {
|
|
21856
24081
|
success: true,
|
|
21857
24082
|
output: this.formatFileContent(actualContent, args),
|
|
@@ -21908,7 +24133,7 @@ var init_readonly_filesystem_overlay = __esm({
|
|
|
21908
24133
|
const filePath = args.path || args.file_path || args.filename;
|
|
21909
24134
|
const content = args.content || "";
|
|
21910
24135
|
const resolvedPath = path8__default.resolve(this.config.baseDirectory, filePath);
|
|
21911
|
-
const fileExists =
|
|
24136
|
+
const fileExists = fs9__default.existsSync(resolvedPath);
|
|
21912
24137
|
const sizeImpact = content.length;
|
|
21913
24138
|
return {
|
|
21914
24139
|
type: "file_creation",
|
|
@@ -21937,7 +24162,7 @@ var init_readonly_filesystem_overlay = __esm({
|
|
|
21937
24162
|
const filePath = args.path || args.file_path || args.filename;
|
|
21938
24163
|
const resolvedPath = path8__default.resolve(this.config.baseDirectory, filePath);
|
|
21939
24164
|
try {
|
|
21940
|
-
const originalContent =
|
|
24165
|
+
const originalContent = fs9__default.existsSync(resolvedPath) ? await fs9__default.promises.readFile(resolvedPath, "utf-8") : "";
|
|
21941
24166
|
let newContent = originalContent;
|
|
21942
24167
|
if (args.old_string && args.new_string !== void 0) {
|
|
21943
24168
|
newContent = args.replace_all ? originalContent.split(args.old_string).join(args.new_string) : originalContent.replace(args.old_string, args.new_string);
|
|
@@ -21980,11 +24205,11 @@ var init_readonly_filesystem_overlay = __esm({
|
|
|
21980
24205
|
async simulateFileDeletion(args) {
|
|
21981
24206
|
const filePath = args.path || args.file_path || args.filename;
|
|
21982
24207
|
const resolvedPath = path8__default.resolve(this.config.baseDirectory, filePath);
|
|
21983
|
-
const fileExists =
|
|
24208
|
+
const fileExists = fs9__default.existsSync(resolvedPath);
|
|
21984
24209
|
let originalSize = 0;
|
|
21985
24210
|
if (fileExists) {
|
|
21986
24211
|
try {
|
|
21987
|
-
const stats = await
|
|
24212
|
+
const stats = await fs9__default.promises.stat(resolvedPath);
|
|
21988
24213
|
originalSize = stats.size;
|
|
21989
24214
|
} catch {
|
|
21990
24215
|
}
|
|
@@ -27050,7 +29275,7 @@ var init_package = __esm({
|
|
|
27050
29275
|
package_default = {
|
|
27051
29276
|
type: "module",
|
|
27052
29277
|
name: "@xagent/one-shot",
|
|
27053
|
-
version: "1.2.
|
|
29278
|
+
version: "1.2.13",
|
|
27054
29279
|
description: "An open-source AI agent that brings advanced AI capabilities directly into your terminal with automatic documentation updates.",
|
|
27055
29280
|
main: "dist/index.js",
|
|
27056
29281
|
module: "dist/index.js",
|
|
@@ -27137,6 +29362,7 @@ var init_package = __esm({
|
|
|
27137
29362
|
chokidar: "^4.0.3",
|
|
27138
29363
|
"cli-highlight": "^2.1.11",
|
|
27139
29364
|
commander: "^12.0.0",
|
|
29365
|
+
diff: "^8.0.2",
|
|
27140
29366
|
dotenv: "^16.4.0",
|
|
27141
29367
|
enquirer: "^2.4.1",
|
|
27142
29368
|
"fs-extra": "^11.2.0",
|
|
@@ -29625,14 +31851,14 @@ function useContextInfo(agent) {
|
|
|
29625
31851
|
async function getWorkspaceFileCount() {
|
|
29626
31852
|
try {
|
|
29627
31853
|
const cwd = process.cwd();
|
|
29628
|
-
const entries = await
|
|
31854
|
+
const entries = await fs9__default.promises.readdir(cwd, { withFileTypes: true });
|
|
29629
31855
|
let count = 0;
|
|
29630
31856
|
for (const entry of entries) {
|
|
29631
31857
|
if (entry.isFile() && !shouldIgnoreFile(entry.name)) {
|
|
29632
31858
|
count++;
|
|
29633
31859
|
} else if (entry.isDirectory() && !shouldIgnoreDirectory(entry.name)) {
|
|
29634
31860
|
try {
|
|
29635
|
-
const subEntries = await
|
|
31861
|
+
const subEntries = await fs9__default.promises.readdir(path8__default.join(cwd, entry.name), { withFileTypes: true });
|
|
29636
31862
|
count += subEntries.filter((sub) => sub.isFile() && !shouldIgnoreFile(sub.name)).length;
|
|
29637
31863
|
} catch {
|
|
29638
31864
|
}
|
|
@@ -29646,15 +31872,15 @@ async function getWorkspaceFileCount() {
|
|
|
29646
31872
|
function shouldIgnoreFile(filename) {
|
|
29647
31873
|
return filename.startsWith(".") || filename.endsWith(".log") || filename.includes(".tmp");
|
|
29648
31874
|
}
|
|
29649
|
-
function shouldIgnoreDirectory(
|
|
31875
|
+
function shouldIgnoreDirectory(dirname6) {
|
|
29650
31876
|
const ignoreDirs = ["node_modules", ".git", "dist", "build", ".next", "coverage"];
|
|
29651
|
-
return ignoreDirs.includes(
|
|
31877
|
+
return ignoreDirs.includes(dirname6) || dirname6.startsWith(".");
|
|
29652
31878
|
}
|
|
29653
31879
|
async function getIndexSize() {
|
|
29654
31880
|
try {
|
|
29655
31881
|
const indexPath = path8__default.join(process.cwd(), ".grok", "index.json");
|
|
29656
|
-
if (
|
|
29657
|
-
const stats = await
|
|
31882
|
+
if (fs9__default.existsSync(indexPath)) {
|
|
31883
|
+
const stats = await fs9__default.promises.stat(indexPath);
|
|
29658
31884
|
const mb = stats.size / (1024 * 1024);
|
|
29659
31885
|
return mb > 1 ? `${mb.toFixed(1)} MB` : `${(stats.size / 1024).toFixed(1)} KB`;
|
|
29660
31886
|
}
|
|
@@ -29665,8 +31891,8 @@ async function getIndexSize() {
|
|
|
29665
31891
|
async function getSessionFileCount() {
|
|
29666
31892
|
try {
|
|
29667
31893
|
const sessionPath = path8__default.join(os__default.homedir(), ".grok", "session.log");
|
|
29668
|
-
if (
|
|
29669
|
-
const content = await
|
|
31894
|
+
if (fs9__default.existsSync(sessionPath)) {
|
|
31895
|
+
const content = await fs9__default.promises.readFile(sessionPath, "utf8");
|
|
29670
31896
|
return content.split("\n").filter((line) => line.trim()).length;
|
|
29671
31897
|
}
|
|
29672
31898
|
} catch {
|
|
@@ -29676,8 +31902,8 @@ async function getSessionFileCount() {
|
|
|
29676
31902
|
async function getGitBranch() {
|
|
29677
31903
|
try {
|
|
29678
31904
|
const gitPath = path8__default.join(process.cwd(), ".git", "HEAD");
|
|
29679
|
-
if (
|
|
29680
|
-
const content = await
|
|
31905
|
+
if (fs9__default.existsSync(gitPath)) {
|
|
31906
|
+
const content = await fs9__default.promises.readFile(gitPath, "utf8");
|
|
29681
31907
|
const match = content.match(/ref: refs\/heads\/(.+)/);
|
|
29682
31908
|
return match ? match[1].trim() : "detached";
|
|
29683
31909
|
}
|
|
@@ -29688,8 +31914,8 @@ async function getGitBranch() {
|
|
|
29688
31914
|
async function getProjectName() {
|
|
29689
31915
|
try {
|
|
29690
31916
|
const packagePath = path8__default.join(process.cwd(), "package.json");
|
|
29691
|
-
if (
|
|
29692
|
-
const content = await
|
|
31917
|
+
if (fs9__default.existsSync(packagePath)) {
|
|
31918
|
+
const content = await fs9__default.promises.readFile(packagePath, "utf8");
|
|
29693
31919
|
const pkg = JSON.parse(content);
|
|
29694
31920
|
return pkg.name;
|
|
29695
31921
|
}
|
|
@@ -29738,14 +31964,14 @@ function useCLAUDEmd(setChatHistory) {
|
|
|
29738
31964
|
let totalChars = 0;
|
|
29739
31965
|
for (const file of filesToLoad) {
|
|
29740
31966
|
let filePath = file.path;
|
|
29741
|
-
let exists =
|
|
31967
|
+
let exists = fs9__default.existsSync(filePath);
|
|
29742
31968
|
if (!exists && file.fallback) {
|
|
29743
31969
|
filePath = file.fallback;
|
|
29744
|
-
exists =
|
|
31970
|
+
exists = fs9__default.existsSync(filePath);
|
|
29745
31971
|
}
|
|
29746
31972
|
if (exists) {
|
|
29747
31973
|
try {
|
|
29748
|
-
const content =
|
|
31974
|
+
const content = fs9__default.readFileSync(filePath, "utf8");
|
|
29749
31975
|
const charCount = content.length;
|
|
29750
31976
|
totalChars += charCount;
|
|
29751
31977
|
loadedDocs.push(file.label);
|
|
@@ -30119,11 +32345,11 @@ function useSessionLogging(chatHistory) {
|
|
|
30119
32345
|
const sessionFile = path8__default.join(os__default.homedir(), ".grok", "session.log");
|
|
30120
32346
|
try {
|
|
30121
32347
|
const dir = path8__default.dirname(sessionFile);
|
|
30122
|
-
if (!
|
|
30123
|
-
|
|
32348
|
+
if (!fs9__default.existsSync(dir)) {
|
|
32349
|
+
fs9__default.mkdirSync(dir, { recursive: true });
|
|
30124
32350
|
}
|
|
30125
32351
|
const lines = newEntries.map((entry) => JSON.stringify(entry)).join("\n") + "\n";
|
|
30126
|
-
|
|
32352
|
+
fs9__default.appendFileSync(sessionFile, lines);
|
|
30127
32353
|
} catch {
|
|
30128
32354
|
}
|
|
30129
32355
|
}
|
|
@@ -30513,8 +32739,123 @@ var init_user_message_entry = __esm({
|
|
|
30513
32739
|
};
|
|
30514
32740
|
}
|
|
30515
32741
|
});
|
|
32742
|
+
function logToSession2(message, data) {
|
|
32743
|
+
try {
|
|
32744
|
+
const timestamp = (/* @__PURE__ */ new Date()).toISOString();
|
|
32745
|
+
const logEntry = `
|
|
32746
|
+
[${timestamp}] \u{1F3A8} COLORED DIFF RENDERER - ${message}
|
|
32747
|
+
=====================================
|
|
32748
|
+
${data ? JSON.stringify(data, null, 2) : "No additional data"}
|
|
32749
|
+
=====================================
|
|
32750
|
+
`;
|
|
32751
|
+
const workingDir = process.cwd();
|
|
32752
|
+
const logsDir = path8__default.join(workingDir, "logs");
|
|
32753
|
+
const sessionFiles = fs9__default.readdirSync(logsDir).filter((f) => f.startsWith("session-") && f.endsWith(".log"));
|
|
32754
|
+
if (sessionFiles.length > 0) {
|
|
32755
|
+
const sessionFile = path8__default.join(logsDir, sessionFiles[sessionFiles.length - 1]);
|
|
32756
|
+
fs9__default.appendFileSync(sessionFile, logEntry);
|
|
32757
|
+
} else {
|
|
32758
|
+
console.log(`[ColoredDiffRenderer] ${message}`, data);
|
|
32759
|
+
}
|
|
32760
|
+
} catch (error) {
|
|
32761
|
+
console.log(`[ColoredDiffRenderer] ${message}`, data);
|
|
32762
|
+
console.error("[ColoredDiffRenderer] Session logging failed:", error);
|
|
32763
|
+
}
|
|
32764
|
+
}
|
|
32765
|
+
function ColoredDiffRenderer({ content }) {
|
|
32766
|
+
try {
|
|
32767
|
+
logToSession2("Rendering content with ANSI codes", {
|
|
32768
|
+
contentLength: content.length,
|
|
32769
|
+
contentPreview: content.substring(0, 200),
|
|
32770
|
+
ansiCodes: [],
|
|
32771
|
+
// ANSI codes detected in content
|
|
32772
|
+
lineCount: content.split("\n").length
|
|
32773
|
+
});
|
|
32774
|
+
const parseAnsiAndRender = (text) => {
|
|
32775
|
+
const parts = [];
|
|
32776
|
+
const lines = text.split("\n");
|
|
32777
|
+
lines.forEach((line, lineIndex) => {
|
|
32778
|
+
if (lineIndex > 0) {
|
|
32779
|
+
parts.push("\n");
|
|
32780
|
+
}
|
|
32781
|
+
if (line.includes("\x1B[32m") && line.includes(" +")) {
|
|
32782
|
+
const ansiEscape = String.fromCharCode(27);
|
|
32783
|
+
const cleanLine = line.replace(new RegExp(`${ansiEscape.replace(/[.*+?^${}()|\\[\\]\\\\]/g, "\\$&")}\\[\\d+m`, "g"), "");
|
|
32784
|
+
parts.push(/* @__PURE__ */ jsx(Text, { color: "green", children: cleanLine }, `${lineIndex}-green`));
|
|
32785
|
+
} else if (line.includes("\x1B[31m") && line.includes(" -")) {
|
|
32786
|
+
const ansiEscape = String.fromCharCode(27);
|
|
32787
|
+
const cleanLine = line.replace(new RegExp(`${ansiEscape.replace(/[.*+?^${}()|\\[\\]\\\\]/g, "\\$&")}\\[\\d+m`, "g"), "");
|
|
32788
|
+
parts.push(/* @__PURE__ */ jsx(Text, { color: "red", children: cleanLine }, `${lineIndex}-red`));
|
|
32789
|
+
} else if (line.includes("\x1B[32m") && line.includes("\u2705")) {
|
|
32790
|
+
const ansiEscape = String.fromCharCode(27);
|
|
32791
|
+
const cleanLine = line.replace(new RegExp(`${ansiEscape.replace(/[.*+?^${}()|\\[\\]\\\\]/g, "\\$&")}\\[\\d+m`, "g"), "");
|
|
32792
|
+
parts.push(/* @__PURE__ */ jsx(Text, { color: "green", children: cleanLine }, `${lineIndex}-summary`));
|
|
32793
|
+
} else if (line.includes("\x1B[36m")) {
|
|
32794
|
+
const ansiEscape = String.fromCharCode(27);
|
|
32795
|
+
const cleanLine = line.replace(new RegExp(`${ansiEscape.replace(/[.*+?^${}()|\\[\\]\\\\]/g, "\\$&")}\\[\\d+m`, "g"), "");
|
|
32796
|
+
parts.push(/* @__PURE__ */ jsx(Text, { color: "cyan", children: cleanLine }, `${lineIndex}-cyan`));
|
|
32797
|
+
} else {
|
|
32798
|
+
const ansiEscape = String.fromCharCode(27);
|
|
32799
|
+
const cleanLine = line.replace(new RegExp(`${ansiEscape.replace(/[.*+?^${}()|\\[\\]\\\\]/g, "\\$&")}\\[\\d+m`, "g"), "");
|
|
32800
|
+
parts.push(/* @__PURE__ */ jsx(Text, { children: cleanLine }, `${lineIndex}-context`));
|
|
32801
|
+
}
|
|
32802
|
+
});
|
|
32803
|
+
return parts;
|
|
32804
|
+
};
|
|
32805
|
+
return /* @__PURE__ */ jsx(Text, { wrap: "wrap", dimColor: false, children: parseAnsiAndRender(content) });
|
|
32806
|
+
} catch (error) {
|
|
32807
|
+
return /* @__PURE__ */ jsxs(Text, { wrap: "wrap", dimColor: false, color: "red", children: [
|
|
32808
|
+
"Error rendering colored diff: ",
|
|
32809
|
+
error.message,
|
|
32810
|
+
"\n",
|
|
32811
|
+
content
|
|
32812
|
+
] });
|
|
32813
|
+
}
|
|
32814
|
+
}
|
|
32815
|
+
var init_colored_diff_renderer = __esm({
|
|
32816
|
+
"src/ui/components/colored-diff-renderer.tsx"() {
|
|
32817
|
+
}
|
|
32818
|
+
});
|
|
32819
|
+
function logToSession3(message, data) {
|
|
32820
|
+
try {
|
|
32821
|
+
const timestamp = (/* @__PURE__ */ new Date()).toISOString();
|
|
32822
|
+
const logEntry = `
|
|
32823
|
+
[${timestamp}] \u{1F3A8} MARKDOWN RENDERER - ${message}
|
|
32824
|
+
=====================================
|
|
32825
|
+
${data ? JSON.stringify(data, null, 2) : "No additional data"}
|
|
32826
|
+
=====================================
|
|
32827
|
+
`;
|
|
32828
|
+
const workingDir = process.cwd();
|
|
32829
|
+
const logsDir = path8__default.join(workingDir, "logs");
|
|
32830
|
+
const sessionFiles = fs9__default.readdirSync(logsDir).filter((f) => f.startsWith("session-") && f.endsWith(".log"));
|
|
32831
|
+
if (sessionFiles.length > 0) {
|
|
32832
|
+
const sessionFile = path8__default.join(logsDir, sessionFiles[sessionFiles.length - 1]);
|
|
32833
|
+
fs9__default.appendFileSync(sessionFile, logEntry);
|
|
32834
|
+
} else {
|
|
32835
|
+
console.log(`[MarkdownRenderer] ${message}`, data);
|
|
32836
|
+
}
|
|
32837
|
+
} catch (error) {
|
|
32838
|
+
console.log(`[MarkdownRenderer] ${message}`, data);
|
|
32839
|
+
console.error("[MarkdownRenderer] Session logging failed:", error);
|
|
32840
|
+
}
|
|
32841
|
+
}
|
|
30516
32842
|
function MarkdownRenderer({ content }) {
|
|
30517
32843
|
try {
|
|
32844
|
+
const ansiEscape = String.fromCharCode(27);
|
|
32845
|
+
const hasAnsiColors = new RegExp(`${ansiEscape.replace(/[.*+?^${}()|\\[\\]\\\\]/g, "\\$&")}\\[\\d+m`).test(content);
|
|
32846
|
+
const hasDiffMarkers = /^[\+\-\s].*$/m.test(content);
|
|
32847
|
+
logToSession3("Content analysis", {
|
|
32848
|
+
contentLength: content.length,
|
|
32849
|
+
contentPreview: content.substring(0, 200),
|
|
32850
|
+
hasAnsiColors,
|
|
32851
|
+
hasDiffMarkers,
|
|
32852
|
+
ansiEscapeUsed: ansiEscape.charCodeAt(0),
|
|
32853
|
+
regexPattern: `${ansiEscape.replace(/[.*+?^${}()|\\[\\]\\\\]/g, "\\$&")}\\[\\d+m`
|
|
32854
|
+
});
|
|
32855
|
+
if (hasAnsiColors && hasDiffMarkers) {
|
|
32856
|
+
logToSession3("Using ColoredDiffRenderer for ANSI + diff content");
|
|
32857
|
+
return /* @__PURE__ */ jsx(ColoredDiffRenderer, { content });
|
|
32858
|
+
}
|
|
30518
32859
|
return /* @__PURE__ */ jsx(InlineMarkdown, { content });
|
|
30519
32860
|
} catch (error) {
|
|
30520
32861
|
console.error("Markdown rendering error:", error);
|
|
@@ -30673,6 +33014,7 @@ function parseInlineMarkdown(content) {
|
|
|
30673
33014
|
}
|
|
30674
33015
|
var init_markdown_renderer = __esm({
|
|
30675
33016
|
"src/ui/utils/markdown-renderer.tsx"() {
|
|
33017
|
+
init_colored_diff_renderer();
|
|
30676
33018
|
}
|
|
30677
33019
|
});
|
|
30678
33020
|
function AssistantMessageEntry({ entry, verbosityLevel: _verbosityLevel }) {
|
|
@@ -30958,13 +33300,18 @@ var init_tool_brevity_service = __esm({
|
|
|
30958
33300
|
const normalizedToolName = this.normalizeToolName(toolName);
|
|
30959
33301
|
const metadata = this.extractMetadata(normalizedToolName, result);
|
|
30960
33302
|
const summary = this.generateSummary(normalizedToolName, result, metadata);
|
|
33303
|
+
const hasColoredDiff = this.hasColoredDiffContent(result);
|
|
30961
33304
|
return {
|
|
30962
33305
|
toolName: normalizedToolName,
|
|
30963
33306
|
summary,
|
|
30964
|
-
expansionHint: result.length > 0 ? "(ctrl+r to expand)" : "",
|
|
33307
|
+
expansionHint: result.length > 0 ? hasColoredDiff ? "(ctrl+r to expand diff)" : "(ctrl+r to expand)" : "",
|
|
30965
33308
|
hasContent: result.length > 0,
|
|
30966
33309
|
originalContent: result,
|
|
30967
|
-
metadata
|
|
33310
|
+
metadata: {
|
|
33311
|
+
...metadata,
|
|
33312
|
+
isColoredDiff: hasColoredDiff
|
|
33313
|
+
// Flag for UI rendering
|
|
33314
|
+
}
|
|
30968
33315
|
};
|
|
30969
33316
|
}
|
|
30970
33317
|
/**
|
|
@@ -31025,6 +33372,9 @@ var init_tool_brevity_service = __esm({
|
|
|
31025
33372
|
if (!content || content.trim().length === 0) {
|
|
31026
33373
|
return `${this.capitalizeFirst(tool)} (no output)`;
|
|
31027
33374
|
}
|
|
33375
|
+
if (this.hasColoredDiffContent(content)) {
|
|
33376
|
+
return this.extractDiffSummary(content);
|
|
33377
|
+
}
|
|
31028
33378
|
switch (tool) {
|
|
31029
33379
|
case "read":
|
|
31030
33380
|
return `Read ${metadata.lineCount || 0} lines`;
|
|
@@ -31129,6 +33479,42 @@ var init_tool_brevity_service = __esm({
|
|
|
31129
33479
|
const resultMatches = content.match(/result\s+\d+/gi);
|
|
31130
33480
|
return resultMatches ? resultMatches.length : 1;
|
|
31131
33481
|
}
|
|
33482
|
+
/**
|
|
33483
|
+
* Check if content contains colored diff output from enhanced TextEditorTool
|
|
33484
|
+
*/
|
|
33485
|
+
static hasColoredDiffContent(content) {
|
|
33486
|
+
const ansiEscape = String.fromCharCode(27);
|
|
33487
|
+
const hasAnsiColors = new RegExp(`${ansiEscape.replace(/[.*+?^${}()|\\[\\]\\\\]/g, "\\$&")}\\[\\d+m`).test(content);
|
|
33488
|
+
const hasDiffMarkers = /^[\+\-\s].*$/m.test(content);
|
|
33489
|
+
const hasDiffSummary = /✅\s+(Updated|Created)/.test(content);
|
|
33490
|
+
return hasAnsiColors && (hasDiffMarkers || hasDiffSummary);
|
|
33491
|
+
}
|
|
33492
|
+
/**
|
|
33493
|
+
* Extract summary from colored diff content
|
|
33494
|
+
*/
|
|
33495
|
+
static extractDiffSummary(content) {
|
|
33496
|
+
const summaryMatch = content.match(/✅\s+((?:Updated|Created)[^✓\n\r]*)/);
|
|
33497
|
+
if (summaryMatch) {
|
|
33498
|
+
const ansiEscape = String.fromCharCode(27);
|
|
33499
|
+
return summaryMatch[1].replace(new RegExp(`${ansiEscape.replace(/[.*+?^${}()|\\[\\]\\\\]/g, "\\$&")}\\[\\d+m`, "g"), "").trim();
|
|
33500
|
+
}
|
|
33501
|
+
const fileMatch = content.match(/\+\+\+\s+b\/([^\s\n]+)/);
|
|
33502
|
+
if (fileMatch) {
|
|
33503
|
+
const filename = fileMatch[1];
|
|
33504
|
+
const additionCount = (content.match(/^\+[^+]/gm) || []).length;
|
|
33505
|
+
const deletionCount = (content.match(/^-[^-]/gm) || []).length;
|
|
33506
|
+
if (additionCount > 0 && deletionCount > 0) {
|
|
33507
|
+
return `Updated ${filename} with ${additionCount} additions and ${deletionCount} deletions`;
|
|
33508
|
+
} else if (additionCount > 0) {
|
|
33509
|
+
return `Updated ${filename} with ${additionCount} additions`;
|
|
33510
|
+
} else if (deletionCount > 0) {
|
|
33511
|
+
return `Updated ${filename} with ${deletionCount} deletions`;
|
|
33512
|
+
} else {
|
|
33513
|
+
return `Updated ${filename}`;
|
|
33514
|
+
}
|
|
33515
|
+
}
|
|
33516
|
+
return "File updated";
|
|
33517
|
+
}
|
|
31132
33518
|
/**
|
|
31133
33519
|
* Capitalize first letter of string
|
|
31134
33520
|
*/
|
|
@@ -31277,7 +33663,8 @@ function ToolCallEntry({ entry, verbosityLevel, explainLevel }) {
|
|
|
31277
33663
|
);
|
|
31278
33664
|
const explanation = getExplanation(toolName, filePath);
|
|
31279
33665
|
const { preview, hasMore, totalLines } = truncateToClaudeStyle(entry.content || "");
|
|
31280
|
-
const useClaudeCodeFormat = verbosityLevel === "quiet" && brevitySummary.hasContent;
|
|
33666
|
+
const useClaudeCodeFormat = verbosityLevel === "quiet" && brevitySummary.hasContent && !brevitySummary.metadata.isColoredDiff;
|
|
33667
|
+
const forceShowColoredDiff = brevitySummary.metadata.isColoredDiff;
|
|
31281
33668
|
return /* @__PURE__ */ jsxs(Box, { flexDirection: "column", marginTop: 1, children: [
|
|
31282
33669
|
/* @__PURE__ */ jsxs(Box, { children: [
|
|
31283
33670
|
/* @__PURE__ */ jsx(Text, { color: "gray", children: "\u23BF" }),
|
|
@@ -31311,8 +33698,8 @@ function ToolCallEntry({ entry, verbosityLevel, explainLevel }) {
|
|
|
31311
33698
|
] }) : /* @__PURE__ */ jsxs(Box, { flexDirection: "column", children: [
|
|
31312
33699
|
/* @__PURE__ */ jsx(Text, { color: "gray", children: "\u23BF File contents:" }),
|
|
31313
33700
|
/* @__PURE__ */ jsx(Box, { marginLeft: 2, flexDirection: "column", children: /* @__PURE__ */ jsx(FileContentRenderer, { content: entry.content }) })
|
|
31314
|
-
] }) }) : shouldShowDiff && shouldShowFullContent ? (
|
|
31315
|
-
// For diff results, show only the summary line, not the raw content
|
|
33701
|
+
] }) }) : shouldShowDiff && shouldShowFullContent && !brevitySummary.metadata.isColoredDiff ? (
|
|
33702
|
+
// For diff results, show only the summary line, not the raw content (unless it's a colored diff)
|
|
31316
33703
|
/* @__PURE__ */ jsxs(Text, { color: "gray", children: [
|
|
31317
33704
|
"\u23BF ",
|
|
31318
33705
|
entry.content.split("\n")[0]
|
|
@@ -31334,7 +33721,7 @@ function ToolCallEntry({ entry, verbosityLevel, explainLevel }) {
|
|
|
31334
33721
|
/* @__PURE__ */ jsx(Text, { color: "gray", children: "\u23BF " }),
|
|
31335
33722
|
/* @__PURE__ */ jsx(Box, { flexDirection: "column", width: "100%", children: /* @__PURE__ */ jsx(MarkdownRenderer, { content: formatToolContent(entry.content, toolName) }) })
|
|
31336
33723
|
] }) }),
|
|
31337
|
-
shouldShowDiff && !isExecuting && shouldShowFullContent && !useClaudeCodeFormat && /* @__PURE__ */ jsx(Box, { marginLeft: 4, flexDirection: "column", children: /* @__PURE__ */ jsx(
|
|
33724
|
+
(shouldShowDiff && !isExecuting && shouldShowFullContent && !useClaudeCodeFormat || forceShowColoredDiff && !isExecuting) && /* @__PURE__ */ jsx(Box, { marginLeft: 4, flexDirection: "column", children: forceShowColoredDiff ? /* @__PURE__ */ jsx(ColoredDiffRenderer, { content: entry.content }) : /* @__PURE__ */ jsx(
|
|
31338
33725
|
DiffRenderer,
|
|
31339
33726
|
{
|
|
31340
33727
|
diffContent: entry.content,
|
|
@@ -31348,6 +33735,7 @@ var truncateContent2;
|
|
|
31348
33735
|
var init_tool_call_entry = __esm({
|
|
31349
33736
|
"src/ui/components/chat-entries/tool-call-entry.tsx"() {
|
|
31350
33737
|
init_diff_renderer();
|
|
33738
|
+
init_colored_diff_renderer();
|
|
31351
33739
|
init_file_content_renderer();
|
|
31352
33740
|
init_tool_brevity_service();
|
|
31353
33741
|
init_markdown_renderer();
|
|
@@ -32387,10 +34775,11 @@ var init_session_logger = __esm({
|
|
|
32387
34775
|
SessionLogger = class {
|
|
32388
34776
|
constructor() {
|
|
32389
34777
|
this.sessionId = (/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-");
|
|
32390
|
-
this.logPath = path8__default.join(process.cwd(), `session-${this.sessionId}.log`);
|
|
34778
|
+
this.logPath = path8__default.join(process.cwd(), "logs", `session-${this.sessionId}.log`);
|
|
32391
34779
|
this.init();
|
|
32392
34780
|
}
|
|
32393
34781
|
init() {
|
|
34782
|
+
fs9__default.mkdirSync(path8__default.dirname(this.logPath), { recursive: true });
|
|
32394
34783
|
const header = `
|
|
32395
34784
|
=================================================================
|
|
32396
34785
|
\u{1F9EA} GROK ONE-SHOT TESTING SESSION
|
|
@@ -32399,7 +34788,7 @@ Started: ${(/* @__PURE__ */ new Date()).toISOString()}
|
|
|
32399
34788
|
=================================================================
|
|
32400
34789
|
|
|
32401
34790
|
`;
|
|
32402
|
-
|
|
34791
|
+
fs9__default.writeFileSync(this.logPath, header);
|
|
32403
34792
|
}
|
|
32404
34793
|
logTerminalState(state) {
|
|
32405
34794
|
const timestamp = (/* @__PURE__ */ new Date()).toISOString();
|
|
@@ -32415,7 +34804,7 @@ LAST ENTRY: ${state.chatHistory.length > 0 ? JSON.stringify(state.chatHistory[st
|
|
|
32415
34804
|
=====================================
|
|
32416
34805
|
|
|
32417
34806
|
`;
|
|
32418
|
-
|
|
34807
|
+
fs9__default.appendFileSync(this.logPath, entry);
|
|
32419
34808
|
}
|
|
32420
34809
|
logUserAction(action, details = {}) {
|
|
32421
34810
|
const timestamp = (/* @__PURE__ */ new Date()).toISOString();
|
|
@@ -32423,7 +34812,7 @@ LAST ENTRY: ${state.chatHistory.length > 0 ? JSON.stringify(state.chatHistory[st
|
|
|
32423
34812
|
Details: ${JSON.stringify(details, null, 2)}
|
|
32424
34813
|
|
|
32425
34814
|
`;
|
|
32426
|
-
|
|
34815
|
+
fs9__default.appendFileSync(this.logPath, entry);
|
|
32427
34816
|
}
|
|
32428
34817
|
logPasteEvent(event) {
|
|
32429
34818
|
const timestamp = (/* @__PURE__ */ new Date()).toISOString();
|
|
@@ -32431,7 +34820,7 @@ Details: ${JSON.stringify(details, null, 2)}
|
|
|
32431
34820
|
Data: ${JSON.stringify(event.data, null, 2)}
|
|
32432
34821
|
|
|
32433
34822
|
`;
|
|
32434
|
-
|
|
34823
|
+
fs9__default.appendFileSync(this.logPath, entry);
|
|
32435
34824
|
}
|
|
32436
34825
|
logTestResult(testName, result, details) {
|
|
32437
34826
|
const timestamp = (/* @__PURE__ */ new Date()).toISOString();
|
|
@@ -32442,7 +34831,7 @@ Details: ${details}
|
|
|
32442
34831
|
=================================================================
|
|
32443
34832
|
|
|
32444
34833
|
`;
|
|
32445
|
-
|
|
34834
|
+
fs9__default.appendFileSync(this.logPath, entry);
|
|
32446
34835
|
}
|
|
32447
34836
|
getLogPath() {
|
|
32448
34837
|
return this.logPath;
|
|
@@ -32899,7 +35288,7 @@ var require_package = __commonJS({
|
|
|
32899
35288
|
module.exports = {
|
|
32900
35289
|
type: "module",
|
|
32901
35290
|
name: "@xagent/one-shot",
|
|
32902
|
-
version: "1.2.
|
|
35291
|
+
version: "1.2.13",
|
|
32903
35292
|
description: "An open-source AI agent that brings advanced AI capabilities directly into your terminal with automatic documentation updates.",
|
|
32904
35293
|
main: "dist/index.js",
|
|
32905
35294
|
module: "dist/index.js",
|
|
@@ -32986,6 +35375,7 @@ var require_package = __commonJS({
|
|
|
32986
35375
|
chokidar: "^4.0.3",
|
|
32987
35376
|
"cli-highlight": "^2.1.11",
|
|
32988
35377
|
commander: "^12.0.0",
|
|
35378
|
+
diff: "^8.0.2",
|
|
32989
35379
|
dotenv: "^16.4.0",
|
|
32990
35380
|
enquirer: "^2.4.1",
|
|
32991
35381
|
"fs-extra": "^11.2.0",
|
|
@@ -33052,7 +35442,7 @@ var require_package = __commonJS({
|
|
|
33052
35442
|
}
|
|
33053
35443
|
});
|
|
33054
35444
|
dotenv.config();
|
|
33055
|
-
var logStream =
|
|
35445
|
+
var logStream = fs9__default.createWriteStream(path8__default.join(process.cwd(), "xcli-startup.log"), { flags: "a" });
|
|
33056
35446
|
var isQuietCommand = process.argv.includes("--version") || process.argv.includes("-V") || process.argv.includes("--help") || process.argv.includes("-h");
|
|
33057
35447
|
if (isQuietCommand) {
|
|
33058
35448
|
process.env.GROK_QUIET_MODE = "true";
|