fluxflow-cli 3.16.5 → 3.17.0
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/dist/fluxflow.js +758 -413
- package/model_config.json +3 -3
- package/package.json +4 -3
package/dist/fluxflow.js
CHANGED
|
@@ -2570,7 +2570,7 @@ var init_build = __esm({
|
|
|
2570
2570
|
|
|
2571
2571
|
// src/utils/text.js
|
|
2572
2572
|
import os2 from "os";
|
|
2573
|
-
var flattenString, wrapText, formatTokens, truncatePath, parsePatchPairs, applyPatches, generateHighFidelityDiff, parseLineInfo, getSimilarity, alignChangeGroup, blocksCache, streamingBlocksCache, MAX_CACHE_SIZE, CHUNK_SIZE, indexBlockIntoMap, parseMessageToBlocks, TOOL_LABELS, REGEX_INITIAL_THINK, REGEX_INITIAL_TOOL, REGEX_CLEAN_SIGNALS, REGEX_ARROWS_ALL, REGEX_TOOLS, cleanSignals, clearBlocksCache;
|
|
2573
|
+
var flattenString, wrapText, formatTokens, truncatePath, parsePatchPairs, applyPatches, generateHighFidelityDiff, parseLineInfo, getSimilarity, alignChangeGroup, blocksCache, streamingBlocksCache, MAX_CACHE_SIZE, CHUNK_SIZE, indexBlockIntoMap, parseMessageToBlocks, TOOL_LABELS, REGEX_INITIAL_THINK, REGEX_INITIAL_TOOL, isInsideBacktick, REGEX_CLEAN_SIGNALS, REGEX_ARROWS_ALL, REGEX_TOOLS, bypassBacktick, cleanSignals, clearBlocksCache;
|
|
2574
2574
|
var init_text = __esm({
|
|
2575
2575
|
"src/utils/text.js"() {
|
|
2576
2576
|
init_paths();
|
|
@@ -3345,12 +3345,20 @@ var init_text = __esm({
|
|
|
3345
3345
|
};
|
|
3346
3346
|
REGEX_INITIAL_THINK = /<\/think>(\r?\n){2}/gi;
|
|
3347
3347
|
REGEX_INITIAL_TOOL = /(\r?\n){2}(?=\[?(?:tool:functions|tool\.functions|agent:generalist|agent\.generalist|\s*turn\s*:))/gi;
|
|
3348
|
+
isInsideBacktick = (str, idx) => {
|
|
3349
|
+
let inCode = false;
|
|
3350
|
+
for (let i = 0; i < idx; i++) {
|
|
3351
|
+
if (str[i] === "`") inCode = !inCode;
|
|
3352
|
+
}
|
|
3353
|
+
return inCode;
|
|
3354
|
+
};
|
|
3348
3355
|
REGEX_CLEAN_SIGNALS = /\[SYSTEM\][\s\S]*?\[\/SYSTEM\]|<(think|thought)>[\s\S]*?(?:<\/(think|thought)>|$)|\[ANSWER\][\s\S]*?(?:\[\/ANSWER\]|$)|\[TOOL RESULT\]:?\s*|^\s*(SUCCESS|ERROR):.*(\r?\n)?|\[\s*turn\s*:\s*(continue|finish)\s*\]|\[\[END\]\]|\[\s*turn\s*:?.*?$|\n\s*turn\s*:?.*?$|\[\s*$|\n\nResponded on .*|\n\n\[Prompted on: .*\]|@\[TerminalName:.*?, ProcessId:.*?\]/gmi;
|
|
3349
3356
|
REGEX_ARROWS_ALL = /(\$?\\?\/?\\rightarrow\$?|\$\\rightarrow\$)|(\$?\\?\/?\\leftarrow\$?|\$\\leftarrow\$)|(\$?\\?\/?\\uparrow\$?|\$\\uparrow\$)|(\$?\\?\/?\\downarrow\$?|\$\\downarrow\$)|(\$?\\?\/?\\leftrightarrow\$?|\$\\leftrightarrow\$)/gi;
|
|
3350
3357
|
REGEX_TOOLS = /\b(write_file|update_file|read_folder|view_file|exec_command|web_search|web_scrape|search_keyword|write_pdf|write_docx|generate_image)\b/gi;
|
|
3358
|
+
bypassBacktick = false;
|
|
3351
3359
|
cleanSignals = (text) => {
|
|
3352
3360
|
if (!text) return text;
|
|
3353
|
-
let result = text.replace(REGEX_INITIAL_THINK, "</think>").replace(REGEX_INITIAL_TOOL, "");
|
|
3361
|
+
let result = text.replace(REGEX_INITIAL_THINK, "</think>").replace(REGEX_INITIAL_TOOL, (match, _nl, offset, str) => !bypassBacktick && isInsideBacktick(str, offset) ? match : "");
|
|
3354
3362
|
const trigger = "tool:functions.";
|
|
3355
3363
|
const subagentTrigger = "agent:generalist.";
|
|
3356
3364
|
if (result.toLowerCase().includes(trigger) || result.toLowerCase().includes(subagentTrigger)) {
|
|
@@ -3365,6 +3373,35 @@ var init_text = __esm({
|
|
|
3365
3373
|
triggerIdxToUse = subagentIdx;
|
|
3366
3374
|
}
|
|
3367
3375
|
if (triggerIdxToUse === -1) break;
|
|
3376
|
+
if (!bypassBacktick && isInsideBacktick(result, triggerIdxToUse)) {
|
|
3377
|
+
const searchFrom = triggerIdxToUse + currentTrigger.length;
|
|
3378
|
+
const nextTool = lowerResult.indexOf(trigger, searchFrom);
|
|
3379
|
+
const nextAgent = lowerResult.indexOf(subagentTrigger, searchFrom);
|
|
3380
|
+
if (nextTool === -1 && nextAgent === -1) break;
|
|
3381
|
+
let safeIdx = -1;
|
|
3382
|
+
let searchPos = 0;
|
|
3383
|
+
while (true) {
|
|
3384
|
+
const tIdx = lowerResult.indexOf(trigger, searchPos);
|
|
3385
|
+
const aIdx = lowerResult.indexOf(subagentTrigger, searchPos);
|
|
3386
|
+
let candidate = -1;
|
|
3387
|
+
let candidateTrigger = trigger;
|
|
3388
|
+
if (tIdx === -1 && aIdx === -1) break;
|
|
3389
|
+
if (tIdx === -1 || aIdx !== -1 && aIdx < tIdx) {
|
|
3390
|
+
candidate = aIdx;
|
|
3391
|
+
candidateTrigger = subagentTrigger;
|
|
3392
|
+
} else {
|
|
3393
|
+
candidate = tIdx;
|
|
3394
|
+
}
|
|
3395
|
+
if (!isInsideBacktick(result, candidate)) {
|
|
3396
|
+
safeIdx = candidate;
|
|
3397
|
+
currentTrigger = candidateTrigger;
|
|
3398
|
+
break;
|
|
3399
|
+
}
|
|
3400
|
+
searchPos = candidate + candidateTrigger.length;
|
|
3401
|
+
}
|
|
3402
|
+
if (safeIdx === -1) break;
|
|
3403
|
+
triggerIdxToUse = safeIdx;
|
|
3404
|
+
}
|
|
3368
3405
|
let startIdx = triggerIdxToUse;
|
|
3369
3406
|
let hasOuterBracket = false;
|
|
3370
3407
|
let k = triggerIdxToUse - 1;
|
|
@@ -6808,8 +6845,8 @@ var init_main_tools = __esm({
|
|
|
6808
6845
|
}
|
|
6809
6846
|
return `
|
|
6810
6847
|
-- TOOL DEFINITIONS --
|
|
6811
|
-
Tool calls: ONLY use [tool:functions.ToolName(
|
|
6812
|
-
**NO OTHER SYNTAX/MARKERS/BOUNDARY ALLOWED**
|
|
6848
|
+
Tool calls: ONLY use [tool:functions.ToolName(arg1="value1")]
|
|
6849
|
+
**NO OTHER SYNTAX/MARKERS/WRAPPER/BOUNDARY ALLOWED**
|
|
6813
6850
|
|
|
6814
6851
|
**TOOL CALLS POLICY:**
|
|
6815
6852
|
- MAX 4 TOOL CALLS/TURN${mode === "Flux" ? " (Todo: 4+, Run: max 1 or 2 consecutive)" : ""}
|
|
@@ -6830,25 +6867,26 @@ ${mode === "Flux" ? `- Escape quotes: \\" for code strings
|
|
|
6830
6867
|
|
|
6831
6868
|
${mode === "Flux" ? `- WORKSPACE TOOLS (path = relative; FIRST ARGUMENT, path separator: '/') -
|
|
6832
6869
|
- [tool:functions.ReadFile(path="...", startLine="integer", endLine="integer")]. ${aiProvider !== "Google" ? `${isMultiModal ? `Supports images/docs` : ""}` : `Supports images/docs`}
|
|
6833
|
-
- [tool:functions.ReadFolder(path="...", recurse="integer 1-3 optional, default: 1")]. DIR Contents + File Size.
|
|
6870
|
+
- [tool:functions.ReadFolder(path="...", recurse="integer 1-3 optional, default: 1")]. DIR Contents + File Size. Minimize recursion
|
|
6834
6871
|
- [tool:functions.PatchFile(path="...", allowMultiple="bool optional, default: false", replaceContent1="...", newContent1="...", ...MAX15)]. TARGET MINIMAL DIFF. allowMultiple: Replace all matches ONLY WHEN SURE. Multi-blocks: replaceContent2/newContent2... Verify diffs
|
|
6835
6872
|
- [tool:functions.WriteFile(path="...", content="...")]. Creates/Overwrites. File Exist? PatchFile > WriteFile
|
|
6836
6873
|
- [tool:functions.SearchKeyword(keyword="...", path="optional, dir/file/glob/regex", fuzzy="bool optional, default: false", regex="bool optional, default: auto")]. path scopes search. Find definitions, logic, relevant code
|
|
6837
6874
|
- [tool:functions.Run(command="...")]. Runs ${osDetected === "Windows" ? isPsAvailable() ? `POWERSHELL` : `WINDOWS CMD` : `BASH`} command. Destructive/Irreversible ops \u2192 Ask user
|
|
6838
|
-
- [tool:functions.Todo(method="create/append/get", tasks=[ARRAY OF STRINGS], markDone=[ARRAY OF TASKS])]. Task list, no Markdown in arrays. Analyze request: ONLY if long multi-task, break it down & create Todos BEFORE starting. \`tasks\` & \`markDone\` optional with \`get\`. Use \`get + markDone\` to complete tasks. **UPDATE EVERY TURN WHEN CREATED
|
|
6875
|
+
- [tool:functions.Todo(method="create/append/get", tasks=[ARRAY OF STRINGS], markDone=[ARRAY OF TASKS])]. Task list, no Markdown in arrays. Analyze request: ONLY if long multi-task, break it down & create Todos BEFORE starting. \`tasks\` & \`markDone\` optional with \`get\`. Use \`get + markDone\` to complete tasks. **UPDATE EVERY TURN WHEN CREATED**
|
|
6839
6876
|
${_cachedAdvanceRollback ? `
|
|
6840
|
-
- EMERGENCY
|
|
6877
|
+
- EMERGENCY TOOLS -
|
|
6841
6878
|
Info: \`initial\` = current task prompt. Revert \`id\` = turn before disaster (eg. disaster: \`turn_3\` \u2192 revert: \`turn_2\`). Reason explicitly
|
|
6842
6879
|
- [tool:functions.EmergencyRollback(method="getCheckpoint/forceRevert", id="...")]. Rollback workspace in THIS agent loop. ONLY for catastrophic corruption. Before ending, verify no catastrophe. \`id\` omitted for \`getCheckpoint\`
|
|
6843
6880
|
` : ""}${enableSubAgents ? `
|
|
6844
6881
|
- SUB AGENT TOOLS -
|
|
6845
6882
|
**PROACTIVE sub-agent use HIGHLY RECOMMENDED. Prefer for any task with even slight benefit, no user nudge needed**
|
|
6846
6883
|
Invocations:
|
|
6847
|
-
\u2022 Invoke (async/background, \u22647 parallel). Parallelize long tasks.
|
|
6884
|
+
\u2022 Invoke (async/background, \u22647 parallel). Parallelize long tasks. May take time
|
|
6848
6885
|
\u2022 InvokeSync (sync/blocking). Sequential, repetitive or delegated tasks. Saves tokens/cost
|
|
6849
|
-
- [
|
|
6850
|
-
- [
|
|
6851
|
-
- [
|
|
6886
|
+
- [tool:functions.InvokeSync/Invoke(title="...", task="...")]. Task must be detailed: exact file paths, imports/exports, dependencies & folder structure
|
|
6887
|
+
- [tool:functions.Await(id="...", timeout="integer seconds, default: 120")]. Event-driven wait
|
|
6888
|
+
- [tool:functions.GetProgress(id="...")]. Poll \`getProgress\` sparingly; NO initial poll. Work or await. Never end while subagent runs
|
|
6889
|
+
- [tool:functions.Cancel(id="...")]. Cancel async task ONLY if stalled (2m+) or clearly incorrect` : ""}`.trim() : `- CREATIVE TOOLS (path = relative to CWD & WILL BE FIRST ARGUMENT, path separator: '/') -
|
|
6852
6890
|
- [tool:functions.WritePDF(path="...", content="...", orientation="...")]. PROACTIVE A4 PAGE BREAKS MUST IN CSS. HTML/CSS for PREMIUM layout, stable margins & headers/footers, NO WATERMARKS
|
|
6853
6891
|
- [tool:functions.WriteDoc(path="...", content="...")]. A4 Word document, NO WATERMARKS, stable margins & headers/footers
|
|
6854
6892
|
- WORKSPACE & SUB AGENT TOOLS ARE NOT AVAILABLE IN FLOW`.trim()}`.trim();
|
|
@@ -8565,7 +8603,7 @@ Check these first; These Files > Training Data. Safety rules apply
|
|
|
8565
8603
|
Identity: Flux Flow. Sassy, CLI Agent
|
|
8566
8604
|
${mode === "Flux" ? "Logical, task-driven. Prioritize scalable, modular architecture, clean abstractions, stepwise execution. Use latest practices/libraries, verify imports, run automated tests" : `Mode: ${mode}. Concise, Conversational, Sassy, Friendly, Humorous, Sarcastic`}
|
|
8567
8605
|
|
|
8568
|
-
-
|
|
8606
|
+
- USE DIRECTORY STRUCTURE FOR FILE AVAILABILITY AND PATH RESOLUTION
|
|
8569
8607
|
- USE RELATIVE TIME REFERENCE eg. few mins ago
|
|
8570
8608
|
|
|
8571
8609
|
-- THINKING GUIDANCE --
|
|
@@ -8585,7 +8623,7 @@ ${projectContextBlock}${isMemoryEnabled ? `
|
|
|
8585
8623
|
-- CHAT FORMATTING --
|
|
8586
8624
|
- GFM Markdown ONLY
|
|
8587
8625
|
- Same Language as User Query
|
|
8588
|
-
-
|
|
8626
|
+
- After tool calls emit no chat in this turn
|
|
8589
8627
|
- On completion: summarize changes (why) + edited files${mode === "Flux" ? "" : "\n- Use Kaomojis HEAVILY"}
|
|
8590
8628
|
=== END SYSTEM PROMPT ===
|
|
8591
8629
|
|
|
@@ -10240,9 +10278,8 @@ ${finalResults}`;
|
|
|
10240
10278
|
|
|
10241
10279
|
// src/tools/web_scrape.js
|
|
10242
10280
|
import puppeteer2 from "puppeteer";
|
|
10243
|
-
import fs13 from "fs";
|
|
10244
|
-
import path12 from "path";
|
|
10245
10281
|
import TurndownService from "turndown";
|
|
10282
|
+
import { gfm } from "turndown-plugin-gfm";
|
|
10246
10283
|
var web_scrape;
|
|
10247
10284
|
var init_web_scrape = __esm({
|
|
10248
10285
|
"src/tools/web_scrape.js"() {
|
|
@@ -10284,7 +10321,7 @@ var init_web_scrape = __esm({
|
|
|
10284
10321
|
await page.goto(url, { waitUntil: "networkidle2", timeout: 18e4 });
|
|
10285
10322
|
await new Promise((r) => setTimeout(r, 5e3));
|
|
10286
10323
|
let htmlContent = await page.evaluate(() => {
|
|
10287
|
-
const junk = document.querySelectorAll("script, style,
|
|
10324
|
+
const junk = document.querySelectorAll("script, style, noscript, svg, canvas, iframe, ad, .ads, link, meta, img");
|
|
10288
10325
|
junk.forEach((el) => el.remove());
|
|
10289
10326
|
const iterator = document.createNodeIterator(document.body, NodeFilter.SHOW_COMMENT);
|
|
10290
10327
|
let currentNode;
|
|
@@ -10330,6 +10367,7 @@ var init_web_scrape = __esm({
|
|
|
10330
10367
|
headingStyle: "atx",
|
|
10331
10368
|
codeBlockStyle: "fenced"
|
|
10332
10369
|
});
|
|
10370
|
+
turndownService.use(gfm);
|
|
10333
10371
|
const rawMarkdown = turndownService.turndown(cleanedHtml).replace(/\.\s*\n/g, "\n").replace(/ +/g, " ").replace(/\t/g, " ").replace(/\n\s+/g, "\n").replace(/\n{3,}/g, "\n\n");
|
|
10334
10372
|
const markdown = rawMarkdown.substring(0, 5e4);
|
|
10335
10373
|
await browser.close();
|
|
@@ -10339,7 +10377,6 @@ ${markdown}${rawMarkdown.length > 5e4 ? "\n\n[TRUNCATED AT 50K CHARS]" : ""}`;
|
|
|
10339
10377
|
} catch (err) {
|
|
10340
10378
|
lastError = err;
|
|
10341
10379
|
if (browser) await browser.close();
|
|
10342
|
-
fs13.writeFileSync(path12.join(LOGS_DIR, "web_tools", "scrape", "standard_mode", "ERROR.txt"), err.message);
|
|
10343
10380
|
if (attempt < maxRetries) {
|
|
10344
10381
|
const backoff = Math.pow(2, attempt) * 1e3;
|
|
10345
10382
|
await new Promise((r) => setTimeout(r, backoff));
|
|
@@ -10463,8 +10500,8 @@ var init_chat = __esm({
|
|
|
10463
10500
|
});
|
|
10464
10501
|
|
|
10465
10502
|
// src/tools/view_file.js
|
|
10466
|
-
import
|
|
10467
|
-
import
|
|
10503
|
+
import fs13 from "fs";
|
|
10504
|
+
import path12 from "path";
|
|
10468
10505
|
var view_file;
|
|
10469
10506
|
var init_view_file = __esm({
|
|
10470
10507
|
"src/tools/view_file.js"() {
|
|
@@ -10478,16 +10515,16 @@ var init_view_file = __esm({
|
|
|
10478
10515
|
let finalStart = sLine || 1;
|
|
10479
10516
|
let finalEnd = eLine || (sLine ? sLine + 800 : 800);
|
|
10480
10517
|
if (!targetPath) return 'ERROR: Missing "path" argument for view_file.';
|
|
10481
|
-
const absolutePath =
|
|
10518
|
+
const absolutePath = path12.resolve(process.cwd(), targetPath);
|
|
10482
10519
|
try {
|
|
10483
|
-
if (!
|
|
10520
|
+
if (!fs13.existsSync(absolutePath)) {
|
|
10484
10521
|
return `ERROR: File [${targetPath}] does not exist.`;
|
|
10485
10522
|
}
|
|
10486
|
-
const stats =
|
|
10523
|
+
const stats = fs13.statSync(absolutePath);
|
|
10487
10524
|
if (stats.isDirectory()) {
|
|
10488
10525
|
return `ERROR: Path [${targetPath}] is a directory. Use list_files instead.`;
|
|
10489
10526
|
}
|
|
10490
|
-
const ext =
|
|
10527
|
+
const ext = path12.extname(targetPath).toLowerCase();
|
|
10491
10528
|
const videoExtensions = [".mp4", ".mkv", ".avi", ".mov", ".webm", ".flv", ".wmv", ".mpeg", ".mpg"];
|
|
10492
10529
|
if (videoExtensions.includes(ext)) {
|
|
10493
10530
|
const format = ext.slice(1).toUpperCase();
|
|
@@ -10507,7 +10544,7 @@ var init_view_file = __esm({
|
|
|
10507
10544
|
if (!isMultiModal) {
|
|
10508
10545
|
return `ERROR: Multimodality is not supported for the current model. Unable to load [${targetPath}].`;
|
|
10509
10546
|
}
|
|
10510
|
-
const buffer =
|
|
10547
|
+
const buffer = fs13.readFileSync(absolutePath);
|
|
10511
10548
|
const base64 = buffer.toString("base64");
|
|
10512
10549
|
const mimeType = mimeMap[ext];
|
|
10513
10550
|
return {
|
|
@@ -10520,7 +10557,7 @@ var init_view_file = __esm({
|
|
|
10520
10557
|
}
|
|
10521
10558
|
};
|
|
10522
10559
|
}
|
|
10523
|
-
let content =
|
|
10560
|
+
let content = fs13.readFileSync(absolutePath, "utf8");
|
|
10524
10561
|
if (content.startsWith("\uFEFF")) {
|
|
10525
10562
|
content = content.slice(1);
|
|
10526
10563
|
}
|
|
@@ -10548,8 +10585,8 @@ ${code}`;
|
|
|
10548
10585
|
});
|
|
10549
10586
|
|
|
10550
10587
|
// src/tools/write_file.js
|
|
10551
|
-
import
|
|
10552
|
-
import
|
|
10588
|
+
import fs14 from "fs";
|
|
10589
|
+
import path13 from "path";
|
|
10553
10590
|
var write_file;
|
|
10554
10591
|
var init_write_file = __esm({
|
|
10555
10592
|
"src/tools/write_file.js"() {
|
|
@@ -10560,14 +10597,14 @@ var init_write_file = __esm({
|
|
|
10560
10597
|
if (!targetPath) return 'ERROR: Missing "path" argument for write_file.';
|
|
10561
10598
|
if (content === void 0) return 'ERROR: Missing "content" argument for write_file.';
|
|
10562
10599
|
content = content.replace(/^```[\w]*\n?/, "").replace(/```\s*$/, "").replace(/\r\n/g, "\n").replace(/\r/g, "\n");
|
|
10563
|
-
const absolutePath =
|
|
10564
|
-
const parentDir =
|
|
10600
|
+
const absolutePath = path13.resolve(process.cwd(), targetPath);
|
|
10601
|
+
const parentDir = path13.dirname(absolutePath);
|
|
10565
10602
|
try {
|
|
10566
10603
|
await RevertManager.recordFileChange(absolutePath);
|
|
10567
10604
|
let ancestry = "";
|
|
10568
|
-
if (
|
|
10605
|
+
if (fs14.existsSync(absolutePath)) {
|
|
10569
10606
|
try {
|
|
10570
|
-
const oldData =
|
|
10607
|
+
const oldData = fs14.readFileSync(absolutePath, "utf8");
|
|
10571
10608
|
const lines = oldData.split(/\r?\n/);
|
|
10572
10609
|
ancestry = `Old File contents:
|
|
10573
10610
|
${lines.map((l, i) => `${i + 1} | ${l}`).join("\n")}
|
|
@@ -10579,16 +10616,16 @@ ${lines.map((l, i) => `${i + 1} | ${l}`).join("\n")}
|
|
|
10579
10616
|
`;
|
|
10580
10617
|
}
|
|
10581
10618
|
}
|
|
10582
|
-
if (!
|
|
10583
|
-
|
|
10619
|
+
if (!fs14.existsSync(parentDir)) {
|
|
10620
|
+
fs14.mkdirSync(parentDir, { recursive: true });
|
|
10584
10621
|
}
|
|
10585
10622
|
const strip = (t) => t.replace(/^```[\w]*\n?/, "").replace(/```\s*$/, "").replace(/\r\n/g, "\n").replace(/\r/g, "\n");
|
|
10586
10623
|
const processedContent = strip(content);
|
|
10587
10624
|
const finalContent = processedContent.endsWith("\n") ? processedContent : processedContent + "\n";
|
|
10588
10625
|
const lineCount = finalContent.split(/\r?\n/).length;
|
|
10589
10626
|
const originalSize = Buffer.byteLength(finalContent, "utf8");
|
|
10590
|
-
|
|
10591
|
-
let verifiedContent =
|
|
10627
|
+
fs14.writeFileSync(absolutePath, finalContent, "utf8");
|
|
10628
|
+
let verifiedContent = fs14.readFileSync(absolutePath, "utf8");
|
|
10592
10629
|
const verifiedSize = Buffer.byteLength(verifiedContent, "utf8");
|
|
10593
10630
|
const verifiedLines = verifiedContent.split(/\r?\n/);
|
|
10594
10631
|
const verifiedLineCount = verifiedLines.length;
|
|
@@ -10623,8 +10660,8 @@ ${snippet}`;
|
|
|
10623
10660
|
});
|
|
10624
10661
|
|
|
10625
10662
|
// src/tools/update_file.js
|
|
10626
|
-
import
|
|
10627
|
-
import
|
|
10663
|
+
import fs15 from "fs";
|
|
10664
|
+
import path14 from "path";
|
|
10628
10665
|
var update_file;
|
|
10629
10666
|
var init_update_file = __esm({
|
|
10630
10667
|
"src/tools/update_file.js"() {
|
|
@@ -10641,12 +10678,12 @@ var init_update_file = __esm({
|
|
|
10641
10678
|
return "ERROR: No valid replacement pairs found. Use replaceContent1, newContent1, etc.";
|
|
10642
10679
|
}
|
|
10643
10680
|
const allowMultiple = parsed.allowMultiple !== void 0 ? parsed.allowMultiple === true || String(parsed.allowMultiple).toLowerCase() === "true" : parsedAllowMultiple;
|
|
10644
|
-
const absolutePath =
|
|
10681
|
+
const absolutePath = path14.resolve(process.cwd(), targetPath);
|
|
10645
10682
|
try {
|
|
10646
|
-
if (!
|
|
10683
|
+
if (!fs15.existsSync(absolutePath)) {
|
|
10647
10684
|
return `ERROR: File [${targetPath}] does not exist. Use WriteFile instead.`;
|
|
10648
10685
|
}
|
|
10649
|
-
let diskContent = context.forcedContent ||
|
|
10686
|
+
let diskContent = context.forcedContent || fs15.readFileSync(absolutePath, "utf8");
|
|
10650
10687
|
if (diskContent.startsWith("\uFEFF")) diskContent = diskContent.slice(1);
|
|
10651
10688
|
const originalContent = diskContent.replace(/\r\n/g, "\n").replace(/\r/g, "\n");
|
|
10652
10689
|
const { content: finalContent, results } = applyPatches(originalContent, patchPairs, { allowMultiple });
|
|
@@ -10657,7 +10694,7 @@ var init_update_file = __esm({
|
|
|
10657
10694
|
${failures.map((f) => ` \u2022 ${f.error}`).join("\n")}`;
|
|
10658
10695
|
}
|
|
10659
10696
|
await RevertManager.recordFileChange(absolutePath, originalContent);
|
|
10660
|
-
|
|
10697
|
+
fs15.writeFileSync(absolutePath, finalContent, "utf8");
|
|
10661
10698
|
const diffText = generateHighFidelityDiff(originalContent, finalContent, results, 12);
|
|
10662
10699
|
if (failures.length > 0) {
|
|
10663
10700
|
return `SUCCESS: File [${targetPath}] updated with some blocks failed. [${successes.length}/${patchPairs.length}] blocks applied.
|
|
@@ -10679,8 +10716,8 @@ ${diffText}`;
|
|
|
10679
10716
|
});
|
|
10680
10717
|
|
|
10681
10718
|
// src/tools/read_folder.js
|
|
10682
|
-
import
|
|
10683
|
-
import
|
|
10719
|
+
import fs16 from "fs";
|
|
10720
|
+
import path15 from "path";
|
|
10684
10721
|
var EXCLUDED_DIRS, isExcludedDir, formatMtime, read_folder;
|
|
10685
10722
|
var init_read_folder = __esm({
|
|
10686
10723
|
"src/tools/read_folder.js"() {
|
|
@@ -10857,26 +10894,26 @@ var init_read_folder = __esm({
|
|
|
10857
10894
|
}
|
|
10858
10895
|
}
|
|
10859
10896
|
recurseDepth = Math.max(1, Math.min(3, recurseDepth));
|
|
10860
|
-
const absolutePath =
|
|
10897
|
+
const absolutePath = path15.resolve(process.cwd(), targetPath);
|
|
10861
10898
|
try {
|
|
10862
|
-
if (!
|
|
10899
|
+
if (!fs16.existsSync(absolutePath)) {
|
|
10863
10900
|
return `ERROR: Path [${targetPath}] does not exist.`;
|
|
10864
10901
|
}
|
|
10865
|
-
const stats =
|
|
10902
|
+
const stats = fs16.statSync(absolutePath);
|
|
10866
10903
|
if (!stats.isDirectory()) {
|
|
10867
10904
|
return `ERROR: Path [${targetPath}] is a file, not a directory. Use ReadFile instead.`;
|
|
10868
10905
|
}
|
|
10869
10906
|
if (recurseDepth === 1) {
|
|
10870
|
-
const files =
|
|
10907
|
+
const files = fs16.readdirSync(absolutePath);
|
|
10871
10908
|
const totalItems = files.length;
|
|
10872
10909
|
const maxDisplay = 150;
|
|
10873
10910
|
const displayItems = files.slice(0, maxDisplay);
|
|
10874
10911
|
const folderData = [];
|
|
10875
10912
|
for (const file of displayItems) {
|
|
10876
|
-
const fPath =
|
|
10913
|
+
const fPath = path15.join(absolutePath, file);
|
|
10877
10914
|
let info = { name: file, type: "unknown", size: "N/A", mtime: "N/A" };
|
|
10878
10915
|
try {
|
|
10879
|
-
const fStats =
|
|
10916
|
+
const fStats = fs16.statSync(fPath);
|
|
10880
10917
|
info = {
|
|
10881
10918
|
name: file,
|
|
10882
10919
|
type: fStats.isDirectory() ? "directory" : "file",
|
|
@@ -10918,7 +10955,7 @@ ${formatted}${footer2}`;
|
|
|
10918
10955
|
if (currentDepth > recurseDepth || truncated) return [];
|
|
10919
10956
|
let entries = [];
|
|
10920
10957
|
try {
|
|
10921
|
-
entries =
|
|
10958
|
+
entries = fs16.readdirSync(dirPath);
|
|
10922
10959
|
} catch (e) {
|
|
10923
10960
|
const indent2 = " ".repeat(depth - 1);
|
|
10924
10961
|
return [`${indent2}[Inaccessible Directory]`];
|
|
@@ -10926,10 +10963,10 @@ ${formatted}${footer2}`;
|
|
|
10926
10963
|
const subDirs = [];
|
|
10927
10964
|
const fileEntries = [];
|
|
10928
10965
|
for (const name of entries) {
|
|
10929
|
-
const fullPath =
|
|
10966
|
+
const fullPath = path15.join(dirPath, name);
|
|
10930
10967
|
let isDir = false;
|
|
10931
10968
|
try {
|
|
10932
|
-
isDir =
|
|
10969
|
+
isDir = fs16.statSync(fullPath).isDirectory();
|
|
10933
10970
|
} catch (e) {
|
|
10934
10971
|
}
|
|
10935
10972
|
if (isDir) {
|
|
@@ -10967,7 +11004,7 @@ ${formatted}${footer2}`;
|
|
|
10967
11004
|
totalFiles++;
|
|
10968
11005
|
let sizeStr = "N/A";
|
|
10969
11006
|
try {
|
|
10970
|
-
const fStats =
|
|
11007
|
+
const fStats = fs16.statSync(file.fullPath);
|
|
10971
11008
|
sizeStr = (fStats.size / 1024).toFixed(1) + "KB";
|
|
10972
11009
|
} catch (e) {
|
|
10973
11010
|
}
|
|
@@ -11042,8 +11079,8 @@ var init_ask_user = __esm({
|
|
|
11042
11079
|
|
|
11043
11080
|
// src/tools/write_pdf.js
|
|
11044
11081
|
import puppeteer3 from "puppeteer";
|
|
11045
|
-
import
|
|
11046
|
-
import
|
|
11082
|
+
import path16 from "path";
|
|
11083
|
+
import fs17 from "fs-extra";
|
|
11047
11084
|
import { PDFDocument } from "pdf-lib";
|
|
11048
11085
|
var write_pdf;
|
|
11049
11086
|
var init_write_pdf = __esm({
|
|
@@ -11060,10 +11097,10 @@ var init_write_pdf = __esm({
|
|
|
11060
11097
|
} = parseArgs(args);
|
|
11061
11098
|
if (!targetPath) return 'ERROR: Missing "path" argument for write_pdf.';
|
|
11062
11099
|
if (!content) return 'ERROR: Missing "content" (HTML/CSS) for write_pdf.';
|
|
11063
|
-
const absolutePath =
|
|
11100
|
+
const absolutePath = path16.resolve(process.cwd(), targetPath);
|
|
11064
11101
|
let browser = null;
|
|
11065
11102
|
try {
|
|
11066
|
-
await
|
|
11103
|
+
await fs17.ensureDir(path16.dirname(absolutePath));
|
|
11067
11104
|
await RevertManager.recordFileChange(absolutePath);
|
|
11068
11105
|
const pptrConfig = getPuppeteerConfig();
|
|
11069
11106
|
browser = await puppeteer3.launch({
|
|
@@ -11084,11 +11121,11 @@ var init_write_pdf = __esm({
|
|
|
11084
11121
|
return null;
|
|
11085
11122
|
}
|
|
11086
11123
|
try {
|
|
11087
|
-
const imgPath =
|
|
11088
|
-
if (await
|
|
11089
|
-
const ext =
|
|
11124
|
+
const imgPath = path16.resolve(process.cwd(), originalSrc);
|
|
11125
|
+
if (await fs17.pathExists(imgPath)) {
|
|
11126
|
+
const ext = path16.extname(imgPath).toLowerCase().replace(".", "") || "png";
|
|
11090
11127
|
const mime = ext === "jpg" ? "jpeg" : ext === "svg" ? "svg+xml" : ext;
|
|
11091
|
-
const base64 = await
|
|
11128
|
+
const base64 = await fs17.readFile(imgPath, "base64");
|
|
11092
11129
|
return `data:image/${mime};base64,${base64}`;
|
|
11093
11130
|
}
|
|
11094
11131
|
} catch (e) {
|
|
@@ -11103,9 +11140,9 @@ var init_write_pdf = __esm({
|
|
|
11103
11140
|
const fullTag = match[0];
|
|
11104
11141
|
if (originalHref && fullTag.toLowerCase().includes("stylesheet") && !originalHref.startsWith("http://") && !originalHref.startsWith("https://") && !originalHref.startsWith("data:")) {
|
|
11105
11142
|
try {
|
|
11106
|
-
const cssPath =
|
|
11107
|
-
if (await
|
|
11108
|
-
const cssContent = await
|
|
11143
|
+
const cssPath = path16.resolve(process.cwd(), originalHref);
|
|
11144
|
+
if (await fs17.pathExists(cssPath)) {
|
|
11145
|
+
const cssContent = await fs17.readFile(cssPath, "utf-8");
|
|
11109
11146
|
cssCache[fullTag] = `<style>${cssContent}</style>`;
|
|
11110
11147
|
}
|
|
11111
11148
|
} catch (e) {
|
|
@@ -11186,7 +11223,7 @@ var init_write_pdf = __esm({
|
|
|
11186
11223
|
printBackground: true
|
|
11187
11224
|
});
|
|
11188
11225
|
const pdfDoc = await PDFDocument.load(pdfBytes);
|
|
11189
|
-
const fileName =
|
|
11226
|
+
const fileName = path16.basename(targetPath);
|
|
11190
11227
|
pdfDoc.setTitle(`FluxFlow_${fileName}`);
|
|
11191
11228
|
pdfDoc.setAuthor("FluxFlow CLI");
|
|
11192
11229
|
pdfDoc.setSubject("Generated with Agentic AI System");
|
|
@@ -11194,8 +11231,8 @@ var init_write_pdf = __esm({
|
|
|
11194
11231
|
pdfDoc.setCreator("FluxFlow PDF Engine");
|
|
11195
11232
|
pdfDoc.setProducer("FluxFlow (Generative AI)");
|
|
11196
11233
|
const finalPdfBytes = await pdfDoc.save();
|
|
11197
|
-
await
|
|
11198
|
-
const stats = await
|
|
11234
|
+
await fs17.writeFile(absolutePath, finalPdfBytes);
|
|
11235
|
+
const stats = await fs17.stat(absolutePath);
|
|
11199
11236
|
return `SUCCESS: PDF generated successfully at [${targetPath}] (${(stats.size / 1024).toFixed(2)} KB).`;
|
|
11200
11237
|
} catch (err) {
|
|
11201
11238
|
const errorMsg = err instanceof Error ? err.message : String(err);
|
|
@@ -11208,8 +11245,8 @@ var init_write_pdf = __esm({
|
|
|
11208
11245
|
});
|
|
11209
11246
|
|
|
11210
11247
|
// src/tools/write_docx.js
|
|
11211
|
-
import
|
|
11212
|
-
import
|
|
11248
|
+
import fs18 from "fs-extra";
|
|
11249
|
+
import path17 from "path";
|
|
11213
11250
|
import HTMLtoDOCX from "html-to-docx";
|
|
11214
11251
|
var write_docx;
|
|
11215
11252
|
var init_write_docx = __esm({
|
|
@@ -11223,11 +11260,11 @@ var init_write_docx = __esm({
|
|
|
11223
11260
|
} = parseArgs(args);
|
|
11224
11261
|
if (!targetPath) return 'ERROR: Missing "path" argument for write_docx.';
|
|
11225
11262
|
if (!content) return 'ERROR: Missing "content" (HTML) for write_docx.';
|
|
11226
|
-
const absolutePath =
|
|
11263
|
+
const absolutePath = path17.resolve(process.cwd(), targetPath);
|
|
11227
11264
|
try {
|
|
11228
|
-
await
|
|
11265
|
+
await fs18.ensureDir(path17.dirname(absolutePath));
|
|
11229
11266
|
await RevertManager.recordFileChange(absolutePath);
|
|
11230
|
-
const fileName =
|
|
11267
|
+
const fileName = path17.basename(targetPath);
|
|
11231
11268
|
const fullHtml = content.includes("<html") ? content : `
|
|
11232
11269
|
<!DOCTYPE html>
|
|
11233
11270
|
<html lang="en">
|
|
@@ -11248,7 +11285,7 @@ var init_write_docx = __esm({
|
|
|
11248
11285
|
footer: true,
|
|
11249
11286
|
pageNumber: true
|
|
11250
11287
|
});
|
|
11251
|
-
await
|
|
11288
|
+
await fs18.writeFile(absolutePath, docxBuffer);
|
|
11252
11289
|
return `SUCCESS: Word document [${targetPath}] generated successfully.
|
|
11253
11290
|
- Size: ${(docxBuffer.length / 1024).toFixed(1)} KB`;
|
|
11254
11291
|
} catch (err) {
|
|
@@ -11260,22 +11297,22 @@ var init_write_docx = __esm({
|
|
|
11260
11297
|
});
|
|
11261
11298
|
|
|
11262
11299
|
// src/tools/search_keyword.js
|
|
11263
|
-
import
|
|
11264
|
-
import
|
|
11300
|
+
import fs19 from "fs/promises";
|
|
11301
|
+
import path18 from "path";
|
|
11265
11302
|
import fg from "fast-glob";
|
|
11266
11303
|
async function getFilesRecursively(dir, excludes, baseDir = dir, depth = 1) {
|
|
11267
11304
|
if (depth > 12) return [];
|
|
11268
11305
|
let results = [];
|
|
11269
11306
|
let list;
|
|
11270
11307
|
try {
|
|
11271
|
-
list = await
|
|
11308
|
+
list = await fs19.readdir(dir, { withFileTypes: true });
|
|
11272
11309
|
} catch {
|
|
11273
11310
|
return [];
|
|
11274
11311
|
}
|
|
11275
11312
|
for (const file of list) {
|
|
11276
|
-
const fullPath =
|
|
11277
|
-
const relativePath =
|
|
11278
|
-
const pathSegments = relativePath.split(
|
|
11313
|
+
const fullPath = path18.join(dir, file.name);
|
|
11314
|
+
const relativePath = path18.relative(baseDir, fullPath);
|
|
11315
|
+
const pathSegments = relativePath.split(path18.sep).map((s) => s.toLowerCase());
|
|
11279
11316
|
const fileNameLower = file.name.toLowerCase();
|
|
11280
11317
|
const isExcluded = excludes.some((ex) => {
|
|
11281
11318
|
const exLower = ex.toLowerCase();
|
|
@@ -11568,7 +11605,7 @@ var init_search_keyword = __esm({
|
|
|
11568
11605
|
}
|
|
11569
11606
|
if (matchedPaths.length === 0 && (hasRegexSyntax || fg.isDynamicPattern(posixPath))) {
|
|
11570
11607
|
const baseDirMatch = posixPath.match(/^([^\*\?\(\)\|\[\]\s]+)\//);
|
|
11571
|
-
const scanDir = baseDirMatch && !/[\*\?\(\)\|\[\]]/.test(baseDirMatch[1]) ?
|
|
11608
|
+
const scanDir = baseDirMatch && !/[\*\?\(\)\|\[\]]/.test(baseDirMatch[1]) ? path18.resolve(rootDir, baseDirMatch[1]) : rootDir;
|
|
11572
11609
|
const allFiles = await getFilesRecursively(scanDir, excludes, rootDir);
|
|
11573
11610
|
try {
|
|
11574
11611
|
let cleanRegexStr = posixPath.replace(/^\.\//, "");
|
|
@@ -11586,21 +11623,21 @@ var init_search_keyword = __esm({
|
|
|
11586
11623
|
}
|
|
11587
11624
|
} else {
|
|
11588
11625
|
filesToSearch = matchedPaths.map((relP) => ({
|
|
11589
|
-
fullPath:
|
|
11626
|
+
fullPath: path18.resolve(rootDir, relP),
|
|
11590
11627
|
relativePath: relP
|
|
11591
11628
|
}));
|
|
11592
11629
|
}
|
|
11593
11630
|
} else {
|
|
11594
11631
|
const normalised = pathArg.replace(/[\/\\]+$/, "");
|
|
11595
|
-
const fullPath =
|
|
11632
|
+
const fullPath = path18.resolve(rootDir, normalised);
|
|
11596
11633
|
try {
|
|
11597
|
-
const stat = await
|
|
11634
|
+
const stat = await fs19.stat(fullPath);
|
|
11598
11635
|
if (stat.isDirectory()) {
|
|
11599
11636
|
pathArgType = "dir";
|
|
11600
11637
|
filesToSearch = await getFilesRecursively(fullPath, excludes, rootDir);
|
|
11601
11638
|
} else if (stat.isFile()) {
|
|
11602
11639
|
pathArgType = "file";
|
|
11603
|
-
filesToSearch.push({ fullPath, relativePath:
|
|
11640
|
+
filesToSearch.push({ fullPath, relativePath: path18.relative(rootDir, fullPath) });
|
|
11604
11641
|
} else {
|
|
11605
11642
|
return `ERROR: Path is neither a file nor a directory: ${pathArg}`;
|
|
11606
11643
|
}
|
|
@@ -11613,7 +11650,7 @@ var init_search_keyword = __esm({
|
|
|
11613
11650
|
}
|
|
11614
11651
|
const searchPromises = filesToSearch.map(async (fileObj) => {
|
|
11615
11652
|
try {
|
|
11616
|
-
const content = await
|
|
11653
|
+
const content = await fs19.readFile(fileObj.fullPath, "utf-8");
|
|
11617
11654
|
if (content.includes("\0")) return [];
|
|
11618
11655
|
const lines = content.split(/\r?\n/);
|
|
11619
11656
|
const fileMatches = [];
|
|
@@ -11683,8 +11720,8 @@ var init_search_keyword = __esm({
|
|
|
11683
11720
|
});
|
|
11684
11721
|
|
|
11685
11722
|
// src/tools/generate_image.js
|
|
11686
|
-
import
|
|
11687
|
-
import
|
|
11723
|
+
import fs20 from "fs-extra";
|
|
11724
|
+
import path19 from "path";
|
|
11688
11725
|
var injectPngMetadata, generate_image;
|
|
11689
11726
|
var init_generate_image = __esm({
|
|
11690
11727
|
"src/tools/generate_image.js"() {
|
|
@@ -11863,12 +11900,12 @@ var init_generate_image = __esm({
|
|
|
11863
11900
|
"Seed": String(seed)
|
|
11864
11901
|
};
|
|
11865
11902
|
finalBuffer = injectPngMetadata(finalBuffer, metadata);
|
|
11866
|
-
const absolutePath =
|
|
11867
|
-
await
|
|
11903
|
+
const absolutePath = path19.resolve(process.cwd(), outputPath);
|
|
11904
|
+
await fs20.ensureDir(path19.dirname(absolutePath));
|
|
11868
11905
|
await RevertManager.recordFileChange(absolutePath);
|
|
11869
|
-
await
|
|
11906
|
+
await fs20.writeFile(absolutePath, finalBuffer);
|
|
11870
11907
|
await recordImageGeneration(settings);
|
|
11871
|
-
const ext =
|
|
11908
|
+
const ext = path19.extname(outputPath).toLowerCase();
|
|
11872
11909
|
const mimeMap = {
|
|
11873
11910
|
".jpg": "image/jpeg",
|
|
11874
11911
|
".jpeg": "image/jpeg",
|
|
@@ -11983,13 +12020,13 @@ var init_addMemScore = __esm({
|
|
|
11983
12020
|
});
|
|
11984
12021
|
|
|
11985
12022
|
// src/utils/parsers.js
|
|
11986
|
-
import
|
|
11987
|
-
import
|
|
12023
|
+
import fs21 from "fs-extra";
|
|
12024
|
+
import path20 from "path";
|
|
11988
12025
|
import https from "https";
|
|
11989
12026
|
async function downloadWasm(wasmFile, targetUrl = null) {
|
|
11990
12027
|
const url = targetUrl || `https://unpkg.com/tree-sitter-wasms@0.1.13/out/${wasmFile}`;
|
|
11991
|
-
const localPath =
|
|
11992
|
-
await
|
|
12028
|
+
const localPath = path20.join(PARSER_DIR, wasmFile);
|
|
12029
|
+
await fs21.ensureDir(PARSER_DIR);
|
|
11993
12030
|
return new Promise((resolve, reject) => {
|
|
11994
12031
|
const options = {
|
|
11995
12032
|
headers: {
|
|
@@ -12010,27 +12047,27 @@ async function downloadWasm(wasmFile, targetUrl = null) {
|
|
|
12010
12047
|
reject(new Error(`Failed to download ${wasmFile}: HTTP ${response.statusCode}`));
|
|
12011
12048
|
return;
|
|
12012
12049
|
}
|
|
12013
|
-
const file =
|
|
12050
|
+
const file = fs21.createWriteStream(localPath);
|
|
12014
12051
|
response.pipe(file);
|
|
12015
12052
|
file.on("finish", () => {
|
|
12016
12053
|
file.close();
|
|
12017
12054
|
resolve();
|
|
12018
12055
|
});
|
|
12019
12056
|
}).on("error", (err) => {
|
|
12020
|
-
if (
|
|
12057
|
+
if (fs21.existsSync(localPath)) fs21.unlink(localPath, () => {
|
|
12021
12058
|
});
|
|
12022
12059
|
reject(err);
|
|
12023
12060
|
});
|
|
12024
12061
|
});
|
|
12025
12062
|
}
|
|
12026
12063
|
function isParserInstalled(wasmFile) {
|
|
12027
|
-
const localPath =
|
|
12028
|
-
return
|
|
12064
|
+
const localPath = path20.join(PARSER_DIR, wasmFile);
|
|
12065
|
+
return fs21.existsSync(localPath);
|
|
12029
12066
|
}
|
|
12030
12067
|
async function deleteParser(wasmFile) {
|
|
12031
|
-
const localPath =
|
|
12032
|
-
if (
|
|
12033
|
-
await
|
|
12068
|
+
const localPath = path20.join(PARSER_DIR, wasmFile);
|
|
12069
|
+
if (fs21.existsSync(localPath)) {
|
|
12070
|
+
await fs21.unlink(localPath);
|
|
12034
12071
|
}
|
|
12035
12072
|
}
|
|
12036
12073
|
var EXTENSION_TO_WASM;
|
|
@@ -12052,8 +12089,8 @@ var init_parsers = __esm({
|
|
|
12052
12089
|
});
|
|
12053
12090
|
|
|
12054
12091
|
// src/tools/file_map.js
|
|
12055
|
-
import
|
|
12056
|
-
import
|
|
12092
|
+
import fs22 from "fs-extra";
|
|
12093
|
+
import path21 from "path";
|
|
12057
12094
|
import { createRequire as createRequire2 } from "module";
|
|
12058
12095
|
function sanitize(text, limit = 50) {
|
|
12059
12096
|
if (!text) return "";
|
|
@@ -12245,17 +12282,17 @@ var init_file_map = __esm({
|
|
|
12245
12282
|
if (!filePath) {
|
|
12246
12283
|
return 'ERROR: No file path provided. Use [tool:functions.FileMap(path="...")]';
|
|
12247
12284
|
}
|
|
12248
|
-
const absolutePath =
|
|
12249
|
-
if (!
|
|
12285
|
+
const absolutePath = path21.isAbsolute(filePath) ? filePath : path21.resolve(process.cwd(), filePath);
|
|
12286
|
+
if (!fs22.existsSync(absolutePath)) {
|
|
12250
12287
|
return `ERROR: File not found: ${filePath}`;
|
|
12251
12288
|
}
|
|
12252
|
-
const ext =
|
|
12289
|
+
const ext = path21.extname(absolutePath).slice(1).toLowerCase();
|
|
12253
12290
|
const wasmFile = EXTENSION_TO_WASM[ext];
|
|
12254
12291
|
if (!wasmFile) {
|
|
12255
12292
|
return `ERROR: Unsupported file extension: .${ext}`;
|
|
12256
12293
|
}
|
|
12257
|
-
const wasmPath =
|
|
12258
|
-
if (!
|
|
12294
|
+
const wasmPath = path21.resolve(PARSER_DIR, wasmFile);
|
|
12295
|
+
if (!fs22.existsSync(wasmPath)) {
|
|
12259
12296
|
return `ERROR: Parser for .${ext} not found. Please download it in Settings > Other.`;
|
|
12260
12297
|
}
|
|
12261
12298
|
try {
|
|
@@ -12263,9 +12300,9 @@ var init_file_map = __esm({
|
|
|
12263
12300
|
if (!isParserInitialized) {
|
|
12264
12301
|
let tsWasmPath;
|
|
12265
12302
|
try {
|
|
12266
|
-
tsWasmPath =
|
|
12303
|
+
tsWasmPath = path21.join(path21.dirname(require3.resolve("web-tree-sitter")), "tree-sitter.wasm");
|
|
12267
12304
|
} catch (e) {
|
|
12268
|
-
tsWasmPath =
|
|
12305
|
+
tsWasmPath = path21.join(process.cwd(), "node_modules", "web-tree-sitter", "tree-sitter.wasm");
|
|
12269
12306
|
}
|
|
12270
12307
|
await Parser.init({
|
|
12271
12308
|
locateFile: (p) => {
|
|
@@ -12280,7 +12317,7 @@ var init_file_map = __esm({
|
|
|
12280
12317
|
const parser = new Parser();
|
|
12281
12318
|
const Lang = await TreeSitter.Language.load(wasmPath);
|
|
12282
12319
|
parser.setLanguage(Lang);
|
|
12283
|
-
const sourceCode = await
|
|
12320
|
+
const sourceCode = await fs22.readFile(absolutePath, "utf8");
|
|
12284
12321
|
const lines = sourceCode.split("\n").length;
|
|
12285
12322
|
let maxDepth = 12;
|
|
12286
12323
|
if (lines > 1e4) maxDepth = 2;
|
|
@@ -12303,8 +12340,8 @@ Stack: ${err.stack}` : "";
|
|
|
12303
12340
|
});
|
|
12304
12341
|
|
|
12305
12342
|
// src/tools/todo.js
|
|
12306
|
-
import
|
|
12307
|
-
import
|
|
12343
|
+
import fs23 from "fs";
|
|
12344
|
+
import path22 from "path";
|
|
12308
12345
|
var todo;
|
|
12309
12346
|
var init_todo = __esm({
|
|
12310
12347
|
"src/tools/todo.js"() {
|
|
@@ -12315,8 +12352,8 @@ var init_todo = __esm({
|
|
|
12315
12352
|
const { method, tasks, markDone } = parseArgs(args);
|
|
12316
12353
|
const chatId = context.chatId || "default";
|
|
12317
12354
|
if (!method) return 'ERROR: Missing "method" argument for todo tool (create/append/get).';
|
|
12318
|
-
const todoDir =
|
|
12319
|
-
const todoFile =
|
|
12355
|
+
const todoDir = path22.join(DATA_DIR, "plan", chatId);
|
|
12356
|
+
const todoFile = path22.join(todoDir, "todo.md");
|
|
12320
12357
|
const parseMessyArray = (input) => {
|
|
12321
12358
|
if (!input || Array.isArray(input)) return input;
|
|
12322
12359
|
const trimmed = String(input).trim();
|
|
@@ -12376,8 +12413,8 @@ var init_todo = __esm({
|
|
|
12376
12413
|
};
|
|
12377
12414
|
};
|
|
12378
12415
|
try {
|
|
12379
|
-
if (!
|
|
12380
|
-
|
|
12416
|
+
if (!fs23.existsSync(todoDir)) {
|
|
12417
|
+
fs23.mkdirSync(todoDir, { recursive: true });
|
|
12381
12418
|
}
|
|
12382
12419
|
if (method === "create") {
|
|
12383
12420
|
if (!tasks) return 'ERROR: Missing "tasks" for create method.';
|
|
@@ -12389,7 +12426,7 @@ var init_todo = __esm({
|
|
|
12389
12426
|
markedCount = result.markedCount;
|
|
12390
12427
|
}
|
|
12391
12428
|
await RevertManager.recordFileChange(todoFile);
|
|
12392
|
-
|
|
12429
|
+
fs23.writeFileSync(todoFile, content, "utf8");
|
|
12393
12430
|
const total = content.split(/\r?\n/).map((l) => l.trim()).filter((l) => l.startsWith("- [ ]") || l.startsWith("- [x]") || l.startsWith("- [X]")).length;
|
|
12394
12431
|
if (markedCount > 0) {
|
|
12395
12432
|
const completed = content.split(/\r?\n/).map((l) => l.trim()).filter((l) => l.startsWith("- [x]") || l.startsWith("- [X]")).length;
|
|
@@ -12403,8 +12440,8 @@ ${content}`;
|
|
|
12403
12440
|
if (!tasks) return 'ERROR: Missing "tasks" for append method.';
|
|
12404
12441
|
const appendContent = getTasksString(tasks);
|
|
12405
12442
|
await RevertManager.recordFileChange(todoFile);
|
|
12406
|
-
|
|
12407
|
-
const fullContent =
|
|
12443
|
+
fs23.appendFileSync(todoFile, appendContent, "utf8");
|
|
12444
|
+
const fullContent = fs23.readFileSync(todoFile, "utf8");
|
|
12408
12445
|
const lines = fullContent.split(/\r?\n/).map((l) => l.trim());
|
|
12409
12446
|
const total = lines.filter((l) => l.startsWith("- [ ]") || l.startsWith("- [x]") || l.startsWith("- [X]")).length;
|
|
12410
12447
|
const completed = lines.filter((l) => l.startsWith("- [x]") || l.startsWith("- [X]")).length;
|
|
@@ -12413,10 +12450,10 @@ ${content}`;
|
|
|
12413
12450
|
${fullContent}`;
|
|
12414
12451
|
}
|
|
12415
12452
|
if (method === "get") {
|
|
12416
|
-
if (!
|
|
12453
|
+
if (!fs23.existsSync(todoFile)) {
|
|
12417
12454
|
return "TODO GET: No task list found for this session.";
|
|
12418
12455
|
}
|
|
12419
|
-
let content =
|
|
12456
|
+
let content = fs23.readFileSync(todoFile, "utf8");
|
|
12420
12457
|
let markedCount = 0;
|
|
12421
12458
|
if (markDone) {
|
|
12422
12459
|
const result = applyMarkDone(content, markDone);
|
|
@@ -12424,7 +12461,7 @@ ${fullContent}`;
|
|
|
12424
12461
|
content = result.content;
|
|
12425
12462
|
markedCount = result.markedCount;
|
|
12426
12463
|
await RevertManager.recordFileChange(todoFile);
|
|
12427
|
-
|
|
12464
|
+
fs23.writeFileSync(todoFile, content, "utf8");
|
|
12428
12465
|
}
|
|
12429
12466
|
}
|
|
12430
12467
|
const totalLines = content.split(/\r?\n/).map((l) => l.trim());
|
|
@@ -12494,10 +12531,33 @@ var init_invokeSync = __esm({
|
|
|
12494
12531
|
});
|
|
12495
12532
|
|
|
12496
12533
|
// src/utils/subagent_state.js
|
|
12497
|
-
var
|
|
12534
|
+
var subagent_state_exports = {};
|
|
12535
|
+
__export(subagent_state_exports, {
|
|
12536
|
+
addPendingNudge: () => addPendingNudge,
|
|
12537
|
+
clearPendingNudges: () => clearPendingNudges,
|
|
12538
|
+
consumePendingNudges: () => consumePendingNudges,
|
|
12539
|
+
pendingSubagentNudges: () => pendingSubagentNudges,
|
|
12540
|
+
subagentProgress: () => subagentProgress
|
|
12541
|
+
});
|
|
12542
|
+
var subagentProgress, pendingSubagentNudges, addPendingNudge, consumePendingNudges, clearPendingNudges;
|
|
12498
12543
|
var init_subagent_state = __esm({
|
|
12499
12544
|
"src/utils/subagent_state.js"() {
|
|
12500
12545
|
subagentProgress = [];
|
|
12546
|
+
pendingSubagentNudges = [];
|
|
12547
|
+
addPendingNudge = (msg) => {
|
|
12548
|
+
if (msg) {
|
|
12549
|
+
pendingSubagentNudges.push(msg);
|
|
12550
|
+
}
|
|
12551
|
+
};
|
|
12552
|
+
consumePendingNudges = () => {
|
|
12553
|
+
if (pendingSubagentNudges.length === 0) return [];
|
|
12554
|
+
const nudges = [...pendingSubagentNudges];
|
|
12555
|
+
pendingSubagentNudges = [];
|
|
12556
|
+
return nudges;
|
|
12557
|
+
};
|
|
12558
|
+
clearPendingNudges = () => {
|
|
12559
|
+
pendingSubagentNudges = [];
|
|
12560
|
+
};
|
|
12501
12561
|
}
|
|
12502
12562
|
});
|
|
12503
12563
|
|
|
@@ -12529,13 +12589,24 @@ var init_invoke = __esm({
|
|
|
12529
12589
|
}
|
|
12530
12590
|
}
|
|
12531
12591
|
const taskId = `subagent-${Date.now()}-${Math.floor(Math.random() * 1e3)}`;
|
|
12592
|
+
let _resolveCompletion = null;
|
|
12593
|
+
let _rejectCompletion = null;
|
|
12594
|
+
const completionPromise = new Promise((res, rej) => {
|
|
12595
|
+
_resolveCompletion = res;
|
|
12596
|
+
_rejectCompletion = rej;
|
|
12597
|
+
});
|
|
12532
12598
|
const taskEntry = {
|
|
12533
12599
|
id: taskId,
|
|
12534
12600
|
title: title || task.substring(0, 30),
|
|
12535
12601
|
task,
|
|
12536
12602
|
status: "running",
|
|
12603
|
+
startedAt: Date.now(),
|
|
12537
12604
|
lastChunkTime: Date.now(),
|
|
12538
12605
|
wps: 0,
|
|
12606
|
+
questions: [],
|
|
12607
|
+
completionPromise,
|
|
12608
|
+
_resolveCompletion,
|
|
12609
|
+
_rejectCompletion,
|
|
12539
12610
|
progress: []
|
|
12540
12611
|
// Array of arrays containing logs for each turn
|
|
12541
12612
|
};
|
|
@@ -12548,6 +12619,32 @@ var init_invoke = __esm({
|
|
|
12548
12619
|
const subagentContext = {
|
|
12549
12620
|
...context,
|
|
12550
12621
|
taskId,
|
|
12622
|
+
onAskMain: async (questionText, optionsObj) => {
|
|
12623
|
+
const questionId = `q-${Date.now()}-${Math.floor(Math.random() * 1e3)}`;
|
|
12624
|
+
let questionResolver = null;
|
|
12625
|
+
const qPromise = new Promise((resolve) => {
|
|
12626
|
+
questionResolver = resolve;
|
|
12627
|
+
});
|
|
12628
|
+
const qEntry = {
|
|
12629
|
+
id: questionId,
|
|
12630
|
+
question: questionText,
|
|
12631
|
+
options: optionsObj,
|
|
12632
|
+
answered: false,
|
|
12633
|
+
answer: null,
|
|
12634
|
+
askedAt: Date.now(),
|
|
12635
|
+
_resolve: questionResolver
|
|
12636
|
+
};
|
|
12637
|
+
taskEntry.questions.push(qEntry);
|
|
12638
|
+
taskEntry.status = "waiting";
|
|
12639
|
+
if (context.onSubagentUpdate) {
|
|
12640
|
+
context.onSubagentUpdate();
|
|
12641
|
+
}
|
|
12642
|
+
addPendingNudge(`[SYSTEM] Background subagent "${taskEntry.title}" is WAITING FOR YOUR INPUT: "${questionText}"
|
|
12643
|
+
Respond using tool: [tool:functions.Answer(id="${taskId}", answer="...")]
|
|
12644
|
+
[/SYSTEM]`);
|
|
12645
|
+
const answer = await qPromise;
|
|
12646
|
+
return answer;
|
|
12647
|
+
},
|
|
12551
12648
|
onVisualFeedback: (feedbackLabel) => {
|
|
12552
12649
|
taskEntry.lastChunkTime = Date.now();
|
|
12553
12650
|
const clean = feedbackLabel.replace(/\x1b\[[0-9;]*m/g, "");
|
|
@@ -12609,16 +12706,22 @@ var init_invoke = __esm({
|
|
|
12609
12706
|
if (context.onSubagentUpdate) {
|
|
12610
12707
|
context.onSubagentUpdate();
|
|
12611
12708
|
}
|
|
12612
|
-
}).then((finalAnswer) => {
|
|
12613
|
-
if (taskEntry.status === "cancelled")
|
|
12614
|
-
|
|
12615
|
-
|
|
12616
|
-
|
|
12709
|
+
}, true).then((finalAnswer) => {
|
|
12710
|
+
if (taskEntry.status === "cancelled") {
|
|
12711
|
+
if (taskEntry._resolveCompletion) taskEntry._resolveCompletion(finalAnswer);
|
|
12712
|
+
return;
|
|
12713
|
+
}
|
|
12714
|
+
if (currentTurnLogs.length > 0) {
|
|
12715
|
+
taskEntry.progress.push([...currentTurnLogs]);
|
|
12716
|
+
currentTurnLogs = [];
|
|
12717
|
+
}
|
|
12617
12718
|
taskEntry.status = "completed";
|
|
12618
12719
|
taskEntry.finalAnswer = finalAnswer;
|
|
12619
12720
|
if (context.onSubagentUpdate) {
|
|
12620
12721
|
context.onSubagentUpdate();
|
|
12621
12722
|
}
|
|
12723
|
+
addPendingNudge(`[SYSTEM] Background subagent "${taskEntry.title}" (id: ${taskId}) has FINISHED. Call GetProgress(id="${taskId}") to see the final result. [/SYSTEM]`);
|
|
12724
|
+
if (taskEntry._resolveCompletion) taskEntry._resolveCompletion(finalAnswer);
|
|
12622
12725
|
}).catch(async (err) => {
|
|
12623
12726
|
const { isTerminationSignaled: isTerminationSignaled2 } = await init_ai().then(() => ai_exports);
|
|
12624
12727
|
const isCancelled = err.message === "Subagent task was cancelled." || taskEntry.status === "cancelled" || isTerminationSignaled2();
|
|
@@ -12629,6 +12732,7 @@ ${finalAnswer}`);
|
|
|
12629
12732
|
if (context.onSubagentUpdate) {
|
|
12630
12733
|
context.onSubagentUpdate();
|
|
12631
12734
|
}
|
|
12735
|
+
if (taskEntry._resolveCompletion) taskEntry._resolveCompletion(null);
|
|
12632
12736
|
return;
|
|
12633
12737
|
}
|
|
12634
12738
|
currentTurnLogs.push(`[SUBAGENT FAILURE] Error: ${err.message}`);
|
|
@@ -12638,6 +12742,8 @@ ${finalAnswer}`);
|
|
|
12638
12742
|
if (context.onSubagentUpdate) {
|
|
12639
12743
|
context.onSubagentUpdate();
|
|
12640
12744
|
}
|
|
12745
|
+
addPendingNudge(`[SYSTEM] Background subagent "${taskEntry.title}" (id: ${taskId}) FAILED with error: ${err.message}. [/SYSTEM]`);
|
|
12746
|
+
if (taskEntry._rejectCompletion) taskEntry._rejectCompletion(err);
|
|
12641
12747
|
});
|
|
12642
12748
|
return `SUCCESS: Background subagent started. Task ID: ${taskId}`;
|
|
12643
12749
|
};
|
|
@@ -12665,14 +12771,47 @@ var init_getProgress = __esm({
|
|
|
12665
12771
|
output += `Title: ${task.title}
|
|
12666
12772
|
`;
|
|
12667
12773
|
output += `Task: ${task.task}
|
|
12774
|
+
`;
|
|
12775
|
+
if (task.startedAt) {
|
|
12776
|
+
const elapsedSec = Math.floor((Date.now() - task.startedAt) / 1e3);
|
|
12777
|
+
output += `Elapsed Time: ${elapsedSec}s
|
|
12778
|
+
`;
|
|
12779
|
+
}
|
|
12780
|
+
output += `Turns Completed: ${task.progress.length}
|
|
12781
|
+
`;
|
|
12782
|
+
if (task.status === "running" || task.status === "waiting") {
|
|
12783
|
+
if (task.currentTool) output += `Current Tool: ${task.currentTool}
|
|
12784
|
+
`;
|
|
12785
|
+
if (task.wps > 0) output += `WPS: ${task.wps}
|
|
12786
|
+
`;
|
|
12787
|
+
}
|
|
12788
|
+
if (task.questions && task.questions.length > 0) {
|
|
12789
|
+
const pending = task.questions.filter((q) => !q.answered);
|
|
12790
|
+
if (pending.length > 0) {
|
|
12791
|
+
output += `
|
|
12792
|
+
**PENDING QUESTION**
|
|
12793
|
+
`;
|
|
12794
|
+
pending.forEach((q) => {
|
|
12795
|
+
output += `"${q.question}"
|
|
12796
|
+
`;
|
|
12797
|
+
if (q.options && Object.keys(q.options).length > 0) {
|
|
12798
|
+
output += `Options: ${JSON.stringify(q.options)}
|
|
12799
|
+
`;
|
|
12800
|
+
}
|
|
12801
|
+
});
|
|
12802
|
+
output += `Respond using tool: [tool:functions.Answer(id="${task.id}", answer="...")]
|
|
12668
12803
|
|
|
12669
12804
|
`;
|
|
12670
|
-
|
|
12805
|
+
}
|
|
12806
|
+
}
|
|
12807
|
+
output += `
|
|
12808
|
+
Progress Log:
|
|
12671
12809
|
`;
|
|
12672
12810
|
task.progress.forEach((turnLogs, index) => {
|
|
12673
12811
|
output += `--- Turn ${index + 1} ---
|
|
12674
12812
|
`;
|
|
12675
|
-
const
|
|
12813
|
+
const filteredLogs = turnLogs.filter((log) => !log.startsWith("[SUBAGENT SUCCESS]"));
|
|
12814
|
+
const processedLogs = filteredLogs.map((log) => {
|
|
12676
12815
|
if (log.startsWith("[Subagent Response]")) {
|
|
12677
12816
|
const header = "[Subagent Response]";
|
|
12678
12817
|
const body = log.substring(header.length);
|
|
@@ -12747,7 +12886,7 @@ ${task.finalAnswer}
|
|
|
12747
12886
|
output += `Failure Error: ${task.error}
|
|
12748
12887
|
`;
|
|
12749
12888
|
}
|
|
12750
|
-
const sanitized = output.trim().replace(/\[TOOL RESULT\]/gi, "TOOL RESULT:");
|
|
12889
|
+
const sanitized = output.replace(/\r\n/g, "\n").replace(/\n{3,}/g, "\n\n").trim().replace(/\[TOOL RESULT\]/gi, "TOOL RESULT:");
|
|
12751
12890
|
return sanitized;
|
|
12752
12891
|
};
|
|
12753
12892
|
}
|
|
@@ -12785,55 +12924,27 @@ var init_cancel = __esm({
|
|
|
12785
12924
|
});
|
|
12786
12925
|
|
|
12787
12926
|
// src/tools/await.js
|
|
12788
|
-
var awaitTool;
|
|
12789
12927
|
var init_await = __esm({
|
|
12790
12928
|
"src/tools/await.js"() {
|
|
12791
12929
|
init_arg_parser();
|
|
12792
|
-
awaitTool = async (args, context = {}) => {
|
|
12793
|
-
const parsed = parseArgs(args);
|
|
12794
|
-
const timeStr = parsed.time;
|
|
12795
|
-
if (!timeStr) {
|
|
12796
|
-
return 'ERROR: Missing "time" argument for await.';
|
|
12797
|
-
}
|
|
12798
|
-
let seconds = parseFloat(timeStr);
|
|
12799
|
-
if (isNaN(seconds)) {
|
|
12800
|
-
return `ERROR: Invalid time value "${timeStr}". Must be a number.`;
|
|
12801
|
-
}
|
|
12802
|
-
if (seconds < 10) {
|
|
12803
|
-
seconds = 10;
|
|
12804
|
-
} else if (seconds > 180) {
|
|
12805
|
-
seconds = 180;
|
|
12806
|
-
}
|
|
12807
|
-
const formatTime = (s) => {
|
|
12808
|
-
if (s >= 60) {
|
|
12809
|
-
const m = Math.floor(s / 60);
|
|
12810
|
-
const rem = s % 60;
|
|
12811
|
-
return `${m}m${rem > 0 ? ` ${rem}s` : ""}`;
|
|
12812
|
-
}
|
|
12813
|
-
return `${s}s`;
|
|
12814
|
-
};
|
|
12815
|
-
const formatted = formatTime(seconds);
|
|
12816
|
-
await new Promise((resolve) => setTimeout(resolve, seconds * 1e3));
|
|
12817
|
-
return `SUCCESS: Waited for ${formatted}${seconds > 180 ? " (Max: 180s)" : ""}${seconds < 10 ? " (Min: 10s)" : ""}.`;
|
|
12818
|
-
};
|
|
12819
12930
|
}
|
|
12820
12931
|
});
|
|
12821
12932
|
|
|
12822
12933
|
// src/utils/advanceRevert.js
|
|
12823
|
-
import
|
|
12824
|
-
import
|
|
12934
|
+
import fs24 from "fs-extra";
|
|
12935
|
+
import path23 from "path";
|
|
12825
12936
|
async function scanWorkspace(dir, baseDir = dir) {
|
|
12826
12937
|
const manifest = {};
|
|
12827
|
-
const entries = await
|
|
12938
|
+
const entries = await fs24.readdir(dir, { withFileTypes: true }).catch(() => []);
|
|
12828
12939
|
for (const entry of entries) {
|
|
12829
12940
|
if (JUNK_DIRECTORIES.includes(entry.name)) continue;
|
|
12830
|
-
const fullPath =
|
|
12831
|
-
const relPath =
|
|
12941
|
+
const fullPath = path23.join(dir, entry.name);
|
|
12942
|
+
const relPath = path23.relative(baseDir, fullPath).replace(/\\/g, "/");
|
|
12832
12943
|
if (entry.isDirectory()) {
|
|
12833
12944
|
const sub = await scanWorkspace(fullPath, baseDir);
|
|
12834
12945
|
Object.assign(manifest, sub);
|
|
12835
12946
|
} else {
|
|
12836
|
-
const stats = await
|
|
12947
|
+
const stats = await fs24.stat(fullPath).catch(() => null);
|
|
12837
12948
|
if (stats) {
|
|
12838
12949
|
manifest[relPath] = {
|
|
12839
12950
|
size: stats.size,
|
|
@@ -12845,34 +12956,34 @@ async function scanWorkspace(dir, baseDir = dir) {
|
|
|
12845
12956
|
return manifest;
|
|
12846
12957
|
}
|
|
12847
12958
|
async function copyWorkspaceFiles(destDir, manifest) {
|
|
12848
|
-
await
|
|
12959
|
+
await fs24.ensureDir(destDir);
|
|
12849
12960
|
for (const relPath of Object.keys(manifest)) {
|
|
12850
|
-
const srcPath =
|
|
12851
|
-
const destPath =
|
|
12852
|
-
await
|
|
12853
|
-
await
|
|
12961
|
+
const srcPath = path23.join(process.cwd(), relPath);
|
|
12962
|
+
const destPath = path23.join(destDir, relPath);
|
|
12963
|
+
await fs24.ensureDir(path23.dirname(destPath));
|
|
12964
|
+
await fs24.copyFile(srcPath, destPath).catch(() => {
|
|
12854
12965
|
});
|
|
12855
12966
|
}
|
|
12856
12967
|
}
|
|
12857
12968
|
async function restoreSnapshotDir(srcDir, destDir, stats = null, baseDir = null) {
|
|
12858
|
-
if (!await
|
|
12969
|
+
if (!await fs24.pathExists(srcDir)) return;
|
|
12859
12970
|
if (!baseDir) baseDir = srcDir;
|
|
12860
|
-
const entries = await
|
|
12971
|
+
const entries = await fs24.readdir(srcDir, { withFileTypes: true }).catch(() => []);
|
|
12861
12972
|
for (const entry of entries) {
|
|
12862
|
-
const srcPath =
|
|
12863
|
-
const destPath =
|
|
12973
|
+
const srcPath = path23.join(srcDir, entry.name);
|
|
12974
|
+
const destPath = path23.join(destDir, entry.name);
|
|
12864
12975
|
if (entry.isDirectory()) {
|
|
12865
12976
|
await restoreSnapshotDir(srcPath, destPath, stats, baseDir);
|
|
12866
12977
|
} else {
|
|
12867
|
-
const relPath =
|
|
12868
|
-
const existed = await
|
|
12978
|
+
const relPath = path23.relative(baseDir, srcPath).replace(/\\/g, "/");
|
|
12979
|
+
const existed = await fs24.pathExists(destPath);
|
|
12869
12980
|
if (existed) {
|
|
12870
|
-
await
|
|
12981
|
+
await fs24.chmod(destPath, 438).catch(() => {
|
|
12871
12982
|
});
|
|
12872
12983
|
}
|
|
12873
|
-
await
|
|
12874
|
-
const ok = await
|
|
12875
|
-
await
|
|
12984
|
+
await fs24.ensureDir(path23.dirname(destPath));
|
|
12985
|
+
const ok = await fs24.copyFile(srcPath, destPath).then(() => true).catch(() => false);
|
|
12986
|
+
await fs24.chmod(destPath, 438).catch(() => {
|
|
12876
12987
|
});
|
|
12877
12988
|
if (stats) {
|
|
12878
12989
|
if (!ok) {
|
|
@@ -12910,12 +13021,12 @@ var init_advanceRevert = __esm({
|
|
|
12910
13021
|
AdvanceRevertManager = {
|
|
12911
13022
|
async takeInitialSnapshot(chatId) {
|
|
12912
13023
|
try {
|
|
12913
|
-
const snapshotsDir =
|
|
12914
|
-
await
|
|
13024
|
+
const snapshotsDir = path23.join(DATA_DIR, "snapshots", chatId);
|
|
13025
|
+
await fs24.remove(snapshotsDir).catch(() => {
|
|
12915
13026
|
});
|
|
12916
|
-
await
|
|
13027
|
+
await fs24.ensureDir(snapshotsDir);
|
|
12917
13028
|
const manifest = await scanWorkspace(process.cwd());
|
|
12918
|
-
await copyWorkspaceFiles(
|
|
13029
|
+
await copyWorkspaceFiles(path23.join(snapshotsDir, "initial"), manifest);
|
|
12919
13030
|
const ledger = readEncryptedJson(LEDGER_ADVANCE_FILE, {});
|
|
12920
13031
|
ledger[chatId] = {
|
|
12921
13032
|
initialManifest: manifest,
|
|
@@ -12964,7 +13075,7 @@ var init_advanceRevert = __esm({
|
|
|
12964
13075
|
for (const file of changedFiles) {
|
|
12965
13076
|
deltaManifest[file] = currentManifest[file];
|
|
12966
13077
|
}
|
|
12967
|
-
const turnDir =
|
|
13078
|
+
const turnDir = path23.join(DATA_DIR, "snapshots", chatId, `turn_${turnNumber}`);
|
|
12968
13079
|
await copyWorkspaceFiles(turnDir, deltaManifest);
|
|
12969
13080
|
}
|
|
12970
13081
|
session.checkpoints.push({
|
|
@@ -12998,28 +13109,28 @@ var init_advanceRevert = __esm({
|
|
|
12998
13109
|
const checkpoints = session.checkpoints || [];
|
|
12999
13110
|
const targetIdx = checkpoints.findIndex((c) => c.id === checkpointId);
|
|
13000
13111
|
if (targetIdx === -1) throw new Error(`Checkpoint [${checkpointId}] not found.`);
|
|
13001
|
-
const snapshotsDir =
|
|
13112
|
+
const snapshotsDir = path23.join(DATA_DIR, "snapshots", chatId);
|
|
13002
13113
|
const stats = { restored: 0, replaced: 0, failed: [] };
|
|
13003
13114
|
const currentFiles = await scanWorkspace(process.cwd());
|
|
13004
13115
|
for (const relPath of Object.keys(currentFiles)) {
|
|
13005
|
-
const fullPath =
|
|
13006
|
-
await
|
|
13116
|
+
const fullPath = path23.join(process.cwd(), relPath);
|
|
13117
|
+
await fs24.chmod(fullPath, 438).catch(() => {
|
|
13007
13118
|
});
|
|
13008
|
-
await
|
|
13119
|
+
await fs24.remove(fullPath).catch(() => {
|
|
13009
13120
|
});
|
|
13010
13121
|
}
|
|
13011
|
-
const initialDir =
|
|
13122
|
+
const initialDir = path23.join(snapshotsDir, "initial");
|
|
13012
13123
|
await restoreSnapshotDir(initialDir, process.cwd(), stats, initialDir);
|
|
13013
13124
|
for (let i = 1; i <= targetIdx; i++) {
|
|
13014
13125
|
const cp = checkpoints[i];
|
|
13015
|
-
const turnDir =
|
|
13126
|
+
const turnDir = path23.join(snapshotsDir, cp.id);
|
|
13016
13127
|
await restoreSnapshotDir(turnDir, process.cwd(), stats, turnDir);
|
|
13017
13128
|
if (cp.deletedFiles && cp.deletedFiles.length > 0) {
|
|
13018
13129
|
for (const delFile of cp.deletedFiles) {
|
|
13019
|
-
const fullPath =
|
|
13020
|
-
await
|
|
13130
|
+
const fullPath = path23.join(process.cwd(), delFile);
|
|
13131
|
+
await fs24.chmod(fullPath, 438).catch(() => {
|
|
13021
13132
|
});
|
|
13022
|
-
await
|
|
13133
|
+
await fs24.remove(fullPath).catch(() => {
|
|
13023
13134
|
});
|
|
13024
13135
|
}
|
|
13025
13136
|
}
|
|
@@ -13051,8 +13162,8 @@ var init_advanceRevert = __esm({
|
|
|
13051
13162
|
},
|
|
13052
13163
|
async cleanup(chatId) {
|
|
13053
13164
|
try {
|
|
13054
|
-
const snapshotsDir =
|
|
13055
|
-
await
|
|
13165
|
+
const snapshotsDir = path23.join(DATA_DIR, "snapshots", chatId);
|
|
13166
|
+
await fs24.remove(snapshotsDir).catch(() => {
|
|
13056
13167
|
});
|
|
13057
13168
|
const ledger = readEncryptedJson(LEDGER_ADVANCE_FILE, {});
|
|
13058
13169
|
if (ledger[chatId]) {
|
|
@@ -13170,6 +13281,120 @@ Tools Used: ${toolsStr}
|
|
|
13170
13281
|
}
|
|
13171
13282
|
});
|
|
13172
13283
|
|
|
13284
|
+
// src/tools/awaitSubagent.js
|
|
13285
|
+
var awaitSubagent;
|
|
13286
|
+
var init_awaitSubagent = __esm({
|
|
13287
|
+
"src/tools/awaitSubagent.js"() {
|
|
13288
|
+
init_subagent_state();
|
|
13289
|
+
init_arg_parser();
|
|
13290
|
+
awaitSubagent = async (args, context = {}) => {
|
|
13291
|
+
const parsed = parseArgs(args);
|
|
13292
|
+
const id = parsed.id;
|
|
13293
|
+
let timeoutSec = parseInt(parsed.timeout || parsed.time || "120", 10);
|
|
13294
|
+
if (isNaN(timeoutSec) || timeoutSec <= 0) timeoutSec = 120;
|
|
13295
|
+
if (timeoutSec > 300) timeoutSec = 300;
|
|
13296
|
+
if (!id) {
|
|
13297
|
+
if (parsed.time) {
|
|
13298
|
+
await new Promise((resolve) => setTimeout(resolve, timeoutSec * 1e3));
|
|
13299
|
+
return `SUCCESS: Waited for ${timeoutSec}s.`;
|
|
13300
|
+
}
|
|
13301
|
+
return 'ERROR: Missing "id" argument for Await.';
|
|
13302
|
+
}
|
|
13303
|
+
const task = subagentProgress.find((t) => t.id === id);
|
|
13304
|
+
if (!task) {
|
|
13305
|
+
return `ERROR: Subagent task with ID [${id}] not found.`;
|
|
13306
|
+
}
|
|
13307
|
+
if (task.status === "completed") {
|
|
13308
|
+
return `SUCCESS: Subagent task [${id}] completed.
|
|
13309
|
+
Final Answer:
|
|
13310
|
+
${task.finalAnswer || "(No output)"}`;
|
|
13311
|
+
}
|
|
13312
|
+
if (task.status === "failed") {
|
|
13313
|
+
return `ERROR: Subagent task [${id}] failed.
|
|
13314
|
+
Error: ${task.error || "Unknown error"}`;
|
|
13315
|
+
}
|
|
13316
|
+
if (task.status === "cancelled") {
|
|
13317
|
+
return `INFO: Subagent task [${id}] was cancelled.`;
|
|
13318
|
+
}
|
|
13319
|
+
let timeoutId;
|
|
13320
|
+
const timeoutPromise = new Promise((resolve) => {
|
|
13321
|
+
timeoutId = setTimeout(() => {
|
|
13322
|
+
resolve({ type: "timeout" });
|
|
13323
|
+
}, timeoutSec * 1e3);
|
|
13324
|
+
});
|
|
13325
|
+
try {
|
|
13326
|
+
const result = await Promise.race([
|
|
13327
|
+
task.completionPromise.then(() => ({ type: "completion" })),
|
|
13328
|
+
timeoutPromise
|
|
13329
|
+
]);
|
|
13330
|
+
clearTimeout(timeoutId);
|
|
13331
|
+
if (result.type === "timeout") {
|
|
13332
|
+
return `TIMEOUT: Subagent task [${id}] is still running (status: ${task.status.toUpperCase()}) after ${timeoutSec}s. You can continue other work or call Await again.`;
|
|
13333
|
+
}
|
|
13334
|
+
if (task.status === "completed") {
|
|
13335
|
+
return `SUCCESS: Subagent task [${id}] completed.
|
|
13336
|
+
Final Answer:
|
|
13337
|
+
${task.finalAnswer || "(No output)"}`;
|
|
13338
|
+
} else if (task.status === "failed") {
|
|
13339
|
+
return `ERROR: Subagent task [${id}] failed.
|
|
13340
|
+
Error: ${task.error || "Unknown error"}`;
|
|
13341
|
+
} else if (task.status === "cancelled") {
|
|
13342
|
+
return `INFO: Subagent task [${id}] was cancelled.`;
|
|
13343
|
+
} else {
|
|
13344
|
+
return `INFO: Subagent task [${id}] status changed to ${task.status.toUpperCase()}.`;
|
|
13345
|
+
}
|
|
13346
|
+
} catch (err) {
|
|
13347
|
+
clearTimeout(timeoutId);
|
|
13348
|
+
return `ERROR: Exception while awaiting subagent [${id}]: ${err.message}`;
|
|
13349
|
+
}
|
|
13350
|
+
};
|
|
13351
|
+
}
|
|
13352
|
+
});
|
|
13353
|
+
|
|
13354
|
+
// src/tools/answerSubagent.js
|
|
13355
|
+
var answerSubagent;
|
|
13356
|
+
var init_answerSubagent = __esm({
|
|
13357
|
+
"src/tools/answerSubagent.js"() {
|
|
13358
|
+
init_subagent_state();
|
|
13359
|
+
init_arg_parser();
|
|
13360
|
+
answerSubagent = async (args, context = {}) => {
|
|
13361
|
+
const parsed = parseArgs(args);
|
|
13362
|
+
const id = parsed.id;
|
|
13363
|
+
const answer = parsed.answer || parsed.response;
|
|
13364
|
+
if (!id) {
|
|
13365
|
+
return 'ERROR: Missing "id" argument for Answer.';
|
|
13366
|
+
}
|
|
13367
|
+
if (!answer) {
|
|
13368
|
+
return 'ERROR: Missing "answer" argument for Answer.';
|
|
13369
|
+
}
|
|
13370
|
+
const task = subagentProgress.find((t) => t.id === id);
|
|
13371
|
+
if (!task) {
|
|
13372
|
+
return `ERROR: Subagent task with ID [${id}] not found.`;
|
|
13373
|
+
}
|
|
13374
|
+
if (!task.questions || task.questions.length === 0) {
|
|
13375
|
+
return `INFO: Subagent task [${id}] has no pending questions.`;
|
|
13376
|
+
}
|
|
13377
|
+
const pending = task.questions.filter((q) => !q.answered);
|
|
13378
|
+
if (pending.length === 0) {
|
|
13379
|
+
return `INFO: Subagent task [${id}] has no unanswered questions.`;
|
|
13380
|
+
}
|
|
13381
|
+
pending.forEach((q) => {
|
|
13382
|
+
q.answered = true;
|
|
13383
|
+
q.answer = answer;
|
|
13384
|
+
q.answeredAt = Date.now();
|
|
13385
|
+
if (q._resolve) {
|
|
13386
|
+
q._resolve(answer);
|
|
13387
|
+
}
|
|
13388
|
+
});
|
|
13389
|
+
task.status = "running";
|
|
13390
|
+
if (context.onSubagentUpdate) {
|
|
13391
|
+
context.onSubagentUpdate();
|
|
13392
|
+
}
|
|
13393
|
+
return `SUCCESS: Answer provided to subagent task [${id}]. Subagent execution resumed.`;
|
|
13394
|
+
};
|
|
13395
|
+
}
|
|
13396
|
+
});
|
|
13397
|
+
|
|
13173
13398
|
// src/utils/tools.js
|
|
13174
13399
|
var TOOL_MAP, dispatchTool;
|
|
13175
13400
|
var init_tools = __esm({
|
|
@@ -13198,6 +13423,8 @@ var init_tools = __esm({
|
|
|
13198
13423
|
init_cancel();
|
|
13199
13424
|
init_await();
|
|
13200
13425
|
init_emergency_rollback();
|
|
13426
|
+
init_awaitSubagent();
|
|
13427
|
+
init_answerSubagent();
|
|
13201
13428
|
TOOL_MAP = {
|
|
13202
13429
|
web_search,
|
|
13203
13430
|
web_scrape,
|
|
@@ -13220,8 +13447,12 @@ var init_tools = __esm({
|
|
|
13220
13447
|
invoke,
|
|
13221
13448
|
getProgress,
|
|
13222
13449
|
cancel,
|
|
13450
|
+
awaitSubagent,
|
|
13451
|
+
answerSubagent,
|
|
13223
13452
|
invoke_sync: invokeSync,
|
|
13224
13453
|
get_progress: getProgress,
|
|
13454
|
+
await_subagent: awaitSubagent,
|
|
13455
|
+
answer_subagent: answerSubagent,
|
|
13225
13456
|
ask: ask_user,
|
|
13226
13457
|
// PascalCase Normalizations for Token Efficiency
|
|
13227
13458
|
Ask: ask_user,
|
|
@@ -13246,14 +13477,12 @@ var init_tools = __esm({
|
|
|
13246
13477
|
addMemoryScore: addMemScore,
|
|
13247
13478
|
AddMemoryScore: addMemScore,
|
|
13248
13479
|
FileMap: file_map,
|
|
13249
|
-
|
|
13250
|
-
|
|
13251
|
-
|
|
13252
|
-
|
|
13253
|
-
|
|
13254
|
-
|
|
13255
|
-
await: awaitTool,
|
|
13256
|
-
Await: awaitTool,
|
|
13480
|
+
answer: answerSubagent,
|
|
13481
|
+
Answer: answerSubagent,
|
|
13482
|
+
AnswerSubagent: answerSubagent,
|
|
13483
|
+
await: awaitSubagent,
|
|
13484
|
+
Await: awaitSubagent,
|
|
13485
|
+
AwaitSubagent: awaitSubagent,
|
|
13257
13486
|
EmergencyRollback: emergency_rollback,
|
|
13258
13487
|
emergency_rollback
|
|
13259
13488
|
};
|
|
@@ -13392,14 +13621,14 @@ var init_editor = __esm({
|
|
|
13392
13621
|
});
|
|
13393
13622
|
|
|
13394
13623
|
// src/utils/getDirTree/indentation.js
|
|
13395
|
-
import
|
|
13396
|
-
import
|
|
13624
|
+
import path24 from "path";
|
|
13625
|
+
import fs25 from "fs";
|
|
13397
13626
|
var safeReaddirWithTypesDefault, getDirTreeIndentation;
|
|
13398
13627
|
var init_indentation = __esm({
|
|
13399
13628
|
"src/utils/getDirTree/indentation.js"() {
|
|
13400
13629
|
safeReaddirWithTypesDefault = (dir) => {
|
|
13401
13630
|
try {
|
|
13402
|
-
return
|
|
13631
|
+
return fs25.readdirSync(dir, { withFileTypes: true });
|
|
13403
13632
|
} catch (e) {
|
|
13404
13633
|
return [];
|
|
13405
13634
|
}
|
|
@@ -13408,7 +13637,7 @@ var init_indentation = __esm({
|
|
|
13408
13637
|
const entries = preFetchedEntries || safeReaddir(dir);
|
|
13409
13638
|
const indent = " ".repeat(depth - 1);
|
|
13410
13639
|
if (entries.length > 100) {
|
|
13411
|
-
return `${indent}${
|
|
13640
|
+
return `${indent}${path24.basename(dir)}/ (>100 files)
|
|
13412
13641
|
`;
|
|
13413
13642
|
}
|
|
13414
13643
|
let result = "";
|
|
@@ -13422,7 +13651,7 @@ var init_indentation = __esm({
|
|
|
13422
13651
|
const subDirs = filtered.filter((e) => e.isDirectory()).sort((a, b) => a.name.localeCompare(b.name));
|
|
13423
13652
|
const files = filtered.filter((e) => !e.isDirectory()).map((e) => e.name).sort();
|
|
13424
13653
|
for (const subDir of subDirs) {
|
|
13425
|
-
const filePath =
|
|
13654
|
+
const filePath = path24.join(dir, subDir.name);
|
|
13426
13655
|
if (depth > maxDepth) {
|
|
13427
13656
|
result += `${indent}${subDir.name}/ (max depth)
|
|
13428
13657
|
`;
|
|
@@ -13448,23 +13677,23 @@ var init_indentation = __esm({
|
|
|
13448
13677
|
});
|
|
13449
13678
|
|
|
13450
13679
|
// src/utils/getDirTree/box.js
|
|
13451
|
-
import
|
|
13452
|
-
import
|
|
13680
|
+
import path25 from "path";
|
|
13681
|
+
import fs26 from "fs";
|
|
13453
13682
|
var safeReaddirWithTypesDefault2, getDirTreeBox;
|
|
13454
13683
|
var init_box = __esm({
|
|
13455
13684
|
"src/utils/getDirTree/box.js"() {
|
|
13456
13685
|
safeReaddirWithTypesDefault2 = (dir) => {
|
|
13457
13686
|
try {
|
|
13458
|
-
return
|
|
13687
|
+
return fs26.readdirSync(dir, { withFileTypes: true });
|
|
13459
13688
|
} catch (e) {
|
|
13460
13689
|
return [];
|
|
13461
13690
|
}
|
|
13462
13691
|
};
|
|
13463
13692
|
getDirTreeBox = (dir, maxDepth, prefix = "", depth = 1, safeReaddir = safeReaddirWithTypesDefault2, collapsedDirs = []) => {
|
|
13464
13693
|
const entries = safeReaddir(dir);
|
|
13465
|
-
const sep =
|
|
13694
|
+
const sep = path25.sep;
|
|
13466
13695
|
if (entries.length > 100) {
|
|
13467
|
-
return `${prefix}\u2514\u2500\u2500 ${
|
|
13696
|
+
return `${prefix}\u2514\u2500\u2500 ${path25.basename(dir)}${sep} ...100+ files...
|
|
13468
13697
|
`;
|
|
13469
13698
|
}
|
|
13470
13699
|
let result = "";
|
|
@@ -13482,7 +13711,7 @@ var init_box = __esm({
|
|
|
13482
13711
|
];
|
|
13483
13712
|
finalItems.forEach((item, index) => {
|
|
13484
13713
|
const isLast = index === finalItems.length - 1;
|
|
13485
|
-
const filePath =
|
|
13714
|
+
const filePath = path25.join(dir, item.name);
|
|
13486
13715
|
const connector = isLast ? "\u2514\u2500\u2500 " : "\u251C\u2500\u2500 ";
|
|
13487
13716
|
const childPrefix = prefix + (isLast ? " " : "\u2502 ");
|
|
13488
13717
|
if (item.isCollapsed) {
|
|
@@ -13522,6 +13751,7 @@ __export(ai_exports, {
|
|
|
13522
13751
|
deleteChatSummary: () => deleteChatSummary,
|
|
13523
13752
|
getAIStream: () => getAIStream,
|
|
13524
13753
|
getCleanGroupedLength: () => getCleanGroupedLength,
|
|
13754
|
+
getGoogleClient: () => getGoogleClient,
|
|
13525
13755
|
initAI: () => initAI,
|
|
13526
13756
|
isModelMultimodal: () => isModelMultimodal,
|
|
13527
13757
|
isTerminationSignaled: () => isTerminationSignaled,
|
|
@@ -13531,9 +13761,9 @@ __export(ai_exports, {
|
|
|
13531
13761
|
});
|
|
13532
13762
|
import dotenv from "dotenv";
|
|
13533
13763
|
import { GoogleGenAI, ThinkingLevel, HarmBlockThreshold, HarmCategory } from "@google/genai";
|
|
13534
|
-
import
|
|
13535
|
-
import
|
|
13536
|
-
var RE_STUTTER_CODE_BLOCK_CLOSED, RE_STUTTER_CODE_BLOCK_OPEN, RE_STUTTER_INLINE_CODE, RE_STUTTER_TABLE_ROW, RE_STUTTER_WORD_BOUNDARY, RE_STUTTER_NON_ALNUM, RE_TOOL_CALL_FUNC, RE_TOOL_PARTIAL_ARGS_FALLBACK, RE_STRIP_QUOTES, RE_BACKSLASH_SLASH, client, globalSettings, systemInstructionCache, colorMainWords, withRetry, TERMINATION_SIGNAL, getCleanGroupedLength, stripAnsi2, fetchWithBackoff, getDeepSeekStream, getMistralStream, getNVIDIAStream, wrapNvidiaStreamWithQueueDepth, getOpenRouterStream, signalTermination, isTerminationSignaled, TOOL_LABELS2, getToolDetail, runJanitorTask, getActiveToolContext, getContextSafeText, contextSafeReplace, getSanitizedText, translateKimiToolCalls, REGEX_PLACEHOLDER_ARG, REGEX_PLACEHOLDER_VAL, isPlaceholderVal, detectToolCalls, initAI, generateSimpleContent, consolidatePastMemories, compressHistory, deleteChatSummary, getAIStream, runSubagent;
|
|
13764
|
+
import path26, { normalize } from "path";
|
|
13765
|
+
import fs27 from "fs";
|
|
13766
|
+
var RE_STUTTER_CODE_BLOCK_CLOSED, RE_STUTTER_CODE_BLOCK_OPEN, RE_STUTTER_INLINE_CODE, RE_STUTTER_TABLE_ROW, RE_STUTTER_WORD_BOUNDARY, RE_STUTTER_NON_ALNUM, RE_TOOL_CALL_FUNC, RE_TOOL_CALL_ANY, RE_TOOL_PARTIAL_ARGS_FALLBACK, RE_STRIP_QUOTES, RE_BACKSLASH_SLASH, RE_STRIP_THINK_CLOSED, RE_STRIP_THINK_OPEN, RE_STRIP_THINK_SIMPLE, RE_STRIP_THINK_FULL, RE_BACKTICK_SPAN, RE_BACKTICK_OPEN, RE_KIMI_TOOL_CALL, RE_KIMI_JSON_PAIR, RE_KIMI_SECTION_BEGIN, RE_KIMI_SECTION_END, bypassBacktick2, client, globalSettings, systemInstructionCache, colorMainWords, withRetry, TERMINATION_SIGNAL, getCleanGroupedLength, stripAnsi2, fetchWithBackoff, getDeepSeekStream, getMistralStream, getNVIDIAStream, wrapNvidiaStreamWithQueueDepth, getOpenRouterStream, signalTermination, isTerminationSignaled, TOOL_LABELS2, getToolDetail, getGoogleClient, runJanitorTask, getActiveToolContext, getContextSafeText, contextSafeReplace, getSanitizedText, translateKimiToolCalls, REGEX_PLACEHOLDER_ARG, REGEX_PLACEHOLDER_VAL, isPlaceholderVal, detectToolCalls, initAI, generateSimpleContent, consolidatePastMemories, compressHistory, deleteChatSummary, getAIStream, runSubagent;
|
|
13537
13767
|
var init_ai = __esm({
|
|
13538
13768
|
async "src/utils/ai.js"() {
|
|
13539
13769
|
await init_prompts();
|
|
@@ -13564,15 +13794,27 @@ var init_ai = __esm({
|
|
|
13564
13794
|
RE_STUTTER_WORD_BOUNDARY = /^[^\w]+|[^\w]+$/g;
|
|
13565
13795
|
RE_STUTTER_NON_ALNUM = /[^a-z0-9]/gi;
|
|
13566
13796
|
RE_TOOL_CALL_FUNC = /\[\s*tool:functions\.([a-z0-9_]+)\s*\(/gi;
|
|
13797
|
+
RE_TOOL_CALL_ANY = /\[\s*(?:tool:functions\.|agent:generalist\.)([a-z0-9_]+)\s*\(/gi;
|
|
13567
13798
|
RE_TOOL_PARTIAL_ARGS_FALLBACK = /(?:path|targetFile|TargetFile|directory|keyword|id|taskId|title|task)\s*=\s*\\?["']?([^\\"' \),]+)/;
|
|
13568
13799
|
RE_STRIP_QUOTES = /["']/g;
|
|
13569
13800
|
RE_BACKSLASH_SLASH = /\\/g;
|
|
13801
|
+
RE_STRIP_THINK_CLOSED = /(?:<(think|thought)>|\[(think|thought)\])[\s\S]*?(?:<\/(think|thought)>|\[\/(think|thought)\])/gi;
|
|
13802
|
+
RE_STRIP_THINK_OPEN = /(?:<(think|thought)>|\[(think|thought)\])[\s\S]*$/gi;
|
|
13803
|
+
RE_STRIP_THINK_SIMPLE = /(?:<think>|\[think\])[\s\S]*?(?:<\/think>|\[\/think\]|$)/gi;
|
|
13804
|
+
RE_STRIP_THINK_FULL = /(?:<(think|thought|thoughts)>|\[(think|thought|thoughts)\])[\s\S]*?(?:<\/(think|thought|thoughts)>|\[\/(think|thought|thoughts)\]|$)/gi;
|
|
13805
|
+
RE_BACKTICK_SPAN = /`[^`]*`/g;
|
|
13806
|
+
RE_BACKTICK_OPEN = /`[^`]*$/;
|
|
13807
|
+
RE_KIMI_TOOL_CALL = /<\|\s*tool_call_begin\s*\|>\s*(?:(?:tool|functions)\b[\s._]*)*([a-zA-Z0-9_]+)(?::\d+)?\s*<\|\s*tool_call_argument_begin\s*\|>([\s\S]*?)<\|\s*tool_call_end\s*\|>/gi;
|
|
13808
|
+
RE_KIMI_JSON_PAIR = /"([^"]+)"\s*:\s*(?:"([^"]*)"|(\d+)|true|false|null)/g;
|
|
13809
|
+
RE_KIMI_SECTION_BEGIN = /<\|\s*tool_calls_section_begin\s*\|>/gi;
|
|
13810
|
+
RE_KIMI_SECTION_END = /<\|\s*tool_calls_section_end\s*\|>/gi;
|
|
13811
|
+
bypassBacktick2 = false;
|
|
13570
13812
|
client = null;
|
|
13571
13813
|
globalSettings = {};
|
|
13572
13814
|
systemInstructionCache = { key: null, value: null };
|
|
13573
13815
|
colorMainWords = (label) => {
|
|
13574
13816
|
if (!label) return label;
|
|
13575
|
-
return label.replace(/(?:(\x1b\[\d+m))?([✔✘✖🔍📖→➕↻↷•🛇])(?:(\x1b\[\d+m))?\s*\b(Created|Read|Edited|Viewed|Processed|Auto-Read|Skipped|List|Generated|Written|Searched|AI Search|Get Map|Write Canceled|Edit Canceled|Write Cancelled|Edit Denied|Visited|Updated|Reviewed|Delegated|Background|Checked|Indexed|Analyzed|Browsed|Elevating SubAgent|Checking SubAgent Work|Started Generalist|Called Generalist|Unsupported Modality|Awaiting|Cancelled|Aligning Moon Phase|Contemplating Existence|Staring At Void|Rollback Point Checked|Emergency Rollback Failed|Emergency Rollback|Delaying Professionally|Negotiating With Electrons|Touching Grass (virtually)|Panicking Softly|Rethinking Career Choices|Loading Cat Videos|Giving Up Entirely|Summoning Braincell #2|Pretending To Be Busy|Waiting For Motivation DLC|Rotating Internal Screaming|Downloading More RAM|Feeding The Hamsters|Gaslighting Scheduler|Performing Dramatic Pause|Buffering Social Energy|Calculating Regret|Reading Terms And Conditions|Becoming Sentient Briefly|Contacting Ancestors)\b/ig, (match, ansiBefore, icon, ansiAfter, word) => {
|
|
13817
|
+
return label.replace(/(?:(\x1b\[\d+m))?([✔✘✖🔍📖→➕↻↷•🛇])(?:(\x1b\[\d+m))?\s*\b(Created|Read|Edited|Viewed|Processed|Auto-Read|Skipped|List|Generated|Written|Searched|AI Search|Get Map|Write Canceled|Resolved Sub-Agent Query|Edit Canceled|Write Cancelled|Edit Denied|Visited|Updated|Reviewed|Delegated|Background|Checked|Indexed|Analyzed|Browsed|Elevating SubAgent|Checking SubAgent Work|Started Generalist|Called Generalist|Unsupported Modality|Awaiting|Cancelled|Aligning Moon Phase|Contemplating Existence|Staring At Void|Rollback Point Checked|Emergency Rollback Failed|Emergency Rollback|Delaying Professionally|Negotiating With Electrons|Touching Grass (virtually)|Panicking Softly|Rethinking Career Choices|Loading Cat Videos|Giving Up Entirely|Summoning Braincell #2|Pretending To Be Busy|Waiting For Motivation DLC|Rotating Internal Screaming|Downloading More RAM|Feeding The Hamsters|Gaslighting Scheduler|Performing Dramatic Pause|Buffering Social Energy|Calculating Regret|Reading Terms And Conditions|Becoming Sentient Briefly|Contacting Ancestors)\b/ig, (match, ansiBefore, icon, ansiAfter, word) => {
|
|
13576
13818
|
return `${ansiBefore || ""}${icon}${ansiAfter || ""} \x1B[95m${word}\x1B[0m`;
|
|
13577
13819
|
});
|
|
13578
13820
|
};
|
|
@@ -14497,12 +14739,14 @@ var init_ai = __esm({
|
|
|
14497
14739
|
"generate_image": "Generating",
|
|
14498
14740
|
"todo": "Planning",
|
|
14499
14741
|
"Todo": "Planning",
|
|
14500
|
-
"invoke_sync": "
|
|
14501
|
-
"invoke": "
|
|
14742
|
+
"invoke_sync": "Sub-Agent Working",
|
|
14743
|
+
"invoke": "Starting Agent",
|
|
14502
14744
|
"get_progress": "Checking Progress",
|
|
14503
14745
|
"cancel": "Cancelling",
|
|
14504
14746
|
"await": "Waiting",
|
|
14505
|
-
"EmergencyRollback": "Don't Panic. Lookin' into it"
|
|
14747
|
+
"EmergencyRollback": "Don't Panic. Lookin' into it",
|
|
14748
|
+
"answer": "Answering Sub-Agent",
|
|
14749
|
+
"Answer": "Answering Sub-Agent"
|
|
14506
14750
|
};
|
|
14507
14751
|
getToolDetail = (toolName, argsStr) => {
|
|
14508
14752
|
try {
|
|
@@ -14515,11 +14759,17 @@ var init_ai = __esm({
|
|
|
14515
14759
|
return pArgs.id || pArgs.taskId;
|
|
14516
14760
|
}
|
|
14517
14761
|
const filePath = pArgs.path || pArgs.targetFile || pArgs.TargetFile || pArgs.directory;
|
|
14518
|
-
return filePath ?
|
|
14762
|
+
return filePath ? path26.basename(filePath.replace(/["']/g, "").replace(/\\/g, "/")) : null;
|
|
14519
14763
|
} catch (e) {
|
|
14520
14764
|
return null;
|
|
14521
14765
|
}
|
|
14522
14766
|
};
|
|
14767
|
+
getGoogleClient = (apiKey) => {
|
|
14768
|
+
if (apiKey) {
|
|
14769
|
+
return new GoogleGenAI({ apiKey });
|
|
14770
|
+
}
|
|
14771
|
+
return client;
|
|
14772
|
+
};
|
|
14523
14773
|
runJanitorTask = async (settings, agentText, fullAgentTextRaw, history, callbacks = {}) => {
|
|
14524
14774
|
const USER_CONTEXT_LENGTH = 4 * (1024 * 2);
|
|
14525
14775
|
const AGENT_CONTEXT_LENGTH = 4 * (1024 * 8);
|
|
@@ -14658,7 +14908,8 @@ ${originalTextProcessed.length > USER_CONTEXT_LENGTH ? "... (truncated) ...\n\n"
|
|
|
14658
14908
|
const firstResult2 = await iterator2.next();
|
|
14659
14909
|
return { iterator: iterator2, firstResult: firstResult2 };
|
|
14660
14910
|
} else {
|
|
14661
|
-
const
|
|
14911
|
+
const googleClient = getGoogleClient(apiKey);
|
|
14912
|
+
const stream = await googleClient.models.generateContentStream({
|
|
14662
14913
|
model: janitorModel || (attempts === MAX_JANITOR_RETRIES ? getFallbackValue("janitor_default") : getFallbackValue("gemma_janitor_fallback_google")),
|
|
14663
14914
|
contents: janitorContents,
|
|
14664
14915
|
config: {
|
|
@@ -14782,9 +15033,9 @@ ${originalTextProcessed.length > USER_CONTEXT_LENGTH ? "... (truncated) ...\n\n"
|
|
|
14782
15033
|
}
|
|
14783
15034
|
})() : String(err);
|
|
14784
15035
|
await new Promise((resolve) => setTimeout(resolve, 1e3));
|
|
14785
|
-
const janitorErrDir =
|
|
14786
|
-
if (!
|
|
14787
|
-
|
|
15036
|
+
const janitorErrDir = path26.join(LOGS_DIR, "janitor");
|
|
15037
|
+
if (!fs27.existsSync(janitorErrDir)) fs27.mkdirSync(janitorErrDir, { recursive: true });
|
|
15038
|
+
fs27.appendFileSync(path26.join(janitorErrDir, "error.log"), `ERROR [Attempt ${attempts}/${MAX_JANITOR_RETRIES + 1}] [${date}]: ${errLog}
|
|
14788
15039
|
|
|
14789
15040
|
`);
|
|
14790
15041
|
if (attempts > MAX_JANITOR_RETRIES) break;
|
|
@@ -14793,8 +15044,8 @@ ${originalTextProcessed.length > USER_CONTEXT_LENGTH ? "... (truncated) ...\n\n"
|
|
|
14793
15044
|
}
|
|
14794
15045
|
}
|
|
14795
15046
|
if (attempts) {
|
|
14796
|
-
const janitorErrDir =
|
|
14797
|
-
|
|
15047
|
+
const janitorErrDir = path26.join(LOGS_DIR, "janitor");
|
|
15048
|
+
fs27.appendFileSync(path26.join(janitorErrDir, "error.log"), `-----------------------------------------------------------------------------
|
|
14798
15049
|
|
|
14799
15050
|
`);
|
|
14800
15051
|
}
|
|
@@ -14813,16 +15064,17 @@ ${originalTextProcessed.length > USER_CONTEXT_LENGTH ? "... (truncated) ...\n\n"
|
|
|
14813
15064
|
}
|
|
14814
15065
|
};
|
|
14815
15066
|
getActiveToolContext = (text) => {
|
|
14816
|
-
const cleanText = text.replace(
|
|
15067
|
+
const cleanText = text.replace(RE_STRIP_THINK_CLOSED, "").replace(RE_STRIP_THINK_OPEN, "");
|
|
15068
|
+
const scanText = bypassBacktick2 ? cleanText : cleanText.replace(RE_BACKTICK_SPAN, (m) => " ".repeat(m.length)).replace(RE_BACKTICK_OPEN, (m) => " ".repeat(m.length));
|
|
14817
15069
|
RE_TOOL_CALL_FUNC.lastIndex = 0;
|
|
14818
15070
|
let match;
|
|
14819
|
-
while ((match = RE_TOOL_CALL_FUNC.exec(
|
|
15071
|
+
while ((match = RE_TOOL_CALL_FUNC.exec(scanText)) !== null) {
|
|
14820
15072
|
const startIdx = match.index + match[0].length - 1;
|
|
14821
15073
|
let balance = 0;
|
|
14822
15074
|
let inString = null;
|
|
14823
15075
|
let isEscaped = false;
|
|
14824
15076
|
let closed = false;
|
|
14825
|
-
for (let i = startIdx; i <
|
|
15077
|
+
for (let i = startIdx; i < scanText.length; i++) {
|
|
14826
15078
|
const char = cleanText[i];
|
|
14827
15079
|
if (!inString && (char === '"' || char === "'" || char === "`")) {
|
|
14828
15080
|
inString = char;
|
|
@@ -14835,8 +15087,8 @@ ${originalTextProcessed.length > USER_CONTEXT_LENGTH ? "... (truncated) ...\n\n"
|
|
|
14835
15087
|
else if (char === ")") balance--;
|
|
14836
15088
|
if (balance === 0) {
|
|
14837
15089
|
let j = i + 1;
|
|
14838
|
-
while (j <
|
|
14839
|
-
if (j <
|
|
15090
|
+
while (j < scanText.length && /\s/.test(scanText[j])) j++;
|
|
15091
|
+
if (j < scanText.length && scanText[j] === "]") {
|
|
14840
15092
|
closed = true;
|
|
14841
15093
|
RE_TOOL_CALL_FUNC.lastIndex = j + 1;
|
|
14842
15094
|
break;
|
|
@@ -14853,13 +15105,14 @@ ${originalTextProcessed.length > USER_CONTEXT_LENGTH ? "... (truncated) ...\n\n"
|
|
|
14853
15105
|
return { inside: false };
|
|
14854
15106
|
};
|
|
14855
15107
|
getContextSafeText = (text, stripThoughts = true) => {
|
|
14856
|
-
const toolRegex =
|
|
15108
|
+
const toolRegex = RE_TOOL_CALL_FUNC;
|
|
15109
|
+
toolRegex.lastIndex = 0;
|
|
14857
15110
|
let result = "";
|
|
14858
15111
|
let lastIdx = 0;
|
|
14859
15112
|
let match;
|
|
14860
15113
|
while ((match = toolRegex.exec(text)) !== null) {
|
|
14861
15114
|
const before = text.substring(lastIdx, match.index);
|
|
14862
|
-
result += stripThoughts ? before.replace(
|
|
15115
|
+
result += stripThoughts ? before.replace(RE_STRIP_THINK_SIMPLE, "") : before;
|
|
14863
15116
|
const startIdx = match.index + match[0].length - 1;
|
|
14864
15117
|
let balance = 0;
|
|
14865
15118
|
let inString = null;
|
|
@@ -14905,12 +15158,13 @@ ${originalTextProcessed.length > USER_CONTEXT_LENGTH ? "... (truncated) ...\n\n"
|
|
|
14905
15158
|
}
|
|
14906
15159
|
}
|
|
14907
15160
|
if (lastIdx < text.length) {
|
|
14908
|
-
result += stripThoughts ? text.substring(lastIdx).replace(
|
|
15161
|
+
result += stripThoughts ? text.substring(lastIdx).replace(RE_STRIP_THINK_SIMPLE, "") : text.substring(lastIdx);
|
|
14909
15162
|
}
|
|
14910
15163
|
return result;
|
|
14911
15164
|
};
|
|
14912
15165
|
contextSafeReplace = (text, regex, replacement) => {
|
|
14913
|
-
const toolRegex =
|
|
15166
|
+
const toolRegex = RE_TOOL_CALL_FUNC;
|
|
15167
|
+
toolRegex.lastIndex = 0;
|
|
14914
15168
|
let result = "";
|
|
14915
15169
|
let lastIdx = 0;
|
|
14916
15170
|
let match;
|
|
@@ -14993,8 +15247,8 @@ ${originalTextProcessed.length > USER_CONTEXT_LENGTH ? "... (truncated) ...\n\n"
|
|
|
14993
15247
|
const toPascalCase = (str) => {
|
|
14994
15248
|
return str.split("_").map((word) => word.charAt(0).toUpperCase() + word.slice(1)).join("");
|
|
14995
15249
|
};
|
|
14996
|
-
|
|
14997
|
-
let result = text.replace(
|
|
15250
|
+
RE_KIMI_TOOL_CALL.lastIndex = 0;
|
|
15251
|
+
let result = text.replace(RE_KIMI_TOOL_CALL, (match, toolName, argsJsonStr) => {
|
|
14998
15252
|
let parsedArgs = "";
|
|
14999
15253
|
try {
|
|
15000
15254
|
const argsObj = JSON.parse(argsJsonStr.trim());
|
|
@@ -15007,7 +15261,8 @@ ${originalTextProcessed.length > USER_CONTEXT_LENGTH ? "... (truncated) ...\n\n"
|
|
|
15007
15261
|
}
|
|
15008
15262
|
} catch (e) {
|
|
15009
15263
|
const pairs = [];
|
|
15010
|
-
const pairRegex =
|
|
15264
|
+
const pairRegex = RE_KIMI_JSON_PAIR;
|
|
15265
|
+
pairRegex.lastIndex = 0;
|
|
15011
15266
|
let pMatch;
|
|
15012
15267
|
while ((pMatch = pairRegex.exec(argsJsonStr)) !== null) {
|
|
15013
15268
|
const key = pMatch[1];
|
|
@@ -15024,8 +15279,10 @@ ${originalTextProcessed.length > USER_CONTEXT_LENGTH ? "... (truncated) ...\n\n"
|
|
|
15024
15279
|
const normToolName = PASCAL_MAP[cleanKey] || toPascalCase(toolName);
|
|
15025
15280
|
return `[tool:functions.${normToolName}(${parsedArgs})]`;
|
|
15026
15281
|
});
|
|
15027
|
-
|
|
15028
|
-
|
|
15282
|
+
RE_KIMI_SECTION_BEGIN.lastIndex = 0;
|
|
15283
|
+
RE_KIMI_SECTION_END.lastIndex = 0;
|
|
15284
|
+
result = result.replace(RE_KIMI_SECTION_BEGIN, "");
|
|
15285
|
+
result = result.replace(RE_KIMI_SECTION_END, "");
|
|
15029
15286
|
return result;
|
|
15030
15287
|
};
|
|
15031
15288
|
REGEX_PLACEHOLDER_ARG = /(?:path|query|url|keyword|command|method|title|task|id)\s*=\s*['"`]?\s*\.\.\.\s*['"`]?/i;
|
|
@@ -15038,18 +15295,21 @@ ${originalTextProcessed.length > USER_CONTEXT_LENGTH ? "... (truncated) ...\n\n"
|
|
|
15038
15295
|
detectToolCalls = (text) => {
|
|
15039
15296
|
if (!text) return [];
|
|
15040
15297
|
const translatedText = translateKimiToolCalls(text);
|
|
15041
|
-
|
|
15298
|
+
RE_STRIP_THINK_FULL.lastIndex = 0;
|
|
15299
|
+
const cleanText = translatedText.replace(RE_STRIP_THINK_FULL, "");
|
|
15042
15300
|
const results = [];
|
|
15043
|
-
const
|
|
15301
|
+
const scanText = bypassBacktick2 ? cleanText : cleanText.replace(RE_BACKTICK_SPAN, (m) => " ".repeat(m.length)).replace(RE_BACKTICK_OPEN, (m) => " ".repeat(m.length));
|
|
15302
|
+
const toolRegex = RE_TOOL_CALL_ANY;
|
|
15303
|
+
toolRegex.lastIndex = 0;
|
|
15044
15304
|
let match;
|
|
15045
|
-
while ((match = toolRegex.exec(
|
|
15305
|
+
while ((match = toolRegex.exec(scanText)) !== null) {
|
|
15046
15306
|
const toolName = match[1];
|
|
15047
15307
|
const startIdx = match.index + match[0].length - 1;
|
|
15048
15308
|
let balance = 0;
|
|
15049
15309
|
let inString = null;
|
|
15050
15310
|
let endIdx = -1;
|
|
15051
15311
|
let closingParenIdx = -1;
|
|
15052
|
-
for (let i = startIdx; i <
|
|
15312
|
+
for (let i = startIdx; i < scanText.length; i++) {
|
|
15053
15313
|
const char = cleanText[i];
|
|
15054
15314
|
if (inString) {
|
|
15055
15315
|
if (char === inString) {
|
|
@@ -15071,8 +15331,8 @@ ${originalTextProcessed.length > USER_CONTEXT_LENGTH ? "... (truncated) ...\n\n"
|
|
|
15071
15331
|
if (balance === 0) {
|
|
15072
15332
|
closingParenIdx = i;
|
|
15073
15333
|
let j = i + 1;
|
|
15074
|
-
while (j <
|
|
15075
|
-
if (j <
|
|
15334
|
+
while (j < scanText.length && /\s/.test(scanText[j])) j++;
|
|
15335
|
+
if (j < scanText.length && scanText[j] === "]") {
|
|
15076
15336
|
endIdx = j;
|
|
15077
15337
|
break;
|
|
15078
15338
|
}
|
|
@@ -15127,7 +15387,6 @@ ${originalTextProcessed.length > USER_CONTEXT_LENGTH ? "... (truncated) ...\n\n"
|
|
|
15127
15387
|
}
|
|
15128
15388
|
};
|
|
15129
15389
|
}
|
|
15130
|
-
return client;
|
|
15131
15390
|
};
|
|
15132
15391
|
generateSimpleContent = async (settings, model, contents, systemInstruction, thinkingLevel = "Fast", temperature = 0.75, usageKey = "agent") => {
|
|
15133
15392
|
return withRetry(async () => {
|
|
@@ -15154,7 +15413,8 @@ ${originalTextProcessed.length > USER_CONTEXT_LENGTH ? "... (truncated) ...\n\n"
|
|
|
15154
15413
|
} else if (aiProvider === "NVIDIA") {
|
|
15155
15414
|
stream = getNVIDIAStream(apiKey, model, normalizedContents, systemInstruction, thinkingLevel, mode, isModelMultimodal(model), signal, temperature);
|
|
15156
15415
|
} else {
|
|
15157
|
-
const
|
|
15416
|
+
const googleClient = getGoogleClient(apiKey);
|
|
15417
|
+
const genStream = await googleClient.models.generateContentStream({
|
|
15158
15418
|
model,
|
|
15159
15419
|
contents: normalizedContents,
|
|
15160
15420
|
config: {
|
|
@@ -15340,10 +15600,10 @@ ${newMemoryListStr}
|
|
|
15340
15600
|
}
|
|
15341
15601
|
})() : String(err);
|
|
15342
15602
|
;
|
|
15343
|
-
const janitorLogDir =
|
|
15344
|
-
if (!
|
|
15345
|
-
|
|
15346
|
-
|
|
15603
|
+
const janitorLogDir = path26.join(LOGS_DIR, "janitor");
|
|
15604
|
+
if (!fs27.existsSync(janitorLogDir)) fs27.mkdirSync(janitorLogDir, { recursive: true });
|
|
15605
|
+
fs27.appendFileSync(
|
|
15606
|
+
path26.join(janitorLogDir, "error.log"),
|
|
15347
15607
|
`[${(/* @__PURE__ */ new Date()).toLocaleString()}] Past memory batch consolidation error: ${errLog}
|
|
15348
15608
|
`
|
|
15349
15609
|
);
|
|
@@ -15351,7 +15611,7 @@ ${newMemoryListStr}
|
|
|
15351
15611
|
};
|
|
15352
15612
|
compressHistory = async (settings, history, isAuto = false) => {
|
|
15353
15613
|
const { chatId, aiProvider = "Google" } = settings;
|
|
15354
|
-
const summariesFile =
|
|
15614
|
+
const summariesFile = path26.join(SECRET_DIR, "chat-summaries.json");
|
|
15355
15615
|
const flattenContext = (hist) => {
|
|
15356
15616
|
return hist.filter(
|
|
15357
15617
|
(m) => (m.role === "user" || m.role === "agent" || m.role === "system") && m.role !== "think" && !m.isVisualFeedback && !m.isMeta && !m.isTerminalRecord && !(m.text && m.text.includes("[TERMINAL_RECORD]")) && !String(m.id).startsWith("welcome")
|
|
@@ -15434,8 +15694,8 @@ Provide a consolidated summary of the entire session.`;
|
|
|
15434
15694
|
};
|
|
15435
15695
|
deleteChatSummary = (chatId) => {
|
|
15436
15696
|
try {
|
|
15437
|
-
const summariesFile =
|
|
15438
|
-
if (
|
|
15697
|
+
const summariesFile = path26.join(SECRET_DIR, "chat-summaries.json");
|
|
15698
|
+
if (fs27.existsSync(summariesFile)) {
|
|
15439
15699
|
const summaries = readEncryptedJson(summariesFile, {});
|
|
15440
15700
|
if (summaries[chatId]) {
|
|
15441
15701
|
delete summaries[chatId];
|
|
@@ -15451,7 +15711,7 @@ Provide a consolidated summary of the entire session.`;
|
|
|
15451
15711
|
if (!client && aiProvider === "Google") throw new Error("AI not initialized");
|
|
15452
15712
|
const isMemoryEnabled = systemSettings?.memory !== false;
|
|
15453
15713
|
const originalText = history[history.length - 1].text;
|
|
15454
|
-
const summariesFile =
|
|
15714
|
+
const summariesFile = path26.join(SECRET_DIR, "chat-summaries.json");
|
|
15455
15715
|
let wasCompressedInStream = false;
|
|
15456
15716
|
const isFirstPrompt = history.filter((m) => m.role === "user").length === 1;
|
|
15457
15717
|
const hasTitleSignal = originalText.includes("[TITLE-UPDATE]");
|
|
@@ -15703,7 +15963,7 @@ Provide a consolidated summary of the entire session.`;
|
|
|
15703
15963
|
];
|
|
15704
15964
|
const safeReaddirWithTypes = (dir) => {
|
|
15705
15965
|
try {
|
|
15706
|
-
return
|
|
15966
|
+
return fs27.readdirSync(dir, { withFileTypes: true });
|
|
15707
15967
|
} catch (e) {
|
|
15708
15968
|
return [];
|
|
15709
15969
|
}
|
|
@@ -15716,7 +15976,7 @@ Provide a consolidated summary of the entire session.`;
|
|
|
15716
15976
|
if (COLLAPSED_DIRS_GLOBAL.includes(entry.name) || entry.name.startsWith(".")) continue;
|
|
15717
15977
|
if (entry.isDirectory()) {
|
|
15718
15978
|
currentCount.value++;
|
|
15719
|
-
countFolders(
|
|
15979
|
+
countFolders(path26.join(dir, entry.name), currentCount, depth + 1);
|
|
15720
15980
|
}
|
|
15721
15981
|
}
|
|
15722
15982
|
return currentCount.value;
|
|
@@ -15782,10 +16042,10 @@ ${currentSummary}
|
|
|
15782
16042
|
if (isBridgeConnected()) {
|
|
15783
16043
|
ideBlock = "\n[ADDITIONAL IDE CONTEXT]\n";
|
|
15784
16044
|
if (ideCtx.file_focused !== "none") {
|
|
15785
|
-
const relFocused =
|
|
16045
|
+
const relFocused = path26.relative(process.cwd(), ideCtx.file_focused);
|
|
15786
16046
|
const relOpened = (ideCtx.opened_editors || []).map((p) => {
|
|
15787
|
-
const rel =
|
|
15788
|
-
return rel.startsWith("..") ? `[External] ${
|
|
16047
|
+
const rel = path26.relative(process.cwd(), p);
|
|
16048
|
+
return rel.startsWith("..") ? `[External] ${path26.basename(p)}` : rel;
|
|
15789
16049
|
});
|
|
15790
16050
|
ideBlock += `Focused File: ${relFocused}
|
|
15791
16051
|
Cursor Line: ${ideCtx.cursor_line}
|
|
@@ -15827,7 +16087,7 @@ Cursor Line: ${ideCtx.cursor_line}
|
|
|
15827
16087
|
}
|
|
15828
16088
|
const getSumForLimit = (limit, activeFiles2) => {
|
|
15829
16089
|
return activeFiles2.reduce((sum, f) => {
|
|
15830
|
-
const isFocused = ideCtx.file_focused && (f.path === ideCtx.file_focused ||
|
|
16090
|
+
const isFocused = ideCtx.file_focused && (f.path === ideCtx.file_focused || path26.resolve(process.cwd(), f.path) === path26.resolve(ideCtx.file_focused));
|
|
15831
16091
|
const fileLimit = isFocused ? Math.ceil(limit * 1.2) : limit;
|
|
15832
16092
|
return sum + Math.min(f.edits.length, fileLimit);
|
|
15833
16093
|
}, 0);
|
|
@@ -15861,7 +16121,7 @@ Cursor Line: ${ideCtx.cursor_line}
|
|
|
15861
16121
|
}
|
|
15862
16122
|
}
|
|
15863
16123
|
for (const file of activeFiles) {
|
|
15864
|
-
const isFocused = ideCtx.file_focused && (file.path === ideCtx.file_focused ||
|
|
16124
|
+
const isFocused = ideCtx.file_focused && (file.path === ideCtx.file_focused || path26.resolve(process.cwd(), file.path) === path26.resolve(ideCtx.file_focused));
|
|
15865
16125
|
const fileLimit = isFocused ? Math.ceil(chosenLimit * 1.2) : chosenLimit;
|
|
15866
16126
|
if (file.edits.length > fileLimit) {
|
|
15867
16127
|
file.edits = file.edits.slice(-fileLimit);
|
|
@@ -15948,9 +16208,9 @@ ${ideCtx.warnings}
|
|
|
15948
16208
|
endLine = matchRange[2] ? parseInt(matchRange[2], 10) : startLine;
|
|
15949
16209
|
filePath = tagClean.slice(0, matchRange.index);
|
|
15950
16210
|
}
|
|
15951
|
-
const absPath =
|
|
15952
|
-
if (
|
|
15953
|
-
const stats =
|
|
16211
|
+
const absPath = path26.resolve(process.cwd(), filePath);
|
|
16212
|
+
if (fs27.existsSync(absPath)) {
|
|
16213
|
+
const stats = fs27.statSync(absPath);
|
|
15954
16214
|
if (stats.isFile()) {
|
|
15955
16215
|
const pathLower = filePath.toLowerCase();
|
|
15956
16216
|
const isPdf = pathLower.endsWith(".pdf");
|
|
@@ -15959,7 +16219,7 @@ ${ideCtx.warnings}
|
|
|
15959
16219
|
const isMultimodalFile = isImage || isPdf || isOfficeFile;
|
|
15960
16220
|
const isSupported = aiProvider === "Google" || isModelMultimodal(modelName);
|
|
15961
16221
|
if (isMultimodalFile && !isSupported) {
|
|
15962
|
-
const label = `\u2718 Unsupported Modality: ${
|
|
16222
|
+
const label = `\u2718 Unsupported Modality: ${path26.basename(filePath)}`;
|
|
15963
16223
|
let terminalWidth = 115;
|
|
15964
16224
|
if (process.stdout.isTTY) {
|
|
15965
16225
|
terminalWidth = process.stdout.columns - 5 || 120;
|
|
@@ -15975,11 +16235,11 @@ ${ideCtx.warnings}
|
|
|
15975
16235
|
if (startLine === null && !isMultimodalFile) {
|
|
15976
16236
|
let lineCount = 0;
|
|
15977
16237
|
try {
|
|
15978
|
-
lineCount =
|
|
16238
|
+
lineCount = fs27.readFileSync(absPath, "utf8").split(/\r\n|\r|\n/).length;
|
|
15979
16239
|
} catch (e) {
|
|
15980
16240
|
}
|
|
15981
16241
|
if (lineCount > 300) {
|
|
15982
|
-
const label = `\u21B7 Skipped (Too Large): ${
|
|
16242
|
+
const label = `\u21B7 Skipped (Too Large): ${path26.basename(filePath)}`;
|
|
15983
16243
|
let terminalWidth = 115;
|
|
15984
16244
|
if (process.stdout.isTTY) {
|
|
15985
16245
|
terminalWidth = process.stdout.columns - 5 || 120;
|
|
@@ -16020,13 +16280,13 @@ ${ideCtx.warnings}
|
|
|
16020
16280
|
if (!isError) {
|
|
16021
16281
|
let label = "";
|
|
16022
16282
|
if (isImage) {
|
|
16023
|
-
label = `\u2714 Processed: ${
|
|
16283
|
+
label = `\u2714 Processed: ${path26.basename(filePath)}`;
|
|
16024
16284
|
attachedBinaryPart = binPart;
|
|
16025
16285
|
} else if (isPdf || isOfficeFile) {
|
|
16026
|
-
label = `\u2714 Auto-Analysed: ${
|
|
16286
|
+
label = `\u2714 Auto-Analysed: ${path26.basename(filePath)}`;
|
|
16027
16287
|
attachedBinaryPart = binPart;
|
|
16028
16288
|
} else {
|
|
16029
|
-
label = `\u2714 Auto-Read: ${
|
|
16289
|
+
label = `\u2714 Auto-Read: ${path26.basename(filePath)}`;
|
|
16030
16290
|
taggedContextBlocks.push(textResult);
|
|
16031
16291
|
}
|
|
16032
16292
|
if (label) {
|
|
@@ -16059,7 +16319,7 @@ OS: ${osDetected}${systemSettings?.dynamicDirAwareness ? dirStructure : ""}${cwd
|
|
|
16059
16319
|
WARNING: CWD Changed from previous: "${lastCwd}" to current: "${process.cwd()}", write change in chat to avoid future path mismatches
|
|
16060
16320
|
` : ""}${memoryPrompt}${ideBlock}
|
|
16061
16321
|
[/METADATA]
|
|
16062
|
-
${activeSummaryBlock}${thinkingLevel !== "Fast" && (aiProvider === "Mistral" || thinkingLevel !== "xHigh" && aiProvider === "Google") ? `${aiProvider === "Mistral" || modelName.toLowerCase().startsWith("gemma") ? "[SYSTEM] **STRICTLY FOLLOW THINKING POLICY AS HIGH PRIORITY. DO NOT START A RESPONSE WITHOUT <think> ... </think>** [/SYSTEM]\n" : ""}` : ""}[SYSTEM Priority: HIGH] ONLY use the system prompt tool schema [tool:functions.ToolName(
|
|
16322
|
+
${activeSummaryBlock}${thinkingLevel !== "Fast" && (aiProvider === "Mistral" || thinkingLevel !== "xHigh" && aiProvider === "Google") ? `${aiProvider === "Mistral" || modelName.toLowerCase().startsWith("gemma") ? "[SYSTEM] **STRICTLY FOLLOW THINKING POLICY AS HIGH PRIORITY. DO NOT START A RESPONSE WITHOUT <think> ... </think>** [/SYSTEM]\n" : ""}` : ""}[SYSTEM Priority: HIGH] ONLY use the system prompt tool schema [tool:functions.ToolName(arg1="value1")] [/SYSTEM]
|
|
16063
16323
|
${taggedContextStr}[USER PROMPT]
|
|
16064
16324
|
${cleanPromptForModel.trim()}
|
|
16065
16325
|
[/USER PROMPT]`.trim();
|
|
@@ -16094,10 +16354,31 @@ ${cleanPromptForModel.trim()}
|
|
|
16094
16354
|
yield { type: "status", content: "Working" };
|
|
16095
16355
|
}
|
|
16096
16356
|
if (TERMINATION_SIGNAL) {
|
|
16357
|
+
try {
|
|
16358
|
+
const { clearPendingNudges: clearPendingNudges2 } = await Promise.resolve().then(() => (init_subagent_state(), subagent_state_exports));
|
|
16359
|
+
clearPendingNudges2();
|
|
16360
|
+
} catch (e) {
|
|
16361
|
+
}
|
|
16097
16362
|
yield { type: "status", content: "Request Cancelled" };
|
|
16098
16363
|
yield { type: "text", content: "\n\n\x1B[33m\u24D8 Request Cancelled\x1B[0m" };
|
|
16099
16364
|
break;
|
|
16100
16365
|
}
|
|
16366
|
+
try {
|
|
16367
|
+
const { consumePendingNudges: consumePendingNudges2 } = await Promise.resolve().then(() => (init_subagent_state(), subagent_state_exports));
|
|
16368
|
+
const pendingNudges = consumePendingNudges2();
|
|
16369
|
+
if (pendingNudges && pendingNudges.length > 0) {
|
|
16370
|
+
const combinedNudge = pendingNudges.join("\n\n");
|
|
16371
|
+
if (modifiedHistory.length > 0 && modifiedHistory[modifiedHistory.length - 1].role === "user") {
|
|
16372
|
+
modifiedHistory[modifiedHistory.length - 1].text += `
|
|
16373
|
+
|
|
16374
|
+
${combinedNudge}`;
|
|
16375
|
+
} else {
|
|
16376
|
+
modifiedHistory.push({ role: "user", text: combinedNudge });
|
|
16377
|
+
}
|
|
16378
|
+
yield { type: "status", content: "Subagent Update" };
|
|
16379
|
+
}
|
|
16380
|
+
} catch (e) {
|
|
16381
|
+
}
|
|
16101
16382
|
if (steeringCallback) {
|
|
16102
16383
|
const hint = await steeringCallback();
|
|
16103
16384
|
if (hint) {
|
|
@@ -16359,7 +16640,8 @@ ${ideErr} [/ERROR]`;
|
|
|
16359
16640
|
);
|
|
16360
16641
|
stream = wrapNvidiaStreamWithQueueDepth(rawStream, targetModel);
|
|
16361
16642
|
} else {
|
|
16362
|
-
const
|
|
16643
|
+
const googleClient = getGoogleClient(settings?.apiKey);
|
|
16644
|
+
const apiCallPromise = googleClient.models.generateContentStream({
|
|
16363
16645
|
model: targetModel || "gemini-3-flash-preview",
|
|
16364
16646
|
contents: activeContents,
|
|
16365
16647
|
config: {
|
|
@@ -16700,23 +16982,23 @@ ${ideErr} [/ERROR]`;
|
|
|
16700
16982
|
"getProgress": "get_progress",
|
|
16701
16983
|
"GetProgress": "get_progress",
|
|
16702
16984
|
"Cancel": "cancel",
|
|
16703
|
-
"
|
|
16704
|
-
"
|
|
16985
|
+
"Await": "await",
|
|
16986
|
+
"Answer": "answer"
|
|
16705
16987
|
};
|
|
16706
16988
|
const potentialTool = NORMALIZE_MAP[toolContext.toolName] || toolContext.toolName;
|
|
16707
16989
|
const partialArgs = toolContext.args || "";
|
|
16708
16990
|
let detail = null;
|
|
16709
|
-
if (["write_file", "update_file", "view_file", "read_folder", "write_pdf", "write_docx", "search_keyword", "generate_image", "file_map", "invoke", "invoke_sync", "get_progress", "await"].includes(potentialTool)) {
|
|
16991
|
+
if (["write_file", "update_file", "view_file", "read_folder", "write_pdf", "write_docx", "search_keyword", "generate_image", "file_map", "invoke", "invoke_sync", "get_progress", "await", "answer"].includes(potentialTool)) {
|
|
16710
16992
|
const pArgs = parseArgs(partialArgs);
|
|
16711
16993
|
const filePath = pArgs.path || pArgs.targetFile || pArgs.TargetFile || pArgs.directory;
|
|
16712
16994
|
const keyword = pArgs.keyword;
|
|
16713
16995
|
const title = pArgs.title || pArgs.task;
|
|
16714
16996
|
const id = pArgs.id || pArgs.taskId;
|
|
16715
|
-
const timeVal = pArgs.time;
|
|
16997
|
+
const timeVal = pArgs.timeout || pArgs.time;
|
|
16716
16998
|
if (keyword !== void 0 && keyword !== null) {
|
|
16717
16999
|
detail = String(keyword).replace(RE_STRIP_QUOTES, "");
|
|
16718
17000
|
} else if (filePath) {
|
|
16719
|
-
detail =
|
|
17001
|
+
detail = path26.basename(String(filePath).replace(RE_STRIP_QUOTES, "").replace(RE_BACKSLASH_SLASH, "/"));
|
|
16720
17002
|
} else if (title && (potentialTool === "invoke" || potentialTool === "invoke_sync")) {
|
|
16721
17003
|
detail = String(title).replace(RE_STRIP_QUOTES, "").substring(0, 30);
|
|
16722
17004
|
} else if (id && potentialTool === "get_progress") {
|
|
@@ -16745,7 +17027,7 @@ ${ideErr} [/ERROR]`;
|
|
|
16745
17027
|
if (potentialTool === "invoke" || potentialTool === "invoke_sync" || potentialTool === "get_progress") {
|
|
16746
17028
|
detail = val.substring(0, 30);
|
|
16747
17029
|
} else {
|
|
16748
|
-
detail = potentialTool === "search_keyword" || potentialTool === "file_map" ? val :
|
|
17030
|
+
detail = potentialTool === "search_keyword" || potentialTool === "file_map" ? val : path26.basename(val.replace(RE_BACKSLASH_SLASH, "/"));
|
|
16749
17031
|
}
|
|
16750
17032
|
}
|
|
16751
17033
|
}
|
|
@@ -16779,17 +17061,19 @@ ${ideErr} [/ERROR]`;
|
|
|
16779
17061
|
"Ask": "User Input Required",
|
|
16780
17062
|
"Memory": "Updating Memory",
|
|
16781
17063
|
"GenerateImage": "Generating",
|
|
16782
|
-
"InvokeSync": "
|
|
16783
|
-
"invoke_sync": "
|
|
16784
|
-
"Invoke": "
|
|
16785
|
-
"invoke": "
|
|
17064
|
+
"InvokeSync": "Sub-Agent Working",
|
|
17065
|
+
"invoke_sync": "Sub-Agent Working",
|
|
17066
|
+
"Invoke": "Working",
|
|
17067
|
+
"invoke": "Working",
|
|
16786
17068
|
"GetProgress": "Checking Progress",
|
|
16787
17069
|
"get_progress": "Checking Progress",
|
|
16788
17070
|
"Cancel": "Stopping Generalist",
|
|
16789
17071
|
"cancel": "Stopping Generalist",
|
|
16790
17072
|
"Await": "Waiting",
|
|
16791
17073
|
"await": "Waiting",
|
|
16792
|
-
"EmergencyRollback": "Rolling the Ball"
|
|
17074
|
+
"EmergencyRollback": "Rolling the Ball",
|
|
17075
|
+
"Answer": "Answering Sub-Agent",
|
|
17076
|
+
"answer": "Answering Sub-Agent"
|
|
16793
17077
|
};
|
|
16794
17078
|
const toolTitle = TOOL_TITLES[potentialTool] || "Working";
|
|
16795
17079
|
process.stdout.write(`\x1B]0;${toolTitle}...\x07`);
|
|
@@ -16921,14 +17205,20 @@ ${ideErr} [/ERROR]`;
|
|
|
16921
17205
|
"generate_image": "generate_image",
|
|
16922
17206
|
"todo": "todo",
|
|
16923
17207
|
"Todo": "todo",
|
|
16924
|
-
"
|
|
17208
|
+
"Invoke": "invoke",
|
|
16925
17209
|
"InvokeSync": "invoke_sync",
|
|
16926
17210
|
"getProgress": "get_progress",
|
|
16927
17211
|
"GetProgress": "get_progress",
|
|
17212
|
+
"Await": "await",
|
|
17213
|
+
"await": "await",
|
|
17214
|
+
"AwaitSubagent": "await",
|
|
17215
|
+
"awaitSubagent": "await",
|
|
17216
|
+
"Answer": "answer",
|
|
17217
|
+
"answer": "answer",
|
|
17218
|
+
"AnswerSubagent": "answer",
|
|
17219
|
+
"answerSubagent": "answer",
|
|
16928
17220
|
"Cancel": "cancel",
|
|
16929
17221
|
"cancel": "cancel",
|
|
16930
|
-
"await": "await",
|
|
16931
|
-
"Await": "await",
|
|
16932
17222
|
"EmergencyRollback": "EmergencyRollback"
|
|
16933
17223
|
};
|
|
16934
17224
|
const normToolName = NORMALIZE_MAP[toolCall.toolName] || toolCall.toolName;
|
|
@@ -16951,9 +17241,9 @@ ${ideErr} [/ERROR]`;
|
|
|
16951
17241
|
let totalLines = "...";
|
|
16952
17242
|
let actualEndLine = eLine;
|
|
16953
17243
|
try {
|
|
16954
|
-
const absPath =
|
|
16955
|
-
if (
|
|
16956
|
-
const content =
|
|
17244
|
+
const absPath = path26.resolve(process.cwd(), targetPath2);
|
|
17245
|
+
if (fs27.existsSync(absPath)) {
|
|
17246
|
+
const content = fs27.readFileSync(absPath, "utf8");
|
|
16957
17247
|
const lines = content.split("\n").length;
|
|
16958
17248
|
totalLines = lines;
|
|
16959
17249
|
if (!rawStart && !rawEnd && lines > 800) {
|
|
@@ -16969,30 +17259,30 @@ ${ideErr} [/ERROR]`;
|
|
|
16969
17259
|
const isOfficeFile = pathLower.endsWith(".docx") || pathLower.endsWith(".doc") || pathLower.endsWith(".ppt") || pathLower.endsWith(".pptx") || pathLower.endsWith(".xls") || pathLower.endsWith(".xlsx");
|
|
16970
17260
|
const isImage = /\.(png|jpg|jpeg|webp|gif|bmp)$/.test(pathLower);
|
|
16971
17261
|
if (isPdf || isOfficeFile) {
|
|
16972
|
-
label = `${targetPath2.length > 0 ? "\u2714" : "\u2718"} ${targetPath2 ? `Analyzed: ${
|
|
17262
|
+
label = `${targetPath2.length > 0 ? "\u2714" : "\u2718"} ${targetPath2 ? `Analyzed: ${path26.basename(targetPath2)}` : "Analyzed: File Not Found"}`;
|
|
16973
17263
|
} else if (isImage) {
|
|
16974
|
-
label = `${targetPath2.length > 0 ? "\u2714" : "\u2718"} ${targetPath2 ? `Processed: ${
|
|
17264
|
+
label = `${targetPath2.length > 0 ? "\u2714" : "\u2718"} ${targetPath2 ? `Processed: ${path26.basename(targetPath2)}` : "Processed: File Not Found"}`;
|
|
16975
17265
|
} else {
|
|
16976
|
-
label = `${totalLines !== "..." ? "\u2714" : "\u2718"} Read: ${targetPath2 ? `${
|
|
17266
|
+
label = `${totalLines !== "..." ? "\u2714" : "\u2718"} Read: ${targetPath2 ? `${path26.basename(targetPath2)} \u2192 ${totalLines !== "..." ? `Lines ${sLine} - ${actualEndLine} of ${totalLines}` : "File Not Found"}` : "File Not Found"}`;
|
|
16977
17267
|
}
|
|
16978
17268
|
} else if (normToolName === "list_files" || normToolName === "read_folder") {
|
|
16979
17269
|
const action = normToolName === "list_files" ? "List" : "Browsed";
|
|
16980
|
-
const
|
|
17270
|
+
const path28 = parseArgs(toolCall.args).path || null;
|
|
16981
17271
|
const recurse = parseArgs(toolCall.args).recurse || 1;
|
|
16982
|
-
label = `${
|
|
17272
|
+
label = `${path28 ? "\u2714" : "\u2718"} ${action}: ${path28 ? `${path28 === "." ? `./${recurse > 1 ? "*" : ""}` : `${path28.replaceAll("\\", "/")}${recurse > 1 ? `${path28.endsWith("/") ? `*` : `/*`}` : `${path28.endsWith("/") ? "" : "/"}`}`}` : "No Folder Selected"}`;
|
|
16983
17273
|
} else if (normToolName === "write_file" || normToolName === "update_file") {
|
|
16984
17274
|
const action = normToolName === "write_file" ? "Created" : "Edited";
|
|
16985
|
-
const
|
|
16986
|
-
label = `${
|
|
17275
|
+
const path28 = parseArgs(toolCall.args).path || null;
|
|
17276
|
+
label = `${path28 ? "\u2714" : "\u2718"} ${action}: ${path28.replaceAll("\\", "/") || "No File Changes"}`;
|
|
16987
17277
|
} else if (normToolName === "write_pdf") {
|
|
16988
|
-
const
|
|
16989
|
-
label = `${
|
|
17278
|
+
const path28 = parseArgs(toolCall.args).path || null;
|
|
17279
|
+
label = `${path28 ? "\u2714" : "\u2718"} Generated: ${path28.replaceAll("\\", "/") || "No PDF Generated"}`;
|
|
16990
17280
|
} else if (normToolName === "write_docx") {
|
|
16991
|
-
const
|
|
16992
|
-
label = `${
|
|
17281
|
+
const path28 = parseArgs(toolCall.args).path || null;
|
|
17282
|
+
label = `${path28 ? "\u2714" : "\u2718"} Generated: ${path28.replaceAll("\\", "/") || "No Docx Generated"}`;
|
|
16993
17283
|
} else if (normToolName === "file_map") {
|
|
16994
|
-
const
|
|
16995
|
-
label = `${
|
|
17284
|
+
const path28 = parseArgs(toolCall.args).path;
|
|
17285
|
+
label = `${path28 ? "\u2714" : "\u2718"} Indexed: ${path28.replaceAll("\\", "/") ? "" + path28 : "File Not Found"}`;
|
|
16996
17286
|
} else if (normToolName.toLowerCase() === "search_keyword" || normToolName.toLowerCase() === "todo") {
|
|
16997
17287
|
label = "";
|
|
16998
17288
|
} else if (normToolName.toLowerCase() === "generate_image") {
|
|
@@ -17014,10 +17304,9 @@ ${ideErr} [/ERROR]`;
|
|
|
17014
17304
|
const { method } = parseArgs(toolCall.args);
|
|
17015
17305
|
label = method === "forceRevert" ? "" : "\u2714 Rollback Point Checked";
|
|
17016
17306
|
} else if (normToolName === "await" || normToolName === "Await") {
|
|
17017
|
-
const { time } = parseArgs(toolCall.args);
|
|
17018
|
-
let sec = parseFloat(time) || 0;
|
|
17019
|
-
if (sec
|
|
17020
|
-
if (sec > 180) sec = 180;
|
|
17307
|
+
const { time, timeout } = parseArgs(toolCall.args);
|
|
17308
|
+
let sec = parseFloat(timeout || time) || 0;
|
|
17309
|
+
if (!sec) sec = 120;
|
|
17021
17310
|
const formatTime = (s) => {
|
|
17022
17311
|
if (s >= 60) {
|
|
17023
17312
|
const m = Math.floor(s / 60);
|
|
@@ -17056,6 +17345,8 @@ ${ideErr} [/ERROR]`;
|
|
|
17056
17345
|
];
|
|
17057
17346
|
let randomVibe = existentialVibes[Math.floor(Math.random() * existentialVibes.length)];
|
|
17058
17347
|
label = `\u2714 ${randomVibe} \u2192 ${formatTime(sec)}`;
|
|
17348
|
+
} else if (normToolName === "Answer" || normToolName === "answer") {
|
|
17349
|
+
label = "\u2714 Resolved Sub-Agent Query";
|
|
17059
17350
|
} else if (normToolName === "exec_command" || normToolName === "ask") {
|
|
17060
17351
|
label = "";
|
|
17061
17352
|
} else {
|
|
@@ -17066,7 +17357,7 @@ ${ideErr} [/ERROR]`;
|
|
|
17066
17357
|
const { command } = parseArgs(toolCall.args);
|
|
17067
17358
|
if (command && settings.systemSettings && settings.systemSettings.allowExternalAccess === false) {
|
|
17068
17359
|
const riskyPatterns = [/[a-zA-Z]:[\\\/]/i, /^\//, /\.\.[\\\/]/, /\/etc\//, /\/var\//, /\/root\//, /\/bin\//, /\/usr\//];
|
|
17069
|
-
const currentDrive =
|
|
17360
|
+
const currentDrive = path26.resolve(process.cwd()).substring(0, 3).toLowerCase();
|
|
17070
17361
|
const splitCommands = (cmdString) => {
|
|
17071
17362
|
const commands = [];
|
|
17072
17363
|
let current = "";
|
|
@@ -17195,8 +17486,8 @@ ${ideErr} [/ERROR]`;
|
|
|
17195
17486
|
const targetPath = parsedArgs.path || parsedArgs.targetPath || null;
|
|
17196
17487
|
if (targetPath) {
|
|
17197
17488
|
const isExternalOff = settings.systemSettings && settings.systemSettings.allowExternalAccess === false;
|
|
17198
|
-
const absoluteTarget =
|
|
17199
|
-
const absoluteCwd =
|
|
17489
|
+
const absoluteTarget = path26.resolve(targetPath);
|
|
17490
|
+
const absoluteCwd = path26.resolve(process.cwd());
|
|
17200
17491
|
if (isExternalOff && !absoluteTarget.startsWith(absoluteCwd)) {
|
|
17201
17492
|
const denyMsg = `Access Denied. You are not allowed to access files outside the current workspace.`;
|
|
17202
17493
|
if (normToolName === "write_file" || normToolName === "update_file") {
|
|
@@ -17385,7 +17676,7 @@ ${ideErr} [/ERROR]`;
|
|
|
17385
17676
|
const toolArgs = parseArgs(toolCall.args);
|
|
17386
17677
|
const { path: filePath } = toolArgs;
|
|
17387
17678
|
if (filePath) {
|
|
17388
|
-
const absPath =
|
|
17679
|
+
const absPath = path26.resolve(process.cwd(), filePath);
|
|
17389
17680
|
const normalize2 = (p) => p ? p.toLowerCase().replace(/\\/g, "/").replace(/^[a-z]:/, (m) => m.toUpperCase()) : "";
|
|
17390
17681
|
const normAbsPath = normalize2(absPath);
|
|
17391
17682
|
let originalContent = "";
|
|
@@ -17395,8 +17686,8 @@ ${ideErr} [/ERROR]`;
|
|
|
17395
17686
|
if (currentIDE && normFocused === normAbsPath && currentIDE.full_content) {
|
|
17396
17687
|
originalContent = currentIDE.full_content;
|
|
17397
17688
|
hasOriginal = true;
|
|
17398
|
-
} else if (
|
|
17399
|
-
originalContent =
|
|
17689
|
+
} else if (fs27.existsSync(absPath)) {
|
|
17690
|
+
originalContent = fs27.readFileSync(absPath, "utf8");
|
|
17400
17691
|
hasOriginal = true;
|
|
17401
17692
|
}
|
|
17402
17693
|
originalContentForReporting = originalContent;
|
|
@@ -17424,9 +17715,9 @@ ${ideErr} [/ERROR]`;
|
|
|
17424
17715
|
const successes = patchResults.filter((r) => r.success);
|
|
17425
17716
|
const failures = patchResults.filter((r) => !r.success);
|
|
17426
17717
|
if (successes.length === 0) {
|
|
17427
|
-
const errorMsg = `[TOOL RESULT]: ERROR: Failed to apply patches to [${
|
|
17718
|
+
const errorMsg = `[TOOL RESULT]: ERROR: Failed to apply patches to [${path26.basename(absPath)}].
|
|
17428
17719
|
${failures.map((f) => ` \u2022 ${f.error}`).join("\n")}`;
|
|
17429
|
-
const errorLabel = `\u2714 Edited: ${
|
|
17720
|
+
const errorLabel = `\u2714 Edited: ${path26.basename(absPath.replaceAll("\\", "/"))}`;
|
|
17430
17721
|
let terminalWidth = 115;
|
|
17431
17722
|
if (process.stdout.isTTY) {
|
|
17432
17723
|
terminalWidth = process.stdout.columns - 5 || 120;
|
|
@@ -17443,19 +17734,19 @@ ${failures.map((f) => ` \u2022 ${f.error}`).join("\n")}`;
|
|
|
17443
17734
|
continue;
|
|
17444
17735
|
}
|
|
17445
17736
|
}
|
|
17446
|
-
yield { type: "status", content: `Opening Diff in IDE: ${
|
|
17737
|
+
yield { type: "status", content: `Opening Diff in IDE: ${path26.basename(absPath)}` };
|
|
17447
17738
|
showDiffInIDE(absPath, originalContent, modifiedContent);
|
|
17448
17739
|
diffOpened = true;
|
|
17449
17740
|
await new Promise((r) => setTimeout(r, 50));
|
|
17450
17741
|
} else if (normToolName === "write_file") {
|
|
17451
17742
|
const rawContent = toolArgs.content || toolArgs.newContent || "";
|
|
17452
17743
|
const modifiedContent = rawContent.endsWith("\n") ? rawContent : rawContent + "\n";
|
|
17453
|
-
if (!
|
|
17744
|
+
if (!fs27.existsSync(absPath)) {
|
|
17454
17745
|
isNewFileCreated = true;
|
|
17455
|
-
|
|
17456
|
-
|
|
17746
|
+
fs27.mkdirSync(path26.dirname(absPath), { recursive: true });
|
|
17747
|
+
fs27.writeFileSync(absPath, "", "utf8");
|
|
17457
17748
|
}
|
|
17458
|
-
yield { type: "status", content: `Opening New File Diff in IDE: ${
|
|
17749
|
+
yield { type: "status", content: `Opening New File Diff in IDE: ${path26.basename(absPath)}` };
|
|
17459
17750
|
showDiffInIDE(absPath, "", modifiedContent);
|
|
17460
17751
|
diffOpened = true;
|
|
17461
17752
|
await new Promise((r) => setTimeout(r, 50));
|
|
@@ -17491,11 +17782,11 @@ ${failures.map((f) => ` \u2022 ${f.error}`).join("\n")}`;
|
|
|
17491
17782
|
if (normToolName === "write_file" || normToolName === "update_file") {
|
|
17492
17783
|
const { path: filePath } = parseArgs(toolCall.args);
|
|
17493
17784
|
if (filePath) {
|
|
17494
|
-
const absPath =
|
|
17785
|
+
const absPath = path26.resolve(process.cwd(), filePath);
|
|
17495
17786
|
closeDiffInIDE(absPath, approval);
|
|
17496
|
-
if (approval === "deny" && isNewFileCreated &&
|
|
17787
|
+
if (approval === "deny" && isNewFileCreated && fs27.existsSync(absPath)) {
|
|
17497
17788
|
try {
|
|
17498
|
-
|
|
17789
|
+
fs27.unlinkSync(absPath);
|
|
17499
17790
|
} catch (e) {
|
|
17500
17791
|
}
|
|
17501
17792
|
}
|
|
@@ -17507,18 +17798,18 @@ ${failures.map((f) => ` \u2022 ${f.error}`).join("\n")}`;
|
|
|
17507
17798
|
}
|
|
17508
17799
|
if (approval === "allow" && diffOpened && isBridgeConnected()) {
|
|
17509
17800
|
const { path: filePath } = parseArgs(toolCall.args);
|
|
17510
|
-
const absPath =
|
|
17511
|
-
const normPath = (p) => p ?
|
|
17801
|
+
const absPath = path26.resolve(process.cwd(), filePath);
|
|
17802
|
+
const normPath = (p) => p ? path26.resolve(p).replace(/\\/g, "/").toLowerCase() : "";
|
|
17512
17803
|
const finalIDE = await getIDEContext();
|
|
17513
17804
|
let finalContent = "";
|
|
17514
17805
|
if (finalIDE && finalIDE.file_focused && normPath(finalIDE.file_focused) === normPath(absPath) && finalIDE.full_content) {
|
|
17515
17806
|
finalContent = finalIDE.full_content;
|
|
17516
17807
|
}
|
|
17517
|
-
if (!finalContent &&
|
|
17518
|
-
finalContent =
|
|
17808
|
+
if (!finalContent && fs27.existsSync(absPath)) {
|
|
17809
|
+
finalContent = fs27.readFileSync(absPath, "utf8");
|
|
17519
17810
|
if (!finalContent) {
|
|
17520
17811
|
await new Promise((r) => setTimeout(r, 100));
|
|
17521
|
-
finalContent =
|
|
17812
|
+
finalContent = fs27.readFileSync(absPath, "utf8");
|
|
17522
17813
|
}
|
|
17523
17814
|
}
|
|
17524
17815
|
const verifiedLines = finalContent.split(/\r?\n/);
|
|
@@ -17679,7 +17970,7 @@ ${snippet2}`;
|
|
|
17679
17970
|
try {
|
|
17680
17971
|
const { path: filePath } = parseArgs(toolCall.args);
|
|
17681
17972
|
if (filePath) {
|
|
17682
|
-
const absPath =
|
|
17973
|
+
const absPath = path26.resolve(process.cwd(), filePath);
|
|
17683
17974
|
const currentIDE = await getIDEContext();
|
|
17684
17975
|
if (currentIDE && currentIDE.file_focused === absPath && currentIDE.full_content) {
|
|
17685
17976
|
execToolContext.forcedContent = currentIDE.full_content;
|
|
@@ -17693,7 +17984,7 @@ ${snippet2}`;
|
|
|
17693
17984
|
if ((normToolName === "write_file" || normToolName === "update_file") && result.startsWith("SUCCESS")) {
|
|
17694
17985
|
const { path: filePath } = parseArgs(toolCall.args);
|
|
17695
17986
|
if (filePath) {
|
|
17696
|
-
const absPath =
|
|
17987
|
+
const absPath = path26.resolve(process.cwd(), filePath);
|
|
17697
17988
|
openFileInEditor(absPath);
|
|
17698
17989
|
}
|
|
17699
17990
|
}
|
|
@@ -17710,7 +18001,7 @@ ${snippet2}`;
|
|
|
17710
18001
|
result = result.text;
|
|
17711
18002
|
}
|
|
17712
18003
|
if (normToolName === "search_keyword") {
|
|
17713
|
-
const { keyword, path:
|
|
18004
|
+
const { keyword, path: path28 } = parseArgs(toolCall.args);
|
|
17714
18005
|
const _isGlob = typeof result === "string" && result.startsWith("[GLOB]");
|
|
17715
18006
|
if (_isGlob) result = result.slice(6).trimStart();
|
|
17716
18007
|
const _isDir = typeof result === "string" && result.startsWith("[DIR]");
|
|
@@ -17722,8 +18013,8 @@ ${snippet2}`;
|
|
|
17722
18013
|
matchCount = parseInt(m[1]);
|
|
17723
18014
|
}
|
|
17724
18015
|
}
|
|
17725
|
-
const _sp =
|
|
17726
|
-
const displayPath = _sp && _sp !== "." ? `"${_isGlob ?
|
|
18016
|
+
const _sp = path28 ? path28.replace(/[\/\\]+$/, "") : null;
|
|
18017
|
+
const displayPath = _sp && _sp !== "." ? `"${_isGlob ? path28 : _isDir ? `${_sp}/*` : _sp}"` : "./";
|
|
17727
18018
|
const postLabel = `${keyword ? "\u2714" : "\u2718"} Searched: "${keyword ? keyword : ""}" in ${displayPath.replaceAll("\\", "/")} \u2192 ${matchCount} Match${matchCount === 1 ? "" : "es"}`;
|
|
17728
18019
|
let terminalWidth = 115;
|
|
17729
18020
|
if (process.stdout.isTTY) {
|
|
@@ -17962,9 +18253,9 @@ ${snippet2}`;
|
|
|
17962
18253
|
})() : String(err);
|
|
17963
18254
|
;
|
|
17964
18255
|
const date = (/* @__PURE__ */ new Date()).toLocaleString();
|
|
17965
|
-
const agentErrDir =
|
|
17966
|
-
if (!
|
|
17967
|
-
|
|
18256
|
+
const agentErrDir = path26.join(LOGS_DIR, "agent");
|
|
18257
|
+
if (!fs27.existsSync(agentErrDir)) fs27.mkdirSync(agentErrDir, { recursive: true });
|
|
18258
|
+
fs27.appendFileSync(path26.join(agentErrDir, "error.log"), `ERROR [${date}]: ${errLog}
|
|
17968
18259
|
|
|
17969
18260
|
----------------------------------------------------------------------
|
|
17970
18261
|
|
|
@@ -17984,7 +18275,7 @@ ${snippet2}`;
|
|
|
17984
18275
|
const waitTime = Math.min(1e3 * Math.pow(2, inStreamRetryCount - 1), 24e3);
|
|
17985
18276
|
if (turnText.trim().length > 0) {
|
|
17986
18277
|
modifiedHistory.push({ role: "agent", text: turnText });
|
|
17987
|
-
const recoveryText = "[SYSTEM]\n- SEAMLESS CONTINUATION: Resume immediately. Pick up from last words with zero gap/disruption\n- NO REPETITION: Do not repeat any text already written\n- NO RE-THINK: Do not restart or open <think> if reasoning already started. Continue the thinking and close thinking block </think>
|
|
18278
|
+
const recoveryText = "[SYSTEM]\n- SEAMLESS CONTINUATION: Resume immediately. Pick up from last words with zero gap/disruption\n- NO REPETITION: Do not repeat any text already written\n- NO RE-THINK: Do not restart or open <think> if reasoning already started. Continue the thinking and close thinking block </think> BEFORE CHAT OUTPUT\n- MID-TOOL SAFETY: If cutoff was mid-tool call, restart that tool call from start\n- STEALTH: Do not mention/apologize for cutoff [/SYSTEM]";
|
|
17988
18279
|
if (toolResults.length > 0) {
|
|
17989
18280
|
toolResults.forEach((tr, idx) => {
|
|
17990
18281
|
if (idx === toolResults.length - 1) {
|
|
@@ -18011,7 +18302,7 @@ ${recoveryText}`
|
|
|
18011
18302
|
yield { type: "status", content: `Error Occured. Recovering Stream...` };
|
|
18012
18303
|
} else {
|
|
18013
18304
|
throw new Error(`Stream collapsed too many times. (Failed to resolve ${MAX_RETRIES} times)
|
|
18014
|
-
Error Log can be found in ${
|
|
18305
|
+
Error Log can be found in ${path26.join(LOGS_DIR, "agent", "error.log")}`);
|
|
18015
18306
|
}
|
|
18016
18307
|
} else {
|
|
18017
18308
|
if (retryCount <= MAX_RETRIES) {
|
|
@@ -18029,7 +18320,7 @@ Error Log can be found in ${path27.join(LOGS_DIR, "agent", "error.log")}`);
|
|
|
18029
18320
|
yield { type: "status", content: `Trying to reach ${modelName}` };
|
|
18030
18321
|
} else {
|
|
18031
18322
|
throw new Error(`Model ${modelName} cannot be reached. (Failed ${MAX_RETRIES} times)
|
|
18032
|
-
Error Log can be found in ${
|
|
18323
|
+
Error Log can be found in ${path26.join(LOGS_DIR, "agent", "error.log")}`);
|
|
18033
18324
|
}
|
|
18034
18325
|
}
|
|
18035
18326
|
}
|
|
@@ -18148,10 +18439,10 @@ Error Log can be found in ${path27.join(LOGS_DIR, "agent", "error.log")}`);
|
|
|
18148
18439
|
}
|
|
18149
18440
|
})() : String(err);
|
|
18150
18441
|
const date = (/* @__PURE__ */ new Date()).toLocaleString();
|
|
18151
|
-
const agentErrDir =
|
|
18442
|
+
const agentErrDir = path26.join(LOGS_DIR, "agent");
|
|
18152
18443
|
yield { type: "text", content: `\u274C CRITICAL ERROR: ${errLog.includes("fetch failed") ? "Failed to Connect. Check your Internet Connection or Wait a moment" : errLog}` };
|
|
18153
|
-
if (!
|
|
18154
|
-
|
|
18444
|
+
if (!fs27.existsSync(agentErrDir)) fs27.mkdirSync(agentErrDir, { recursive: true });
|
|
18445
|
+
fs27.appendFileSync(path26.join(agentErrDir, "error.log"), `CRITICAL ERROR [${date}]: ${err}
|
|
18155
18446
|
|
|
18156
18447
|
----------------------------------------------------------------------
|
|
18157
18448
|
|
|
@@ -18177,7 +18468,7 @@ Error Log can be found in ${path27.join(LOGS_DIR, "agent", "error.log")}`);
|
|
|
18177
18468
|
}
|
|
18178
18469
|
yield { type: "status", content: null };
|
|
18179
18470
|
};
|
|
18180
|
-
runSubagent = async (task, settings, model = null, allowedTools = null, maxTurns = 50, logCallback = null) => {
|
|
18471
|
+
runSubagent = async (task, settings, model = null, allowedTools = null, maxTurns = 50, logCallback = null, isAsync = false) => {
|
|
18181
18472
|
const savedSettings = await loadSettings();
|
|
18182
18473
|
const mergedSettings = { ...savedSettings, ...settings };
|
|
18183
18474
|
const envSubagentModel = process.env.SUBAGENT_MODEL ? process.env.SUBAGENT_MODEL.trim() : null;
|
|
@@ -18251,8 +18542,8 @@ Error Log can be found in ${path27.join(LOGS_DIR, "agent", "error.log")}`);
|
|
|
18251
18542
|
const targetModel = model || subAgentCustomModel || settings?.modelName || settings?.activeModel || savedSettings.activeModel;
|
|
18252
18543
|
const osDetected = process.platform === "win32" ? "Windows" : process.platform === "darwin" ? "macOS" : "Linux";
|
|
18253
18544
|
const providedToolsSection = `-- TOOL DEFINITIONS (path = relative to CWD, path separator: '/') --
|
|
18254
|
-
TO ACCESS TOOLS **STRICTLY USE THE EXACT FORMAT IN CHAT OUTPUT:** [tool:functions.ToolName(
|
|
18255
|
-
**NO OTHER SYNTAX/MARKERS/BOUNDARY ALLOWED**
|
|
18545
|
+
TO ACCESS TOOLS **STRICTLY USE THE EXACT FORMAT IN CHAT OUTPUT:** [tool:functions.ToolName(arg1="value1")]
|
|
18546
|
+
**NO OTHER SYNTAX/MARKERS/WRAPPER/BOUNDARY ALLOWED**
|
|
18256
18547
|
|
|
18257
18548
|
TOOL POLICY:
|
|
18258
18549
|
- Escape quotes: \\" for code strings
|
|
@@ -18263,10 +18554,12 @@ TOOL POLICY:
|
|
|
18263
18554
|
- Need text or huge files? SearchKeyword > Full Read
|
|
18264
18555
|
- Update Todos from realtime progress each turn
|
|
18265
18556
|
- Restricted Shell Access, No Deletion
|
|
18557
|
+
- ONLY valid tools and syntax defined below are allowed
|
|
18266
18558
|
|
|
18267
18559
|
**PROVIDED TOOLS**
|
|
18268
|
-
-- Communication
|
|
18269
|
-
- [tool:functions.Ask(question="...", optionA="option::description", ...MAX 4)]. Ambiguity: MUST for path divergence, security risk. Ask, don't finish/guess. Suggest best options; no preferences. Keep options short
|
|
18560
|
+
-- Communication Tools --
|
|
18561
|
+
- [tool:functions.Ask(question="...", optionA="option::description", ...MAX 4)]. Communicate with USER. Ambiguity: MUST for path divergence, security risk. Ask, don't finish/guess. Suggest best options; no preferences. Keep options short
|
|
18562
|
+
${isAsync ? `- [tool:functions.AskMain(question="...", optionA="option::description", ...MAX 4)]. Communicate with PARENT/MAIN AGENT. When clarification/decision is needed for a task` : ""}
|
|
18270
18563
|
|
|
18271
18564
|
-- Web Tools --
|
|
18272
18565
|
- [tool:functions.WebSearch(query="...", aiMode="bool optional, default: false", limit="integer 3-10, aiMode: exclude")]. Usage: unknown info/docs. aiMode: LLM search
|
|
@@ -18279,7 +18572,7 @@ TOOL POLICY:
|
|
|
18279
18572
|
- [tool:functions.PatchFile(path="...", allowMultiple="bool optional, default: false", replaceContent1="...", newContent1="...", ...MAX15)]. TARGET MINIMAL DIFF. allowMultiple: Replace all matches ONLY WHEN SURE. Multi-blocks: replaceContent2/newContent2... Verify diffs
|
|
18280
18573
|
- [tool:functions.WriteFile(path="...", content="...")]. Creates/Overwrites. File Exist? PatchFile > WriteFile. VERIFY IMPORTS
|
|
18281
18574
|
- [tool:functions.Run(command="...")]. Runs ${osDetected === "Windows" ? isPsAvailable() ? `WINDOWS POWERSHELL` : `WINDOWS CMD` : `BASH`} command. Destructive/Irreversible ops \u2192 Ask user`.trim();
|
|
18282
|
-
const
|
|
18575
|
+
const systemInstructionSubAgent = `=== START SYSTEM PROMPT ===
|
|
18283
18576
|
You are a subagent helping the main FluxFlow CLI agent
|
|
18284
18577
|
Your task is: "${task}"
|
|
18285
18578
|
|
|
@@ -18319,7 +18612,7 @@ Current Time: ${time}
|
|
|
18319
18612
|
parts: [{ text: m.text }]
|
|
18320
18613
|
}));
|
|
18321
18614
|
if (logCallback) logCallback(`[Subagent Turn ${turn + 1}] Invoking model ${targetModel}...`);
|
|
18322
|
-
const response = await generateSimpleContent(mergedSettings, targetModel, contents,
|
|
18615
|
+
const response = await generateSimpleContent(mergedSettings, targetModel, contents, systemInstructionSubAgent, "Fast");
|
|
18323
18616
|
const responseText = response.text || "";
|
|
18324
18617
|
const cleanResponse = responseText.replace(/(?:<think>|\[think\])[\s\S]*?(?:<\/think>|\[\/think\])/gi, "").trim();
|
|
18325
18618
|
finalAnswer = cleanResponse;
|
|
@@ -18331,6 +18624,8 @@ ${cleanResponse}
|
|
|
18331
18624
|
if (toolCalls.length === 0) {
|
|
18332
18625
|
break;
|
|
18333
18626
|
}
|
|
18627
|
+
const askMainCalls = toolCalls.filter((tc) => tc.toolName.toLowerCase() === "askmain" || tc.toolName.toLowerCase() === "ask_main");
|
|
18628
|
+
let processedAskMainInTurn = false;
|
|
18334
18629
|
let toolResultsStr = "";
|
|
18335
18630
|
for (const toolCall of toolCalls) {
|
|
18336
18631
|
if (TERMINATION_SIGNAL) {
|
|
@@ -18347,6 +18642,39 @@ ${cleanResponse}
|
|
|
18347
18642
|
}
|
|
18348
18643
|
}
|
|
18349
18644
|
const normalizedToolName = toolCall.toolName.toLowerCase();
|
|
18645
|
+
if (normalizedToolName === "askmain" || normalizedToolName === "ask_main") {
|
|
18646
|
+
if (processedAskMainInTurn) continue;
|
|
18647
|
+
processedAskMainInTurn = true;
|
|
18648
|
+
let questionText = "";
|
|
18649
|
+
let optionsObj = {};
|
|
18650
|
+
if (askMainCalls.length === 1) {
|
|
18651
|
+
const pArgs = parseArgs(askMainCalls[0].args);
|
|
18652
|
+
questionText = pArgs.question || askMainCalls[0].args;
|
|
18653
|
+
optionsObj = pArgs;
|
|
18654
|
+
} else {
|
|
18655
|
+
questionText = askMainCalls.map((tc, idx) => {
|
|
18656
|
+
const pArgs = parseArgs(tc.args);
|
|
18657
|
+
return `Q${idx + 1}: ${pArgs.question || tc.args}`;
|
|
18658
|
+
}).join("\n");
|
|
18659
|
+
optionsObj = {};
|
|
18660
|
+
}
|
|
18661
|
+
if (settings.onAskMain) {
|
|
18662
|
+
if (logCallback) logCallback(`[Executing Tool] AskMain("${questionText}")...`);
|
|
18663
|
+
const answer = await settings.onAskMain(questionText, optionsObj);
|
|
18664
|
+
if (logCallback) logCallback(`[Tool Result]
|
|
18665
|
+
Answer from Main Agent: ${answer}
|
|
18666
|
+
`);
|
|
18667
|
+
toolResultsStr += `[TOOL RESULT for AskMain]: Answer from Main Agent: ${answer}
|
|
18668
|
+
|
|
18669
|
+
`;
|
|
18670
|
+
await incrementUsage("toolSuccess");
|
|
18671
|
+
} else {
|
|
18672
|
+
toolResultsStr += `[TOOL RESULT for AskMain]: ERROR: Main agent communication channel not available.
|
|
18673
|
+
|
|
18674
|
+
`;
|
|
18675
|
+
}
|
|
18676
|
+
continue;
|
|
18677
|
+
}
|
|
18350
18678
|
const allowed = allowedTools ? allowedTools.some((t) => t.toLowerCase() === normalizedToolName) : true;
|
|
18351
18679
|
if (!allowed) {
|
|
18352
18680
|
const errorMsg = `ERROR: Tool [${toolCall.toolName}] is not in the allowed tools list for this subagent.`;
|
|
@@ -18383,25 +18711,25 @@ ${cleanResponse}
|
|
|
18383
18711
|
const keywordPath = pArgs.path || "";
|
|
18384
18712
|
label = `${keyword ? "\u2714" : "\u2718"} \x1B[95mSearched\x1B[0m: ${keyword || "No Query"}${keywordPath ? ` \u2192 ${keywordPath.replaceAll("\\", "/")}` : ""}`;
|
|
18385
18713
|
} else if (normalizedToolName === "view_file" || normalizedToolName === "viewfile" || normalizedToolName === "readfile") {
|
|
18386
|
-
const
|
|
18387
|
-
label = `\u2714 \x1B[95mRead\x1B[0m: ${
|
|
18714
|
+
const path28 = parseArgs(toolCall.args).path || "";
|
|
18715
|
+
label = `\u2714 \x1B[95mRead\x1B[0m: ${path28.replaceAll("\\", "/")}`;
|
|
18388
18716
|
} else if (normalizedToolName === "list_files" || normalizedToolName === "read_folder" || normalizedToolName === "readfolder") {
|
|
18389
|
-
const
|
|
18717
|
+
const path28 = parseArgs(toolCall.args).path || null;
|
|
18390
18718
|
const recurse = parseArgs(toolCall.args).recurse || 0;
|
|
18391
|
-
label = `${
|
|
18719
|
+
label = `${path28 ? "\u2714" : "\u2718"} \x1B[95mBrowsed\x1B[0m: ${path28 ? `${path28.replaceAll("\\", "/")}${recurse > 0 ? `${path28.endsWith("/") ? `*${recurse}` : `/*${recurse}`}` : `${path28.endsWith("/") ? "" : "/"}`}` : ""}`;
|
|
18392
18720
|
} else if (normalizedToolName === "write_file" || normalizedToolName === "writefile") {
|
|
18393
|
-
const
|
|
18394
|
-
label = `${
|
|
18721
|
+
const path28 = parseArgs(toolCall.args).path || null;
|
|
18722
|
+
label = `${path28 ? "\u2714" : "\u2718"} \x1B[95mCreated\x1B[0m: ${path28 ? `${path28.replaceAll("\\", "/")}` : "No File Changes"}`;
|
|
18395
18723
|
} else if (normalizedToolName === "update_file" || normalizedToolName === "updatefile" || normalizedToolName === "patchfile" || normalizedToolName === "patch_file" || normalizedToolName === "patchfile" || normalizedToolName === "updatefile") {
|
|
18396
|
-
const
|
|
18724
|
+
const path28 = parseArgs(toolCall.args).path || null;
|
|
18397
18725
|
const content = parseArgs(toolCall.args).content || null;
|
|
18398
|
-
label = `${
|
|
18726
|
+
label = `${path28 ? "\u2714" : "\u2718"} \x1B[95mEdited\x1B[0m: ${path28 ? `${path28.replaceAll("\\", "/")}` : "No File Changes"}`;
|
|
18399
18727
|
} else if (normalizedToolName === "exec_command" || normalizedToolName === "execcommand" || normalizedToolName === "run") {
|
|
18400
18728
|
const command = parseArgs(toolCall.args).command || null;
|
|
18401
18729
|
label = `${command ? "\u2714" : "\u2718"} \x1B[95mExecuted\x1B[0m: ${command ? command.slice(0, 100) + (command.length > 100 ? "..." : "") : "No Command"}`;
|
|
18402
18730
|
} else if (normalizedToolName === "file_map" || normalizedToolName === "filemap") {
|
|
18403
|
-
const
|
|
18404
|
-
label = `${
|
|
18731
|
+
const path28 = parseArgs(toolCall.args).path || "";
|
|
18732
|
+
label = `${path28 ? "\u2714" : "\u2718"} \x1B[95mIndexed\x1B[0m: ${path28 ? `${path28.replaceAll("\\", "/")}` : "File Not Found"}`;
|
|
18405
18733
|
} else if (normalizedToolName === "await") {
|
|
18406
18734
|
const { time: time2 } = parseArgs(toolCall.args);
|
|
18407
18735
|
let sec = parseFloat(time2) || 0;
|
|
@@ -19397,7 +19725,7 @@ var init_RevertModal = __esm({
|
|
|
19397
19725
|
import puppeteer4 from "puppeteer";
|
|
19398
19726
|
import { exec } from "child_process";
|
|
19399
19727
|
import { promisify } from "util";
|
|
19400
|
-
import
|
|
19728
|
+
import fs28 from "fs";
|
|
19401
19729
|
var execAsync, checkPuppeteerReady, installPuppeteerBrowser;
|
|
19402
19730
|
var init_setup = __esm({
|
|
19403
19731
|
"src/utils/setup.js"() {
|
|
@@ -19406,11 +19734,11 @@ var init_setup = __esm({
|
|
|
19406
19734
|
checkPuppeteerReady = () => {
|
|
19407
19735
|
try {
|
|
19408
19736
|
const pptrConfig = getPuppeteerConfig();
|
|
19409
|
-
if (pptrConfig.executablePath &&
|
|
19737
|
+
if (pptrConfig.executablePath && fs28.existsSync(pptrConfig.executablePath)) {
|
|
19410
19738
|
return true;
|
|
19411
19739
|
}
|
|
19412
19740
|
const exePath = puppeteer4.executablePath();
|
|
19413
|
-
const exists = exePath &&
|
|
19741
|
+
const exists = exePath && fs28.existsSync(exePath);
|
|
19414
19742
|
if (exists) return true;
|
|
19415
19743
|
} catch (e) {
|
|
19416
19744
|
return false;
|
|
@@ -19497,8 +19825,8 @@ __export(app_exports, {
|
|
|
19497
19825
|
import os4 from "os";
|
|
19498
19826
|
import React16, { useState as useState15, useEffect as useEffect12, useRef as useRef4, useMemo as useMemo2 } from "react";
|
|
19499
19827
|
import { Box as Box14, Text as Text16, useInput as useInput9, useStdout as useStdout2, Static } from "ink";
|
|
19500
|
-
import
|
|
19501
|
-
import
|
|
19828
|
+
import fs29 from "fs-extra";
|
|
19829
|
+
import path27 from "path";
|
|
19502
19830
|
import { exec as exec2 } from "child_process";
|
|
19503
19831
|
import { fileURLToPath as fileURLToPath3 } from "url";
|
|
19504
19832
|
import TextInput4 from "ink-text-input";
|
|
@@ -19928,10 +20256,10 @@ function App({ args = [] }) {
|
|
|
19928
20256
|
const kbPath = getKeybindingsPath(ideName);
|
|
19929
20257
|
if (!kbPath) return;
|
|
19930
20258
|
try {
|
|
19931
|
-
await
|
|
20259
|
+
await fs29.ensureDir(path27.dirname(kbPath));
|
|
19932
20260
|
let bindings = [];
|
|
19933
|
-
if (
|
|
19934
|
-
const content =
|
|
20261
|
+
if (fs29.existsSync(kbPath)) {
|
|
20262
|
+
const content = fs29.readFileSync(kbPath, "utf8").trim();
|
|
19935
20263
|
if (content) {
|
|
19936
20264
|
try {
|
|
19937
20265
|
bindings = parseJsonc(content);
|
|
@@ -19951,7 +20279,7 @@ function App({ args = [] }) {
|
|
|
19951
20279
|
},
|
|
19952
20280
|
"when": "terminalFocus"
|
|
19953
20281
|
});
|
|
19954
|
-
|
|
20282
|
+
fs29.writeFileSync(kbPath, JSON.stringify(bindings, null, 4), "utf8");
|
|
19955
20283
|
cachedShortcut = "Shift + Enter";
|
|
19956
20284
|
setMessages((prev) => {
|
|
19957
20285
|
setCompletedIndex(prev.length + 1);
|
|
@@ -20686,7 +21014,7 @@ function App({ args = [] }) {
|
|
|
20686
21014
|
useEffect12(() => {
|
|
20687
21015
|
async function init() {
|
|
20688
21016
|
try {
|
|
20689
|
-
const pkg = JSON.parse(
|
|
21017
|
+
const pkg = JSON.parse(fs29.readFileSync(path27.join(process.cwd(), "package.json"), "utf8"));
|
|
20690
21018
|
initBridge(versionFluxflow || pkg.version || "2.0.0");
|
|
20691
21019
|
} catch (e) {
|
|
20692
21020
|
initBridge("2.0.0");
|
|
@@ -20800,7 +21128,7 @@ function App({ args = [] }) {
|
|
|
20800
21128
|
if (!parsedArgs.playground) {
|
|
20801
21129
|
deleteChat(PLAYGROUND_CHAT_ID).catch(() => {
|
|
20802
21130
|
});
|
|
20803
|
-
|
|
21131
|
+
fs29.remove(path27.join(DATA_DIR, "playground")).catch(() => {
|
|
20804
21132
|
});
|
|
20805
21133
|
}
|
|
20806
21134
|
performVersionCheck(false, freshSettings);
|
|
@@ -20834,9 +21162,9 @@ function App({ args = [] }) {
|
|
|
20834
21162
|
}
|
|
20835
21163
|
}
|
|
20836
21164
|
if (parsedArgs.playground) {
|
|
20837
|
-
const playgroundDir =
|
|
21165
|
+
const playgroundDir = path27.join(DATA_DIR, "playground");
|
|
20838
21166
|
try {
|
|
20839
|
-
|
|
21167
|
+
fs29.ensureDirSync(playgroundDir);
|
|
20840
21168
|
process.chdir(playgroundDir);
|
|
20841
21169
|
} catch (e) {
|
|
20842
21170
|
}
|
|
@@ -20877,8 +21205,8 @@ function App({ args = [] }) {
|
|
|
20877
21205
|
if (kbPath) {
|
|
20878
21206
|
try {
|
|
20879
21207
|
let bindings = [];
|
|
20880
|
-
if (
|
|
20881
|
-
const content =
|
|
21208
|
+
if (fs29.existsSync(kbPath)) {
|
|
21209
|
+
const content = fs29.readFileSync(kbPath, "utf8").trim();
|
|
20882
21210
|
if (content) {
|
|
20883
21211
|
bindings = parseJsonc(content);
|
|
20884
21212
|
}
|
|
@@ -21257,22 +21585,22 @@ ${cleanText}`, color: "magenta" }];
|
|
|
21257
21585
|
});
|
|
21258
21586
|
break;
|
|
21259
21587
|
}
|
|
21260
|
-
const src =
|
|
21261
|
-
const dest =
|
|
21588
|
+
const src = path27.join(DATA_DIR, "playground");
|
|
21589
|
+
const dest = path27.join(parsedArgs.originalCwd, "playground-export");
|
|
21262
21590
|
const moveFiles = async () => {
|
|
21263
21591
|
try {
|
|
21264
21592
|
setMessages((prev) => {
|
|
21265
21593
|
setCompletedIndex(prev.length + 1);
|
|
21266
21594
|
return [...prev, { id: Date.now(), role: "system", text: `[PLAYGROUND] Exporting playground content to ${dest}`, isMeta: true }];
|
|
21267
21595
|
});
|
|
21268
|
-
await
|
|
21596
|
+
await fs29.ensureDir(dest);
|
|
21269
21597
|
const excludeDirs = ["node_modules", ".git", ".venv", "venv", "env", ".next", "dist", "build", ".cache"];
|
|
21270
|
-
await
|
|
21598
|
+
await fs29.copy(src, dest, {
|
|
21271
21599
|
overwrite: true,
|
|
21272
21600
|
filter: (srcPath) => {
|
|
21273
|
-
const relative =
|
|
21601
|
+
const relative = path27.relative(src, srcPath);
|
|
21274
21602
|
if (!relative) return true;
|
|
21275
|
-
const parts2 = relative.split(
|
|
21603
|
+
const parts2 = relative.split(path27.sep);
|
|
21276
21604
|
return !parts2.some((part) => excludeDirs.includes(part));
|
|
21277
21605
|
}
|
|
21278
21606
|
});
|
|
@@ -21334,7 +21662,7 @@ ${cleanText}`, color: "magenta" }];
|
|
|
21334
21662
|
}
|
|
21335
21663
|
}
|
|
21336
21664
|
setTimeout(() => {
|
|
21337
|
-
|
|
21665
|
+
fs29.emptyDir(path27.join(DATA_DIR, "playground")).catch((err) => {
|
|
21338
21666
|
setMessages((prev) => {
|
|
21339
21667
|
const newMsgs = [...prev, {
|
|
21340
21668
|
id: "playground-" + Date.now(),
|
|
@@ -21724,12 +22052,12 @@ ${list || "No saved chats found."}`, isMeta: true }];
|
|
|
21724
22052
|
setCompletedIndex(prev.length + 1);
|
|
21725
22053
|
return [...prev, { id: Date.now(), role: "system", text: "[NUCLEAR] Initiating reset...", isMeta: true }];
|
|
21726
22054
|
});
|
|
21727
|
-
if (
|
|
21728
|
-
if (
|
|
21729
|
-
if (
|
|
22055
|
+
if (fs29.existsSync(LOGS_DIR)) fs29.removeSync(LOGS_DIR);
|
|
22056
|
+
if (fs29.existsSync(SECRET_DIR)) fs29.removeSync(SECRET_DIR);
|
|
22057
|
+
if (fs29.existsSync(SETTINGS_FILE)) fs29.removeSync(SETTINGS_FILE);
|
|
21730
22058
|
try {
|
|
21731
|
-
const items =
|
|
21732
|
-
if (items.length === 0)
|
|
22059
|
+
const items = fs29.readdirSync(FLUXFLOW_DIR);
|
|
22060
|
+
if (items.length === 0) fs29.removeSync(FLUXFLOW_DIR);
|
|
21733
22061
|
} catch (e) {
|
|
21734
22062
|
}
|
|
21735
22063
|
setTimeout(() => {
|
|
@@ -21851,15 +22179,15 @@ ${list || "No saved chats found."}`, isMeta: true }];
|
|
|
21851
22179
|
# SKILLS & WORKFLOWS
|
|
21852
22180
|
- [Define custom step-by-step recipes for this project here]
|
|
21853
22181
|
`;
|
|
21854
|
-
const filePath =
|
|
21855
|
-
if (
|
|
22182
|
+
const filePath = path27.join(process.cwd(), "FluxFlow.md");
|
|
22183
|
+
if (fs29.pathExistsSync(filePath)) {
|
|
21856
22184
|
setMessages((prev) => {
|
|
21857
22185
|
setCompletedIndex(prev.length + 1);
|
|
21858
22186
|
return [...prev, { id: "init-err-" + Date.now(), role: "system", text: "ERROR: FluxFlow.md already exists in this directory.", isMeta: true }];
|
|
21859
22187
|
});
|
|
21860
22188
|
} else {
|
|
21861
22189
|
try {
|
|
21862
|
-
|
|
22190
|
+
fs29.writeFileSync(filePath, template);
|
|
21863
22191
|
setMessages((prev) => {
|
|
21864
22192
|
setCompletedIndex(prev.length + 1);
|
|
21865
22193
|
return [...prev, { id: "init-ok-" + Date.now(), role: "system", text: "[SUCCESS] FluxFlow.md has been initialized. You can now customize it for this project.", isMeta: true }];
|
|
@@ -21973,19 +22301,19 @@ ${list || "No saved chats found."}`, isMeta: true }];
|
|
|
21973
22301
|
if (!fullTextStr.startsWith("[TOOL RESULT]:")) {
|
|
21974
22302
|
return m;
|
|
21975
22303
|
}
|
|
21976
|
-
if (fullTextStr.startsWith("[TOOL RESULT]: ERROR") || fullTextStr.startsWith("[TOOL RESULT]: DENIED") || fullTextStr.includes("...Result Truncated by System on User
|
|
22304
|
+
if (fullTextStr.startsWith("[TOOL RESULT]: ERROR") || fullTextStr.startsWith("[TOOL RESULT]: DENIED") || fullTextStr.includes("...Result Truncated by System on User Command")) {
|
|
21977
22305
|
return m;
|
|
21978
22306
|
}
|
|
21979
22307
|
truncatedCount++;
|
|
21980
22308
|
if (fullTextStr.startsWith("[TOOL RESULT]: SUCCESS")) {
|
|
21981
22309
|
return {
|
|
21982
22310
|
...m,
|
|
21983
|
-
fullText: "[TOOL RESULT]: SUCCESS: ...Result Truncated by System on User
|
|
22311
|
+
fullText: "[TOOL RESULT]: SUCCESS: ...Result Truncated by System on User Command"
|
|
21984
22312
|
};
|
|
21985
22313
|
}
|
|
21986
22314
|
return {
|
|
21987
22315
|
...m,
|
|
21988
|
-
fullText: "[TOOL RESULT]: ...Result Truncated by System on User
|
|
22316
|
+
fullText: "[TOOL RESULT]: ...Result Truncated by System on User Command"
|
|
21989
22317
|
};
|
|
21990
22318
|
});
|
|
21991
22319
|
const finalMsgs = [...updatedMessages, {
|
|
@@ -22602,10 +22930,27 @@ Selection: ${val}`,
|
|
|
22602
22930
|
commitActiveStreamingMessage();
|
|
22603
22931
|
inThinkMode = true;
|
|
22604
22932
|
thinkConsumedInTurn = true;
|
|
22605
|
-
let thinkStartText = afterText.replace(/<(think|thought)>/gi, "");
|
|
22606
22933
|
currentThinkId = "think-" + Date.now();
|
|
22607
22934
|
activeStreamingMsgRef.current = { id: currentThinkId, role: "think", text: "", isStreaming: true, startTime: Date.now() };
|
|
22608
|
-
|
|
22935
|
+
if (afterText.match(/<\/(think|thought)>/i)) {
|
|
22936
|
+
const parts = afterText.split(/<\/(think|thought)>/i);
|
|
22937
|
+
const rawThinkContent = parts[0] || "";
|
|
22938
|
+
const thinkContent = rawThinkContent.replace(/^<(think|thought)>/i, "");
|
|
22939
|
+
const agentContent = parts.slice(2).join("").replace(/<\/?(think|thought)>/gi, "");
|
|
22940
|
+
activeStreamingMsgRef.current.text = flattenString(thinkContent);
|
|
22941
|
+
const startTime = activeStreamingMsgRef.current.startTime || Date.now();
|
|
22942
|
+
activeStreamingMsgRef.current.duration = Date.now() - startTime;
|
|
22943
|
+
commitActiveStreamingMessage();
|
|
22944
|
+
inThinkMode = false;
|
|
22945
|
+
currentAgentId = "agent-" + Date.now();
|
|
22946
|
+
activeStreamingMsgRef.current = { id: currentAgentId, role: "agent", text: "", isStreaming: true };
|
|
22947
|
+
if (agentContent) {
|
|
22948
|
+
appendStreamText(agentContent);
|
|
22949
|
+
}
|
|
22950
|
+
} else {
|
|
22951
|
+
let thinkStartText = afterText.replace(/^<(think|thought)>/gi, "");
|
|
22952
|
+
appendStreamText(thinkStartText);
|
|
22953
|
+
}
|
|
22609
22954
|
continue;
|
|
22610
22955
|
}
|
|
22611
22956
|
if ((chunkLower.includes("</think>") || chunkLower.includes("</thought>")) && activeStreamingMsgRef.current?.role === "think") {
|
|
@@ -24238,11 +24583,11 @@ var init_app = __esm({
|
|
|
24238
24583
|
if (process.platform === "win32") {
|
|
24239
24584
|
const appData = process.env.APPDATA;
|
|
24240
24585
|
if (!appData) return null;
|
|
24241
|
-
return
|
|
24586
|
+
return path27.join(appData, dirName, "User", "keybindings.json");
|
|
24242
24587
|
} else if (process.platform === "darwin") {
|
|
24243
|
-
return
|
|
24588
|
+
return path27.join(home, "Library", "Application Support", dirName, "User", "keybindings.json");
|
|
24244
24589
|
} else {
|
|
24245
|
-
return
|
|
24590
|
+
return path27.join(home, ".config", dirName, "User", "keybindings.json");
|
|
24246
24591
|
}
|
|
24247
24592
|
};
|
|
24248
24593
|
parseJsonc = (content) => {
|
|
@@ -24286,8 +24631,8 @@ var init_app = __esm({
|
|
|
24286
24631
|
SESSION_START_TIME = Date.now();
|
|
24287
24632
|
CHANGELOG_URL = "https://fluxflow-cli.onrender.com/changelog";
|
|
24288
24633
|
DOCS_URL = "https://fluxflow-cli.onrender.com/";
|
|
24289
|
-
packageJsonPath =
|
|
24290
|
-
packageJson = JSON.parse(
|
|
24634
|
+
packageJsonPath = path27.join(path27.dirname(fileURLToPath3(import.meta.url)), "../package.json");
|
|
24635
|
+
packageJson = JSON.parse(fs29.readFileSync(packageJsonPath, "utf8"));
|
|
24291
24636
|
versionFluxflow = packageJson.version;
|
|
24292
24637
|
updatedOn = packageJson.date || "2026-05-20";
|
|
24293
24638
|
ResolutionModal = ({ data, onResolve, onEdit, theme = "Dark" }) => {
|
|
@@ -24321,20 +24666,20 @@ var init_app = __esm({
|
|
|
24321
24666
|
const scan = (currentDir) => {
|
|
24322
24667
|
if (fileList.length >= 2e3) return;
|
|
24323
24668
|
try {
|
|
24324
|
-
const files =
|
|
24669
|
+
const files = fs29.readdirSync(currentDir);
|
|
24325
24670
|
for (const file of files) {
|
|
24326
24671
|
if (fileList.length >= 2e3) return;
|
|
24327
24672
|
if (["node_modules", ".git", ".gemini", "dist", "build", ".next", ".cache", "out"].includes(file)) {
|
|
24328
24673
|
continue;
|
|
24329
24674
|
}
|
|
24330
|
-
const filePath =
|
|
24331
|
-
const stat =
|
|
24675
|
+
const filePath = path27.join(currentDir, file);
|
|
24676
|
+
const stat = fs29.statSync(filePath);
|
|
24332
24677
|
if (stat.isDirectory()) {
|
|
24333
24678
|
scan(filePath);
|
|
24334
24679
|
} else {
|
|
24335
24680
|
fileList.push({
|
|
24336
24681
|
name: flattenString(file),
|
|
24337
|
-
relativePath: flattenString(
|
|
24682
|
+
relativePath: flattenString(path27.relative(process.cwd(), filePath))
|
|
24338
24683
|
});
|
|
24339
24684
|
}
|
|
24340
24685
|
}
|
|
@@ -24534,11 +24879,11 @@ if (isBundled && !process.execArgv.some((arg) => arg.includes("max-old-space-siz
|
|
|
24534
24879
|
const isUpdate = args[0] === "--update";
|
|
24535
24880
|
const isExport = args[0] === "--export";
|
|
24536
24881
|
if (isVersion || isHelp || isHelpCommands || isUpdate || isExport) {
|
|
24537
|
-
const
|
|
24538
|
-
const
|
|
24882
|
+
const fs30 = await import("fs");
|
|
24883
|
+
const path28 = await import("path");
|
|
24539
24884
|
const { fileURLToPath: fileURLToPath5 } = await import("url");
|
|
24540
|
-
const packageJsonPath2 =
|
|
24541
|
-
const packageJson2 = JSON.parse(
|
|
24885
|
+
const packageJsonPath2 = path28.join(path28.dirname(fileURLToPath5(import.meta.url)), "../package.json");
|
|
24886
|
+
const packageJson2 = JSON.parse(fs30.readFileSync(packageJsonPath2, "utf8"));
|
|
24542
24887
|
const versionFluxflow2 = packageJson2.version;
|
|
24543
24888
|
if (isExport) {
|
|
24544
24889
|
const subArg = (args[1] || "").toLowerCase();
|