fluxflow-cli 3.8.0 → 3.9.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 +457 -269
- package/package.json +1 -1
package/dist/fluxflow.js
CHANGED
|
@@ -5346,7 +5346,7 @@ ${mode === "Flux" ? "- **File Tools >> Code in chat**\n\n" : ""}- COMMUNICATION
|
|
|
5346
5346
|
1. [tool:functions.Ask(question="...", optionA="option::description", ...MAX 4)]. Ambiguity Resolution. Mandatory Triggers: Path Divergence, Security, Risk Mitigation. ask >> finish/guess. Suggest best options; don't ask for preferences. 'option' SHOULD be short
|
|
5347
5347
|
|
|
5348
5348
|
- WEB TOOLS -
|
|
5349
|
-
1. [tool:functions.WebSearch(query="...", limit=number)]. Limit 3-10. Proactive use for unknown info/docs
|
|
5349
|
+
1. [tool:functions.WebSearch(query="...", aiMode="true optional", limit=number)]. Limit 3-10 (not needed with aiMode). Proactive use for unknown info/docs. DON'T hallucinate. aiMode for LLM based search results and richer data, default: false
|
|
5350
5350
|
2. [tool:functions.WebScrape(url="...")]. Proactive use for specific webpage/docs/api
|
|
5351
5351
|
|
|
5352
5352
|
${mode === "Flux" ? `- WORKSPACE TOOLS (path = relative to CWD & WILL BE FIRST ARGUMENT, path separator: '/') -
|
|
@@ -8276,6 +8276,8 @@ var init_puppeteer_helper = __esm({
|
|
|
8276
8276
|
|
|
8277
8277
|
// src/tools/web_search.js
|
|
8278
8278
|
import puppeteer from "puppeteer";
|
|
8279
|
+
import fs11 from "fs";
|
|
8280
|
+
import path10 from "path";
|
|
8279
8281
|
var web_search;
|
|
8280
8282
|
var init_web_search = __esm({
|
|
8281
8283
|
"src/tools/web_search.js"() {
|
|
@@ -8283,10 +8285,156 @@ var init_web_search = __esm({
|
|
|
8283
8285
|
init_paths();
|
|
8284
8286
|
init_puppeteer_helper();
|
|
8285
8287
|
web_search = async (argsString) => {
|
|
8286
|
-
const { query, limit = 10 } = parseArgs(argsString);
|
|
8288
|
+
const { query, limit = 10, aiMode = false } = parseArgs(argsString);
|
|
8287
8289
|
if (!query) return 'ERROR: Missing "query" argument for web_search.';
|
|
8288
8290
|
const maxRetries = 3;
|
|
8289
8291
|
let lastError = null;
|
|
8292
|
+
if (aiMode) {
|
|
8293
|
+
const aiPrompt = `Query: ${query}
|
|
8294
|
+
|
|
8295
|
+
RESPONSE RULES:
|
|
8296
|
+
- ANSWER CONCISELY WITH REQUIRED DETAILS UNDER 300 WORDS.
|
|
8297
|
+
- DO NOT CITE, REFERENCE, OR MENTION SOURCES ANYWHERE BETWEEN THE MAIN RESPONSE.
|
|
8298
|
+
- DO NOT USE MARKDOWN EXCEPT FOR THE SOURCES SECTION BELOW.
|
|
8299
|
+
- END THE RESPONSE WITH EXACTLY:
|
|
8300
|
+
|
|
8301
|
+
Sources:
|
|
8302
|
+
- <URL 1>
|
|
8303
|
+
- <URL 2>
|
|
8304
|
+
- <URL 3>
|
|
8305
|
+
|
|
8306
|
+
- LIST ONE RAW URL PER BULLET.
|
|
8307
|
+
- DO NOT USE MARKDOWN LINKS.
|
|
8308
|
+
- DO NOT INCLUDE ANY TEXT, NOTES, OR EXPLANATIONS AFTER THE SOURCES SECTION.`;
|
|
8309
|
+
for (let attempt = 1; attempt <= maxRetries; attempt++) {
|
|
8310
|
+
let browser = null;
|
|
8311
|
+
try {
|
|
8312
|
+
const pptrConfig = getPuppeteerConfig();
|
|
8313
|
+
browser = await puppeteer.launch({
|
|
8314
|
+
headless: true,
|
|
8315
|
+
executablePath: pptrConfig.executablePath || void 0,
|
|
8316
|
+
args: [
|
|
8317
|
+
"--no-sandbox",
|
|
8318
|
+
"--disable-setuid-sandbox",
|
|
8319
|
+
"--disable-gpu",
|
|
8320
|
+
"--disable-dev-shm-usage"
|
|
8321
|
+
]
|
|
8322
|
+
});
|
|
8323
|
+
const page = await browser.newPage();
|
|
8324
|
+
await page.setUserAgent("Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/148.0.7778.178 Safari/537.36");
|
|
8325
|
+
await page.setViewport({ width: 1366, height: 768 });
|
|
8326
|
+
const jitter = attempt === 1 ? Math.random() * 1e3 + 500 : Math.random() * 2e3 + 1e3;
|
|
8327
|
+
await new Promise((r) => setTimeout(r, jitter));
|
|
8328
|
+
const searchUrl = `https://search.brave.com/ask?q=${encodeURIComponent(aiPrompt)}&source=web`;
|
|
8329
|
+
await page.goto(searchUrl, { waitUntil: "domcontentloaded", timeout: 18e4 });
|
|
8330
|
+
let extractedData = null;
|
|
8331
|
+
const maxWaitMs = 45e3;
|
|
8332
|
+
const startTime = Date.now();
|
|
8333
|
+
while (Date.now() - startTime < maxWaitMs) {
|
|
8334
|
+
extractedData = await page.evaluate(() => {
|
|
8335
|
+
const assistantMsgs = Array.from(document.querySelectorAll('.message:not(.user), .answer-text, .llm-content, [data-type="answer"]'));
|
|
8336
|
+
let text = "";
|
|
8337
|
+
if (assistantMsgs.length > 0) {
|
|
8338
|
+
text = assistantMsgs.map((m) => m.innerText.trim()).filter(Boolean).join("\n\n");
|
|
8339
|
+
}
|
|
8340
|
+
if (!text) {
|
|
8341
|
+
text = document.body.innerText;
|
|
8342
|
+
}
|
|
8343
|
+
if (text.includes("anomaly")) throw new Error("ANOMALY_DETECTED");
|
|
8344
|
+
const isStreaming = Boolean(
|
|
8345
|
+
document.querySelector('.spinner, .loading, .typing, .streaming, [data-streaming="true"], [data-state="loading"], svg.animate-spin, circle[cx], div[class*="spin"]')
|
|
8346
|
+
);
|
|
8347
|
+
const assistantEl = assistantMsgs[0] || document.body;
|
|
8348
|
+
const assistantText = assistantEl ? assistantEl.innerText.trim() : "";
|
|
8349
|
+
const hasFinishedText = /^(?:[✓✔]\s*)?Finished/i.test(assistantText) || Boolean(assistantEl && assistantEl.querySelector(".status-finished, .finished"));
|
|
8350
|
+
const isFinished = !isStreaming && (hasFinishedText || text.includes("Sources:") && !isStreaming);
|
|
8351
|
+
const hrefMap2 = {};
|
|
8352
|
+
document.querySelectorAll("a[href]").forEach((a) => {
|
|
8353
|
+
let href = a.getAttribute("href") || a.href || "";
|
|
8354
|
+
if (href.includes("uddg=")) href = decodeURIComponent(href.split("uddg=")[1].split("&")[0]);
|
|
8355
|
+
if (href.includes("url=")) href = decodeURIComponent(href.split("url=")[1].split("&")[0]);
|
|
8356
|
+
if (href && (href.startsWith("http://") || href.startsWith("https://")) && !href.includes("search.brave.com")) {
|
|
8357
|
+
const linkText = a.innerText.trim();
|
|
8358
|
+
if (linkText) hrefMap2[linkText] = href;
|
|
8359
|
+
a.textContent = href;
|
|
8360
|
+
}
|
|
8361
|
+
});
|
|
8362
|
+
return { isFinished, text, hrefMap: hrefMap2 };
|
|
8363
|
+
});
|
|
8364
|
+
if (extractedData && extractedData.isFinished) {
|
|
8365
|
+
break;
|
|
8366
|
+
}
|
|
8367
|
+
await new Promise((r) => setTimeout(r, 1e3));
|
|
8368
|
+
}
|
|
8369
|
+
let rawText = (extractedData ? extractedData.text : "") || "";
|
|
8370
|
+
const hrefMap = extractedData ? extractedData.hrefMap || {} : {};
|
|
8371
|
+
const promptMarker = "DO NOT INCLUDE ANY TEXT, NOTES, OR EXPLANATIONS AFTER THE SOURCES SECTION.";
|
|
8372
|
+
if (rawText.includes(promptMarker)) {
|
|
8373
|
+
rawText = rawText.split(promptMarker).pop();
|
|
8374
|
+
}
|
|
8375
|
+
rawText = rawText.replace(/^.*?(Ctrl \+ Shift \+ O|Ask\nAll\nImages)/s, "").replace(/AI-generated answer\. Please verify critical facts\..*/s, "").replace(/Brave Search uses private usage metrics.*/s, "");
|
|
8376
|
+
let mainPart = rawText;
|
|
8377
|
+
let sourcesPart = "";
|
|
8378
|
+
if (rawText.includes("Sources:")) {
|
|
8379
|
+
const parts = rawText.split("Sources:");
|
|
8380
|
+
mainPart = parts[0];
|
|
8381
|
+
sourcesPart = parts.slice(1).join("Sources:");
|
|
8382
|
+
}
|
|
8383
|
+
const cleanLines = [];
|
|
8384
|
+
for (let line of mainPart.split("\n")) {
|
|
8385
|
+
const trimmed = line.trim();
|
|
8386
|
+
if (!trimmed) continue;
|
|
8387
|
+
if (/^(View all|Finished|Searching|Answering|Thinking)$/i.test(trimmed)) continue;
|
|
8388
|
+
if (/^[\+\-]?\d+$/.test(trimmed)) continue;
|
|
8389
|
+
if (trimmed.includes("search.brave.com")) continue;
|
|
8390
|
+
if (trimmed.startsWith("https://www.youtube.com/watch") || trimmed.startsWith("https://youtube.com/watch")) continue;
|
|
8391
|
+
cleanLines.push(line);
|
|
8392
|
+
}
|
|
8393
|
+
let cleanMain = cleanLines.join("\n").replace(/^(?:[\+\-]?\d+\s*)+/i, "").replace(/\n{3,}/g, "\n\n").trim();
|
|
8394
|
+
const isIgnoredUrl = (u) => !u || u.includes("search.brave.com") || u.includes("youtube.com") || u.includes("youtu.be");
|
|
8395
|
+
let finalSources = "";
|
|
8396
|
+
if (sourcesPart) {
|
|
8397
|
+
const rawUrls = sourcesPart.match(/https?:\/\/[^\s\)\>]+/g) || [];
|
|
8398
|
+
const expandedUrls = [];
|
|
8399
|
+
for (let url of rawUrls) {
|
|
8400
|
+
let cleanUrl = url.replace(/[\.\,\;]+$/, "");
|
|
8401
|
+
const matchedKey = Object.keys(hrefMap).find((k) => k.startsWith(cleanUrl) || cleanUrl.startsWith(k));
|
|
8402
|
+
if (matchedKey && hrefMap[matchedKey]) {
|
|
8403
|
+
cleanUrl = hrefMap[matchedKey];
|
|
8404
|
+
}
|
|
8405
|
+
if (!isIgnoredUrl(cleanUrl)) {
|
|
8406
|
+
expandedUrls.push(cleanUrl);
|
|
8407
|
+
}
|
|
8408
|
+
}
|
|
8409
|
+
Object.values(hrefMap).forEach((url) => {
|
|
8410
|
+
if (!isIgnoredUrl(url) && !expandedUrls.includes(url)) {
|
|
8411
|
+
expandedUrls.push(url);
|
|
8412
|
+
}
|
|
8413
|
+
});
|
|
8414
|
+
const uniqueUrls = Array.from(new Set(expandedUrls));
|
|
8415
|
+
if (uniqueUrls.length > 0) {
|
|
8416
|
+
finalSources = "Sources:\n" + uniqueUrls.map((u) => `- ${u}`).join("\n");
|
|
8417
|
+
}
|
|
8418
|
+
}
|
|
8419
|
+
const aiResult = cleanMain + (finalSources ? "\n\n" + finalSources : "");
|
|
8420
|
+
if (!aiResult || /^(\+\d+|Searching|Answering|Thinking|Finished)$/i.test(aiResult)) {
|
|
8421
|
+
throw new Error("EMPTY_AI_RESPONSE");
|
|
8422
|
+
}
|
|
8423
|
+
await browser.close();
|
|
8424
|
+
return `AI Search results for [${query}]:
|
|
8425
|
+
|
|
8426
|
+
${aiResult}`;
|
|
8427
|
+
} catch (err) {
|
|
8428
|
+
lastError = err;
|
|
8429
|
+
fs11.writeFileSync(path10.join(LOGS_DIR, "web_tools", "search", "ai_mode", "ERROR.txt"), err.message);
|
|
8430
|
+
if (browser) await browser.close();
|
|
8431
|
+
if (attempt < maxRetries) {
|
|
8432
|
+
const backoff = Math.pow(2, attempt) * 1e3;
|
|
8433
|
+
await new Promise((r) => setTimeout(r, backoff));
|
|
8434
|
+
}
|
|
8435
|
+
}
|
|
8436
|
+
}
|
|
8437
|
+
}
|
|
8290
8438
|
for (let attempt = 1; attempt <= maxRetries; attempt++) {
|
|
8291
8439
|
let browser = null;
|
|
8292
8440
|
try {
|
|
@@ -8333,12 +8481,14 @@ Snippet: ${snippet}`;
|
|
|
8333
8481
|
}
|
|
8334
8482
|
const finalResults = results.join("\n\n");
|
|
8335
8483
|
await browser.close();
|
|
8336
|
-
|
|
8484
|
+
const prefix = aiMode ? "AI Mode temporarily failed, used Standard search.\n\n" : "";
|
|
8485
|
+
return `${prefix}Search results for [${query}]:
|
|
8337
8486
|
|
|
8338
8487
|
${finalResults}`;
|
|
8339
8488
|
} catch (err) {
|
|
8340
8489
|
lastError = err;
|
|
8341
8490
|
if (browser) await browser.close();
|
|
8491
|
+
fs11.writeFileSync(path10.join(LOGS_DIR, "web_tools", "search", "standard_mode", "ERROR.txt"), err.message);
|
|
8342
8492
|
if (attempt < maxRetries) {
|
|
8343
8493
|
const backoff = Math.pow(2, attempt) * 1e3;
|
|
8344
8494
|
await new Promise((r) => setTimeout(r, backoff));
|
|
@@ -8352,6 +8502,8 @@ ${finalResults}`;
|
|
|
8352
8502
|
|
|
8353
8503
|
// src/tools/web_scrape.js
|
|
8354
8504
|
import puppeteer2 from "puppeteer";
|
|
8505
|
+
import fs12 from "fs";
|
|
8506
|
+
import path11 from "path";
|
|
8355
8507
|
var web_scrape;
|
|
8356
8508
|
var init_web_scrape = __esm({
|
|
8357
8509
|
"src/tools/web_scrape.js"() {
|
|
@@ -8428,6 +8580,7 @@ ${cleanedHtml}${htmlContent.length > 5e4 ? "\n\n[TRUNCATED AT 50K CHARS]" : ""}`
|
|
|
8428
8580
|
} catch (err) {
|
|
8429
8581
|
lastError = err;
|
|
8430
8582
|
if (browser) await browser.close();
|
|
8583
|
+
fs12.writeFileSync(path11.join(LOGS_DIR, "web_tools", "scrape", "standard_mode", "ERROR.txt"), err.message);
|
|
8431
8584
|
if (attempt < maxRetries) {
|
|
8432
8585
|
const backoff = Math.pow(2, attempt) * 1e3;
|
|
8433
8586
|
await new Promise((r) => setTimeout(r, backoff));
|
|
@@ -8551,8 +8704,8 @@ var init_chat = __esm({
|
|
|
8551
8704
|
});
|
|
8552
8705
|
|
|
8553
8706
|
// src/tools/view_file.js
|
|
8554
|
-
import
|
|
8555
|
-
import
|
|
8707
|
+
import fs13 from "fs";
|
|
8708
|
+
import path12 from "path";
|
|
8556
8709
|
var view_file;
|
|
8557
8710
|
var init_view_file = __esm({
|
|
8558
8711
|
"src/tools/view_file.js"() {
|
|
@@ -8564,16 +8717,16 @@ var init_view_file = __esm({
|
|
|
8564
8717
|
const finalStart = sLine || 1;
|
|
8565
8718
|
const finalEnd = eLine || (sLine ? sLine + 800 : 800);
|
|
8566
8719
|
if (!targetPath) return 'ERROR: Missing "path" argument for view_file.';
|
|
8567
|
-
const absolutePath =
|
|
8720
|
+
const absolutePath = path12.resolve(process.cwd(), targetPath);
|
|
8568
8721
|
try {
|
|
8569
|
-
if (!
|
|
8722
|
+
if (!fs13.existsSync(absolutePath)) {
|
|
8570
8723
|
return `ERROR: File [${targetPath}] does not exist.`;
|
|
8571
8724
|
}
|
|
8572
|
-
const stats =
|
|
8725
|
+
const stats = fs13.statSync(absolutePath);
|
|
8573
8726
|
if (stats.isDirectory()) {
|
|
8574
8727
|
return `ERROR: Path [${targetPath}] is a directory. Use list_files instead.`;
|
|
8575
8728
|
}
|
|
8576
|
-
const ext =
|
|
8729
|
+
const ext = path12.extname(targetPath).toLowerCase();
|
|
8577
8730
|
const videoExtensions = [".mp4", ".mkv", ".avi", ".mov", ".webm", ".flv", ".wmv", ".mpeg", ".mpg"];
|
|
8578
8731
|
if (videoExtensions.includes(ext)) {
|
|
8579
8732
|
const format = ext.slice(1).toUpperCase();
|
|
@@ -8593,7 +8746,7 @@ var init_view_file = __esm({
|
|
|
8593
8746
|
if (!isMultiModal) {
|
|
8594
8747
|
return `ERROR: Multimodality is not supported for the current model. Unable to load [${targetPath}].`;
|
|
8595
8748
|
}
|
|
8596
|
-
const buffer =
|
|
8749
|
+
const buffer = fs13.readFileSync(absolutePath);
|
|
8597
8750
|
const base64 = buffer.toString("base64");
|
|
8598
8751
|
const mimeType = mimeMap[ext];
|
|
8599
8752
|
return {
|
|
@@ -8606,7 +8759,7 @@ var init_view_file = __esm({
|
|
|
8606
8759
|
}
|
|
8607
8760
|
};
|
|
8608
8761
|
}
|
|
8609
|
-
let content =
|
|
8762
|
+
let content = fs13.readFileSync(absolutePath, "utf8");
|
|
8610
8763
|
if (content.startsWith("\uFEFF")) {
|
|
8611
8764
|
content = content.slice(1);
|
|
8612
8765
|
}
|
|
@@ -8630,8 +8783,8 @@ ${code}`;
|
|
|
8630
8783
|
});
|
|
8631
8784
|
|
|
8632
8785
|
// src/tools/write_file.js
|
|
8633
|
-
import
|
|
8634
|
-
import
|
|
8786
|
+
import fs14 from "fs";
|
|
8787
|
+
import path13 from "path";
|
|
8635
8788
|
var write_file;
|
|
8636
8789
|
var init_write_file = __esm({
|
|
8637
8790
|
"src/tools/write_file.js"() {
|
|
@@ -8642,14 +8795,14 @@ var init_write_file = __esm({
|
|
|
8642
8795
|
if (!targetPath) return 'ERROR: Missing "path" argument for write_file.';
|
|
8643
8796
|
if (content === void 0) return 'ERROR: Missing "content" argument for write_file.';
|
|
8644
8797
|
content = content.replace(/^```[\w]*\n?/, "").replace(/```\s*$/, "").replace(/\r\n/g, "\n").replace(/\r/g, "\n");
|
|
8645
|
-
const absolutePath =
|
|
8646
|
-
const parentDir =
|
|
8798
|
+
const absolutePath = path13.resolve(process.cwd(), targetPath);
|
|
8799
|
+
const parentDir = path13.dirname(absolutePath);
|
|
8647
8800
|
try {
|
|
8648
8801
|
await RevertManager.recordFileChange(absolutePath);
|
|
8649
8802
|
let ancestry = "";
|
|
8650
|
-
if (
|
|
8803
|
+
if (fs14.existsSync(absolutePath)) {
|
|
8651
8804
|
try {
|
|
8652
|
-
const oldData =
|
|
8805
|
+
const oldData = fs14.readFileSync(absolutePath, "utf8");
|
|
8653
8806
|
const lines = oldData.split(/\r?\n/);
|
|
8654
8807
|
ancestry = `Old File contents:
|
|
8655
8808
|
${lines.map((l, i) => `${i + 1} | ${l}`).join("\n")}
|
|
@@ -8661,16 +8814,16 @@ ${lines.map((l, i) => `${i + 1} | ${l}`).join("\n")}
|
|
|
8661
8814
|
`;
|
|
8662
8815
|
}
|
|
8663
8816
|
}
|
|
8664
|
-
if (!
|
|
8665
|
-
|
|
8817
|
+
if (!fs14.existsSync(parentDir)) {
|
|
8818
|
+
fs14.mkdirSync(parentDir, { recursive: true });
|
|
8666
8819
|
}
|
|
8667
8820
|
const strip = (t) => t.replace(/^```[\w]*\n?/, "").replace(/```\s*$/, "").replace(/\r\n/g, "\n").replace(/\r/g, "\n");
|
|
8668
8821
|
const processedContent = strip(content);
|
|
8669
8822
|
const finalContent = processedContent.endsWith("\n") ? processedContent : processedContent + "\n";
|
|
8670
8823
|
const lineCount = finalContent.split(/\r?\n/).length;
|
|
8671
8824
|
const originalSize = Buffer.byteLength(finalContent, "utf8");
|
|
8672
|
-
|
|
8673
|
-
let verifiedContent =
|
|
8825
|
+
fs14.writeFileSync(absolutePath, finalContent, "utf8");
|
|
8826
|
+
let verifiedContent = fs14.readFileSync(absolutePath, "utf8");
|
|
8674
8827
|
const verifiedSize = Buffer.byteLength(verifiedContent, "utf8");
|
|
8675
8828
|
const verifiedLines = verifiedContent.split(/\r?\n/);
|
|
8676
8829
|
const verifiedLineCount = verifiedLines.length;
|
|
@@ -8705,8 +8858,8 @@ ${snippet}`;
|
|
|
8705
8858
|
});
|
|
8706
8859
|
|
|
8707
8860
|
// src/tools/update_file.js
|
|
8708
|
-
import
|
|
8709
|
-
import
|
|
8861
|
+
import fs15 from "fs";
|
|
8862
|
+
import path14 from "path";
|
|
8710
8863
|
var update_file;
|
|
8711
8864
|
var init_update_file = __esm({
|
|
8712
8865
|
"src/tools/update_file.js"() {
|
|
@@ -8722,12 +8875,12 @@ var init_update_file = __esm({
|
|
|
8722
8875
|
if (patchPairs.length === 0) {
|
|
8723
8876
|
return "ERROR: No valid replacement pairs found. Use replaceContent1, newContent1, etc.";
|
|
8724
8877
|
}
|
|
8725
|
-
const absolutePath =
|
|
8878
|
+
const absolutePath = path14.resolve(process.cwd(), targetPath);
|
|
8726
8879
|
try {
|
|
8727
|
-
if (!
|
|
8880
|
+
if (!fs15.existsSync(absolutePath)) {
|
|
8728
8881
|
return `ERROR: File [${targetPath}] does not exist. Use write_file instead.`;
|
|
8729
8882
|
}
|
|
8730
|
-
let diskContent = context.forcedContent ||
|
|
8883
|
+
let diskContent = context.forcedContent || fs15.readFileSync(absolutePath, "utf8");
|
|
8731
8884
|
if (diskContent.startsWith("\uFEFF")) diskContent = diskContent.slice(1);
|
|
8732
8885
|
const originalContent = diskContent.replace(/\r\n/g, "\n").replace(/\r/g, "\n");
|
|
8733
8886
|
const { content: finalContent, results } = applyPatches(originalContent, patchPairs);
|
|
@@ -8738,7 +8891,7 @@ var init_update_file = __esm({
|
|
|
8738
8891
|
${failures.map((f) => ` \u2022 ${f.error}`).join("\n")}`;
|
|
8739
8892
|
}
|
|
8740
8893
|
await RevertManager.recordFileChange(absolutePath, originalContent);
|
|
8741
|
-
|
|
8894
|
+
fs15.writeFileSync(absolutePath, finalContent, "utf8");
|
|
8742
8895
|
const diffText = generateHighFidelityDiff(originalContent, finalContent, results, 12);
|
|
8743
8896
|
if (failures.length > 0) {
|
|
8744
8897
|
return `SUCCESS: File [${targetPath}] updated with some blocks failed. [${successes.length}/${patchPairs.length}] blocks applied.
|
|
@@ -8760,34 +8913,34 @@ ${diffText}`;
|
|
|
8760
8913
|
});
|
|
8761
8914
|
|
|
8762
8915
|
// src/tools/read_folder.js
|
|
8763
|
-
import
|
|
8764
|
-
import
|
|
8916
|
+
import fs16 from "fs";
|
|
8917
|
+
import path15 from "path";
|
|
8765
8918
|
var read_folder;
|
|
8766
8919
|
var init_read_folder = __esm({
|
|
8767
8920
|
"src/tools/read_folder.js"() {
|
|
8768
8921
|
init_arg_parser();
|
|
8769
8922
|
read_folder = async (args) => {
|
|
8770
8923
|
const { path: targetPath = "." } = parseArgs(args);
|
|
8771
|
-
const absolutePath =
|
|
8924
|
+
const absolutePath = path15.resolve(process.cwd(), targetPath);
|
|
8772
8925
|
try {
|
|
8773
|
-
if (!
|
|
8926
|
+
if (!fs16.existsSync(absolutePath)) {
|
|
8774
8927
|
return `ERROR: Path [${targetPath}] does not exist.`;
|
|
8775
8928
|
}
|
|
8776
|
-
const stats =
|
|
8929
|
+
const stats = fs16.statSync(absolutePath);
|
|
8777
8930
|
if (!stats.isDirectory()) {
|
|
8778
8931
|
return `ERROR: Path [${targetPath}] is a file, not a directory. Use view_file instead.`;
|
|
8779
8932
|
}
|
|
8780
|
-
const files =
|
|
8933
|
+
const files = fs16.readdirSync(absolutePath);
|
|
8781
8934
|
const totalItems = files.length;
|
|
8782
8935
|
const maxDisplay = 100;
|
|
8783
8936
|
const displayItems = files.slice(0, maxDisplay);
|
|
8784
8937
|
const folderData = [];
|
|
8785
8938
|
for (const file of displayItems) {
|
|
8786
|
-
const fPath =
|
|
8939
|
+
const fPath = path15.join(absolutePath, file);
|
|
8787
8940
|
let indicator = "\u{1F4C4}";
|
|
8788
8941
|
let info = { name: file, type: "unknown", size: "N/A", mtime: "N/A" };
|
|
8789
8942
|
try {
|
|
8790
|
-
const fStats =
|
|
8943
|
+
const fStats = fs16.statSync(fPath);
|
|
8791
8944
|
info = {
|
|
8792
8945
|
name: file,
|
|
8793
8946
|
type: fStats.isDirectory() ? "directory" : "file",
|
|
@@ -8872,8 +9025,8 @@ var init_ask_user = __esm({
|
|
|
8872
9025
|
|
|
8873
9026
|
// src/tools/write_pdf.js
|
|
8874
9027
|
import puppeteer3 from "puppeteer";
|
|
8875
|
-
import
|
|
8876
|
-
import
|
|
9028
|
+
import path16 from "path";
|
|
9029
|
+
import fs17 from "fs-extra";
|
|
8877
9030
|
import { PDFDocument } from "pdf-lib";
|
|
8878
9031
|
var write_pdf;
|
|
8879
9032
|
var init_write_pdf = __esm({
|
|
@@ -8890,10 +9043,10 @@ var init_write_pdf = __esm({
|
|
|
8890
9043
|
} = parseArgs(args);
|
|
8891
9044
|
if (!targetPath) return 'ERROR: Missing "path" argument for write_pdf.';
|
|
8892
9045
|
if (!content) return 'ERROR: Missing "content" (HTML/CSS) for write_pdf.';
|
|
8893
|
-
const absolutePath =
|
|
9046
|
+
const absolutePath = path16.resolve(process.cwd(), targetPath);
|
|
8894
9047
|
let browser = null;
|
|
8895
9048
|
try {
|
|
8896
|
-
await
|
|
9049
|
+
await fs17.ensureDir(path16.dirname(absolutePath));
|
|
8897
9050
|
await RevertManager.recordFileChange(absolutePath);
|
|
8898
9051
|
const pptrConfig = getPuppeteerConfig();
|
|
8899
9052
|
browser = await puppeteer3.launch({
|
|
@@ -8914,11 +9067,11 @@ var init_write_pdf = __esm({
|
|
|
8914
9067
|
return null;
|
|
8915
9068
|
}
|
|
8916
9069
|
try {
|
|
8917
|
-
const imgPath =
|
|
8918
|
-
if (await
|
|
8919
|
-
const ext =
|
|
9070
|
+
const imgPath = path16.resolve(process.cwd(), originalSrc);
|
|
9071
|
+
if (await fs17.pathExists(imgPath)) {
|
|
9072
|
+
const ext = path16.extname(imgPath).toLowerCase().replace(".", "") || "png";
|
|
8920
9073
|
const mime = ext === "jpg" ? "jpeg" : ext === "svg" ? "svg+xml" : ext;
|
|
8921
|
-
const base64 = await
|
|
9074
|
+
const base64 = await fs17.readFile(imgPath, "base64");
|
|
8922
9075
|
return `data:image/${mime};base64,${base64}`;
|
|
8923
9076
|
}
|
|
8924
9077
|
} catch (e) {
|
|
@@ -8933,9 +9086,9 @@ var init_write_pdf = __esm({
|
|
|
8933
9086
|
const fullTag = match[0];
|
|
8934
9087
|
if (originalHref && fullTag.toLowerCase().includes("stylesheet") && !originalHref.startsWith("http://") && !originalHref.startsWith("https://") && !originalHref.startsWith("data:")) {
|
|
8935
9088
|
try {
|
|
8936
|
-
const cssPath =
|
|
8937
|
-
if (await
|
|
8938
|
-
const cssContent = await
|
|
9089
|
+
const cssPath = path16.resolve(process.cwd(), originalHref);
|
|
9090
|
+
if (await fs17.pathExists(cssPath)) {
|
|
9091
|
+
const cssContent = await fs17.readFile(cssPath, "utf-8");
|
|
8939
9092
|
cssCache[fullTag] = `<style>${cssContent}</style>`;
|
|
8940
9093
|
}
|
|
8941
9094
|
} catch (e) {
|
|
@@ -9016,7 +9169,7 @@ var init_write_pdf = __esm({
|
|
|
9016
9169
|
printBackground: true
|
|
9017
9170
|
});
|
|
9018
9171
|
const pdfDoc = await PDFDocument.load(pdfBytes);
|
|
9019
|
-
const fileName =
|
|
9172
|
+
const fileName = path16.basename(targetPath);
|
|
9020
9173
|
pdfDoc.setTitle(`FluxFlow_${fileName}`);
|
|
9021
9174
|
pdfDoc.setAuthor("FluxFlow CLI");
|
|
9022
9175
|
pdfDoc.setSubject("Generated with Agentic AI System");
|
|
@@ -9024,8 +9177,8 @@ var init_write_pdf = __esm({
|
|
|
9024
9177
|
pdfDoc.setCreator("FluxFlow PDF Engine");
|
|
9025
9178
|
pdfDoc.setProducer("FluxFlow (Generative AI)");
|
|
9026
9179
|
const finalPdfBytes = await pdfDoc.save();
|
|
9027
|
-
await
|
|
9028
|
-
const stats = await
|
|
9180
|
+
await fs17.writeFile(absolutePath, finalPdfBytes);
|
|
9181
|
+
const stats = await fs17.stat(absolutePath);
|
|
9029
9182
|
return `SUCCESS: PDF generated successfully at [${targetPath}] (${(stats.size / 1024).toFixed(2)} KB).`;
|
|
9030
9183
|
} catch (err) {
|
|
9031
9184
|
const errorMsg = err instanceof Error ? err.message : String(err);
|
|
@@ -9038,8 +9191,8 @@ var init_write_pdf = __esm({
|
|
|
9038
9191
|
});
|
|
9039
9192
|
|
|
9040
9193
|
// src/tools/write_docx.js
|
|
9041
|
-
import
|
|
9042
|
-
import
|
|
9194
|
+
import fs18 from "fs-extra";
|
|
9195
|
+
import path17 from "path";
|
|
9043
9196
|
import HTMLtoDOCX from "html-to-docx";
|
|
9044
9197
|
var write_docx;
|
|
9045
9198
|
var init_write_docx = __esm({
|
|
@@ -9053,11 +9206,11 @@ var init_write_docx = __esm({
|
|
|
9053
9206
|
} = parseArgs(args);
|
|
9054
9207
|
if (!targetPath) return 'ERROR: Missing "path" argument for write_docx.';
|
|
9055
9208
|
if (!content) return 'ERROR: Missing "content" (HTML) for write_docx.';
|
|
9056
|
-
const absolutePath =
|
|
9209
|
+
const absolutePath = path17.resolve(process.cwd(), targetPath);
|
|
9057
9210
|
try {
|
|
9058
|
-
await
|
|
9211
|
+
await fs18.ensureDir(path17.dirname(absolutePath));
|
|
9059
9212
|
await RevertManager.recordFileChange(absolutePath);
|
|
9060
|
-
const fileName =
|
|
9213
|
+
const fileName = path17.basename(targetPath);
|
|
9061
9214
|
const fullHtml = content.includes("<html") ? content : `
|
|
9062
9215
|
<!DOCTYPE html>
|
|
9063
9216
|
<html lang="en">
|
|
@@ -9078,7 +9231,7 @@ var init_write_docx = __esm({
|
|
|
9078
9231
|
footer: true,
|
|
9079
9232
|
pageNumber: true
|
|
9080
9233
|
});
|
|
9081
|
-
await
|
|
9234
|
+
await fs18.writeFile(absolutePath, docxBuffer);
|
|
9082
9235
|
return `SUCCESS: Word document [${targetPath}] generated successfully.
|
|
9083
9236
|
- Size: ${(docxBuffer.length / 1024).toFixed(1)} KB`;
|
|
9084
9237
|
} catch (err) {
|
|
@@ -9090,21 +9243,21 @@ var init_write_docx = __esm({
|
|
|
9090
9243
|
});
|
|
9091
9244
|
|
|
9092
9245
|
// src/tools/search_keyword.js
|
|
9093
|
-
import
|
|
9094
|
-
import
|
|
9246
|
+
import fs19 from "fs/promises";
|
|
9247
|
+
import path18 from "path";
|
|
9095
9248
|
async function getFilesRecursively(dir, excludes, baseDir = dir, depth = 1) {
|
|
9096
9249
|
if (depth > 12) return [];
|
|
9097
9250
|
let results = [];
|
|
9098
9251
|
let list;
|
|
9099
9252
|
try {
|
|
9100
|
-
list = await
|
|
9253
|
+
list = await fs19.readdir(dir, { withFileTypes: true });
|
|
9101
9254
|
} catch {
|
|
9102
9255
|
return [];
|
|
9103
9256
|
}
|
|
9104
9257
|
for (const file of list) {
|
|
9105
|
-
const fullPath =
|
|
9106
|
-
const relativePath =
|
|
9107
|
-
const pathSegments = relativePath.split(
|
|
9258
|
+
const fullPath = path18.join(dir, file.name);
|
|
9259
|
+
const relativePath = path18.relative(baseDir, fullPath);
|
|
9260
|
+
const pathSegments = relativePath.split(path18.sep).map((s) => s.toLowerCase());
|
|
9108
9261
|
const isExcluded = excludes.some((ex) => pathSegments.includes(ex.toLowerCase()));
|
|
9109
9262
|
if (isExcluded) continue;
|
|
9110
9263
|
if (file.isDirectory()) {
|
|
@@ -9202,11 +9355,11 @@ var init_search_keyword = __esm({
|
|
|
9202
9355
|
let filesToSearch = [];
|
|
9203
9356
|
const rootDir = process.cwd();
|
|
9204
9357
|
if (file) {
|
|
9205
|
-
const fullPath =
|
|
9358
|
+
const fullPath = path18.resolve(rootDir, file);
|
|
9206
9359
|
try {
|
|
9207
|
-
const stat = await
|
|
9360
|
+
const stat = await fs19.stat(fullPath);
|
|
9208
9361
|
if (stat.isFile()) {
|
|
9209
|
-
filesToSearch.push({ fullPath, relativePath:
|
|
9362
|
+
filesToSearch.push({ fullPath, relativePath: path18.relative(rootDir, fullPath) });
|
|
9210
9363
|
}
|
|
9211
9364
|
} catch {
|
|
9212
9365
|
return `ERROR: File not found: ${file}`;
|
|
@@ -9216,7 +9369,7 @@ var init_search_keyword = __esm({
|
|
|
9216
9369
|
}
|
|
9217
9370
|
const searchPromises = filesToSearch.map(async (fileObj) => {
|
|
9218
9371
|
try {
|
|
9219
|
-
const content = await
|
|
9372
|
+
const content = await fs19.readFile(fileObj.fullPath, "utf-8");
|
|
9220
9373
|
if (content.includes("\0")) return [];
|
|
9221
9374
|
const lines = content.split(/\r?\n/);
|
|
9222
9375
|
const fileMatches = [];
|
|
@@ -9274,8 +9427,8 @@ var init_search_keyword = __esm({
|
|
|
9274
9427
|
});
|
|
9275
9428
|
|
|
9276
9429
|
// src/tools/generate_image.js
|
|
9277
|
-
import
|
|
9278
|
-
import
|
|
9430
|
+
import fs20 from "fs-extra";
|
|
9431
|
+
import path19 from "path";
|
|
9279
9432
|
var injectPngMetadata, generate_image;
|
|
9280
9433
|
var init_generate_image = __esm({
|
|
9281
9434
|
"src/tools/generate_image.js"() {
|
|
@@ -9454,12 +9607,12 @@ var init_generate_image = __esm({
|
|
|
9454
9607
|
"Seed": String(seed)
|
|
9455
9608
|
};
|
|
9456
9609
|
finalBuffer = injectPngMetadata(finalBuffer, metadata);
|
|
9457
|
-
const absolutePath =
|
|
9458
|
-
await
|
|
9610
|
+
const absolutePath = path19.resolve(process.cwd(), outputPath);
|
|
9611
|
+
await fs20.ensureDir(path19.dirname(absolutePath));
|
|
9459
9612
|
await RevertManager.recordFileChange(absolutePath);
|
|
9460
|
-
await
|
|
9613
|
+
await fs20.writeFile(absolutePath, finalBuffer);
|
|
9461
9614
|
await recordImageGeneration(settings);
|
|
9462
|
-
const ext =
|
|
9615
|
+
const ext = path19.extname(outputPath).toLowerCase();
|
|
9463
9616
|
const mimeMap = {
|
|
9464
9617
|
".jpg": "image/jpeg",
|
|
9465
9618
|
".jpeg": "image/jpeg",
|
|
@@ -9574,13 +9727,13 @@ var init_addMemScore = __esm({
|
|
|
9574
9727
|
});
|
|
9575
9728
|
|
|
9576
9729
|
// src/utils/parsers.js
|
|
9577
|
-
import
|
|
9578
|
-
import
|
|
9730
|
+
import fs21 from "fs-extra";
|
|
9731
|
+
import path20 from "path";
|
|
9579
9732
|
import https from "https";
|
|
9580
9733
|
async function downloadWasm(wasmFile, targetUrl = null) {
|
|
9581
9734
|
const url = targetUrl || `https://unpkg.com/tree-sitter-wasms@0.1.13/out/${wasmFile}`;
|
|
9582
|
-
const localPath =
|
|
9583
|
-
await
|
|
9735
|
+
const localPath = path20.join(PARSER_DIR, wasmFile);
|
|
9736
|
+
await fs21.ensureDir(PARSER_DIR);
|
|
9584
9737
|
return new Promise((resolve, reject) => {
|
|
9585
9738
|
const options = {
|
|
9586
9739
|
headers: {
|
|
@@ -9601,27 +9754,27 @@ async function downloadWasm(wasmFile, targetUrl = null) {
|
|
|
9601
9754
|
reject(new Error(`Failed to download ${wasmFile}: HTTP ${response.statusCode}`));
|
|
9602
9755
|
return;
|
|
9603
9756
|
}
|
|
9604
|
-
const file =
|
|
9757
|
+
const file = fs21.createWriteStream(localPath);
|
|
9605
9758
|
response.pipe(file);
|
|
9606
9759
|
file.on("finish", () => {
|
|
9607
9760
|
file.close();
|
|
9608
9761
|
resolve();
|
|
9609
9762
|
});
|
|
9610
9763
|
}).on("error", (err) => {
|
|
9611
|
-
if (
|
|
9764
|
+
if (fs21.existsSync(localPath)) fs21.unlink(localPath, () => {
|
|
9612
9765
|
});
|
|
9613
9766
|
reject(err);
|
|
9614
9767
|
});
|
|
9615
9768
|
});
|
|
9616
9769
|
}
|
|
9617
9770
|
function isParserInstalled(wasmFile) {
|
|
9618
|
-
const localPath =
|
|
9619
|
-
return
|
|
9771
|
+
const localPath = path20.join(PARSER_DIR, wasmFile);
|
|
9772
|
+
return fs21.existsSync(localPath);
|
|
9620
9773
|
}
|
|
9621
9774
|
async function deleteParser(wasmFile) {
|
|
9622
|
-
const localPath =
|
|
9623
|
-
if (
|
|
9624
|
-
await
|
|
9775
|
+
const localPath = path20.join(PARSER_DIR, wasmFile);
|
|
9776
|
+
if (fs21.existsSync(localPath)) {
|
|
9777
|
+
await fs21.unlink(localPath);
|
|
9625
9778
|
}
|
|
9626
9779
|
}
|
|
9627
9780
|
var EXTENSION_TO_WASM;
|
|
@@ -9643,8 +9796,8 @@ var init_parsers = __esm({
|
|
|
9643
9796
|
});
|
|
9644
9797
|
|
|
9645
9798
|
// src/tools/file_map.js
|
|
9646
|
-
import
|
|
9647
|
-
import
|
|
9799
|
+
import fs22 from "fs-extra";
|
|
9800
|
+
import path21 from "path";
|
|
9648
9801
|
import { createRequire as createRequire2 } from "module";
|
|
9649
9802
|
function sanitize(text, limit = 50) {
|
|
9650
9803
|
if (!text) return "";
|
|
@@ -9836,17 +9989,17 @@ var init_file_map = __esm({
|
|
|
9836
9989
|
if (!filePath) {
|
|
9837
9990
|
return 'ERROR: No file path provided. Use [tool:functions.FileMap(path="...")]';
|
|
9838
9991
|
}
|
|
9839
|
-
const absolutePath =
|
|
9840
|
-
if (!
|
|
9992
|
+
const absolutePath = path21.isAbsolute(filePath) ? filePath : path21.resolve(process.cwd(), filePath);
|
|
9993
|
+
if (!fs22.existsSync(absolutePath)) {
|
|
9841
9994
|
return `ERROR: File not found: ${filePath}`;
|
|
9842
9995
|
}
|
|
9843
|
-
const ext =
|
|
9996
|
+
const ext = path21.extname(absolutePath).slice(1).toLowerCase();
|
|
9844
9997
|
const wasmFile = EXTENSION_TO_WASM[ext];
|
|
9845
9998
|
if (!wasmFile) {
|
|
9846
9999
|
return `ERROR: Unsupported file extension: .${ext}`;
|
|
9847
10000
|
}
|
|
9848
|
-
const wasmPath =
|
|
9849
|
-
if (!
|
|
10001
|
+
const wasmPath = path21.resolve(PARSER_DIR, wasmFile);
|
|
10002
|
+
if (!fs22.existsSync(wasmPath)) {
|
|
9850
10003
|
return `ERROR: Parser for .${ext} not found. Please download it in Settings > Other.`;
|
|
9851
10004
|
}
|
|
9852
10005
|
try {
|
|
@@ -9854,9 +10007,9 @@ var init_file_map = __esm({
|
|
|
9854
10007
|
if (!isParserInitialized) {
|
|
9855
10008
|
let tsWasmPath;
|
|
9856
10009
|
try {
|
|
9857
|
-
tsWasmPath =
|
|
10010
|
+
tsWasmPath = path21.join(path21.dirname(require3.resolve("web-tree-sitter")), "tree-sitter.wasm");
|
|
9858
10011
|
} catch (e) {
|
|
9859
|
-
tsWasmPath =
|
|
10012
|
+
tsWasmPath = path21.join(process.cwd(), "node_modules", "web-tree-sitter", "tree-sitter.wasm");
|
|
9860
10013
|
}
|
|
9861
10014
|
await Parser.init({
|
|
9862
10015
|
locateFile: (p) => {
|
|
@@ -9871,7 +10024,7 @@ var init_file_map = __esm({
|
|
|
9871
10024
|
const parser = new Parser();
|
|
9872
10025
|
const Lang = await TreeSitter.Language.load(wasmPath);
|
|
9873
10026
|
parser.setLanguage(Lang);
|
|
9874
|
-
const sourceCode = await
|
|
10027
|
+
const sourceCode = await fs22.readFile(absolutePath, "utf8");
|
|
9875
10028
|
const lines = sourceCode.split("\n").length;
|
|
9876
10029
|
let maxDepth = 12;
|
|
9877
10030
|
if (lines > 1e4) maxDepth = 2;
|
|
@@ -9894,8 +10047,8 @@ Stack: ${err.stack}` : "";
|
|
|
9894
10047
|
});
|
|
9895
10048
|
|
|
9896
10049
|
// src/tools/todo.js
|
|
9897
|
-
import
|
|
9898
|
-
import
|
|
10050
|
+
import fs23 from "fs";
|
|
10051
|
+
import path22 from "path";
|
|
9899
10052
|
var todo;
|
|
9900
10053
|
var init_todo = __esm({
|
|
9901
10054
|
"src/tools/todo.js"() {
|
|
@@ -9906,8 +10059,8 @@ var init_todo = __esm({
|
|
|
9906
10059
|
const { method, tasks, markDone } = parseArgs(args);
|
|
9907
10060
|
const chatId = context.chatId || "default";
|
|
9908
10061
|
if (!method) return 'ERROR: Missing "method" argument for todo tool (create/append/get).';
|
|
9909
|
-
const todoDir =
|
|
9910
|
-
const todoFile =
|
|
10062
|
+
const todoDir = path22.join(DATA_DIR, "plan", chatId);
|
|
10063
|
+
const todoFile = path22.join(todoDir, "todo.md");
|
|
9911
10064
|
const parseMessyArray = (input) => {
|
|
9912
10065
|
if (!input || Array.isArray(input)) return input;
|
|
9913
10066
|
const trimmed = String(input).trim();
|
|
@@ -9967,8 +10120,8 @@ var init_todo = __esm({
|
|
|
9967
10120
|
};
|
|
9968
10121
|
};
|
|
9969
10122
|
try {
|
|
9970
|
-
if (!
|
|
9971
|
-
|
|
10123
|
+
if (!fs23.existsSync(todoDir)) {
|
|
10124
|
+
fs23.mkdirSync(todoDir, { recursive: true });
|
|
9972
10125
|
}
|
|
9973
10126
|
if (method === "create") {
|
|
9974
10127
|
if (!tasks) return 'ERROR: Missing "tasks" for create method.';
|
|
@@ -9980,7 +10133,7 @@ var init_todo = __esm({
|
|
|
9980
10133
|
markedCount = result.markedCount;
|
|
9981
10134
|
}
|
|
9982
10135
|
await RevertManager.recordFileChange(todoFile);
|
|
9983
|
-
|
|
10136
|
+
fs23.writeFileSync(todoFile, content, "utf8");
|
|
9984
10137
|
const total = content.split(/\r?\n/).map((l) => l.trim()).filter((l) => l.startsWith("- [ ]") || l.startsWith("- [x]") || l.startsWith("- [X]")).length;
|
|
9985
10138
|
if (markedCount > 0) {
|
|
9986
10139
|
const completed = content.split(/\r?\n/).map((l) => l.trim()).filter((l) => l.startsWith("- [x]") || l.startsWith("- [X]")).length;
|
|
@@ -9994,8 +10147,8 @@ ${content}`;
|
|
|
9994
10147
|
if (!tasks) return 'ERROR: Missing "tasks" for append method.';
|
|
9995
10148
|
const appendContent = getTasksString(tasks);
|
|
9996
10149
|
await RevertManager.recordFileChange(todoFile);
|
|
9997
|
-
|
|
9998
|
-
const fullContent =
|
|
10150
|
+
fs23.appendFileSync(todoFile, appendContent, "utf8");
|
|
10151
|
+
const fullContent = fs23.readFileSync(todoFile, "utf8");
|
|
9999
10152
|
const lines = fullContent.split(/\r?\n/).map((l) => l.trim());
|
|
10000
10153
|
const total = lines.filter((l) => l.startsWith("- [ ]") || l.startsWith("- [x]") || l.startsWith("- [X]")).length;
|
|
10001
10154
|
const completed = lines.filter((l) => l.startsWith("- [x]") || l.startsWith("- [X]")).length;
|
|
@@ -10004,10 +10157,10 @@ ${content}`;
|
|
|
10004
10157
|
${fullContent}`;
|
|
10005
10158
|
}
|
|
10006
10159
|
if (method === "get") {
|
|
10007
|
-
if (!
|
|
10160
|
+
if (!fs23.existsSync(todoFile)) {
|
|
10008
10161
|
return "TODO GET: No task list found for this session.";
|
|
10009
10162
|
}
|
|
10010
|
-
let content =
|
|
10163
|
+
let content = fs23.readFileSync(todoFile, "utf8");
|
|
10011
10164
|
let markedCount = 0;
|
|
10012
10165
|
if (markDone) {
|
|
10013
10166
|
const result = applyMarkDone(content, markDone);
|
|
@@ -10015,7 +10168,7 @@ ${fullContent}`;
|
|
|
10015
10168
|
content = result.content;
|
|
10016
10169
|
markedCount = result.markedCount;
|
|
10017
10170
|
await RevertManager.recordFileChange(todoFile);
|
|
10018
|
-
|
|
10171
|
+
fs23.writeFileSync(todoFile, content, "utf8");
|
|
10019
10172
|
}
|
|
10020
10173
|
}
|
|
10021
10174
|
const totalLines = content.split(/\r?\n/).map((l) => l.trim());
|
|
@@ -10396,20 +10549,20 @@ var init_await = __esm({
|
|
|
10396
10549
|
});
|
|
10397
10550
|
|
|
10398
10551
|
// src/utils/advanceRevert.js
|
|
10399
|
-
import
|
|
10400
|
-
import
|
|
10552
|
+
import fs24 from "fs-extra";
|
|
10553
|
+
import path23 from "path";
|
|
10401
10554
|
async function scanWorkspace(dir, baseDir = dir) {
|
|
10402
10555
|
const manifest = {};
|
|
10403
|
-
const entries = await
|
|
10556
|
+
const entries = await fs24.readdir(dir, { withFileTypes: true }).catch(() => []);
|
|
10404
10557
|
for (const entry of entries) {
|
|
10405
10558
|
if (JUNK_DIRECTORIES.includes(entry.name)) continue;
|
|
10406
|
-
const fullPath =
|
|
10407
|
-
const relPath =
|
|
10559
|
+
const fullPath = path23.join(dir, entry.name);
|
|
10560
|
+
const relPath = path23.relative(baseDir, fullPath).replace(/\\/g, "/");
|
|
10408
10561
|
if (entry.isDirectory()) {
|
|
10409
10562
|
const sub = await scanWorkspace(fullPath, baseDir);
|
|
10410
10563
|
Object.assign(manifest, sub);
|
|
10411
10564
|
} else {
|
|
10412
|
-
const stats = await
|
|
10565
|
+
const stats = await fs24.stat(fullPath).catch(() => null);
|
|
10413
10566
|
if (stats) {
|
|
10414
10567
|
manifest[relPath] = {
|
|
10415
10568
|
size: stats.size,
|
|
@@ -10421,34 +10574,34 @@ async function scanWorkspace(dir, baseDir = dir) {
|
|
|
10421
10574
|
return manifest;
|
|
10422
10575
|
}
|
|
10423
10576
|
async function copyWorkspaceFiles(destDir, manifest) {
|
|
10424
|
-
await
|
|
10577
|
+
await fs24.ensureDir(destDir);
|
|
10425
10578
|
for (const relPath of Object.keys(manifest)) {
|
|
10426
|
-
const srcPath =
|
|
10427
|
-
const destPath =
|
|
10428
|
-
await
|
|
10429
|
-
await
|
|
10579
|
+
const srcPath = path23.join(process.cwd(), relPath);
|
|
10580
|
+
const destPath = path23.join(destDir, relPath);
|
|
10581
|
+
await fs24.ensureDir(path23.dirname(destPath));
|
|
10582
|
+
await fs24.copyFile(srcPath, destPath).catch(() => {
|
|
10430
10583
|
});
|
|
10431
10584
|
}
|
|
10432
10585
|
}
|
|
10433
10586
|
async function restoreSnapshotDir(srcDir, destDir, stats = null, baseDir = null) {
|
|
10434
|
-
if (!await
|
|
10587
|
+
if (!await fs24.pathExists(srcDir)) return;
|
|
10435
10588
|
if (!baseDir) baseDir = srcDir;
|
|
10436
|
-
const entries = await
|
|
10589
|
+
const entries = await fs24.readdir(srcDir, { withFileTypes: true }).catch(() => []);
|
|
10437
10590
|
for (const entry of entries) {
|
|
10438
|
-
const srcPath =
|
|
10439
|
-
const destPath =
|
|
10591
|
+
const srcPath = path23.join(srcDir, entry.name);
|
|
10592
|
+
const destPath = path23.join(destDir, entry.name);
|
|
10440
10593
|
if (entry.isDirectory()) {
|
|
10441
10594
|
await restoreSnapshotDir(srcPath, destPath, stats, baseDir);
|
|
10442
10595
|
} else {
|
|
10443
|
-
const relPath =
|
|
10444
|
-
const existed = await
|
|
10596
|
+
const relPath = path23.relative(baseDir, srcPath).replace(/\\/g, "/");
|
|
10597
|
+
const existed = await fs24.pathExists(destPath);
|
|
10445
10598
|
if (existed) {
|
|
10446
|
-
await
|
|
10599
|
+
await fs24.chmod(destPath, 438).catch(() => {
|
|
10447
10600
|
});
|
|
10448
10601
|
}
|
|
10449
|
-
await
|
|
10450
|
-
const ok = await
|
|
10451
|
-
await
|
|
10602
|
+
await fs24.ensureDir(path23.dirname(destPath));
|
|
10603
|
+
const ok = await fs24.copyFile(srcPath, destPath).then(() => true).catch(() => false);
|
|
10604
|
+
await fs24.chmod(destPath, 438).catch(() => {
|
|
10452
10605
|
});
|
|
10453
10606
|
if (stats) {
|
|
10454
10607
|
if (!ok) {
|
|
@@ -10486,12 +10639,12 @@ var init_advanceRevert = __esm({
|
|
|
10486
10639
|
AdvanceRevertManager = {
|
|
10487
10640
|
async takeInitialSnapshot(chatId) {
|
|
10488
10641
|
try {
|
|
10489
|
-
const snapshotsDir =
|
|
10490
|
-
await
|
|
10642
|
+
const snapshotsDir = path23.join(DATA_DIR, "snapshots", chatId);
|
|
10643
|
+
await fs24.remove(snapshotsDir).catch(() => {
|
|
10491
10644
|
});
|
|
10492
|
-
await
|
|
10645
|
+
await fs24.ensureDir(snapshotsDir);
|
|
10493
10646
|
const manifest = await scanWorkspace(process.cwd());
|
|
10494
|
-
await copyWorkspaceFiles(
|
|
10647
|
+
await copyWorkspaceFiles(path23.join(snapshotsDir, "initial"), manifest);
|
|
10495
10648
|
const ledger = readEncryptedJson(LEDGER_ADVANCE_FILE, {});
|
|
10496
10649
|
ledger[chatId] = {
|
|
10497
10650
|
initialManifest: manifest,
|
|
@@ -10540,7 +10693,7 @@ var init_advanceRevert = __esm({
|
|
|
10540
10693
|
for (const file of changedFiles) {
|
|
10541
10694
|
deltaManifest[file] = currentManifest[file];
|
|
10542
10695
|
}
|
|
10543
|
-
const turnDir =
|
|
10696
|
+
const turnDir = path23.join(DATA_DIR, "snapshots", chatId, `turn_${turnNumber}`);
|
|
10544
10697
|
await copyWorkspaceFiles(turnDir, deltaManifest);
|
|
10545
10698
|
}
|
|
10546
10699
|
session.checkpoints.push({
|
|
@@ -10574,28 +10727,28 @@ var init_advanceRevert = __esm({
|
|
|
10574
10727
|
const checkpoints = session.checkpoints || [];
|
|
10575
10728
|
const targetIdx = checkpoints.findIndex((c) => c.id === checkpointId);
|
|
10576
10729
|
if (targetIdx === -1) throw new Error(`Checkpoint [${checkpointId}] not found.`);
|
|
10577
|
-
const snapshotsDir =
|
|
10730
|
+
const snapshotsDir = path23.join(DATA_DIR, "snapshots", chatId);
|
|
10578
10731
|
const stats = { restored: 0, replaced: 0, failed: [] };
|
|
10579
10732
|
const currentFiles = await scanWorkspace(process.cwd());
|
|
10580
10733
|
for (const relPath of Object.keys(currentFiles)) {
|
|
10581
|
-
const fullPath =
|
|
10582
|
-
await
|
|
10734
|
+
const fullPath = path23.join(process.cwd(), relPath);
|
|
10735
|
+
await fs24.chmod(fullPath, 438).catch(() => {
|
|
10583
10736
|
});
|
|
10584
|
-
await
|
|
10737
|
+
await fs24.remove(fullPath).catch(() => {
|
|
10585
10738
|
});
|
|
10586
10739
|
}
|
|
10587
|
-
const initialDir =
|
|
10740
|
+
const initialDir = path23.join(snapshotsDir, "initial");
|
|
10588
10741
|
await restoreSnapshotDir(initialDir, process.cwd(), stats, initialDir);
|
|
10589
10742
|
for (let i = 1; i <= targetIdx; i++) {
|
|
10590
10743
|
const cp = checkpoints[i];
|
|
10591
|
-
const turnDir =
|
|
10744
|
+
const turnDir = path23.join(snapshotsDir, cp.id);
|
|
10592
10745
|
await restoreSnapshotDir(turnDir, process.cwd(), stats, turnDir);
|
|
10593
10746
|
if (cp.deletedFiles && cp.deletedFiles.length > 0) {
|
|
10594
10747
|
for (const delFile of cp.deletedFiles) {
|
|
10595
|
-
const fullPath =
|
|
10596
|
-
await
|
|
10748
|
+
const fullPath = path23.join(process.cwd(), delFile);
|
|
10749
|
+
await fs24.chmod(fullPath, 438).catch(() => {
|
|
10597
10750
|
});
|
|
10598
|
-
await
|
|
10751
|
+
await fs24.remove(fullPath).catch(() => {
|
|
10599
10752
|
});
|
|
10600
10753
|
}
|
|
10601
10754
|
}
|
|
@@ -10627,8 +10780,8 @@ var init_advanceRevert = __esm({
|
|
|
10627
10780
|
},
|
|
10628
10781
|
async cleanup(chatId) {
|
|
10629
10782
|
try {
|
|
10630
|
-
const snapshotsDir =
|
|
10631
|
-
await
|
|
10783
|
+
const snapshotsDir = path23.join(DATA_DIR, "snapshots", chatId);
|
|
10784
|
+
await fs24.remove(snapshotsDir).catch(() => {
|
|
10632
10785
|
});
|
|
10633
10786
|
const ledger = readEncryptedJson(LEDGER_ADVANCE_FILE, {});
|
|
10634
10787
|
if (ledger[chatId]) {
|
|
@@ -10982,8 +11135,8 @@ __export(ai_exports, {
|
|
|
10982
11135
|
signalTermination: () => signalTermination
|
|
10983
11136
|
});
|
|
10984
11137
|
import { GoogleGenAI, ThinkingLevel, HarmBlockThreshold, HarmCategory } from "@google/genai";
|
|
10985
|
-
import
|
|
10986
|
-
import
|
|
11138
|
+
import path24, { normalize } from "path";
|
|
11139
|
+
import fs25 from "fs";
|
|
10987
11140
|
var client, globalSettings, colorMainWords, withRetry, TERMINATION_SIGNAL, getCleanGroupedLength, stripAnsi2, fetchWithBackoff, getDeepSeekStream, getNVIDIAStream, wrapNvidiaStreamWithQueueDepth, getOpenRouterStream, signalTermination, isTerminationSignaled, TOOL_LABELS2, getToolDetail, runJanitorTask, getActiveToolContext, getContextSafeText, contextSafeReplace, getSanitizedText, translateKimiToolCalls, detectToolCalls, initAI, generateSimpleContent, consolidatePastMemories, compressHistory, deleteChatSummary, getAIStream, runSubagent;
|
|
10988
11141
|
var init_ai = __esm({
|
|
10989
11142
|
async "src/utils/ai.js"() {
|
|
@@ -11008,7 +11161,7 @@ var init_ai = __esm({
|
|
|
11008
11161
|
globalSettings = {};
|
|
11009
11162
|
colorMainWords = (label) => {
|
|
11010
11163
|
if (!label) return label;
|
|
11011
|
-
return label.replace(/(?:(\x1b\[\d+m))?([✔✘✖🔍📖→➕↻•🛇])(?:(\x1b\[\d+m))?\s*\b(Created|Read|Edited|Viewed|Auto-Read|List|Generated|Written|Searched|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) => {
|
|
11164
|
+
return label.replace(/(?:(\x1b\[\d+m))?([✔✘✖🔍📖→➕↻•🛇])(?:(\x1b\[\d+m))?\s*\b(Created|Read|Edited|Viewed|Auto-Read|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) => {
|
|
11012
11165
|
return `${ansiBefore || ""}${icon}${ansiAfter || ""} \x1B[95m${word}\x1B[0m`;
|
|
11013
11166
|
});
|
|
11014
11167
|
};
|
|
@@ -11826,7 +11979,7 @@ var init_ai = __esm({
|
|
|
11826
11979
|
return pArgs.id || pArgs.taskId;
|
|
11827
11980
|
}
|
|
11828
11981
|
const filePath = pArgs.path || pArgs.targetFile || pArgs.TargetFile || pArgs.directory;
|
|
11829
|
-
return filePath ?
|
|
11982
|
+
return filePath ? path24.basename(filePath.replace(/["']/g, "").replace(/\\/g, "/")) : null;
|
|
11830
11983
|
} catch (e) {
|
|
11831
11984
|
return null;
|
|
11832
11985
|
}
|
|
@@ -12073,9 +12226,9 @@ ${originalTextProcessed.length > USER_CONTEXT_LENGTH ? "... (truncated) ...\n\n"
|
|
|
12073
12226
|
}
|
|
12074
12227
|
})() : String(err);
|
|
12075
12228
|
await new Promise((resolve) => setTimeout(resolve, 1e3));
|
|
12076
|
-
const janitorErrDir =
|
|
12077
|
-
if (!
|
|
12078
|
-
|
|
12229
|
+
const janitorErrDir = path24.join(LOGS_DIR, "janitor");
|
|
12230
|
+
if (!fs25.existsSync(janitorErrDir)) fs25.mkdirSync(janitorErrDir, { recursive: true });
|
|
12231
|
+
fs25.appendFileSync(path24.join(janitorErrDir, "error.log"), `ERROR [Attempt ${attempts}/${MAX_JANITOR_RETRIES + 1}] [${date}]: ${errLog}
|
|
12079
12232
|
|
|
12080
12233
|
`);
|
|
12081
12234
|
if (attempts > MAX_JANITOR_RETRIES) break;
|
|
@@ -12084,8 +12237,8 @@ ${originalTextProcessed.length > USER_CONTEXT_LENGTH ? "... (truncated) ...\n\n"
|
|
|
12084
12237
|
}
|
|
12085
12238
|
}
|
|
12086
12239
|
if (attempts) {
|
|
12087
|
-
const janitorErrDir =
|
|
12088
|
-
|
|
12240
|
+
const janitorErrDir = path24.join(LOGS_DIR, "janitor");
|
|
12241
|
+
fs25.appendFileSync(path24.join(janitorErrDir, "error.log"), `-----------------------------------------------------------------------------
|
|
12089
12242
|
|
|
12090
12243
|
`);
|
|
12091
12244
|
}
|
|
@@ -12610,10 +12763,10 @@ ${newMemoryListStr}
|
|
|
12610
12763
|
}
|
|
12611
12764
|
})() : String(err);
|
|
12612
12765
|
;
|
|
12613
|
-
const janitorLogDir =
|
|
12614
|
-
if (!
|
|
12615
|
-
|
|
12616
|
-
|
|
12766
|
+
const janitorLogDir = path24.join(LOGS_DIR, "janitor");
|
|
12767
|
+
if (!fs25.existsSync(janitorLogDir)) fs25.mkdirSync(janitorLogDir, { recursive: true });
|
|
12768
|
+
fs25.appendFileSync(
|
|
12769
|
+
path24.join(janitorLogDir, "error.log"),
|
|
12617
12770
|
`[${(/* @__PURE__ */ new Date()).toLocaleString()}] Past memory batch consolidation error: ${errLog}
|
|
12618
12771
|
`
|
|
12619
12772
|
);
|
|
@@ -12621,7 +12774,7 @@ ${newMemoryListStr}
|
|
|
12621
12774
|
};
|
|
12622
12775
|
compressHistory = async (settings, history, isAuto = false) => {
|
|
12623
12776
|
const { chatId, aiProvider = "Google" } = settings;
|
|
12624
|
-
const summariesFile =
|
|
12777
|
+
const summariesFile = path24.join(SECRET_DIR, "chat-summaries.json");
|
|
12625
12778
|
const flattenContext = (hist) => {
|
|
12626
12779
|
return hist.filter(
|
|
12627
12780
|
(m) => (m.role === "user" || m.role === "agent" || m.role === "system") && m.role !== "think" && !m.isVisualFeedback && !m.isMeta && !String(m.id).startsWith("welcome")
|
|
@@ -12695,8 +12848,8 @@ Provide a consolidated summary of the entire session.`;
|
|
|
12695
12848
|
};
|
|
12696
12849
|
deleteChatSummary = (chatId) => {
|
|
12697
12850
|
try {
|
|
12698
|
-
const summariesFile =
|
|
12699
|
-
if (
|
|
12851
|
+
const summariesFile = path24.join(SECRET_DIR, "chat-summaries.json");
|
|
12852
|
+
if (fs25.existsSync(summariesFile)) {
|
|
12700
12853
|
const summaries = readEncryptedJson(summariesFile, {});
|
|
12701
12854
|
if (summaries[chatId]) {
|
|
12702
12855
|
delete summaries[chatId];
|
|
@@ -12712,7 +12865,7 @@ Provide a consolidated summary of the entire session.`;
|
|
|
12712
12865
|
if (!client && aiProvider === "Google") throw new Error("AI not initialized");
|
|
12713
12866
|
const isMemoryEnabled = systemSettings?.memory !== false;
|
|
12714
12867
|
const originalText = history[history.length - 1].text;
|
|
12715
|
-
const summariesFile =
|
|
12868
|
+
const summariesFile = path24.join(SECRET_DIR, "chat-summaries.json");
|
|
12716
12869
|
let wasCompressedInStream = false;
|
|
12717
12870
|
const isFirstPrompt = history.filter((m) => m.role === "user").length === 1;
|
|
12718
12871
|
const hasTitleSignal = originalText.includes("[TITLE-UPDATE]");
|
|
@@ -12958,7 +13111,7 @@ Provide a consolidated summary of the entire session.`;
|
|
|
12958
13111
|
];
|
|
12959
13112
|
const safeReaddirWithTypes = (dir) => {
|
|
12960
13113
|
try {
|
|
12961
|
-
return
|
|
13114
|
+
return fs25.readdirSync(dir, { withFileTypes: true });
|
|
12962
13115
|
} catch (e) {
|
|
12963
13116
|
return [];
|
|
12964
13117
|
}
|
|
@@ -12971,16 +13124,16 @@ Provide a consolidated summary of the entire session.`;
|
|
|
12971
13124
|
if (COLLAPSED_DIRS_GLOBAL.includes(entry.name)) continue;
|
|
12972
13125
|
if (entry.isDirectory()) {
|
|
12973
13126
|
currentCount.value++;
|
|
12974
|
-
countFolders(
|
|
13127
|
+
countFolders(path24.join(dir, entry.name), currentCount, depth + 1);
|
|
12975
13128
|
}
|
|
12976
13129
|
}
|
|
12977
13130
|
return currentCount.value;
|
|
12978
13131
|
};
|
|
12979
13132
|
const getDirTree = (dir, maxDepth, prefix = "", depth = 1) => {
|
|
12980
13133
|
const entries = safeReaddirWithTypes(dir);
|
|
12981
|
-
const sep =
|
|
13134
|
+
const sep = path24.sep;
|
|
12982
13135
|
if (entries.length > 100) {
|
|
12983
|
-
return `${prefix}\u2514\u2500\u2500 ${
|
|
13136
|
+
return `${prefix}\u2514\u2500\u2500 ${path24.basename(dir)}${sep} ...100+ files...
|
|
12984
13137
|
`;
|
|
12985
13138
|
}
|
|
12986
13139
|
let result = "";
|
|
@@ -12998,7 +13151,7 @@ Provide a consolidated summary of the entire session.`;
|
|
|
12998
13151
|
];
|
|
12999
13152
|
finalItems.forEach((item, index) => {
|
|
13000
13153
|
const isLast = index === finalItems.length - 1;
|
|
13001
|
-
const filePath =
|
|
13154
|
+
const filePath = path24.join(dir, item.name);
|
|
13002
13155
|
const connector = isLast ? "\u2514\u2500\u2500 " : "\u251C\u2500\u2500 ";
|
|
13003
13156
|
const childPrefix = prefix + (isLast ? " " : "\u2502 ");
|
|
13004
13157
|
if (item.isCollapsed) {
|
|
@@ -13081,10 +13234,10 @@ ${currentSummary}
|
|
|
13081
13234
|
if (isBridgeConnected()) {
|
|
13082
13235
|
ideBlock = "[IDE CONTEXT]\n";
|
|
13083
13236
|
if (ideCtx.file_focused !== "none") {
|
|
13084
|
-
const relFocused =
|
|
13237
|
+
const relFocused = path24.relative(process.cwd(), ideCtx.file_focused);
|
|
13085
13238
|
const relOpened = (ideCtx.opened_editors || []).map((p) => {
|
|
13086
|
-
const rel =
|
|
13087
|
-
return rel.startsWith("..") ? `[External] ${
|
|
13239
|
+
const rel = path24.relative(process.cwd(), p);
|
|
13240
|
+
return rel.startsWith("..") ? `[External] ${path24.basename(p)}` : rel;
|
|
13088
13241
|
});
|
|
13089
13242
|
ideBlock += `Focused File: ${relFocused}
|
|
13090
13243
|
Cursor Line: ${ideCtx.cursor_line}
|
|
@@ -13126,7 +13279,7 @@ Cursor Line: ${ideCtx.cursor_line}
|
|
|
13126
13279
|
}
|
|
13127
13280
|
const getSumForLimit = (limit, activeFiles2) => {
|
|
13128
13281
|
return activeFiles2.reduce((sum, f) => {
|
|
13129
|
-
const isFocused = ideCtx.file_focused && (f.path === ideCtx.file_focused ||
|
|
13282
|
+
const isFocused = ideCtx.file_focused && (f.path === ideCtx.file_focused || path24.resolve(process.cwd(), f.path) === path24.resolve(ideCtx.file_focused));
|
|
13130
13283
|
const fileLimit = isFocused ? Math.ceil(limit * 1.2) : limit;
|
|
13131
13284
|
return sum + Math.min(f.edits.length, fileLimit);
|
|
13132
13285
|
}, 0);
|
|
@@ -13160,7 +13313,7 @@ Cursor Line: ${ideCtx.cursor_line}
|
|
|
13160
13313
|
}
|
|
13161
13314
|
}
|
|
13162
13315
|
for (const file of activeFiles) {
|
|
13163
|
-
const isFocused = ideCtx.file_focused && (file.path === ideCtx.file_focused ||
|
|
13316
|
+
const isFocused = ideCtx.file_focused && (file.path === ideCtx.file_focused || path24.resolve(process.cwd(), file.path) === path24.resolve(ideCtx.file_focused));
|
|
13164
13317
|
const fileLimit = isFocused ? Math.ceil(chosenLimit * 1.2) : chosenLimit;
|
|
13165
13318
|
if (file.edits.length > fileLimit) {
|
|
13166
13319
|
file.edits = file.edits.slice(-fileLimit);
|
|
@@ -13247,9 +13400,9 @@ ${ideCtx.warnings}
|
|
|
13247
13400
|
endLine = matchRange[2] ? parseInt(matchRange[2], 10) : startLine;
|
|
13248
13401
|
filePath = tagClean.slice(0, matchRange.index);
|
|
13249
13402
|
}
|
|
13250
|
-
const absPath =
|
|
13251
|
-
if (
|
|
13252
|
-
const stats =
|
|
13403
|
+
const absPath = path24.resolve(process.cwd(), filePath);
|
|
13404
|
+
if (fs25.existsSync(absPath)) {
|
|
13405
|
+
const stats = fs25.statSync(absPath);
|
|
13253
13406
|
if (stats.isFile()) {
|
|
13254
13407
|
const pathLower = filePath.toLowerCase();
|
|
13255
13408
|
const isPdf = pathLower.endsWith(".pdf");
|
|
@@ -13258,7 +13411,7 @@ ${ideCtx.warnings}
|
|
|
13258
13411
|
const isMultimodalFile = isImage || isPdf || isOfficeFile;
|
|
13259
13412
|
const isSupported = aiProvider === "Google" || isModelMultimodal(modelName);
|
|
13260
13413
|
if (isMultimodalFile && !isSupported) {
|
|
13261
|
-
const label = `\u2718 Unsupported Modality: ${
|
|
13414
|
+
const label = `\u2718 Unsupported Modality: ${path24.basename(filePath)}`;
|
|
13262
13415
|
let terminalWidth = 115;
|
|
13263
13416
|
if (process.stdout.isTTY) {
|
|
13264
13417
|
terminalWidth = process.stdout.columns - 5 || 120;
|
|
@@ -13308,7 +13461,7 @@ ${ideCtx.warnings}
|
|
|
13308
13461
|
} else {
|
|
13309
13462
|
let totalLines = "...";
|
|
13310
13463
|
try {
|
|
13311
|
-
const content =
|
|
13464
|
+
const content = fs25.readFileSync(absPath, "utf8");
|
|
13312
13465
|
totalLines = content.split("\n").length;
|
|
13313
13466
|
} catch (e) {
|
|
13314
13467
|
}
|
|
@@ -13974,7 +14127,7 @@ ${ideErr} [/ERROR]`;
|
|
|
13974
14127
|
if (keyword) {
|
|
13975
14128
|
detail = keyword.replace(/["']/g, "");
|
|
13976
14129
|
} else if (filePath) {
|
|
13977
|
-
detail =
|
|
14130
|
+
detail = path24.basename(filePath.replace(/["']/g, "").replace(/\\/g, "/"));
|
|
13978
14131
|
} else if (title && (potentialTool === "invoke" || potentialTool === "invoke_sync")) {
|
|
13979
14132
|
detail = title.replace(/["']/g, "").substring(0, 30);
|
|
13980
14133
|
} else if (id && potentialTool === "get_progress") {
|
|
@@ -14003,7 +14156,7 @@ ${ideErr} [/ERROR]`;
|
|
|
14003
14156
|
if (potentialTool === "invoke" || potentialTool === "invoke_sync" || potentialTool === "get_progress") {
|
|
14004
14157
|
detail = val.substring(0, 30);
|
|
14005
14158
|
} else {
|
|
14006
|
-
detail = potentialTool === "search_keyword" || potentialTool === "file_map" ? val :
|
|
14159
|
+
detail = potentialTool === "search_keyword" || potentialTool === "file_map" ? val : path24.basename(val.replace(/\\/g, "/"));
|
|
14007
14160
|
}
|
|
14008
14161
|
}
|
|
14009
14162
|
}
|
|
@@ -14191,8 +14344,8 @@ ${ideErr} [/ERROR]`;
|
|
|
14191
14344
|
yield { type: "status", content: `${displayLabel}${detail ? ` ${detail}` : ""}` };
|
|
14192
14345
|
let label = "";
|
|
14193
14346
|
if (normToolName === "web_search") {
|
|
14194
|
-
const { query, limit = 10 } = parseArgs(toolCall.args);
|
|
14195
|
-
label = `\u2714 Searched: ${query} \u2192 ${limit}`;
|
|
14347
|
+
const { query, limit = 10, aiMode = false } = parseArgs(toolCall.args);
|
|
14348
|
+
label = `\u2714 ${aiMode ? "AI Search" : "Searched"}: ${query}${aiMode === false ? ` \u2192 ${limit}` : ""}`;
|
|
14196
14349
|
} else if (normToolName === "web_scrape") {
|
|
14197
14350
|
const url = parseArgs(toolCall.args).url || "...";
|
|
14198
14351
|
label = `\u2714 Visited: ${url}`;
|
|
@@ -14205,9 +14358,9 @@ ${ideErr} [/ERROR]`;
|
|
|
14205
14358
|
let totalLines = "...";
|
|
14206
14359
|
let actualEndLine = eLine;
|
|
14207
14360
|
try {
|
|
14208
|
-
const absPath =
|
|
14209
|
-
if (
|
|
14210
|
-
const content =
|
|
14361
|
+
const absPath = path24.resolve(process.cwd(), targetPath2);
|
|
14362
|
+
if (fs25.existsSync(absPath)) {
|
|
14363
|
+
const content = fs25.readFileSync(absPath, "utf8");
|
|
14211
14364
|
const lines = content.split("\n").length;
|
|
14212
14365
|
totalLines = lines;
|
|
14213
14366
|
actualEndLine = Math.min(eLine, lines);
|
|
@@ -14227,8 +14380,8 @@ ${ideErr} [/ERROR]`;
|
|
|
14227
14380
|
}
|
|
14228
14381
|
} else if (normToolName === "list_files" || normToolName === "read_folder") {
|
|
14229
14382
|
const action = normToolName === "list_files" ? "List" : "Browsed";
|
|
14230
|
-
const
|
|
14231
|
-
label = `\u2714 ${action}: ${
|
|
14383
|
+
const path26 = parseArgs(toolCall.args).path;
|
|
14384
|
+
label = `\u2714 ${action}: ${path26 === "." ? "./" : path26}`;
|
|
14232
14385
|
} else if (normToolName === "write_file" || normToolName === "update_file") {
|
|
14233
14386
|
const action = normToolName === "write_file" ? "Created" : "Edited";
|
|
14234
14387
|
label = `\u2714 ${action}: ${parseArgs(toolCall.args).path || "..."}`;
|
|
@@ -14239,8 +14392,8 @@ ${ideErr} [/ERROR]`;
|
|
|
14239
14392
|
label = `\u2714 Generated: ${parseArgs(toolCall.args).path || "..."}
|
|
14240
14393
|
`;
|
|
14241
14394
|
} else if (normToolName === "file_map") {
|
|
14242
|
-
const
|
|
14243
|
-
label = `${
|
|
14395
|
+
const path26 = parseArgs(toolCall.args).path;
|
|
14396
|
+
label = `${path26 ? "\u2714" : "\u2718"} Indexed${path26 ? ": " + path26 : " File Not Found"}`;
|
|
14244
14397
|
} else if (normToolName.toLowerCase() === "search_keyword" || normToolName.toLowerCase() === "todo") {
|
|
14245
14398
|
label = "";
|
|
14246
14399
|
} else if (normToolName.toLowerCase() === "generate_image") {
|
|
@@ -14315,7 +14468,7 @@ ${ideErr} [/ERROR]`;
|
|
|
14315
14468
|
const { command } = parseArgs(toolCall.args);
|
|
14316
14469
|
if (command && settings.systemSettings && settings.systemSettings.allowExternalAccess === false) {
|
|
14317
14470
|
const riskyPatterns = [/[a-zA-Z]:[\\\/]/i, /^\//, /\.\.[\\\/]/, /\/etc\//, /\/var\//, /\/root\//, /\/bin\//, /\/usr\//];
|
|
14318
|
-
const currentDrive =
|
|
14471
|
+
const currentDrive = path24.resolve(process.cwd()).substring(0, 3).toLowerCase();
|
|
14319
14472
|
const splitCommands = (cmdString) => {
|
|
14320
14473
|
const commands = [];
|
|
14321
14474
|
let current = "";
|
|
@@ -14444,8 +14597,8 @@ ${ideErr} [/ERROR]`;
|
|
|
14444
14597
|
const targetPath = parsedArgs.path || parsedArgs.targetPath || null;
|
|
14445
14598
|
if (targetPath) {
|
|
14446
14599
|
const isExternalOff = settings.systemSettings && settings.systemSettings.allowExternalAccess === false;
|
|
14447
|
-
const absoluteTarget =
|
|
14448
|
-
const absoluteCwd =
|
|
14600
|
+
const absoluteTarget = path24.resolve(targetPath);
|
|
14601
|
+
const absoluteCwd = path24.resolve(process.cwd());
|
|
14449
14602
|
if (isExternalOff && !absoluteTarget.startsWith(absoluteCwd)) {
|
|
14450
14603
|
const denyMsg = `Access Denied. You are not allowed to access files outside the current workspace.`;
|
|
14451
14604
|
if (normToolName === "write_file" || normToolName === "update_file") {
|
|
@@ -14634,7 +14787,7 @@ ${ideErr} [/ERROR]`;
|
|
|
14634
14787
|
const toolArgs = parseArgs(toolCall.args);
|
|
14635
14788
|
const { path: filePath } = toolArgs;
|
|
14636
14789
|
if (filePath) {
|
|
14637
|
-
const absPath =
|
|
14790
|
+
const absPath = path24.resolve(process.cwd(), filePath);
|
|
14638
14791
|
const normalize2 = (p) => p ? p.toLowerCase().replace(/\\/g, "/").replace(/^[a-z]:/, (m) => m.toUpperCase()) : "";
|
|
14639
14792
|
const normAbsPath = normalize2(absPath);
|
|
14640
14793
|
let originalContent = "";
|
|
@@ -14644,8 +14797,8 @@ ${ideErr} [/ERROR]`;
|
|
|
14644
14797
|
if (currentIDE && normFocused === normAbsPath && currentIDE.full_content) {
|
|
14645
14798
|
originalContent = currentIDE.full_content;
|
|
14646
14799
|
hasOriginal = true;
|
|
14647
|
-
} else if (
|
|
14648
|
-
originalContent =
|
|
14800
|
+
} else if (fs25.existsSync(absPath)) {
|
|
14801
|
+
originalContent = fs25.readFileSync(absPath, "utf8");
|
|
14649
14802
|
hasOriginal = true;
|
|
14650
14803
|
}
|
|
14651
14804
|
originalContentForReporting = originalContent;
|
|
@@ -14672,9 +14825,9 @@ ${ideErr} [/ERROR]`;
|
|
|
14672
14825
|
const successes = patchResults.filter((r) => r.success);
|
|
14673
14826
|
const failures = patchResults.filter((r) => !r.success);
|
|
14674
14827
|
if (successes.length === 0) {
|
|
14675
|
-
const errorMsg = `[TOOL RESULT]: ERROR: Failed to apply patches to [${
|
|
14828
|
+
const errorMsg = `[TOOL RESULT]: ERROR: Failed to apply patches to [${path24.basename(absPath)}].
|
|
14676
14829
|
${failures.map((f) => ` \u2022 ${f.error}`).join("\n")}`;
|
|
14677
|
-
const errorLabel = `\u2714 Edited: ${
|
|
14830
|
+
const errorLabel = `\u2714 Edited: ${path24.basename(absPath)}`.toUpperCase();
|
|
14678
14831
|
let terminalWidth = 115;
|
|
14679
14832
|
if (process.stdout.isTTY) {
|
|
14680
14833
|
terminalWidth = process.stdout.columns - 5 || 120;
|
|
@@ -14692,19 +14845,19 @@ ${failures.map((f) => ` \u2022 ${f.error}`).join("\n")}`;
|
|
|
14692
14845
|
continue;
|
|
14693
14846
|
}
|
|
14694
14847
|
}
|
|
14695
|
-
yield { type: "status", content: `Opening Diff in IDE: ${
|
|
14848
|
+
yield { type: "status", content: `Opening Diff in IDE: ${path24.basename(absPath)}` };
|
|
14696
14849
|
showDiffInIDE(absPath, originalContent, modifiedContent);
|
|
14697
14850
|
diffOpened = true;
|
|
14698
14851
|
await new Promise((r) => setTimeout(r, 50));
|
|
14699
14852
|
} else if (normToolName === "write_file") {
|
|
14700
14853
|
const rawContent = toolArgs.content || toolArgs.newContent || "";
|
|
14701
14854
|
const modifiedContent = rawContent.endsWith("\n") ? rawContent : rawContent + "\n";
|
|
14702
|
-
if (!
|
|
14855
|
+
if (!fs25.existsSync(absPath)) {
|
|
14703
14856
|
isNewFileCreated = true;
|
|
14704
|
-
|
|
14705
|
-
|
|
14857
|
+
fs25.mkdirSync(path24.dirname(absPath), { recursive: true });
|
|
14858
|
+
fs25.writeFileSync(absPath, "", "utf8");
|
|
14706
14859
|
}
|
|
14707
|
-
yield { type: "status", content: `Opening New File Diff in IDE: ${
|
|
14860
|
+
yield { type: "status", content: `Opening New File Diff in IDE: ${path24.basename(absPath)}` };
|
|
14708
14861
|
showDiffInIDE(absPath, "", modifiedContent);
|
|
14709
14862
|
diffOpened = true;
|
|
14710
14863
|
await new Promise((r) => setTimeout(r, 50));
|
|
@@ -14740,11 +14893,11 @@ ${failures.map((f) => ` \u2022 ${f.error}`).join("\n")}`;
|
|
|
14740
14893
|
if (normToolName === "write_file" || normToolName === "update_file") {
|
|
14741
14894
|
const { path: filePath } = parseArgs(toolCall.args);
|
|
14742
14895
|
if (filePath) {
|
|
14743
|
-
const absPath =
|
|
14896
|
+
const absPath = path24.resolve(process.cwd(), filePath);
|
|
14744
14897
|
closeDiffInIDE(absPath, approval);
|
|
14745
|
-
if (approval === "deny" && isNewFileCreated &&
|
|
14898
|
+
if (approval === "deny" && isNewFileCreated && fs25.existsSync(absPath)) {
|
|
14746
14899
|
try {
|
|
14747
|
-
|
|
14900
|
+
fs25.unlinkSync(absPath);
|
|
14748
14901
|
} catch (e) {
|
|
14749
14902
|
}
|
|
14750
14903
|
}
|
|
@@ -14756,13 +14909,13 @@ ${failures.map((f) => ` \u2022 ${f.error}`).join("\n")}`;
|
|
|
14756
14909
|
}
|
|
14757
14910
|
if (approval === "allow" && diffOpened && isBridgeConnected()) {
|
|
14758
14911
|
const { path: filePath } = parseArgs(toolCall.args);
|
|
14759
|
-
const absPath =
|
|
14912
|
+
const absPath = path24.resolve(process.cwd(), filePath);
|
|
14760
14913
|
const finalIDE = await getIDEContext();
|
|
14761
14914
|
let finalContent = "";
|
|
14762
14915
|
if (finalIDE && finalIDE.file_focused === absPath && finalIDE.full_content) {
|
|
14763
14916
|
finalContent = finalIDE.full_content;
|
|
14764
|
-
} else if (
|
|
14765
|
-
finalContent =
|
|
14917
|
+
} else if (fs25.existsSync(absPath)) {
|
|
14918
|
+
finalContent = fs25.readFileSync(absPath, "utf8");
|
|
14766
14919
|
}
|
|
14767
14920
|
const verifiedLines = finalContent.split(/\r?\n/);
|
|
14768
14921
|
const verifiedLineCount = verifiedLines.length;
|
|
@@ -14924,7 +15077,7 @@ ${snippet2}
|
|
|
14924
15077
|
try {
|
|
14925
15078
|
const { path: filePath } = parseArgs(toolCall.args);
|
|
14926
15079
|
if (filePath) {
|
|
14927
|
-
const absPath =
|
|
15080
|
+
const absPath = path24.resolve(process.cwd(), filePath);
|
|
14928
15081
|
const currentIDE = await getIDEContext();
|
|
14929
15082
|
if (currentIDE && currentIDE.file_focused === absPath && currentIDE.full_content) {
|
|
14930
15083
|
execToolContext.forcedContent = currentIDE.full_content;
|
|
@@ -14938,7 +15091,7 @@ ${snippet2}
|
|
|
14938
15091
|
if ((normToolName === "write_file" || normToolName === "update_file") && result.startsWith("SUCCESS")) {
|
|
14939
15092
|
const { path: filePath } = parseArgs(toolCall.args);
|
|
14940
15093
|
if (filePath) {
|
|
14941
|
-
const absPath =
|
|
15094
|
+
const absPath = path24.resolve(process.cwd(), filePath);
|
|
14942
15095
|
openFileInEditor(absPath);
|
|
14943
15096
|
}
|
|
14944
15097
|
}
|
|
@@ -15201,9 +15354,9 @@ ${snippet2}
|
|
|
15201
15354
|
})() : String(err);
|
|
15202
15355
|
;
|
|
15203
15356
|
const date = (/* @__PURE__ */ new Date()).toLocaleString();
|
|
15204
|
-
const agentErrDir =
|
|
15205
|
-
if (!
|
|
15206
|
-
|
|
15357
|
+
const agentErrDir = path24.join(LOGS_DIR, "agent");
|
|
15358
|
+
if (!fs25.existsSync(agentErrDir)) fs25.mkdirSync(agentErrDir, { recursive: true });
|
|
15359
|
+
fs25.appendFileSync(path24.join(agentErrDir, "error.log"), `ERROR [${date}]: ${errLog}
|
|
15207
15360
|
|
|
15208
15361
|
----------------------------------------------------------------------
|
|
15209
15362
|
|
|
@@ -15250,7 +15403,7 @@ ${recoveryText}`
|
|
|
15250
15403
|
yield { type: "status", content: `Error Occured. Recovering Stream...` };
|
|
15251
15404
|
} else {
|
|
15252
15405
|
throw new Error(`Stream collapsed too many times. (Failed to resolve ${MAX_RETRIES} times)
|
|
15253
|
-
Error Log can be found in ${
|
|
15406
|
+
Error Log can be found in ${path24.join(LOGS_DIR, "agent", "error.log")}`);
|
|
15254
15407
|
}
|
|
15255
15408
|
} else {
|
|
15256
15409
|
if (retryCount <= MAX_RETRIES) {
|
|
@@ -15268,7 +15421,7 @@ Error Log can be found in ${path22.join(LOGS_DIR, "agent", "error.log")}`);
|
|
|
15268
15421
|
yield { type: "status", content: `Trying to reach ${modelName}` };
|
|
15269
15422
|
} else {
|
|
15270
15423
|
throw new Error(`Model ${modelName} cannot be reached. (Failed ${MAX_RETRIES} times)
|
|
15271
|
-
Error Log can be found in ${
|
|
15424
|
+
Error Log can be found in ${path24.join(LOGS_DIR, "agent", "error.log")}`);
|
|
15272
15425
|
}
|
|
15273
15426
|
}
|
|
15274
15427
|
}
|
|
@@ -15386,10 +15539,10 @@ Error Log can be found in ${path22.join(LOGS_DIR, "agent", "error.log")}`);
|
|
|
15386
15539
|
}
|
|
15387
15540
|
})() : String(err);
|
|
15388
15541
|
const date = (/* @__PURE__ */ new Date()).toLocaleString();
|
|
15389
|
-
const agentErrDir =
|
|
15542
|
+
const agentErrDir = path24.join(LOGS_DIR, "agent");
|
|
15390
15543
|
yield { type: "text", content: `\u274C CRITICAL ERROR: ${errLog}` };
|
|
15391
|
-
if (!
|
|
15392
|
-
|
|
15544
|
+
if (!fs25.existsSync(agentErrDir)) fs25.mkdirSync(agentErrDir, { recursive: true });
|
|
15545
|
+
fs25.appendFileSync(path24.join(agentErrDir, "error.log"), `CRITICAL ERROR [${date}]: ${err}
|
|
15393
15546
|
|
|
15394
15547
|
----------------------------------------------------------------------
|
|
15395
15548
|
|
|
@@ -15534,20 +15687,20 @@ ${cleanResponse}
|
|
|
15534
15687
|
} else if (normalizedToolName === "web_scrape" || normalizedToolName === "webscrape") {
|
|
15535
15688
|
label = `\u2714 \x1B[95mScraped\x1B[0m`;
|
|
15536
15689
|
} else if (normalizedToolName === "view_file" || normalizedToolName === "viewfile" || normalizedToolName === "readfile") {
|
|
15537
|
-
const
|
|
15538
|
-
label = `\u2714 \x1B[95mRead File\x1B[0m: ${
|
|
15690
|
+
const path26 = parseArgs(toolCall.args).path || "";
|
|
15691
|
+
label = `\u2714 \x1B[95mRead File\x1B[0m: ${path26}`;
|
|
15539
15692
|
} else if (normalizedToolName === "list_files" || normalizedToolName === "read_folder" || normalizedToolName === "readfolder") {
|
|
15540
|
-
const
|
|
15541
|
-
label = `\u2714 \x1B[95mBrowsed Folder\x1B[0m: ${
|
|
15693
|
+
const path26 = parseArgs(toolCall.args).path || "";
|
|
15694
|
+
label = `\u2714 \x1B[95mBrowsed Folder\x1B[0m: ${path26}`;
|
|
15542
15695
|
} else if (normalizedToolName === "write_file" || normalizedToolName === "writefile") {
|
|
15543
|
-
const
|
|
15544
|
-
label = `\u2714 \x1B[95mFile Created\x1B[0m: ${
|
|
15696
|
+
const path26 = parseArgs(toolCall.args).path || "";
|
|
15697
|
+
label = `\u2714 \x1B[95mFile Created\x1B[0m: ${path26}`;
|
|
15545
15698
|
} else if (normalizedToolName === "update_file" || normalizedToolName === "updatefile" || normalizedToolName === "patchfile" || normalizedToolName === "patch_file" || normalizedToolName === "patchfile" || normalizedToolName === "updatefile") {
|
|
15546
|
-
const
|
|
15547
|
-
label = `\u2714 \x1B[95mFile Edited\x1B[0m: ${
|
|
15699
|
+
const path26 = parseArgs(toolCall.args).path || "";
|
|
15700
|
+
label = `\u2714 \x1B[95mFile Edited\x1B[0m: ${path26}`;
|
|
15548
15701
|
} else if (normalizedToolName === "file_map" || normalizedToolName === "filemap") {
|
|
15549
|
-
const
|
|
15550
|
-
label = `\u2714 \x1B[95mIndexed\x1B[0m: ${
|
|
15702
|
+
const path26 = parseArgs(toolCall.args).path || "";
|
|
15703
|
+
label = `\u2714 \x1B[95mIndexed\x1B[0m: ${path26}`;
|
|
15551
15704
|
} else if (normalizedToolName === "await") {
|
|
15552
15705
|
const { time } = parseArgs(toolCall.args);
|
|
15553
15706
|
let sec = parseFloat(time) || 0;
|
|
@@ -16466,7 +16619,7 @@ var init_RevertModal = __esm({
|
|
|
16466
16619
|
import puppeteer4 from "puppeteer";
|
|
16467
16620
|
import { exec } from "child_process";
|
|
16468
16621
|
import { promisify } from "util";
|
|
16469
|
-
import
|
|
16622
|
+
import fs26 from "fs";
|
|
16470
16623
|
var execAsync, checkPuppeteerReady, installPuppeteerBrowser;
|
|
16471
16624
|
var init_setup = __esm({
|
|
16472
16625
|
"src/utils/setup.js"() {
|
|
@@ -16475,11 +16628,11 @@ var init_setup = __esm({
|
|
|
16475
16628
|
checkPuppeteerReady = () => {
|
|
16476
16629
|
try {
|
|
16477
16630
|
const pptrConfig = getPuppeteerConfig();
|
|
16478
|
-
if (pptrConfig.executablePath &&
|
|
16631
|
+
if (pptrConfig.executablePath && fs26.existsSync(pptrConfig.executablePath)) {
|
|
16479
16632
|
return true;
|
|
16480
16633
|
}
|
|
16481
16634
|
const exePath = puppeteer4.executablePath();
|
|
16482
|
-
const exists = exePath &&
|
|
16635
|
+
const exists = exePath && fs26.existsSync(exePath);
|
|
16483
16636
|
if (exists) return true;
|
|
16484
16637
|
} catch (e) {
|
|
16485
16638
|
return false;
|
|
@@ -16566,8 +16719,8 @@ __export(app_exports, {
|
|
|
16566
16719
|
import os5 from "os";
|
|
16567
16720
|
import React16, { useState as useState15, useEffect as useEffect12, useRef as useRef4, useMemo as useMemo2 } from "react";
|
|
16568
16721
|
import { Box as Box14, Text as Text16, useInput as useInput9, useStdout as useStdout2, Static } from "ink";
|
|
16569
|
-
import
|
|
16570
|
-
import
|
|
16722
|
+
import fs27 from "fs-extra";
|
|
16723
|
+
import path25 from "path";
|
|
16571
16724
|
import { exec as exec2 } from "child_process";
|
|
16572
16725
|
import { fileURLToPath as fileURLToPath3 } from "url";
|
|
16573
16726
|
import TextInput4 from "ink-text-input";
|
|
@@ -16887,10 +17040,10 @@ function App({ args = [] }) {
|
|
|
16887
17040
|
const kbPath = getKeybindingsPath(ideName);
|
|
16888
17041
|
if (!kbPath) return;
|
|
16889
17042
|
try {
|
|
16890
|
-
await
|
|
17043
|
+
await fs27.ensureDir(path25.dirname(kbPath));
|
|
16891
17044
|
let bindings = [];
|
|
16892
|
-
if (
|
|
16893
|
-
const content =
|
|
17045
|
+
if (fs27.existsSync(kbPath)) {
|
|
17046
|
+
const content = fs27.readFileSync(kbPath, "utf8").trim();
|
|
16894
17047
|
if (content) {
|
|
16895
17048
|
try {
|
|
16896
17049
|
bindings = parseJsonc(content);
|
|
@@ -16910,7 +17063,7 @@ function App({ args = [] }) {
|
|
|
16910
17063
|
},
|
|
16911
17064
|
"when": "terminalFocus"
|
|
16912
17065
|
});
|
|
16913
|
-
|
|
17066
|
+
fs27.writeFileSync(kbPath, JSON.stringify(bindings, null, 4), "utf8");
|
|
16914
17067
|
cachedShortcut = "Shift + Enter";
|
|
16915
17068
|
setMessages((prev) => {
|
|
16916
17069
|
setCompletedIndex(prev.length + 1);
|
|
@@ -17594,7 +17747,7 @@ function App({ args = [] }) {
|
|
|
17594
17747
|
useEffect12(() => {
|
|
17595
17748
|
async function init() {
|
|
17596
17749
|
try {
|
|
17597
|
-
const pkg = JSON.parse(
|
|
17750
|
+
const pkg = JSON.parse(fs27.readFileSync(path25.join(process.cwd(), "package.json"), "utf8"));
|
|
17598
17751
|
initBridge(versionFluxflow || pkg.version || "2.0.0");
|
|
17599
17752
|
} catch (e) {
|
|
17600
17753
|
initBridge("2.0.0");
|
|
@@ -17697,7 +17850,7 @@ function App({ args = [] }) {
|
|
|
17697
17850
|
if (!parsedArgs.playground) {
|
|
17698
17851
|
deleteChat(PLAYGROUND_CHAT_ID).catch(() => {
|
|
17699
17852
|
});
|
|
17700
|
-
|
|
17853
|
+
fs27.remove(path25.join(DATA_DIR, "playground")).catch(() => {
|
|
17701
17854
|
});
|
|
17702
17855
|
}
|
|
17703
17856
|
performVersionCheck(false, freshSettings);
|
|
@@ -17731,9 +17884,9 @@ function App({ args = [] }) {
|
|
|
17731
17884
|
}
|
|
17732
17885
|
}
|
|
17733
17886
|
if (parsedArgs.playground) {
|
|
17734
|
-
const playgroundDir =
|
|
17887
|
+
const playgroundDir = path25.join(DATA_DIR, "playground");
|
|
17735
17888
|
try {
|
|
17736
|
-
|
|
17889
|
+
fs27.ensureDirSync(playgroundDir);
|
|
17737
17890
|
process.chdir(playgroundDir);
|
|
17738
17891
|
} catch (e) {
|
|
17739
17892
|
}
|
|
@@ -17774,8 +17927,8 @@ function App({ args = [] }) {
|
|
|
17774
17927
|
if (kbPath) {
|
|
17775
17928
|
try {
|
|
17776
17929
|
let bindings = [];
|
|
17777
|
-
if (
|
|
17778
|
-
const content =
|
|
17930
|
+
if (fs27.existsSync(kbPath)) {
|
|
17931
|
+
const content = fs27.readFileSync(kbPath, "utf8").trim();
|
|
17779
17932
|
if (content) {
|
|
17780
17933
|
bindings = parseJsonc(content);
|
|
17781
17934
|
}
|
|
@@ -18106,22 +18259,22 @@ ${cleanText}`, color: "magenta" }];
|
|
|
18106
18259
|
});
|
|
18107
18260
|
break;
|
|
18108
18261
|
}
|
|
18109
|
-
const src =
|
|
18110
|
-
const dest =
|
|
18262
|
+
const src = path25.join(DATA_DIR, "playground");
|
|
18263
|
+
const dest = path25.join(parsedArgs.originalCwd, "playground-export");
|
|
18111
18264
|
const moveFiles = async () => {
|
|
18112
18265
|
try {
|
|
18113
18266
|
setMessages((prev) => {
|
|
18114
18267
|
setCompletedIndex(prev.length + 1);
|
|
18115
18268
|
return [...prev, { id: Date.now(), role: "system", text: `[PLAYGROUND] Exporting playground content to ${dest}`, isMeta: true }];
|
|
18116
18269
|
});
|
|
18117
|
-
await
|
|
18270
|
+
await fs27.ensureDir(dest);
|
|
18118
18271
|
const excludeDirs = ["node_modules", ".git", ".venv", "venv", "env", ".next", "dist", "build", ".cache"];
|
|
18119
|
-
await
|
|
18272
|
+
await fs27.copy(src, dest, {
|
|
18120
18273
|
overwrite: true,
|
|
18121
18274
|
filter: (srcPath) => {
|
|
18122
|
-
const relative =
|
|
18275
|
+
const relative = path25.relative(src, srcPath);
|
|
18123
18276
|
if (!relative) return true;
|
|
18124
|
-
const parts2 = relative.split(
|
|
18277
|
+
const parts2 = relative.split(path25.sep);
|
|
18125
18278
|
return !parts2.some((part) => excludeDirs.includes(part));
|
|
18126
18279
|
}
|
|
18127
18280
|
});
|
|
@@ -18183,7 +18336,7 @@ ${cleanText}`, color: "magenta" }];
|
|
|
18183
18336
|
}
|
|
18184
18337
|
}
|
|
18185
18338
|
setTimeout(() => {
|
|
18186
|
-
|
|
18339
|
+
fs27.emptyDir(path25.join(DATA_DIR, "playground")).catch((err) => {
|
|
18187
18340
|
setMessages((prev) => {
|
|
18188
18341
|
const newMsgs = [...prev, {
|
|
18189
18342
|
id: "playground-" + Date.now(),
|
|
@@ -18503,7 +18656,7 @@ ${cleanText}`, color: "magenta" }];
|
|
|
18503
18656
|
}
|
|
18504
18657
|
case "/export": {
|
|
18505
18658
|
const exportFile = `export-fluxflow-${chatId}.txt`;
|
|
18506
|
-
const exportPath =
|
|
18659
|
+
const exportPath = path25.join(process.cwd(), exportFile);
|
|
18507
18660
|
const exportLines = [];
|
|
18508
18661
|
let insideAgentBlock = false;
|
|
18509
18662
|
for (let i = 0; i < messages.length; i++) {
|
|
@@ -18555,7 +18708,7 @@ ${cleanText}`, color: "magenta" }];
|
|
|
18555
18708
|
}
|
|
18556
18709
|
const fileContent = exportLines.join("\n");
|
|
18557
18710
|
try {
|
|
18558
|
-
|
|
18711
|
+
fs27.writeFileSync(exportPath, fileContent, "utf8");
|
|
18559
18712
|
setMessages((prev) => {
|
|
18560
18713
|
setCompletedIndex(prev.length + 1);
|
|
18561
18714
|
return [...prev, {
|
|
@@ -18602,12 +18755,12 @@ ${list || "No saved chats found."}`, isMeta: true }];
|
|
|
18602
18755
|
setCompletedIndex(prev.length + 1);
|
|
18603
18756
|
return [...prev, { id: Date.now(), role: "system", text: "[NUCLEAR] Initiating reset...", isMeta: true }];
|
|
18604
18757
|
});
|
|
18605
|
-
if (
|
|
18606
|
-
if (
|
|
18607
|
-
if (
|
|
18758
|
+
if (fs27.existsSync(LOGS_DIR)) fs27.removeSync(LOGS_DIR);
|
|
18759
|
+
if (fs27.existsSync(SECRET_DIR)) fs27.removeSync(SECRET_DIR);
|
|
18760
|
+
if (fs27.existsSync(SETTINGS_FILE)) fs27.removeSync(SETTINGS_FILE);
|
|
18608
18761
|
try {
|
|
18609
|
-
const items =
|
|
18610
|
-
if (items.length === 0)
|
|
18762
|
+
const items = fs27.readdirSync(FLUXFLOW_DIR);
|
|
18763
|
+
if (items.length === 0) fs27.removeSync(FLUXFLOW_DIR);
|
|
18611
18764
|
} catch (e) {
|
|
18612
18765
|
}
|
|
18613
18766
|
setTimeout(() => {
|
|
@@ -18729,15 +18882,15 @@ ${list || "No saved chats found."}`, isMeta: true }];
|
|
|
18729
18882
|
# SKILLS & WORKFLOWS
|
|
18730
18883
|
- [Define custom step-by-step recipes for this project here]
|
|
18731
18884
|
`;
|
|
18732
|
-
const filePath =
|
|
18733
|
-
if (
|
|
18885
|
+
const filePath = path25.join(process.cwd(), "FluxFlow.md");
|
|
18886
|
+
if (fs27.pathExistsSync(filePath)) {
|
|
18734
18887
|
setMessages((prev) => {
|
|
18735
18888
|
setCompletedIndex(prev.length + 1);
|
|
18736
18889
|
return [...prev, { id: "init-err-" + Date.now(), role: "system", text: "ERROR: FluxFlow.md already exists in this directory.", isMeta: true }];
|
|
18737
18890
|
});
|
|
18738
18891
|
} else {
|
|
18739
18892
|
try {
|
|
18740
|
-
|
|
18893
|
+
fs27.writeFileSync(filePath, template);
|
|
18741
18894
|
setMessages((prev) => {
|
|
18742
18895
|
setCompletedIndex(prev.length + 1);
|
|
18743
18896
|
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 }];
|
|
@@ -20604,7 +20757,42 @@ Selection: ${val}`,
|
|
|
20604
20757
|
glintWidth: 2,
|
|
20605
20758
|
typeSpeed: 10
|
|
20606
20759
|
}
|
|
20607
|
-
), /* @__PURE__ */ React16.createElement(Text16, { color: "gray" }, activeTime > 0 ? `(${activeTime.toFixed(0)}s)` : "")) : /* @__PURE__ */ React16.createElement(Text16, { color: "grey", italic: true }, input.length > 0 && escPressCount ? "Press ESC again to clear input" : hasPasteBlock ? "Press CTRL + O to expand" : "Waiting for input...")), /* @__PURE__ */ React16.createElement(Box14, null,
|
|
20760
|
+
), /* @__PURE__ */ React16.createElement(Text16, { color: "gray" }, activeTime > 0 ? `(${activeTime.toFixed(0)}s)` : "")) : /* @__PURE__ */ React16.createElement(Text16, { color: "grey", italic: true }, input.length > 0 && escPressCount ? "Press ESC again to clear input" : hasPasteBlock ? "Press CTRL + O to expand" : "Waiting for input...")), /* @__PURE__ */ React16.createElement(Box14, null, (() => {
|
|
20761
|
+
const status = statusText?.toLowerCase() ?? "";
|
|
20762
|
+
const showWaiting = isProcessing && Date.now() - lastChunkTime > 15e3 && activeSubagents.length === 0 && (status.includes("connecting") || status.includes("working"));
|
|
20763
|
+
if (showWaiting) {
|
|
20764
|
+
return /* @__PURE__ */ React16.createElement(Box14, null, /* @__PURE__ */ React16.createElement(
|
|
20765
|
+
GlintText_default,
|
|
20766
|
+
{
|
|
20767
|
+
text: "Waiting for API",
|
|
20768
|
+
baseColor: "white",
|
|
20769
|
+
glintColor: "gray",
|
|
20770
|
+
glintWidth: 4,
|
|
20771
|
+
speed: 80
|
|
20772
|
+
}
|
|
20773
|
+
), /* @__PURE__ */ React16.createElement(Text16, { color: "gray", dimColor: true }, " \u2503 "));
|
|
20774
|
+
}
|
|
20775
|
+
if (wittyPhrase) {
|
|
20776
|
+
return /* @__PURE__ */ React16.createElement(Box14, null, /* @__PURE__ */ React16.createElement(
|
|
20777
|
+
GlintText_default,
|
|
20778
|
+
{
|
|
20779
|
+
text: wittyPhrase,
|
|
20780
|
+
italic: true,
|
|
20781
|
+
speed: 80,
|
|
20782
|
+
typeSpeed: 15
|
|
20783
|
+
}
|
|
20784
|
+
), /* @__PURE__ */ React16.createElement(Text16, { color: "gray", dimColor: true }, " \u2503 "));
|
|
20785
|
+
}
|
|
20786
|
+
return null;
|
|
20787
|
+
})(), /* @__PURE__ */ React16.createElement(
|
|
20788
|
+
GlintText_default,
|
|
20789
|
+
{
|
|
20790
|
+
text: tempModelOverride || activeModel.split("/")[1] || activeModel,
|
|
20791
|
+
baseColor: "white",
|
|
20792
|
+
glintColor: "gray",
|
|
20793
|
+
glintWidth: 3
|
|
20794
|
+
}
|
|
20795
|
+
))), /* @__PURE__ */ React16.createElement(Box14, { flexDirection: "column", width: "100%" }, /* @__PURE__ */ React16.createElement(Box14, { width: "100%", height: 1, overflow: "hidden" }, /* @__PURE__ */ React16.createElement(Text16, { color: "#555555" }, "\u2584".repeat(Math.max(1, terminalSize.columns)))), /* @__PURE__ */ React16.createElement(
|
|
20608
20796
|
Box14,
|
|
20609
20797
|
{
|
|
20610
20798
|
backgroundColor: "#555555",
|
|
@@ -20870,11 +21058,11 @@ var init_app = __esm({
|
|
|
20870
21058
|
if (process.platform === "win32") {
|
|
20871
21059
|
const appData = process.env.APPDATA;
|
|
20872
21060
|
if (!appData) return null;
|
|
20873
|
-
return
|
|
21061
|
+
return path25.join(appData, dirName, "User", "keybindings.json");
|
|
20874
21062
|
} else if (process.platform === "darwin") {
|
|
20875
|
-
return
|
|
21063
|
+
return path25.join(home, "Library", "Application Support", dirName, "User", "keybindings.json");
|
|
20876
21064
|
} else {
|
|
20877
|
-
return
|
|
21065
|
+
return path25.join(home, ".config", dirName, "User", "keybindings.json");
|
|
20878
21066
|
}
|
|
20879
21067
|
};
|
|
20880
21068
|
parseJsonc = (content) => {
|
|
@@ -20918,8 +21106,8 @@ var init_app = __esm({
|
|
|
20918
21106
|
SESSION_START_TIME = Date.now();
|
|
20919
21107
|
CHANGELOG_URL = "https://fluxflow-cli.onrender.com/changelog";
|
|
20920
21108
|
DOCS_URL = "https://fluxflow-cli.onrender.com/";
|
|
20921
|
-
packageJsonPath =
|
|
20922
|
-
packageJson = JSON.parse(
|
|
21109
|
+
packageJsonPath = path25.join(path25.dirname(fileURLToPath3(import.meta.url)), "../package.json");
|
|
21110
|
+
packageJson = JSON.parse(fs27.readFileSync(packageJsonPath, "utf8"));
|
|
20923
21111
|
versionFluxflow = packageJson.version;
|
|
20924
21112
|
updatedOn = packageJson.date || "2026-05-20";
|
|
20925
21113
|
ResolutionModal = ({ data, onResolve, onEdit }) => /* @__PURE__ */ React16.createElement(Box14, { flexDirection: "column", borderStyle: "round", borderColor: "grey", padding: 0, width: "100%" }, /* @__PURE__ */ React16.createElement(Box14, { paddingX: 1 }, /* @__PURE__ */ React16.createElement(Text16, { color: "white", bold: true, underline: true }, data.startsWith("/btw") ? "QUESTION" : "STEERING HINT", " RESOLUTION")), /* @__PURE__ */ React16.createElement(Box14, { paddingX: 1, marginTop: 1 }, /* @__PURE__ */ React16.createElement(Text16, null, "The agent already finished the task before your ", data.startsWith("/btw") ? "question" : "hint", " was consumed.")), /* @__PURE__ */ React16.createElement(Box14, { marginTop: 1, backgroundColor: "#222", paddingX: 2, width: "100%" }, /* @__PURE__ */ React16.createElement(Text16, { italic: true, color: "gray" }, '"', data.replace("/btw", "").trim(), '"')), /* @__PURE__ */ React16.createElement(Box14, { paddingX: 1, marginTop: 1 }, /* @__PURE__ */ React16.createElement(Text16, { color: "grey" }, "How would you like to proceed?")), /* @__PURE__ */ React16.createElement(Box14, { marginTop: 0 }, /* @__PURE__ */ React16.createElement(
|
|
@@ -21016,20 +21204,20 @@ var init_app = __esm({
|
|
|
21016
21204
|
const scan = (currentDir) => {
|
|
21017
21205
|
if (fileList.length >= 2e3) return;
|
|
21018
21206
|
try {
|
|
21019
|
-
const files =
|
|
21207
|
+
const files = fs27.readdirSync(currentDir);
|
|
21020
21208
|
for (const file of files) {
|
|
21021
21209
|
if (fileList.length >= 2e3) return;
|
|
21022
21210
|
if (["node_modules", ".git", ".gemini", "dist", "build", ".next", ".cache", "out"].includes(file)) {
|
|
21023
21211
|
continue;
|
|
21024
21212
|
}
|
|
21025
|
-
const filePath =
|
|
21026
|
-
const stat =
|
|
21213
|
+
const filePath = path25.join(currentDir, file);
|
|
21214
|
+
const stat = fs27.statSync(filePath);
|
|
21027
21215
|
if (stat.isDirectory()) {
|
|
21028
21216
|
scan(filePath);
|
|
21029
21217
|
} else {
|
|
21030
21218
|
fileList.push({
|
|
21031
21219
|
name: flattenString(file),
|
|
21032
|
-
relativePath: flattenString(
|
|
21220
|
+
relativePath: flattenString(path25.relative(process.cwd(), filePath))
|
|
21033
21221
|
});
|
|
21034
21222
|
}
|
|
21035
21223
|
}
|
|
@@ -21172,11 +21360,11 @@ if (isBundled && !process.execArgv.some((arg) => arg.includes("max-old-space-siz
|
|
|
21172
21360
|
const isVersion = args.includes("--version") || args.includes("-v");
|
|
21173
21361
|
const isUpdate = args[0] === "--update";
|
|
21174
21362
|
if (isVersion || isHelp || isHelpCommands || isUpdate) {
|
|
21175
|
-
const
|
|
21176
|
-
const
|
|
21363
|
+
const fs28 = await import("fs");
|
|
21364
|
+
const path26 = await import("path");
|
|
21177
21365
|
const { fileURLToPath: fileURLToPath5 } = await import("url");
|
|
21178
|
-
const packageJsonPath2 =
|
|
21179
|
-
const packageJson2 = JSON.parse(
|
|
21366
|
+
const packageJsonPath2 = path26.join(path26.dirname(fileURLToPath5(import.meta.url)), "../package.json");
|
|
21367
|
+
const packageJson2 = JSON.parse(fs28.readFileSync(packageJsonPath2, "utf8"));
|
|
21180
21368
|
const versionFluxflow2 = packageJson2.version;
|
|
21181
21369
|
if (isVersion) {
|
|
21182
21370
|
console.log(`v${versionFluxflow2}`);
|