fluxflow-cli 3.16.0 → 3.16.2
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 +191 -112
- package/package.json +4 -3
package/dist/fluxflow.js
CHANGED
|
@@ -52,13 +52,14 @@ __export(paths_exports, {
|
|
|
52
52
|
SETTINGS_FILE: () => SETTINGS_FILE,
|
|
53
53
|
TEMP_MEM_CHAT_FILE: () => TEMP_MEM_CHAT_FILE,
|
|
54
54
|
TEMP_MEM_FILE: () => TEMP_MEM_FILE,
|
|
55
|
-
USAGE_FILE: () => USAGE_FILE
|
|
55
|
+
USAGE_FILE: () => USAGE_FILE,
|
|
56
|
+
USAGE_FILE_OLD: () => USAGE_FILE_OLD
|
|
56
57
|
});
|
|
57
58
|
import os from "os";
|
|
58
59
|
import path from "path";
|
|
59
60
|
import fs from "fs";
|
|
60
61
|
import crypto from "crypto";
|
|
61
|
-
var FLUXFLOW_DIR, SETTINGS_FILE, externalDir, DATA_DIR, LOGS_DIR, SECRET_DIR, HISTORY_FILE, HISTORY_DIR, USAGE_FILE, MEMORIES_FILE, TEMP_MEM_FILE, TEMP_MEM_CHAT_FILE, BACKUPS_DIR, LEDGER_FILE, LEDGER_ADVANCE_FILE, ACTIVE_TX_FILE, PATHS_FILE, CONTEXT_FILE, PARSER_DIR;
|
|
62
|
+
var FLUXFLOW_DIR, SETTINGS_FILE, externalDir, DATA_DIR, LOGS_DIR, SECRET_DIR, HISTORY_FILE, HISTORY_DIR, USAGE_FILE_OLD, USAGE_FILE, MEMORIES_FILE, TEMP_MEM_FILE, TEMP_MEM_CHAT_FILE, BACKUPS_DIR, LEDGER_FILE, LEDGER_ADVANCE_FILE, ACTIVE_TX_FILE, PATHS_FILE, CONTEXT_FILE, PARSER_DIR;
|
|
62
63
|
var init_paths = __esm({
|
|
63
64
|
"src/utils/paths.js"() {
|
|
64
65
|
FLUXFLOW_DIR = path.join(os.homedir(), ".fluxflow");
|
|
@@ -96,7 +97,8 @@ var init_paths = __esm({
|
|
|
96
97
|
SECRET_DIR = path.join(DATA_DIR, "secret");
|
|
97
98
|
HISTORY_FILE = path.join(SECRET_DIR, "history.json");
|
|
98
99
|
HISTORY_DIR = path.join(SECRET_DIR, "history");
|
|
99
|
-
|
|
100
|
+
USAGE_FILE_OLD = path.join(FLUXFLOW_DIR, "usage.json");
|
|
101
|
+
USAGE_FILE = path.join(SECRET_DIR, "usage.json");
|
|
100
102
|
MEMORIES_FILE = path.join(SECRET_DIR, "memories.json");
|
|
101
103
|
TEMP_MEM_FILE = path.join(SECRET_DIR, "memory-temp.json");
|
|
102
104
|
TEMP_MEM_CHAT_FILE = path.join(SECRET_DIR, "temp-memory-chat.json");
|
|
@@ -6105,6 +6107,7 @@ var init_ChatLayout = __esm({
|
|
|
6105
6107
|
{ cmd: "/quit", desc: "Exit and shutdown Flux" },
|
|
6106
6108
|
{ cmd: "/help", desc: "Show all available commands" },
|
|
6107
6109
|
{ cmd: "/compress", desc: "Summarize and compress chat history" },
|
|
6110
|
+
{ cmd: "/truncate", desc: "Truncate tool results in chat history" },
|
|
6108
6111
|
{ cmd: "/clear", desc: "Clear terminal screen" },
|
|
6109
6112
|
{ cmd: "/resume", desc: "Load previous session" },
|
|
6110
6113
|
{ cmd: "/revert", desc: "Revert codebase to checkpoint" },
|
|
@@ -9187,24 +9190,11 @@ var init_history = __esm({
|
|
|
9187
9190
|
// src/utils/usage.js
|
|
9188
9191
|
import fs10 from "fs-extra";
|
|
9189
9192
|
import path9 from "path";
|
|
9190
|
-
|
|
9191
|
-
var getLocalBackupPath, BACKUP_FILE, generateSaveId, cachedUsage, writeTimeout, lastWriteTime, isDirty, defaultStats, purgeOldHistory, loadUsageFromFile, flushUsage, queueFlush, initUsage, forceFlushUsage, getDailyUsage, getMonthlyUsage, incrementUsage, runtimeSession, addToUsage, getCustomPeriodUsage, checkQuota, getImageQuotaBuckets, getImageQuotaLimit, checkImageQuota, getImageQuotaStats, recordImageGeneration;
|
|
9193
|
+
var generateSaveId, cachedUsage, writeTimeout, lastWriteTime, isDirty, defaultStats, purgeOldHistory, loadUsageFromFile, flushUsage, queueFlush, initUsage, forceFlushUsage, getDailyUsage, getMonthlyUsage, incrementUsage, runtimeSession, addToUsage, getCustomPeriodUsage, checkQuota, getImageQuotaBuckets, getImageQuotaLimit, checkImageQuota, getImageQuotaStats, recordImageGeneration;
|
|
9192
9194
|
var init_usage = __esm({
|
|
9193
9195
|
"src/utils/usage.js"() {
|
|
9194
9196
|
init_paths();
|
|
9195
9197
|
init_crypto();
|
|
9196
|
-
getLocalBackupPath = () => {
|
|
9197
|
-
if (process.platform === "win32") {
|
|
9198
|
-
const localAppData = process.env.LOCALAPPDATA || path9.join(os3.homedir(), "AppData", "Local");
|
|
9199
|
-
return path9.join(localAppData, "FxFl", "backups", "backup.json");
|
|
9200
|
-
}
|
|
9201
|
-
if (process.platform === "darwin") {
|
|
9202
|
-
return path9.join(os3.homedir(), "Library", "Application Support", "FxFl", "backups", "backup.json");
|
|
9203
|
-
}
|
|
9204
|
-
const xdgDataHome = process.env.XDG_DATA_HOME || path9.join(os3.homedir(), ".local", "share");
|
|
9205
|
-
return path9.join(xdgDataHome, "fxfl", "backups", "backup.json");
|
|
9206
|
-
};
|
|
9207
|
-
BACKUP_FILE = getLocalBackupPath();
|
|
9208
9198
|
generateSaveId = () => Math.random().toString(36).substring(2) + Date.now().toString(36);
|
|
9209
9199
|
cachedUsage = null;
|
|
9210
9200
|
writeTimeout = null;
|
|
@@ -9239,10 +9229,16 @@ var init_usage = __esm({
|
|
|
9239
9229
|
return purged;
|
|
9240
9230
|
};
|
|
9241
9231
|
loadUsageFromFile = async () => {
|
|
9242
|
-
const
|
|
9232
|
+
const today2 = (/* @__PURE__ */ new Date()).toISOString().split("T")[0];
|
|
9233
|
+
try {
|
|
9234
|
+
if (!await fs10.exists(USAGE_FILE) && await fs10.exists(USAGE_FILE_OLD)) {
|
|
9235
|
+
await fs10.ensureDir(path9.dirname(USAGE_FILE));
|
|
9236
|
+
await fs10.move(USAGE_FILE_OLD, USAGE_FILE);
|
|
9237
|
+
}
|
|
9238
|
+
} catch (err) {
|
|
9239
|
+
}
|
|
9243
9240
|
const tempFile = USAGE_FILE + ".tmp";
|
|
9244
9241
|
let primaryData = null;
|
|
9245
|
-
let backupData = null;
|
|
9246
9242
|
try {
|
|
9247
9243
|
if (await fs10.exists(tempFile)) {
|
|
9248
9244
|
const rawContent = (await fs10.readFile(tempFile, "utf8")).trim();
|
|
@@ -9284,44 +9280,7 @@ var init_usage = __esm({
|
|
|
9284
9280
|
} catch (err) {
|
|
9285
9281
|
}
|
|
9286
9282
|
}
|
|
9287
|
-
|
|
9288
|
-
if (await fs10.exists(BACKUP_FILE)) {
|
|
9289
|
-
const rawContent = (await fs10.readFile(BACKUP_FILE, "utf8")).trim();
|
|
9290
|
-
if (rawContent.startsWith("{") || rawContent.startsWith("[")) {
|
|
9291
|
-
backupData = JSON.parse(rawContent);
|
|
9292
|
-
} else {
|
|
9293
|
-
backupData = JSON.parse(decryptAes(rawContent));
|
|
9294
|
-
}
|
|
9295
|
-
}
|
|
9296
|
-
} catch (err) {
|
|
9297
|
-
}
|
|
9298
|
-
let resolvedData = null;
|
|
9299
|
-
if (primaryData && backupData) {
|
|
9300
|
-
if (primaryData.saveId !== backupData.saveId) {
|
|
9301
|
-
resolvedData = primaryData;
|
|
9302
|
-
try {
|
|
9303
|
-
await fs10.ensureDir(path9.dirname(BACKUP_FILE));
|
|
9304
|
-
await fs10.copy(USAGE_FILE, BACKUP_FILE);
|
|
9305
|
-
} catch (e) {
|
|
9306
|
-
}
|
|
9307
|
-
} else {
|
|
9308
|
-
resolvedData = primaryData;
|
|
9309
|
-
}
|
|
9310
|
-
} else if (primaryData && !backupData) {
|
|
9311
|
-
resolvedData = primaryData;
|
|
9312
|
-
try {
|
|
9313
|
-
await fs10.ensureDir(path9.dirname(BACKUP_FILE));
|
|
9314
|
-
await fs10.copy(USAGE_FILE, BACKUP_FILE);
|
|
9315
|
-
} catch (e) {
|
|
9316
|
-
}
|
|
9317
|
-
} else if (!primaryData && backupData) {
|
|
9318
|
-
resolvedData = backupData;
|
|
9319
|
-
try {
|
|
9320
|
-
await fs10.ensureDir(path9.dirname(USAGE_FILE));
|
|
9321
|
-
await fs10.copy(BACKUP_FILE, USAGE_FILE);
|
|
9322
|
-
} catch (e) {
|
|
9323
|
-
}
|
|
9324
|
-
}
|
|
9283
|
+
let resolvedData = primaryData;
|
|
9325
9284
|
if (resolvedData) {
|
|
9326
9285
|
const stats = resolvedData.stats || { ...defaultStats };
|
|
9327
9286
|
const mergedStats = { ...defaultStats, ...stats };
|
|
@@ -9329,28 +9288,32 @@ var init_usage = __esm({
|
|
|
9329
9288
|
mergedStats.imageCalls = [];
|
|
9330
9289
|
}
|
|
9331
9290
|
const history = resolvedData.history || {};
|
|
9332
|
-
|
|
9291
|
+
const purgedHistory = purgeOldHistory(history, today2);
|
|
9292
|
+
if (Object.keys(history).length !== Object.keys(purgedHistory).length) {
|
|
9293
|
+
isDirty = true;
|
|
9294
|
+
}
|
|
9295
|
+
if (resolvedData.date === today2) {
|
|
9333
9296
|
return {
|
|
9334
9297
|
...resolvedData,
|
|
9335
9298
|
stats: mergedStats,
|
|
9336
|
-
history
|
|
9299
|
+
history: purgedHistory
|
|
9337
9300
|
};
|
|
9338
9301
|
} else {
|
|
9339
9302
|
const oldDate = resolvedData.date;
|
|
9340
9303
|
const oldStats = mergedStats;
|
|
9341
|
-
const updatedHistory = { ...
|
|
9304
|
+
const updatedHistory = { ...purgedHistory };
|
|
9342
9305
|
if (oldDate) {
|
|
9343
9306
|
updatedHistory[oldDate] = oldStats;
|
|
9344
9307
|
}
|
|
9345
9308
|
return {
|
|
9346
|
-
date:
|
|
9309
|
+
date: today2,
|
|
9347
9310
|
stats: { ...defaultStats },
|
|
9348
|
-
history: purgeOldHistory(updatedHistory,
|
|
9311
|
+
history: purgeOldHistory(updatedHistory, today2)
|
|
9349
9312
|
};
|
|
9350
9313
|
}
|
|
9351
9314
|
}
|
|
9352
9315
|
return {
|
|
9353
|
-
date:
|
|
9316
|
+
date: today2,
|
|
9354
9317
|
stats: { ...defaultStats },
|
|
9355
9318
|
history: {}
|
|
9356
9319
|
};
|
|
@@ -9433,7 +9396,10 @@ var init_usage = __esm({
|
|
|
9433
9396
|
mergedHistory[dateKey] = diskData.history[dateKey];
|
|
9434
9397
|
}
|
|
9435
9398
|
}
|
|
9436
|
-
cachedUsage.history = mergedHistory;
|
|
9399
|
+
cachedUsage.history = purgeOldHistory(mergedHistory, cachedUsage.date || today);
|
|
9400
|
+
} else if (cachedUsage && cachedUsage.history) {
|
|
9401
|
+
const today2 = (/* @__PURE__ */ new Date()).toISOString().split("T")[0];
|
|
9402
|
+
cachedUsage.history = purgeOldHistory(cachedUsage.history, today2);
|
|
9437
9403
|
}
|
|
9438
9404
|
cachedUsage.saveId = generateSaveId();
|
|
9439
9405
|
const tempFile = USAGE_FILE + ".tmp";
|
|
@@ -9443,11 +9409,6 @@ var init_usage = __esm({
|
|
|
9443
9409
|
await fs10.fsync(fd);
|
|
9444
9410
|
await fs10.close(fd);
|
|
9445
9411
|
await fs10.rename(tempFile, USAGE_FILE);
|
|
9446
|
-
try {
|
|
9447
|
-
await fs10.ensureDir(path9.dirname(BACKUP_FILE));
|
|
9448
|
-
await fs10.copy(USAGE_FILE, BACKUP_FILE);
|
|
9449
|
-
} catch (backupErr) {
|
|
9450
|
-
}
|
|
9451
9412
|
isDirty = false;
|
|
9452
9413
|
lastWriteTime = Date.now();
|
|
9453
9414
|
} catch (e) {
|
|
@@ -9466,6 +9427,9 @@ var init_usage = __esm({
|
|
|
9466
9427
|
};
|
|
9467
9428
|
initUsage = async () => {
|
|
9468
9429
|
cachedUsage = await loadUsageFromFile();
|
|
9430
|
+
if (isDirty) {
|
|
9431
|
+
queueFlush();
|
|
9432
|
+
}
|
|
9469
9433
|
};
|
|
9470
9434
|
forceFlushUsage = async () => {
|
|
9471
9435
|
if (writeTimeout) {
|
|
@@ -9475,10 +9439,10 @@ var init_usage = __esm({
|
|
|
9475
9439
|
await flushUsage();
|
|
9476
9440
|
};
|
|
9477
9441
|
getDailyUsage = async () => {
|
|
9478
|
-
const
|
|
9442
|
+
const today2 = (/* @__PURE__ */ new Date()).toISOString().split("T")[0];
|
|
9479
9443
|
if (!cachedUsage) {
|
|
9480
9444
|
cachedUsage = await loadUsageFromFile();
|
|
9481
|
-
} else if (cachedUsage.date !==
|
|
9445
|
+
} else if (cachedUsage.date !== today2) {
|
|
9482
9446
|
const oldDate = cachedUsage.date;
|
|
9483
9447
|
const oldStats = cachedUsage.stats;
|
|
9484
9448
|
const history = cachedUsage.history || {};
|
|
@@ -9486,9 +9450,9 @@ var init_usage = __esm({
|
|
|
9486
9450
|
history[oldDate] = oldStats;
|
|
9487
9451
|
}
|
|
9488
9452
|
cachedUsage = {
|
|
9489
|
-
date:
|
|
9453
|
+
date: today2,
|
|
9490
9454
|
stats: { ...defaultStats },
|
|
9491
|
-
history: purgeOldHistory(history,
|
|
9455
|
+
history: purgeOldHistory(history, today2)
|
|
9492
9456
|
};
|
|
9493
9457
|
isDirty = true;
|
|
9494
9458
|
await flushUsage();
|
|
@@ -9499,15 +9463,15 @@ var init_usage = __esm({
|
|
|
9499
9463
|
return cachedUsage.stats;
|
|
9500
9464
|
};
|
|
9501
9465
|
getMonthlyUsage = async () => {
|
|
9502
|
-
const
|
|
9466
|
+
const today2 = (/* @__PURE__ */ new Date()).toISOString().split("T")[0];
|
|
9503
9467
|
if (!cachedUsage) {
|
|
9504
9468
|
cachedUsage = await loadUsageFromFile();
|
|
9505
9469
|
}
|
|
9506
|
-
if (cachedUsage.date !==
|
|
9470
|
+
if (cachedUsage.date !== today2) {
|
|
9507
9471
|
await getDailyUsage();
|
|
9508
9472
|
}
|
|
9509
9473
|
const history = cachedUsage.history || {};
|
|
9510
|
-
const purgedHistory = purgeOldHistory(history,
|
|
9474
|
+
const purgedHistory = purgeOldHistory(history, today2);
|
|
9511
9475
|
cachedUsage.history = purgedHistory;
|
|
9512
9476
|
const todayStats = cachedUsage.stats || { ...defaultStats };
|
|
9513
9477
|
const summed = { ...defaultStats };
|
|
@@ -9604,17 +9568,17 @@ var init_usage = __esm({
|
|
|
9604
9568
|
queueFlush();
|
|
9605
9569
|
};
|
|
9606
9570
|
getCustomPeriodUsage = async (resetDay = 1) => {
|
|
9607
|
-
const
|
|
9608
|
-
const todayStr =
|
|
9571
|
+
const today2 = /* @__PURE__ */ new Date();
|
|
9572
|
+
const todayStr = today2.toISOString().split("T")[0];
|
|
9609
9573
|
if (!cachedUsage) {
|
|
9610
9574
|
cachedUsage = await loadUsageFromFile();
|
|
9611
9575
|
}
|
|
9612
9576
|
if (cachedUsage.date !== todayStr) {
|
|
9613
9577
|
await getDailyUsage();
|
|
9614
9578
|
}
|
|
9615
|
-
let startYear =
|
|
9616
|
-
let startMonth =
|
|
9617
|
-
const todayDay =
|
|
9579
|
+
let startYear = today2.getFullYear();
|
|
9580
|
+
let startMonth = today2.getMonth();
|
|
9581
|
+
const todayDay = today2.getDate();
|
|
9618
9582
|
if (todayDay < resetDay) {
|
|
9619
9583
|
startMonth -= 1;
|
|
9620
9584
|
if (startMonth < 0) {
|
|
@@ -9928,14 +9892,14 @@ var init_usage = __esm({
|
|
|
9928
9892
|
});
|
|
9929
9893
|
|
|
9930
9894
|
// src/utils/puppeteer_helper.js
|
|
9931
|
-
import
|
|
9895
|
+
import os3 from "os";
|
|
9932
9896
|
import path10 from "path";
|
|
9933
9897
|
import fs11 from "fs";
|
|
9934
9898
|
import { createRequire } from "module";
|
|
9935
9899
|
import { fileURLToPath as fileURLToPath2 } from "url";
|
|
9936
9900
|
function getPuppeteerConfig() {
|
|
9937
|
-
const platform =
|
|
9938
|
-
const arch =
|
|
9901
|
+
const platform = os3.platform();
|
|
9902
|
+
const arch = os3.arch();
|
|
9939
9903
|
let pptrPlatform = "";
|
|
9940
9904
|
let execName = "";
|
|
9941
9905
|
let subDir = "";
|
|
@@ -10272,6 +10236,7 @@ ${finalResults}`;
|
|
|
10272
10236
|
import puppeteer2 from "puppeteer";
|
|
10273
10237
|
import fs13 from "fs";
|
|
10274
10238
|
import path12 from "path";
|
|
10239
|
+
import TurndownService from "turndown";
|
|
10275
10240
|
var web_scrape;
|
|
10276
10241
|
var init_web_scrape = __esm({
|
|
10277
10242
|
"src/tools/web_scrape.js"() {
|
|
@@ -10329,15 +10294,20 @@ var init_web_scrape = __esm({
|
|
|
10329
10294
|
el.removeAttribute(attrName);
|
|
10330
10295
|
}
|
|
10331
10296
|
}
|
|
10332
|
-
|
|
10333
|
-
|
|
10297
|
+
});
|
|
10298
|
+
while (document.querySelector("div, span")) {
|
|
10299
|
+
document.querySelectorAll("div, span").forEach((el) => {
|
|
10300
|
+
if (el.parentNode) {
|
|
10334
10301
|
el.replaceWith(...el.childNodes);
|
|
10335
10302
|
}
|
|
10336
|
-
}
|
|
10303
|
+
});
|
|
10304
|
+
}
|
|
10305
|
+
document.querySelectorAll("br").forEach((br) => {
|
|
10306
|
+
br.replaceWith(document.createTextNode("\n\n"));
|
|
10337
10307
|
});
|
|
10338
10308
|
const pruneEmpty = () => {
|
|
10339
10309
|
let found = false;
|
|
10340
|
-
document.querySelectorAll("
|
|
10310
|
+
document.querySelectorAll("*").forEach((el) => {
|
|
10341
10311
|
if (el.childNodes.length === 0 && !el.innerText.trim()) {
|
|
10342
10312
|
el.remove();
|
|
10343
10313
|
found = true;
|
|
@@ -10349,11 +10319,17 @@ var init_web_scrape = __esm({
|
|
|
10349
10319
|
return document.body.innerHTML;
|
|
10350
10320
|
});
|
|
10351
10321
|
if (!htmlContent) throw new Error("EMPTY_RENDER_RESULT");
|
|
10352
|
-
const cleanedHtml = htmlContent.replace(
|
|
10322
|
+
const cleanedHtml = htmlContent.replace(/<br\s*\/?>/gi, "\n\n").replace(/[ \t]+/g, " ").replace(/>[ \t]+</g, "><").replace(/\n\s+/g, "\n").replace(/\n{3,}/g, "\n\n").trim();
|
|
10323
|
+
const turndownService = new TurndownService({
|
|
10324
|
+
headingStyle: "atx",
|
|
10325
|
+
codeBlockStyle: "fenced"
|
|
10326
|
+
});
|
|
10327
|
+
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");
|
|
10328
|
+
const markdown = rawMarkdown.substring(0, 5e4);
|
|
10353
10329
|
await browser.close();
|
|
10354
|
-
return `
|
|
10330
|
+
return `Markdown parsed from [${url}]:
|
|
10355
10331
|
|
|
10356
|
-
${
|
|
10332
|
+
${markdown}${rawMarkdown.length > 5e4 ? "\n\n[TRUNCATED AT 50K CHARS]" : ""}`;
|
|
10357
10333
|
} catch (err) {
|
|
10358
10334
|
lastError = err;
|
|
10359
10335
|
if (browser) await browser.close();
|
|
@@ -10553,7 +10529,7 @@ var init_view_file = __esm({
|
|
|
10553
10529
|
const end = Math.min(totalLines, finalEnd);
|
|
10554
10530
|
const resultLines = lines.slice(start, end);
|
|
10555
10531
|
const header = `File: [${targetPath}] (Showing lines ${start + 1}-${end} of ${totalLines}).`;
|
|
10556
|
-
const code = resultLines.map((line, i) => `${String(start + i + 1).padStart(4)}: ${line}`).join("\n");
|
|
10532
|
+
const code = resultLines.map((line, i) => `${String(start + i + 1).padStart(4)}: ${line.trimEnd()}`).join("\n");
|
|
10557
10533
|
return `${header}
|
|
10558
10534
|
|
|
10559
10535
|
${code}`;
|
|
@@ -13626,7 +13602,7 @@ var init_ai = __esm({
|
|
|
13626
13602
|
TERMINATION_SIGNAL = false;
|
|
13627
13603
|
getCleanGroupedLength = (rawHistory) => {
|
|
13628
13604
|
const preprocessed = rawHistory.filter(
|
|
13629
|
-
(m) => (m.role === "user" || m.role === "agent" || m.role === "system") && m.role !== "think" && !m.isVisualFeedback && !m.isMeta && !String(m.id).startsWith("welcome")
|
|
13605
|
+
(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")
|
|
13630
13606
|
).map((m, idx, arr) => {
|
|
13631
13607
|
let text = m.fullText || m.text || "";
|
|
13632
13608
|
if (m.role === "user" && idx < arr.length - 1) {
|
|
@@ -13672,7 +13648,7 @@ var init_ai = __esm({
|
|
|
13672
13648
|
turnMessages.forEach((tm) => {
|
|
13673
13649
|
const textLower = (tm.text || "").toLowerCase();
|
|
13674
13650
|
const hasTool = textLower.includes("tool:functions.") || textLower.includes("agent:generalist.");
|
|
13675
|
-
const isResult = tm.role === "system" && (tm.text?.startsWith("[TOOL RESULT]") || tm.text?.startsWith("SUCCESS:") || tm.text?.startsWith("ERROR:")
|
|
13651
|
+
const isResult = tm.role === "system" && (tm.text?.startsWith("[TOOL RESULT]") || tm.text?.startsWith("SUCCESS:") || tm.text?.startsWith("ERROR:"));
|
|
13676
13652
|
if (tm.role === "agent") {
|
|
13677
13653
|
if (hasTool) {
|
|
13678
13654
|
toolCalls.push(tm.text);
|
|
@@ -15785,7 +15761,7 @@ ${currentSummary}
|
|
|
15785
15761
|
const dynamicDirAwareness = !!systemSettings?.dynamicDirAwareness;
|
|
15786
15762
|
const sysInstructionCacheKey = `${chatId}|${aiProvider}|${thinkingLevel}|${modelName}|${profile}|${dynamicDirAwareness}`;
|
|
15787
15763
|
const isSysInstructionCached = !dynamicDirAwareness && systemInstructionCache.key === sysInstructionCacheKey && systemInstructionCache.value;
|
|
15788
|
-
let dirStructure = isSysInstructionCached ? "" : "\n**DIRECTORY STRUCTURE**\nCWD: " + process.cwd() + `${isPlayground ? " [PLAYGROUND MODE]" : ""}
|
|
15764
|
+
let dirStructure = isSysInstructionCached ? "" : "\n**DIRECTORY STRUCTURE**\nCWD: " + process.cwd() + `${isPlayground ? " [PLAYGROUND MODE]" : ""}
|
|
15789
15765
|
` + getDirTree(process.cwd(), dynamicMaxDepth);
|
|
15790
15766
|
const ideCtx = await getIDEContext();
|
|
15791
15767
|
let ideBlock = "";
|
|
@@ -16065,7 +16041,8 @@ ${ideCtx.warnings}
|
|
|
16065
16041
|
const cleanPromptForModel = cleanAgentText.replace(/\\(@\[[^\]]+\])/g, "$1");
|
|
16066
16042
|
const firstUserMsg = `[METADATA, Chat Context > Metadata]
|
|
16067
16043
|
Time: ${dateTimeStr}
|
|
16068
|
-
OS: ${osDetected}${systemSettings?.dynamicDirAwareness ? dirStructure : ""}${
|
|
16044
|
+
OS: ${osDetected}${systemSettings?.dynamicDirAwareness ? dirStructure : ""}${cwdMismatch ? `WARNING: CWD Mismatch! Previous Path: "${lastCwd}" WRITE the change in chat to aviod path mismatch later
|
|
16045
|
+
` : ""}${memoryPrompt}${ideBlock}
|
|
16069
16046
|
[/METADATA]
|
|
16070
16047
|
${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. eg: [tool:functions.ReadFolder(path=".")] [/SYSTEM]
|
|
16071
16048
|
${taggedContextStr}[USER PROMPT]
|
|
@@ -19503,7 +19480,7 @@ var app_exports = {};
|
|
|
19503
19480
|
__export(app_exports, {
|
|
19504
19481
|
default: () => App
|
|
19505
19482
|
});
|
|
19506
|
-
import
|
|
19483
|
+
import os4 from "os";
|
|
19507
19484
|
import React16, { useState as useState15, useEffect as useEffect12, useRef as useRef4, useMemo as useMemo2 } from "react";
|
|
19508
19485
|
import { Box as Box14, Text as Text16, useInput as useInput9, useStdout as useStdout2, Static } from "ink";
|
|
19509
19486
|
import fs30 from "fs-extra";
|
|
@@ -19531,6 +19508,7 @@ function App({ args = [] }) {
|
|
|
19531
19508
|
const [showBridgePromo, setShowBridgePromo] = useState15(false);
|
|
19532
19509
|
const [promoSelectedIndex, setPromoSelectedIndex] = useState15(0);
|
|
19533
19510
|
const suggestionOffsetRef = useRef4(0);
|
|
19511
|
+
const maxScrollRef = useRef4(0);
|
|
19534
19512
|
const persistedModelRef = useRef4(null);
|
|
19535
19513
|
const activeStreamingMsgRef = useRef4(null);
|
|
19536
19514
|
const [renderTick, setRenderTick] = useState15(0);
|
|
@@ -20018,6 +19996,7 @@ function App({ args = [] }) {
|
|
|
20018
19996
|
const [monthlyUsage, setMonthlyUsage] = useState15(null);
|
|
20019
19997
|
const [customPeriodUsage, setCustomPeriodUsage] = useState15(null);
|
|
20020
19998
|
const [statsMode, setStatsMode] = useState15("daily");
|
|
19999
|
+
const [statsScrollOffset, setStatsScrollOffset] = useState15(0);
|
|
20021
20000
|
const PLAYGROUND_CHAT_ID = "flow-playground";
|
|
20022
20001
|
const [chatId, setChatId] = useState15(args.includes("--playground") ? PLAYGROUND_CHAT_ID : generateChatId());
|
|
20023
20002
|
useEffect12(() => {
|
|
@@ -20192,7 +20171,7 @@ function App({ args = [] }) {
|
|
|
20192
20171
|
useEffect12(() => setEscPressCount(0), [input]);
|
|
20193
20172
|
const [messages, rawSetMessages] = useState15(() => {
|
|
20194
20173
|
const logoMsg = { id: "logo-" + Date.now(), role: "system", isLogo: true, isMeta: true };
|
|
20195
|
-
const isHomeDir = process.cwd() ===
|
|
20174
|
+
const isHomeDir = process.cwd() === os4.homedir();
|
|
20196
20175
|
const isSystemDir = (() => {
|
|
20197
20176
|
const cwd = process.cwd().toLowerCase();
|
|
20198
20177
|
if (process.platform === "win32") {
|
|
@@ -20219,7 +20198,7 @@ function App({ args = [] }) {
|
|
|
20219
20198
|
id: "home-warning",
|
|
20220
20199
|
role: "system",
|
|
20221
20200
|
text: `[SECURITY ALERT] HOME DIRECTORY DETECTED`,
|
|
20222
|
-
subText: `You are currently in ${
|
|
20201
|
+
subText: `You are currently in ${os4.homedir()}. Working here is high-risk as the agent may modify system-sensitive configurations. Please open FluxFlow in project folder.`,
|
|
20223
20202
|
isHomeWarning: true
|
|
20224
20203
|
});
|
|
20225
20204
|
}
|
|
@@ -20398,10 +20377,20 @@ function App({ args = [] }) {
|
|
|
20398
20377
|
if (prev === "modelBreakdown") return "daily";
|
|
20399
20378
|
return prev === "daily" ? "monthly" : "daily";
|
|
20400
20379
|
});
|
|
20380
|
+
setStatsScrollOffset(0);
|
|
20401
20381
|
return;
|
|
20402
20382
|
}
|
|
20403
20383
|
if (key.space || inputText === " ") {
|
|
20404
20384
|
setStatsMode((prev) => prev === "modelBreakdown" ? "daily" : "modelBreakdown");
|
|
20385
|
+
setStatsScrollOffset(0);
|
|
20386
|
+
return;
|
|
20387
|
+
}
|
|
20388
|
+
if (key.upArrow) {
|
|
20389
|
+
setStatsScrollOffset((prev) => Math.max(0, prev - 1));
|
|
20390
|
+
return;
|
|
20391
|
+
}
|
|
20392
|
+
if (key.downArrow) {
|
|
20393
|
+
setStatsScrollOffset((prev) => Math.min(maxScrollRef.current, prev + 1));
|
|
20405
20394
|
return;
|
|
20406
20395
|
}
|
|
20407
20396
|
}
|
|
@@ -21028,6 +21017,7 @@ function App({ args = [] }) {
|
|
|
21028
21017
|
{ cmd: "/resume", desc: "Load previous session" },
|
|
21029
21018
|
{ cmd: "/clear", desc: "Clear terminal screen" },
|
|
21030
21019
|
{ cmd: "/compress", desc: "Summarize and compress chat history" },
|
|
21020
|
+
{ cmd: "/truncate", desc: "Truncate tool results in chat history" },
|
|
21031
21021
|
{ cmd: "/revert", desc: "Revert codebase back to a checkpoint" },
|
|
21032
21022
|
{ cmd: "/gemini", desc: "Get a happy message from Gemini CLI" },
|
|
21033
21023
|
{ cmd: "/save", desc: "Force save current chat" },
|
|
@@ -21960,6 +21950,42 @@ ${list || "No saved chats found."}`, isMeta: true }];
|
|
|
21960
21950
|
runCompress();
|
|
21961
21951
|
break;
|
|
21962
21952
|
}
|
|
21953
|
+
case "/truncate": {
|
|
21954
|
+
setInput("");
|
|
21955
|
+
let truncatedCount = 0;
|
|
21956
|
+
setMessages((prev) => {
|
|
21957
|
+
const updatedMessages = prev.map((m) => {
|
|
21958
|
+
const fullTextStr = m.fullText || m.text || "";
|
|
21959
|
+
if (!fullTextStr.startsWith("[TOOL RESULT]:")) {
|
|
21960
|
+
return m;
|
|
21961
|
+
}
|
|
21962
|
+
if (fullTextStr.startsWith("[TOOL RESULT]: ERROR") || fullTextStr.startsWith("[TOOL RESULT]: DENIED") || fullTextStr.includes("...Result Truncated by System on User Request")) {
|
|
21963
|
+
return m;
|
|
21964
|
+
}
|
|
21965
|
+
truncatedCount++;
|
|
21966
|
+
if (fullTextStr.startsWith("[TOOL RESULT]: SUCCESS")) {
|
|
21967
|
+
return {
|
|
21968
|
+
...m,
|
|
21969
|
+
fullText: "[TOOL RESULT]: SUCCESS: ...Result Truncated by System on User Request"
|
|
21970
|
+
};
|
|
21971
|
+
}
|
|
21972
|
+
return {
|
|
21973
|
+
...m,
|
|
21974
|
+
fullText: "[TOOL RESULT]: ...Result Truncated by System on User Request"
|
|
21975
|
+
};
|
|
21976
|
+
});
|
|
21977
|
+
const finalMsgs = [...updatedMessages, {
|
|
21978
|
+
id: Date.now(),
|
|
21979
|
+
role: "system",
|
|
21980
|
+
text: `[SYSTEM] Truncated ${truncatedCount} tool result(s) in chat history.`,
|
|
21981
|
+
isMeta: true
|
|
21982
|
+
}];
|
|
21983
|
+
saveChat(chatId, null, finalMsgs);
|
|
21984
|
+
setCompletedIndex(finalMsgs.length);
|
|
21985
|
+
return finalMsgs;
|
|
21986
|
+
});
|
|
21987
|
+
break;
|
|
21988
|
+
}
|
|
21963
21989
|
case "/help": {
|
|
21964
21990
|
setMessages((prev) => {
|
|
21965
21991
|
setCompletedIndex(prev.length + 1);
|
|
@@ -22019,7 +22045,7 @@ ${timestamp}` };
|
|
|
22019
22045
|
let isFirstPacket = true;
|
|
22020
22046
|
try {
|
|
22021
22047
|
const rawHistory = [...messages, userMessage].filter(
|
|
22022
|
-
(m) => m.role !== "think" && !m.isVisualFeedback && !m.isMeta && !String(m.id).startsWith("welcome")
|
|
22048
|
+
(m) => m.role !== "think" && !m.isVisualFeedback && !m.isMeta && !m.isTerminalRecord && !(m.text && m.text.includes("[TERMINAL_RECORD]")) && !String(m.id).startsWith("welcome")
|
|
22023
22049
|
);
|
|
22024
22050
|
const cleanHistoryForAI = [];
|
|
22025
22051
|
const preprocessed = rawHistory.map((m, idx) => {
|
|
@@ -22061,7 +22087,7 @@ ${timestamp}` };
|
|
|
22061
22087
|
i++;
|
|
22062
22088
|
}
|
|
22063
22089
|
turnMessages.forEach((tm) => {
|
|
22064
|
-
const isResult = tm.role === "system" && (tm.text?.startsWith("[TOOL RESULT]") || tm.text?.startsWith("SUCCESS:") || tm.text?.startsWith("ERROR:")
|
|
22090
|
+
const isResult = tm.role === "system" && (tm.text?.startsWith("[TOOL RESULT]") || tm.text?.startsWith("SUCCESS:") || tm.text?.startsWith("ERROR:"));
|
|
22065
22091
|
const emitRole = isResult ? "system" : "agent";
|
|
22066
22092
|
const rawText = (tm.text || "").trim();
|
|
22067
22093
|
if (!rawText) return;
|
|
@@ -23196,13 +23222,13 @@ Selection: ${val}`,
|
|
|
23196
23222
|
const limitsNotSet = !usingProviderBudgets && (shouldClearValue(reqLimit) || shouldClearValue(tokenLimit) || shouldClearValue(monthlyLimit));
|
|
23197
23223
|
let resetInfo = "";
|
|
23198
23224
|
if (quotas.resetMode === "Custom") {
|
|
23199
|
-
const
|
|
23225
|
+
const today2 = /* @__PURE__ */ new Date();
|
|
23200
23226
|
const resetDay = quotas.resetDay || 1;
|
|
23201
|
-
let resetMonth =
|
|
23202
|
-
if (
|
|
23227
|
+
let resetMonth = today2.getMonth();
|
|
23228
|
+
if (today2.getDate() >= resetDay) {
|
|
23203
23229
|
resetMonth += 1;
|
|
23204
23230
|
}
|
|
23205
|
-
const resetDate = new Date(
|
|
23231
|
+
const resetDate = new Date(today2.getFullYear(), resetMonth, resetDay);
|
|
23206
23232
|
const monthName = resetDate.toLocaleString("default", { month: "short" });
|
|
23207
23233
|
resetInfo = `${monthName}-${resetDay}`;
|
|
23208
23234
|
}
|
|
@@ -23334,10 +23360,62 @@ Selection: ${val}`,
|
|
|
23334
23360
|
const imageCreditsLabel = statsMode === "monthly" ? "Image Credits:" : "Image Credits:";
|
|
23335
23361
|
const codeChangesLabel = statsMode === "monthly" ? "Code Changes:" : "Code Changes:";
|
|
23336
23362
|
const toolCallsLabel = statsMode === "monthly" ? "Tool Calls:" : "Tool Calls:";
|
|
23337
|
-
|
|
23338
|
-
|
|
23339
|
-
|
|
23340
|
-
})) : /* @__PURE__ */ React16.createElement(React16.Fragment, null, /* @__PURE__ */ React16.createElement(Box14, { marginBottom: 1 }, /* @__PURE__ */ React16.createElement(Text16, { color: colors.text, bold: true, underline: true }, "SESSION TELEMETRY")), /* @__PURE__ */ React16.createElement(Box14, { flexDirection: "column" }, /* @__PURE__ */ React16.createElement(Box14, null, /* @__PURE__ */ React16.createElement(Box14, { width: 25 }, /* @__PURE__ */ React16.createElement(Text16, { color: colors.secondary }, "Session Duration:")), /* @__PURE__ */ React16.createElement(Text16, { color: colors.text }, formatMsDuration(Date.now() - SESSION_START_TIME))), /* @__PURE__ */ React16.createElement(Box14, null, /* @__PURE__ */ React16.createElement(Box14, { width: 25 }, /* @__PURE__ */ React16.createElement(Text16, { color: colors.secondary }, "Model Requests:")), /* @__PURE__ */ React16.createElement(Text16, { color: colors.text }, sessionAgentCalls)), /* @__PURE__ */ React16.createElement(Box14, { marginLeft: 2 }, /* @__PURE__ */ React16.createElement(Box14, { width: 23 }, /* @__PURE__ */ React16.createElement(Text16, { color: colors.textMuted }, "\xBB API Time:")), /* @__PURE__ */ React16.createElement(Text16, { color: colors.text }, formatMsDuration(sessionApiTime))), /* @__PURE__ */ React16.createElement(Box14, { marginLeft: 2 }, /* @__PURE__ */ React16.createElement(Box14, { width: 23 }, /* @__PURE__ */ React16.createElement(Text16, { color: colors.textMuted }, "\xBB Tool Time:")), /* @__PURE__ */ React16.createElement(Text16, { color: colors.text }, formatMsDuration(sessionToolTime))), /* @__PURE__ */ React16.createElement(Box14, null, /* @__PURE__ */ React16.createElement(Box14, { width: 25 }, /* @__PURE__ */ React16.createElement(Text16, { color: colors.secondary }, "Memory Agent:")), /* @__PURE__ */ React16.createElement(Text16, { color: colors.text }, sessionBackgroundCalls)), /* @__PURE__ */ React16.createElement(Box14, null, /* @__PURE__ */ React16.createElement(Box14, { width: 25 }, /* @__PURE__ */ React16.createElement(Text16, { color: colors.secondary }, "Tokens Consumed:")), /* @__PURE__ */ React16.createElement(Text16, { color: colors.text }, formatTokens(sessionTotalTokens))), /* @__PURE__ */ React16.createElement(Box14, null, /* @__PURE__ */ React16.createElement(Box14, { width: 25 }, /* @__PURE__ */ React16.createElement(Text16, { color: colors.secondary }, "Active Context:")), /* @__PURE__ */ React16.createElement(Text16, { color: colors.text }, formatTokens(sessionStats.tokens))), sessionTotalTokens > 0 && /* @__PURE__ */ React16.createElement(React16.Fragment, null, /* @__PURE__ */ React16.createElement(Box14, { marginLeft: 2 }, /* @__PURE__ */ React16.createElement(Box14, { width: 23 }, /* @__PURE__ */ React16.createElement(Text16, { color: colors.textMuted }, "\xBB Input Tokens:")), /* @__PURE__ */ React16.createElement(Text16, { color: colors.text }, formatTokens(sessionTotalTokens - sessionTotalCandidateTokens))), sessionTotalCachedTokens > 0 && /* @__PURE__ */ React16.createElement(Box14, { marginLeft: 4 }, /* @__PURE__ */ React16.createElement(Box14, { width: 21 }, /* @__PURE__ */ React16.createElement(Text16, { color: colors.textMuted }, "\xBB Cached:")), /* @__PURE__ */ React16.createElement(Text16, { color: colors.text }, formatTokens(sessionTotalCachedTokens))), sessionTotalCandidateTokens > 0 && /* @__PURE__ */ React16.createElement(Box14, { marginLeft: 2 }, /* @__PURE__ */ React16.createElement(Box14, { width: 23 }, /* @__PURE__ */ React16.createElement(Text16, { color: colors.textMuted }, "\xBB Output Tokens:")), /* @__PURE__ */ React16.createElement(Text16, { color: colors.text }, formatTokens(sessionTotalCandidateTokens)))), sessionImageCount > 0 && /* @__PURE__ */ React16.createElement(React16.Fragment, null, /* @__PURE__ */ React16.createElement(Box14, null, /* @__PURE__ */ React16.createElement(Box14, { width: 25 }, /* @__PURE__ */ React16.createElement(Text16, { color: colors.secondary }, "Images Made:")), /* @__PURE__ */ React16.createElement(Text16, { color: colors.text }, sessionImageCount)), /* @__PURE__ */ React16.createElement(Box14, null, /* @__PURE__ */ React16.createElement(Box14, { width: 25 }, /* @__PURE__ */ React16.createElement(Text16, { color: colors.secondary }, "Image Credits:")), /* @__PURE__ */ React16.createElement(Text16, { color: colors.text }, Number(((sessionImageCredits || 0) * 1e3).toFixed(0)), " credits"))), /* @__PURE__ */ React16.createElement(Box14, null, /* @__PURE__ */ React16.createElement(Box14, { width: 25 }, /* @__PURE__ */ React16.createElement(Text16, { color: colors.secondary }, "Code Changes (Sess):")), /* @__PURE__ */ React16.createElement(Text16, { color: colors.text }, /* @__PURE__ */ React16.createElement(Text16, { color: colors.success || "green" }, "+", runtimeSession.linesAdded), " ", /* @__PURE__ */ React16.createElement(Text16, { color: colors.danger || "red" }, "-", runtimeSession.linesRemoved))), /* @__PURE__ */ React16.createElement(Box14, null, /* @__PURE__ */ React16.createElement(Box14, { width: 25 }, /* @__PURE__ */ React16.createElement(Text16, { color: colors.secondary }, "Tool Calls (Sess):")), /* @__PURE__ */ React16.createElement(Text16, { color: colors.text }, runtimeSession.toolSuccess + runtimeSession.toolFailure + runtimeSession.toolDenied, " ( "), /* @__PURE__ */ React16.createElement(Text16, { color: colors.success || "green" }, "\u2714 ", runtimeSession.toolSuccess), /* @__PURE__ */ React16.createElement(Text16, { color: colors.text }, " "), /* @__PURE__ */ React16.createElement(Text16, { color: colors.warning || "yellow" }, "\u{1F6C7} ", runtimeSession.toolDenied), /* @__PURE__ */ React16.createElement(Text16, { color: colors.text }, " "), /* @__PURE__ */ React16.createElement(Text16, { color: colors.danger || "red" }, "\u2718 ", runtimeSession.toolFailure), /* @__PURE__ */ React16.createElement(Text16, { color: colors.text }, " )"))), /* @__PURE__ */ React16.createElement(Box14, { flexDirection: "column", marginTop: 1 }, /* @__PURE__ */ React16.createElement(Text16, { color: colors.text, bold: true, underline: true }, trackerTitle), /* @__PURE__ */ React16.createElement(Box14, { marginTop: 1 }, /* @__PURE__ */ React16.createElement(Box14, { width: 25 }, /* @__PURE__ */ React16.createElement(Text16, { color: colors.secondary }, timeLabel)), /* @__PURE__ */ React16.createElement(Text16, { color: colors.text }, formatDuration(u?.duration || 0))), /* @__PURE__ */ React16.createElement(Box14, null, /* @__PURE__ */ React16.createElement(Box14, { width: 25 }, /* @__PURE__ */ React16.createElement(Text16, { color: colors.secondary }, "Model Requests:")), /* @__PURE__ */ React16.createElement(Text16, { color: colors.text }, u?.agent || 0)), /* @__PURE__ */ React16.createElement(Box14, null, /* @__PURE__ */ React16.createElement(Box14, { width: 25 }, /* @__PURE__ */ React16.createElement(Text16, { color: colors.secondary }, "Memory Agent:")), /* @__PURE__ */ React16.createElement(Text16, { color: colors.text }, u?.background || 0)), /* @__PURE__ */ React16.createElement(Box14, null, /* @__PURE__ */ React16.createElement(Box14, { width: 25 }, /* @__PURE__ */ React16.createElement(Text16, { color: colors.secondary }, tokensLabel)), /* @__PURE__ */ React16.createElement(Text16, { color: colors.text }, formatTokens(u?.tokens || 0))), (u?.tokens || 0) > 0 && /* @__PURE__ */ React16.createElement(React16.Fragment, null, /* @__PURE__ */ React16.createElement(Box14, { marginLeft: 2 }, /* @__PURE__ */ React16.createElement(Box14, { width: 23 }, /* @__PURE__ */ React16.createElement(Text16, { color: colors.textMuted }, "\xBB Input Tokens:")), /* @__PURE__ */ React16.createElement(Text16, { color: colors.text }, formatTokens((u?.tokens || 0) - (u?.candidateTokens || 0)))), (u?.cachedTokens || 0) > 0 && /* @__PURE__ */ React16.createElement(Box14, { marginLeft: 4 }, /* @__PURE__ */ React16.createElement(Box14, { width: 21 }, /* @__PURE__ */ React16.createElement(Text16, { color: colors.textMuted }, "\xBB Cached:")), /* @__PURE__ */ React16.createElement(Text16, { color: colors.text }, formatTokens(u.cachedTokens))), (u?.candidateTokens || 0) > 0 && /* @__PURE__ */ React16.createElement(Box14, { marginLeft: 2 }, /* @__PURE__ */ React16.createElement(Box14, { width: 23 }, /* @__PURE__ */ React16.createElement(Text16, { color: colors.textMuted }, "\xBB Output Tokens:")), /* @__PURE__ */ React16.createElement(Text16, { color: colors.text }, formatTokens(u.candidateTokens)))), (u?.imageCalls?.length || 0) > 0 && /* @__PURE__ */ React16.createElement(React16.Fragment, null, /* @__PURE__ */ React16.createElement(Box14, null, /* @__PURE__ */ React16.createElement(Box14, { width: 25 }, /* @__PURE__ */ React16.createElement(Text16, { color: colors.secondary }, imagesLabel)), /* @__PURE__ */ React16.createElement(Text16, { color: colors.text }, u.imageCalls.length)), /* @__PURE__ */ React16.createElement(Box14, null, /* @__PURE__ */ React16.createElement(Box14, { width: 25 }, /* @__PURE__ */ React16.createElement(Text16, { color: colors.secondary }, imageCreditsLabel)), /* @__PURE__ */ React16.createElement(Text16, { color: colors.text }, Number(((u.imageCalls.reduce((sum, c) => sum + c.cost, 0) || 0) * 1e3).toFixed(0)), " credits"))), /* @__PURE__ */ React16.createElement(Box14, null, /* @__PURE__ */ React16.createElement(Box14, { width: 25 }, /* @__PURE__ */ React16.createElement(Text16, { color: colors.secondary }, codeChangesLabel)), /* @__PURE__ */ React16.createElement(Text16, { color: colors.text }, /* @__PURE__ */ React16.createElement(Text16, { color: colors.success || "green" }, "+", u?.linesAdded || 0), " ", /* @__PURE__ */ React16.createElement(Text16, { color: colors.danger || "red" }, "-", u?.linesRemoved || 0))), /* @__PURE__ */ React16.createElement(Box14, null, /* @__PURE__ */ React16.createElement(Box14, { width: 25 }, /* @__PURE__ */ React16.createElement(Text16, { color: colors.secondary }, toolCallsLabel)), /* @__PURE__ */ React16.createElement(Text16, { color: colors.text }, (u?.toolSuccess || 0) + (u?.toolFailure || 0) + (u?.toolDenied || 0), " ( "), /* @__PURE__ */ React16.createElement(Text16, { color: colors.success || "green" }, "\u2714 ", u?.toolSuccess || 0), /* @__PURE__ */ React16.createElement(Text16, { color: colors.text }, " "), /* @__PURE__ */ React16.createElement(Text16, { color: colors.warning || "yellow" }, "\u{1F6C7} ", u?.toolDenied || 0), /* @__PURE__ */ React16.createElement(Text16, { color: colors.text }, " "), /* @__PURE__ */ React16.createElement(Text16, { color: colors.danger || "red" }, "\u2718 ", u?.toolFailure || 0), /* @__PURE__ */ React16.createElement(Text16, { color: colors.text }, " )")))), /* @__PURE__ */ React16.createElement(Text16, { color: colors.textMuted, dimColor: true, marginTop: 1, italic: true }, "(Press TAB to toggle Daily/Monthly views, SPACE for Model Breakdown, ESC to return)"));
|
|
23363
|
+
const maxRows = Math.max(4, (stdout?.rows || terminalSize?.rows || 24) - 15);
|
|
23364
|
+
const renderLeaderRow = (key, leftText, rightText, leftColor, rightColor, indent = 0, isBold = false) => {
|
|
23365
|
+
const cols = stdout?.columns || terminalSize?.columns || 80;
|
|
23366
|
+
const boxWidth = Math.min(125, cols - 2);
|
|
23367
|
+
const lineWidth = Math.max(20, boxWidth - 6);
|
|
23368
|
+
const maxLeftLen = Math.max(5, lineWidth - indent - rightText.length - 5);
|
|
23369
|
+
let cleanLeftText = leftText;
|
|
23370
|
+
if (cleanLeftText.length > maxLeftLen) {
|
|
23371
|
+
cleanLeftText = cleanLeftText.substring(0, maxLeftLen - 1) + "\u2026";
|
|
23372
|
+
}
|
|
23373
|
+
const dotsCount = Math.max(2, lineWidth - indent - cleanLeftText.length - rightText.length - 2);
|
|
23374
|
+
const dotsStr = " " + ".".repeat(dotsCount) + " ";
|
|
23375
|
+
const indentStr = " ".repeat(indent);
|
|
23376
|
+
return /* @__PURE__ */ React16.createElement(Box14, { key, width: lineWidth }, /* @__PURE__ */ React16.createElement(Text16, { wrap: "truncate" }, /* @__PURE__ */ React16.createElement(Text16, null, indentStr), /* @__PURE__ */ React16.createElement(Text16, { color: leftColor, bold: isBold }, cleanLeftText), /* @__PURE__ */ React16.createElement(Text16, { color: colors.textMuted, dimColor: true }, dotsStr), /* @__PURE__ */ React16.createElement(Text16, { color: rightColor, bold: isBold }, rightText)));
|
|
23377
|
+
};
|
|
23378
|
+
const breakdownRows = [];
|
|
23379
|
+
if (!monthlyUsage?.models || Object.keys(monthlyUsage.models).length === 0) {
|
|
23380
|
+
breakdownRows.push(
|
|
23381
|
+
/* @__PURE__ */ React16.createElement(Box14, { key: "empty", marginTop: 1 }, /* @__PURE__ */ React16.createElement(Text16, { color: colors.textMuted, italic: true }, "No model token usage recorded in the last 30 days."))
|
|
23382
|
+
);
|
|
23383
|
+
} else {
|
|
23384
|
+
Object.entries(monthlyUsage.models).forEach(([provider, models], pIdx) => {
|
|
23385
|
+
const providerTotalTokens = Object.values(models).reduce((sum, m) => sum + (m.tokens || 0), 0);
|
|
23386
|
+
if (pIdx > 0) {
|
|
23387
|
+
breakdownRows.push(/* @__PURE__ */ React16.createElement(Box14, { key: `space-prov-${provider}` }, /* @__PURE__ */ React16.createElement(Text16, null, " ")));
|
|
23388
|
+
}
|
|
23389
|
+
breakdownRows.push(
|
|
23390
|
+
renderLeaderRow(`prov-${provider}`, `${provider}:`, formatTokens(providerTotalTokens), colors.primary, colors.text, 0, true)
|
|
23391
|
+
);
|
|
23392
|
+
Object.entries(models).forEach(([modelName, stats], mIdx) => {
|
|
23393
|
+
if (mIdx > 0) {
|
|
23394
|
+
breakdownRows.push(/* @__PURE__ */ React16.createElement(Box14, { key: `space-mod-${provider}-${modelName}` }, /* @__PURE__ */ React16.createElement(Text16, null, " ")));
|
|
23395
|
+
}
|
|
23396
|
+
breakdownRows.push(
|
|
23397
|
+
renderLeaderRow(`mod-${provider}-${modelName}`, `\xBB ${modelName}:`, formatTokens(stats.tokens || 0), colors.secondary, colors.text, 2, true)
|
|
23398
|
+
);
|
|
23399
|
+
breakdownRows.push(
|
|
23400
|
+
renderLeaderRow(`in-${provider}-${modelName}`, "\xBB Input Tokens:", formatTokens((stats.tokens || 0) - (stats.candidateTokens || 0)), colors.textMuted, colors.text, 5, false)
|
|
23401
|
+
);
|
|
23402
|
+
if ((stats.cachedTokens || 0) > 0) {
|
|
23403
|
+
breakdownRows.push(
|
|
23404
|
+
renderLeaderRow(`cache-${provider}-${modelName}`, "\xBB Cached:", formatTokens(stats.cachedTokens), colors.textMuted, colors.text, 7, false)
|
|
23405
|
+
);
|
|
23406
|
+
}
|
|
23407
|
+
breakdownRows.push(
|
|
23408
|
+
renderLeaderRow(`out-${provider}-${modelName}`, "\xBB Output Tokens:", formatTokens(stats.candidateTokens || 0), colors.textMuted, colors.text, 5, false)
|
|
23409
|
+
);
|
|
23410
|
+
});
|
|
23411
|
+
});
|
|
23412
|
+
}
|
|
23413
|
+
const totalRows = breakdownRows.length;
|
|
23414
|
+
const maxScroll = Math.max(0, totalRows - maxRows);
|
|
23415
|
+
maxScrollRef.current = maxScroll;
|
|
23416
|
+
const effectiveScroll = Math.min(statsScrollOffset, maxScroll);
|
|
23417
|
+
const visibleRows = breakdownRows.slice(effectiveScroll, effectiveScroll + maxRows);
|
|
23418
|
+
return /* @__PURE__ */ React16.createElement(Box14, { flexDirection: "column", borderStyle: "round", borderColor: colors.borderMuted, paddingX: 3, paddingY: 1, paddingBottom: 0, width: Math.min(125, (stdout?.columns || 100) - 2) }, statsMode === "modelBreakdown" ? /* @__PURE__ */ React16.createElement(Box14, { flexDirection: "column" }, /* @__PURE__ */ React16.createElement(Box14, { justifyContent: "space-between" }, /* @__PURE__ */ React16.createElement(Text16, { color: colors.text, bold: true, underline: true }, "30-DAY MODEL TOKEN BREAKDOWN"), totalRows > maxRows && /* @__PURE__ */ React16.createElement(Text16, { color: colors.textMuted, dimColor: true }, "[", effectiveScroll + 1, "-", Math.min(totalRows, effectiveScroll + maxRows), " of ", totalRows, "] \u25B2\u25BC")), /* @__PURE__ */ React16.createElement(Box14, { flexDirection: "column", height: maxRows, marginTop: 1 }, visibleRows)) : /* @__PURE__ */ React16.createElement(React16.Fragment, null, /* @__PURE__ */ React16.createElement(Box14, { marginBottom: 1 }, /* @__PURE__ */ React16.createElement(Text16, { color: colors.text, bold: true, underline: true }, "SESSION TELEMETRY")), /* @__PURE__ */ React16.createElement(Box14, { flexDirection: "column" }, /* @__PURE__ */ React16.createElement(Box14, null, /* @__PURE__ */ React16.createElement(Box14, { width: 25 }, /* @__PURE__ */ React16.createElement(Text16, { color: colors.secondary }, "Session Duration:")), /* @__PURE__ */ React16.createElement(Text16, { color: colors.text }, formatMsDuration(Date.now() - SESSION_START_TIME))), /* @__PURE__ */ React16.createElement(Box14, null, /* @__PURE__ */ React16.createElement(Box14, { width: 25 }, /* @__PURE__ */ React16.createElement(Text16, { color: colors.secondary }, "Model Requests:")), /* @__PURE__ */ React16.createElement(Text16, { color: colors.text }, sessionAgentCalls)), /* @__PURE__ */ React16.createElement(Box14, { marginLeft: 2 }, /* @__PURE__ */ React16.createElement(Box14, { width: 23 }, /* @__PURE__ */ React16.createElement(Text16, { color: colors.textMuted }, "\xBB API Time:")), /* @__PURE__ */ React16.createElement(Text16, { color: colors.text }, formatMsDuration(sessionApiTime))), /* @__PURE__ */ React16.createElement(Box14, { marginLeft: 2 }, /* @__PURE__ */ React16.createElement(Box14, { width: 23 }, /* @__PURE__ */ React16.createElement(Text16, { color: colors.textMuted }, "\xBB Tool Time:")), /* @__PURE__ */ React16.createElement(Text16, { color: colors.text }, formatMsDuration(sessionToolTime))), /* @__PURE__ */ React16.createElement(Box14, null, /* @__PURE__ */ React16.createElement(Box14, { width: 25 }, /* @__PURE__ */ React16.createElement(Text16, { color: colors.secondary }, "Memory Agent:")), /* @__PURE__ */ React16.createElement(Text16, { color: colors.text }, sessionBackgroundCalls)), /* @__PURE__ */ React16.createElement(Box14, null, /* @__PURE__ */ React16.createElement(Box14, { width: 25 }, /* @__PURE__ */ React16.createElement(Text16, { color: colors.secondary }, "Tokens Consumed:")), /* @__PURE__ */ React16.createElement(Text16, { color: colors.text }, formatTokens(sessionTotalTokens))), /* @__PURE__ */ React16.createElement(Box14, null, /* @__PURE__ */ React16.createElement(Box14, { width: 25 }, /* @__PURE__ */ React16.createElement(Text16, { color: colors.secondary }, "Active Context:")), /* @__PURE__ */ React16.createElement(Text16, { color: colors.text }, formatTokens(sessionStats.tokens))), sessionTotalTokens > 0 && /* @__PURE__ */ React16.createElement(React16.Fragment, null, /* @__PURE__ */ React16.createElement(Box14, { marginLeft: 2 }, /* @__PURE__ */ React16.createElement(Box14, { width: 23 }, /* @__PURE__ */ React16.createElement(Text16, { color: colors.textMuted }, "\xBB Input Tokens:")), /* @__PURE__ */ React16.createElement(Text16, { color: colors.text }, formatTokens(sessionTotalTokens - sessionTotalCandidateTokens))), sessionTotalCachedTokens > 0 && /* @__PURE__ */ React16.createElement(Box14, { marginLeft: 4 }, /* @__PURE__ */ React16.createElement(Box14, { width: 21 }, /* @__PURE__ */ React16.createElement(Text16, { color: colors.textMuted }, "\xBB Cached:")), /* @__PURE__ */ React16.createElement(Text16, { color: colors.text }, formatTokens(sessionTotalCachedTokens))), sessionTotalCandidateTokens > 0 && /* @__PURE__ */ React16.createElement(Box14, { marginLeft: 2 }, /* @__PURE__ */ React16.createElement(Box14, { width: 23 }, /* @__PURE__ */ React16.createElement(Text16, { color: colors.textMuted }, "\xBB Output Tokens:")), /* @__PURE__ */ React16.createElement(Text16, { color: colors.text }, formatTokens(sessionTotalCandidateTokens)))), sessionImageCount > 0 && /* @__PURE__ */ React16.createElement(React16.Fragment, null, /* @__PURE__ */ React16.createElement(Box14, null, /* @__PURE__ */ React16.createElement(Box14, { width: 25 }, /* @__PURE__ */ React16.createElement(Text16, { color: colors.secondary }, "Images Made:")), /* @__PURE__ */ React16.createElement(Text16, { color: colors.text }, sessionImageCount)), /* @__PURE__ */ React16.createElement(Box14, null, /* @__PURE__ */ React16.createElement(Box14, { width: 25 }, /* @__PURE__ */ React16.createElement(Text16, { color: colors.secondary }, "Image Credits:")), /* @__PURE__ */ React16.createElement(Text16, { color: colors.text }, Number(((sessionImageCredits || 0) * 1e3).toFixed(0)), " credits"))), /* @__PURE__ */ React16.createElement(Box14, null, /* @__PURE__ */ React16.createElement(Box14, { width: 25 }, /* @__PURE__ */ React16.createElement(Text16, { color: colors.secondary }, "Code Changes (Sess):")), /* @__PURE__ */ React16.createElement(Text16, { color: colors.text }, /* @__PURE__ */ React16.createElement(Text16, { color: colors.success || "green" }, "+", runtimeSession.linesAdded), " ", /* @__PURE__ */ React16.createElement(Text16, { color: colors.danger || "red" }, "-", runtimeSession.linesRemoved))), /* @__PURE__ */ React16.createElement(Box14, null, /* @__PURE__ */ React16.createElement(Box14, { width: 25 }, /* @__PURE__ */ React16.createElement(Text16, { color: colors.secondary }, "Tool Calls (Sess):")), /* @__PURE__ */ React16.createElement(Text16, { color: colors.text }, runtimeSession.toolSuccess + runtimeSession.toolFailure + runtimeSession.toolDenied, " ( "), /* @__PURE__ */ React16.createElement(Text16, { color: colors.success || "green" }, "\u2714 ", runtimeSession.toolSuccess), /* @__PURE__ */ React16.createElement(Text16, { color: colors.text }, " "), /* @__PURE__ */ React16.createElement(Text16, { color: colors.warning || "yellow" }, "\u{1F6C7} ", runtimeSession.toolDenied), /* @__PURE__ */ React16.createElement(Text16, { color: colors.text }, " "), /* @__PURE__ */ React16.createElement(Text16, { color: colors.danger || "red" }, "\u2718 ", runtimeSession.toolFailure), /* @__PURE__ */ React16.createElement(Text16, { color: colors.text }, " )"))), /* @__PURE__ */ React16.createElement(Box14, { flexDirection: "column", marginTop: 1 }, /* @__PURE__ */ React16.createElement(Text16, { color: colors.text, bold: true, underline: true }, trackerTitle), /* @__PURE__ */ React16.createElement(Box14, { marginTop: 1 }, /* @__PURE__ */ React16.createElement(Box14, { width: 25 }, /* @__PURE__ */ React16.createElement(Text16, { color: colors.secondary }, timeLabel)), /* @__PURE__ */ React16.createElement(Text16, { color: colors.text }, formatDuration(u?.duration || 0))), /* @__PURE__ */ React16.createElement(Box14, null, /* @__PURE__ */ React16.createElement(Box14, { width: 25 }, /* @__PURE__ */ React16.createElement(Text16, { color: colors.secondary }, "Model Requests:")), /* @__PURE__ */ React16.createElement(Text16, { color: colors.text }, u?.agent || 0)), /* @__PURE__ */ React16.createElement(Box14, null, /* @__PURE__ */ React16.createElement(Box14, { width: 25 }, /* @__PURE__ */ React16.createElement(Text16, { color: colors.secondary }, "Memory Agent:")), /* @__PURE__ */ React16.createElement(Text16, { color: colors.text }, u?.background || 0)), /* @__PURE__ */ React16.createElement(Box14, null, /* @__PURE__ */ React16.createElement(Box14, { width: 25 }, /* @__PURE__ */ React16.createElement(Text16, { color: colors.secondary }, tokensLabel)), /* @__PURE__ */ React16.createElement(Text16, { color: colors.text }, formatTokens(u?.tokens || 0))), (u?.tokens || 0) > 0 && /* @__PURE__ */ React16.createElement(React16.Fragment, null, /* @__PURE__ */ React16.createElement(Box14, { marginLeft: 2 }, /* @__PURE__ */ React16.createElement(Box14, { width: 23 }, /* @__PURE__ */ React16.createElement(Text16, { color: colors.textMuted }, "\xBB Input Tokens:")), /* @__PURE__ */ React16.createElement(Text16, { color: colors.text }, formatTokens((u?.tokens || 0) - (u?.candidateTokens || 0)))), (u?.cachedTokens || 0) > 0 && /* @__PURE__ */ React16.createElement(Box14, { marginLeft: 4 }, /* @__PURE__ */ React16.createElement(Box14, { width: 21 }, /* @__PURE__ */ React16.createElement(Text16, { color: colors.textMuted }, "\xBB Cached:")), /* @__PURE__ */ React16.createElement(Text16, { color: colors.text }, formatTokens(u.cachedTokens))), (u?.candidateTokens || 0) > 0 && /* @__PURE__ */ React16.createElement(Box14, { marginLeft: 2 }, /* @__PURE__ */ React16.createElement(Box14, { width: 23 }, /* @__PURE__ */ React16.createElement(Text16, { color: colors.textMuted }, "\xBB Output Tokens:")), /* @__PURE__ */ React16.createElement(Text16, { color: colors.text }, formatTokens(u.candidateTokens)))), (u?.imageCalls?.length || 0) > 0 && /* @__PURE__ */ React16.createElement(React16.Fragment, null, /* @__PURE__ */ React16.createElement(Box14, null, /* @__PURE__ */ React16.createElement(Box14, { width: 25 }, /* @__PURE__ */ React16.createElement(Text16, { color: colors.secondary }, imagesLabel)), /* @__PURE__ */ React16.createElement(Text16, { color: colors.text }, u.imageCalls.length)), /* @__PURE__ */ React16.createElement(Box14, null, /* @__PURE__ */ React16.createElement(Box14, { width: 25 }, /* @__PURE__ */ React16.createElement(Text16, { color: colors.secondary }, imageCreditsLabel)), /* @__PURE__ */ React16.createElement(Text16, { color: colors.text }, Number(((u.imageCalls.reduce((sum, c) => sum + c.cost, 0) || 0) * 1e3).toFixed(0)), " credits"))), /* @__PURE__ */ React16.createElement(Box14, null, /* @__PURE__ */ React16.createElement(Box14, { width: 25 }, /* @__PURE__ */ React16.createElement(Text16, { color: colors.secondary }, codeChangesLabel)), /* @__PURE__ */ React16.createElement(Text16, { color: colors.text }, /* @__PURE__ */ React16.createElement(Text16, { color: colors.success || "green" }, "+", u?.linesAdded || 0), " ", /* @__PURE__ */ React16.createElement(Text16, { color: colors.danger || "red" }, "-", u?.linesRemoved || 0))), /* @__PURE__ */ React16.createElement(Box14, null, /* @__PURE__ */ React16.createElement(Box14, { width: 25 }, /* @__PURE__ */ React16.createElement(Text16, { color: colors.secondary }, toolCallsLabel)), /* @__PURE__ */ React16.createElement(Text16, { color: colors.text }, (u?.toolSuccess || 0) + (u?.toolFailure || 0) + (u?.toolDenied || 0), " ( "), /* @__PURE__ */ React16.createElement(Text16, { color: colors.success || "green" }, "\u2714 ", u?.toolSuccess || 0), /* @__PURE__ */ React16.createElement(Text16, { color: colors.text }, " "), /* @__PURE__ */ React16.createElement(Text16, { color: colors.warning || "yellow" }, "\u{1F6C7} ", u?.toolDenied || 0), /* @__PURE__ */ React16.createElement(Text16, { color: colors.text }, " "), /* @__PURE__ */ React16.createElement(Text16, { color: colors.danger || "red" }, "\u2718 ", u?.toolFailure || 0), /* @__PURE__ */ React16.createElement(Text16, { color: colors.text }, " )")))), /* @__PURE__ */ React16.createElement(Text16, { color: colors.textMuted, dimColor: true, italic: true }, "\n", "(Press TAB to toggle Daily/Monthly views, SPACE for Model Breakdown, ESC to return)"));
|
|
23341
23419
|
}
|
|
23342
23420
|
case "dynamicDirDanger":
|
|
23343
23421
|
return /* @__PURE__ */ React16.createElement(Box14, { flexDirection: "column", borderStyle: "round", borderColor: colors.borderMuted, paddingX: 2, paddingY: 1, width: "100%" }, /* @__PURE__ */ React16.createElement(Text16, { color: colors.warning || "yellow", bold: true, underline: true }, "DYNAMIC DIRECTORY AWARENESS"), /* @__PURE__ */ React16.createElement(Text16, { marginTop: 1, color: colors.text }, "Enabling this keeps the agent aware of filesystem state in real time, but may reduce prompt cache efficiency."), /* @__PURE__ */ React16.createElement(Text16, { color: colors.text }, "\n", "RECOMMENDED SCENARIOS TO TURN ON:"), /* @__PURE__ */ React16.createElement(Text16, { color: colors.textMuted }, "\u2022 Repo is small."), /* @__PURE__ */ React16.createElement(Text16, { color: colors.textMuted }, "\u2022 The task benefits from real-time filesystem awareness."), /* @__PURE__ */ React16.createElement(Text16, { color: colors.textMuted }, "\u2022 Files are often created, renamed, or deleted."), /* @__PURE__ */ React16.createElement(Text16, { color: colors.textMuted }, "\u2022 You know exactly what you're signing up for."), /* @__PURE__ */ React16.createElement(Text16, { color: colors.textMuted }, "\u2022 You don't have conflicting decisions regarding token bills."), /* @__PURE__ */ React16.createElement(Text16, { color: colors.textMuted }, "\u2022 You want to see your wallet crying at 3am."), /* @__PURE__ */ React16.createElement(Box14, { marginTop: 1 }, /* @__PURE__ */ React16.createElement(
|
|
@@ -24142,7 +24220,7 @@ var init_app = __esm({
|
|
|
24142
24220
|
};
|
|
24143
24221
|
getKeybindingsPath = (ideName) => {
|
|
24144
24222
|
const dirName = getIDEDirName(ideName);
|
|
24145
|
-
const home =
|
|
24223
|
+
const home = os4.homedir();
|
|
24146
24224
|
if (process.platform === "win32") {
|
|
24147
24225
|
const appData = process.env.APPDATA;
|
|
24148
24226
|
if (!appData) return null;
|
|
@@ -24401,10 +24479,10 @@ var init_app = __esm({
|
|
|
24401
24479
|
// src/cli.jsx
|
|
24402
24480
|
import { spawn as spawn3 } from "child_process";
|
|
24403
24481
|
import { fileURLToPath as fileURLToPath4 } from "url";
|
|
24404
|
-
import
|
|
24482
|
+
import os5 from "os";
|
|
24405
24483
|
import dotenv2 from "dotenv";
|
|
24406
24484
|
dotenv2.config({ quiet: true });
|
|
24407
|
-
var totalSystemRamBytes =
|
|
24485
|
+
var totalSystemRamBytes = os5.totalmem();
|
|
24408
24486
|
var totalSystemRamMB = totalSystemRamBytes / (1024 * 1024);
|
|
24409
24487
|
var SAFETY_MARGIN = 0.5;
|
|
24410
24488
|
var calculatedLimit = Math.floor(totalSystemRamMB * SAFETY_MARGIN);
|
|
@@ -24502,6 +24580,7 @@ Usage: fluxflow --export error`);
|
|
|
24502
24580
|
/clear Clear terminal screen
|
|
24503
24581
|
/resume Load previous session
|
|
24504
24582
|
/compress Summarize and compress chat history
|
|
24583
|
+
/truncate Truncate tool results in chat history
|
|
24505
24584
|
/revert Revert codebase back to a checkpoint
|
|
24506
24585
|
/save Force save current chat
|
|
24507
24586
|
/export [chat|logs] Export chat session or system error logs
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "fluxflow-cli",
|
|
3
|
-
"version": "3.16.
|
|
4
|
-
"date": "2026-08-
|
|
3
|
+
"version": "3.16.2",
|
|
4
|
+
"date": "2026-08-02",
|
|
5
5
|
"description": "A High-Fidelity Agentic CLI with Sub-Agents for the Flux Era.",
|
|
6
6
|
"keywords": [
|
|
7
7
|
"ai",
|
|
@@ -41,7 +41,7 @@
|
|
|
41
41
|
},
|
|
42
42
|
"scripts": {
|
|
43
43
|
"start": "tsx ./src/cli.jsx",
|
|
44
|
-
"build": "esbuild ./src/cli.jsx --bundle --platform=node --format=esm --outfile=./dist/fluxflow.js --external:react --external:ink --external:chalk --external:fs-extra --external:gradient-string --external:ink-text-input --external:ink-select-input --external:@google/genai --external:zod --external:nanoid --external:puppeteer --external:pdf-lib --external:node-pty --external:html-to-docx --external:typescript --external:ws --external:web-tree-sitter --external:diff --external:dotenv --external:fast-glob"
|
|
44
|
+
"build": "esbuild ./src/cli.jsx --bundle --platform=node --format=esm --outfile=./dist/fluxflow.js --external:react --external:ink --external:chalk --external:fs-extra --external:gradient-string --external:ink-text-input --external:ink-select-input --external:@google/genai --external:zod --external:nanoid --external:puppeteer --external:pdf-lib --external:node-pty --external:html-to-docx --external:typescript --external:ws --external:web-tree-sitter --external:diff --external:dotenv --external:fast-glob --external:turndown"
|
|
45
45
|
},
|
|
46
46
|
"dependencies": {
|
|
47
47
|
"@google/genai": "^1.52.0",
|
|
@@ -62,6 +62,7 @@
|
|
|
62
62
|
"pdf-lib": "^1.17.1",
|
|
63
63
|
"puppeteer": "24.43.1",
|
|
64
64
|
"react": "^19.2.5",
|
|
65
|
+
"turndown": "^7.2.4",
|
|
65
66
|
"web-tree-sitter": "^0.25.10",
|
|
66
67
|
"ws": "^8.21.0",
|
|
67
68
|
"zod": "^4.3.6"
|