fluxflow-cli 1.18.19 → 1.18.21
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 +123 -59
- package/package.json +2 -2
package/dist/fluxflow.js
CHANGED
|
@@ -1123,10 +1123,15 @@ var init_arg_parser = __esm({
|
|
|
1123
1123
|
i = argsString.length;
|
|
1124
1124
|
}
|
|
1125
1125
|
} else {
|
|
1126
|
-
let
|
|
1127
|
-
|
|
1128
|
-
|
|
1129
|
-
|
|
1126
|
+
let rest = argsString.substring(i);
|
|
1127
|
+
let boundaryMatch = rest.match(/,\s*\w+\s*=|(?:\s*\)\s*(?:$|\]))/);
|
|
1128
|
+
if (boundaryMatch) {
|
|
1129
|
+
let boundaryIndex = boundaryMatch.index;
|
|
1130
|
+
value = rest.substring(0, boundaryIndex).trim();
|
|
1131
|
+
i += boundaryIndex;
|
|
1132
|
+
} else {
|
|
1133
|
+
value = rest.trim();
|
|
1134
|
+
i = argsString.length;
|
|
1130
1135
|
}
|
|
1131
1136
|
}
|
|
1132
1137
|
if (value === "true") value = true;
|
|
@@ -1163,11 +1168,10 @@ var init_main_tools = __esm({
|
|
|
1163
1168
|
TOOL_PROTOCOL = (mode, osDetected) => `
|
|
1164
1169
|
-- TOOL DEFINITIONS --
|
|
1165
1170
|
Access to internal tools. MUST use the exact syntax on a new line: [tool:functions.ToolName(args)]
|
|
1166
|
-
|
|
1167
|
-
- **MAX 3 TOOL CALLS PER TURN. Next Turn, verify results, plan next
|
|
1168
|
-
- Use contextually BEST tool, no brute force, no spamming
|
|
1169
|
-
|
|
1170
|
-
|
|
1171
|
+
MANDATORY TOOL POLICY:
|
|
1172
|
+
- **MAX 3 TOOL CALLS PER TURN. Next Turn, verify results, plan next**
|
|
1173
|
+
${mode === "" ? "- Prefer multiple search & replace on patch tool if same file/path\n" : ""}- Use contextually BEST tool, no brute force, no spamming
|
|
1174
|
+
${mode === "Flux" ? "- **File Tools >> Code in chat**\n" : ""}
|
|
1171
1175
|
- COMMUNICATION TOOLS -
|
|
1172
1176
|
1. [tool:functions.Ask(question="...", optionA="option::description", ...MAX 4)]. Ambiguity Resolution. Mandatory Triggers: Path Divergence, Security, Risk Mitigation. ask >> finish
|
|
1173
1177
|
Suggest best options; don't ask for preferences
|
|
@@ -2210,6 +2214,7 @@ __export(paths_exports, {
|
|
|
2210
2214
|
LEDGER_FILE: () => LEDGER_FILE,
|
|
2211
2215
|
LOGS_DIR: () => LOGS_DIR,
|
|
2212
2216
|
MEMORIES_FILE: () => MEMORIES_FILE,
|
|
2217
|
+
PATHS_FILE: () => PATHS_FILE,
|
|
2213
2218
|
SECRET_DIR: () => SECRET_DIR,
|
|
2214
2219
|
SETTINGS_FILE: () => SETTINGS_FILE,
|
|
2215
2220
|
TEMP_MEM_CHAT_FILE: () => TEMP_MEM_CHAT_FILE,
|
|
@@ -2220,7 +2225,7 @@ import os2 from "os";
|
|
|
2220
2225
|
import path2 from "path";
|
|
2221
2226
|
import fs2 from "fs";
|
|
2222
2227
|
import crypto2 from "crypto";
|
|
2223
|
-
var FLUXFLOW_DIR, SETTINGS_FILE, externalDir, DATA_DIR, LOGS_DIR, SECRET_DIR, HISTORY_FILE, USAGE_FILE, MEMORIES_FILE, TEMP_MEM_FILE, TEMP_MEM_CHAT_FILE, BACKUPS_DIR, LEDGER_FILE;
|
|
2228
|
+
var FLUXFLOW_DIR, SETTINGS_FILE, externalDir, DATA_DIR, LOGS_DIR, SECRET_DIR, HISTORY_FILE, USAGE_FILE, MEMORIES_FILE, TEMP_MEM_FILE, TEMP_MEM_CHAT_FILE, BACKUPS_DIR, LEDGER_FILE, PATHS_FILE;
|
|
2224
2229
|
var init_paths = __esm({
|
|
2225
2230
|
"src/utils/paths.js"() {
|
|
2226
2231
|
FLUXFLOW_DIR = path2.join(os2.homedir(), ".fluxflow");
|
|
@@ -2263,6 +2268,7 @@ var init_paths = __esm({
|
|
|
2263
2268
|
TEMP_MEM_CHAT_FILE = path2.join(SECRET_DIR, "temp-memory-chat.json");
|
|
2264
2269
|
BACKUPS_DIR = path2.join(DATA_DIR, "backups");
|
|
2265
2270
|
LEDGER_FILE = path2.join(SECRET_DIR, "ledger.json");
|
|
2271
|
+
PATHS_FILE = path2.join(SECRET_DIR, "path.json");
|
|
2266
2272
|
}
|
|
2267
2273
|
});
|
|
2268
2274
|
|
|
@@ -2453,6 +2459,7 @@ Mode: ${mode}${thinkingLevel !== "Fast" ? " (Thinking Mode)" : ""}. ${mode === "
|
|
|
2453
2459
|
|
|
2454
2460
|
SYSTEM PRIORITY: [SYSTEM], [TOOL RESULT]
|
|
2455
2461
|
HIGH PRIORITY: [STEERING HINT]
|
|
2462
|
+
USER PRIORITY: [USER]
|
|
2456
2463
|
|
|
2457
2464
|
-- THINKING RULES --
|
|
2458
2465
|
${thinkingConfig}
|
|
@@ -4283,6 +4290,7 @@ var init_write_docx = __esm({
|
|
|
4283
4290
|
|
|
4284
4291
|
// src/tools/search_keyword.js
|
|
4285
4292
|
import { exec } from "child_process";
|
|
4293
|
+
import path13 from "path";
|
|
4286
4294
|
var search_keyword;
|
|
4287
4295
|
var init_search_keyword = __esm({
|
|
4288
4296
|
"src/tools/search_keyword.js"() {
|
|
@@ -4295,14 +4303,14 @@ var init_search_keyword = __esm({
|
|
|
4295
4303
|
let command = "";
|
|
4296
4304
|
if (file) {
|
|
4297
4305
|
if (isWindows) {
|
|
4298
|
-
command = `powershell -Command "if (Test-Path '${file}') { Select-String -Path '${file}' -Pattern '${keyword}' | Select-Object -First 150 | ForEach-Object {
|
|
4306
|
+
command = `powershell -NoProfile -Command "if (Test-Path '${file}') { Select-String -Path '${file}' -Pattern '${keyword}' -ErrorAction SilentlyContinue | Select-Object -First 150 | ForEach-Object { '{0}|{1}' -f $_.Path, $_.LineNumber } } else { Write-Error 'File not found: ${file}' }"`;
|
|
4299
4307
|
} else {
|
|
4300
4308
|
command = `grep -HnI "${keyword}" "${file}" | head -n 150`;
|
|
4301
4309
|
}
|
|
4302
4310
|
} else {
|
|
4303
4311
|
if (isWindows) {
|
|
4304
4312
|
const excludePattern = excludes.join("|").replace(/\./g, "\\.");
|
|
4305
|
-
command = `powershell -Command "Get-ChildItem -Path . -Recurse -File | Where-Object { $_.FullName -notmatch '${excludePattern}' } | Select-String -Pattern '${keyword}' | Select-Object -First 150 | ForEach-Object {
|
|
4313
|
+
command = `powershell -NoProfile -Command "Get-ChildItem -Path . -Recurse -File -ErrorAction SilentlyContinue | Where-Object { $_.FullName -notmatch '${excludePattern}' } | Select-String -Pattern '${keyword}' -ErrorAction SilentlyContinue | Select-Object -First 150 | ForEach-Object { '{0}|{1}' -f $_.Path, $_.LineNumber }"`;
|
|
4306
4314
|
} else {
|
|
4307
4315
|
const excludeDirArgs = excludes.map((d) => `--exclude-dir="${d}"`).join(" ");
|
|
4308
4316
|
command = `grep -rnI ${excludeDirArgs} "${keyword}" . | head -n 150`;
|
|
@@ -4327,12 +4335,41 @@ var init_search_keyword = __esm({
|
|
|
4327
4335
|
});
|
|
4328
4336
|
if (filteredLines.length === 0) return resolve(`Found 0 matches for keyword: "${keyword}"${file ? ` in file: ${file}` : ""}`);
|
|
4329
4337
|
const matches = filteredLines.slice(0, 150).map((line) => {
|
|
4330
|
-
|
|
4331
|
-
|
|
4332
|
-
|
|
4333
|
-
|
|
4334
|
-
|
|
4335
|
-
|
|
4338
|
+
if (line.includes("|")) {
|
|
4339
|
+
const parts = line.split("|");
|
|
4340
|
+
let rawPath = parts[0];
|
|
4341
|
+
if (path13.isAbsolute(rawPath)) {
|
|
4342
|
+
rawPath = path13.relative(process.cwd(), rawPath);
|
|
4343
|
+
}
|
|
4344
|
+
const filePath = rawPath.replace(/^(\.\/|\.\\)/, "").replace(/\\/g, "/");
|
|
4345
|
+
const lineNum = parts[1];
|
|
4346
|
+
return `${filePath} ${lineNum}`;
|
|
4347
|
+
} else {
|
|
4348
|
+
let rawPath, lineNum;
|
|
4349
|
+
const driveMatch = line.match(/^([a-zA-Z]:)/);
|
|
4350
|
+
if (driveMatch) {
|
|
4351
|
+
const startSearch = 2;
|
|
4352
|
+
const nextColon = line.indexOf(":", startSearch);
|
|
4353
|
+
const thirdColon = line.indexOf(":", nextColon + 1);
|
|
4354
|
+
if (nextColon !== -1 && thirdColon !== -1) {
|
|
4355
|
+
rawPath = line.substring(0, nextColon);
|
|
4356
|
+
lineNum = line.substring(nextColon + 1, thirdColon);
|
|
4357
|
+
}
|
|
4358
|
+
} else {
|
|
4359
|
+
const firstColon = line.indexOf(":");
|
|
4360
|
+
const secondColon = line.indexOf(":", firstColon + 1);
|
|
4361
|
+
if (firstColon !== -1 && secondColon !== -1) {
|
|
4362
|
+
rawPath = line.substring(0, firstColon);
|
|
4363
|
+
lineNum = line.substring(firstColon + 1, secondColon);
|
|
4364
|
+
}
|
|
4365
|
+
}
|
|
4366
|
+
if (!rawPath || !lineNum) return null;
|
|
4367
|
+
if (path13.isAbsolute(rawPath)) {
|
|
4368
|
+
rawPath = path13.relative(process.cwd(), rawPath);
|
|
4369
|
+
}
|
|
4370
|
+
const filePath = rawPath.replace(/^(\.\/|\.\\)/, "").replace(/\\/g, "/");
|
|
4371
|
+
return `${filePath} ${lineNum}`;
|
|
4372
|
+
}
|
|
4336
4373
|
}).filter(Boolean);
|
|
4337
4374
|
let output = `Found ${filteredLines.length} matches:
|
|
4338
4375
|
|
|
@@ -4350,7 +4387,7 @@ var init_search_keyword = __esm({
|
|
|
4350
4387
|
|
|
4351
4388
|
// src/utils/settings.js
|
|
4352
4389
|
import fs14 from "fs-extra";
|
|
4353
|
-
import
|
|
4390
|
+
import path14 from "path";
|
|
4354
4391
|
var DEFAULT_SETTINGS, loadSettings, migrateToExternal, saveSettings;
|
|
4355
4392
|
var init_settings = __esm({
|
|
4356
4393
|
"src/utils/settings.js"() {
|
|
@@ -4437,8 +4474,8 @@ var init_settings = __esm({
|
|
|
4437
4474
|
const { FLUXFLOW_DIR: FLUXFLOW_DIR2 } = await Promise.resolve().then(() => (init_paths(), paths_exports));
|
|
4438
4475
|
const folders = ["logs", "secret"];
|
|
4439
4476
|
for (const folder of folders) {
|
|
4440
|
-
const src =
|
|
4441
|
-
const dest =
|
|
4477
|
+
const src = path14.join(FLUXFLOW_DIR2, folder);
|
|
4478
|
+
const dest = path14.join(newPath, folder);
|
|
4442
4479
|
try {
|
|
4443
4480
|
if (await fs14.exists(src)) {
|
|
4444
4481
|
await fs14.ensureDir(dest);
|
|
@@ -4468,7 +4505,7 @@ var init_settings = __esm({
|
|
|
4468
4505
|
if (updated.imageSettings) {
|
|
4469
4506
|
updated.imageSettings = { ...updated.imageSettings, apiKey: "" };
|
|
4470
4507
|
}
|
|
4471
|
-
await fs14.ensureDir(
|
|
4508
|
+
await fs14.ensureDir(path14.dirname(SETTINGS_FILE));
|
|
4472
4509
|
writeAesEncryptedJson(SETTINGS_FILE, updated);
|
|
4473
4510
|
return true;
|
|
4474
4511
|
} catch (err) {
|
|
@@ -4489,7 +4526,7 @@ var init_fallback_key = __esm({
|
|
|
4489
4526
|
|
|
4490
4527
|
// src/tools/generate_image.js
|
|
4491
4528
|
import fs15 from "fs-extra";
|
|
4492
|
-
import
|
|
4529
|
+
import path15 from "path";
|
|
4493
4530
|
var injectPngMetadata, generate_image;
|
|
4494
4531
|
var init_generate_image = __esm({
|
|
4495
4532
|
"src/tools/generate_image.js"() {
|
|
@@ -4669,12 +4706,12 @@ var init_generate_image = __esm({
|
|
|
4669
4706
|
"Seed": String(seed)
|
|
4670
4707
|
};
|
|
4671
4708
|
finalBuffer = injectPngMetadata(finalBuffer, metadata);
|
|
4672
|
-
const absolutePath =
|
|
4673
|
-
await fs15.ensureDir(
|
|
4709
|
+
const absolutePath = path15.resolve(process.cwd(), outputPath);
|
|
4710
|
+
await fs15.ensureDir(path15.dirname(absolutePath));
|
|
4674
4711
|
await RevertManager.recordFileChange(absolutePath);
|
|
4675
4712
|
await fs15.writeFile(absolutePath, finalBuffer);
|
|
4676
4713
|
await recordImageGeneration(settings);
|
|
4677
|
-
const ext =
|
|
4714
|
+
const ext = path15.extname(outputPath).toLowerCase();
|
|
4678
4715
|
const mimeMap = {
|
|
4679
4716
|
".jpg": "image/jpeg",
|
|
4680
4717
|
".jpeg": "image/jpeg",
|
|
@@ -4842,6 +4879,13 @@ var init_tools = __esm({
|
|
|
4842
4879
|
AddMemoryScore: addMemScore
|
|
4843
4880
|
};
|
|
4844
4881
|
dispatchTool = async (toolName, args, context = {}) => {
|
|
4882
|
+
if (context.mode && context.mode.toLowerCase() === "flow") {
|
|
4883
|
+
const normalized = toolName.toLowerCase();
|
|
4884
|
+
const isWebOrAsk = normalized.startsWith("web") || normalized.startsWith("ask");
|
|
4885
|
+
if (!isWebOrAsk) {
|
|
4886
|
+
return `ERROR: Tool [${toolName}] is restricted in Flow mode.`;
|
|
4887
|
+
}
|
|
4888
|
+
}
|
|
4845
4889
|
const tool = TOOL_MAP[toolName];
|
|
4846
4890
|
if (!tool) {
|
|
4847
4891
|
return `ERROR: Tool [${toolName}] not found in registry.`;
|
|
@@ -4857,7 +4901,7 @@ var init_tools = __esm({
|
|
|
4857
4901
|
|
|
4858
4902
|
// src/utils/ai.js
|
|
4859
4903
|
import { GoogleGenAI, ThinkingLevel, HarmBlockThreshold, HarmCategory } from "@google/genai";
|
|
4860
|
-
import
|
|
4904
|
+
import path16 from "path";
|
|
4861
4905
|
import fs16 from "fs";
|
|
4862
4906
|
var client, TERMINATION_SIGNAL, stripAnsi2, signalTermination, TOOL_LABELS2, getToolDetail, runJanitorTask, getActiveToolContext, getContextSafeText, contextSafeReplace, getSanitizedText, detectToolCalls, initAI, consolidatePastMemories, getAIStream;
|
|
4863
4907
|
var init_ai = __esm({
|
|
@@ -4899,7 +4943,7 @@ var init_ai = __esm({
|
|
|
4899
4943
|
try {
|
|
4900
4944
|
const pArgs = parseArgs(argsStr);
|
|
4901
4945
|
const filePath = pArgs.path || pArgs.targetFile || pArgs.TargetFile || pArgs.directory;
|
|
4902
|
-
return filePath ?
|
|
4946
|
+
return filePath ? path16.basename(filePath.replace(/["']/g, "").replace(/\\/g, "/")) : null;
|
|
4903
4947
|
} catch (e) {
|
|
4904
4948
|
return null;
|
|
4905
4949
|
}
|
|
@@ -5066,9 +5110,9 @@ ${originalTextProcessed.length > USER_CONTEXT_LENGTH ? "... (truncated) ...\n\n"
|
|
|
5066
5110
|
process.stdout.write(`\x1B]0;Finalizing Error\x07`);
|
|
5067
5111
|
}
|
|
5068
5112
|
await new Promise((resolve) => setTimeout(resolve, 1e3));
|
|
5069
|
-
const janitorErrDir =
|
|
5113
|
+
const janitorErrDir = path16.join(LOGS_DIR, "janitor");
|
|
5070
5114
|
if (!fs16.existsSync(janitorErrDir)) fs16.mkdirSync(janitorErrDir, { recursive: true });
|
|
5071
|
-
fs16.appendFileSync(
|
|
5115
|
+
fs16.appendFileSync(path16.join(janitorErrDir, "error.log"), `ERROR [Attempt ${attempts}/${MAX_JANITOR_RETRIES + 1}] [${date}]: ${String(janitorErr)}
|
|
5072
5116
|
|
|
5073
5117
|
`);
|
|
5074
5118
|
if (attempts > MAX_JANITOR_RETRIES) break;
|
|
@@ -5077,8 +5121,8 @@ ${originalTextProcessed.length > USER_CONTEXT_LENGTH ? "... (truncated) ...\n\n"
|
|
|
5077
5121
|
}
|
|
5078
5122
|
}
|
|
5079
5123
|
if (attempts) {
|
|
5080
|
-
const janitorErrDir =
|
|
5081
|
-
fs16.appendFileSync(
|
|
5124
|
+
const janitorErrDir = path16.join(LOGS_DIR, "janitor");
|
|
5125
|
+
fs16.appendFileSync(path16.join(janitorErrDir, "error.log"), `-----------------------------------------------------------------------------
|
|
5082
5126
|
|
|
5083
5127
|
|
|
5084
5128
|
`);
|
|
@@ -5394,10 +5438,10 @@ ${newMemoryListStr}
|
|
|
5394
5438
|
}
|
|
5395
5439
|
}
|
|
5396
5440
|
} catch (err) {
|
|
5397
|
-
const janitorLogDir =
|
|
5441
|
+
const janitorLogDir = path16.join(LOGS_DIR, "janitor");
|
|
5398
5442
|
if (!fs16.existsSync(janitorLogDir)) fs16.mkdirSync(janitorLogDir, { recursive: true });
|
|
5399
5443
|
fs16.appendFileSync(
|
|
5400
|
-
|
|
5444
|
+
path16.join(janitorLogDir, "error.log"),
|
|
5401
5445
|
`[${(/* @__PURE__ */ new Date()).toLocaleString()}] Past memory batch consolidation error: ${err.message}
|
|
5402
5446
|
`
|
|
5403
5447
|
);
|
|
@@ -5601,16 +5645,16 @@ ${newMemoryListStr}
|
|
|
5601
5645
|
if (COLLAPSED_DIRS_GLOBAL.includes(entry.name)) continue;
|
|
5602
5646
|
if (entry.isDirectory()) {
|
|
5603
5647
|
currentCount.value++;
|
|
5604
|
-
countFolders(
|
|
5648
|
+
countFolders(path16.join(dir, entry.name), currentCount, depth + 1);
|
|
5605
5649
|
}
|
|
5606
5650
|
}
|
|
5607
5651
|
return currentCount.value;
|
|
5608
5652
|
};
|
|
5609
5653
|
const getDirTree = (dir, maxDepth, prefix = "", depth = 1) => {
|
|
5610
5654
|
const entries = safeReaddirWithTypes(dir);
|
|
5611
|
-
const sep =
|
|
5655
|
+
const sep = path16.sep;
|
|
5612
5656
|
if (entries.length > 100) {
|
|
5613
|
-
return `${prefix}\u2514\u2500\u2500 ${
|
|
5657
|
+
return `${prefix}\u2514\u2500\u2500 ${path16.basename(dir)}${sep} ...100+ files...
|
|
5614
5658
|
`;
|
|
5615
5659
|
}
|
|
5616
5660
|
let result = "";
|
|
@@ -5628,7 +5672,7 @@ ${newMemoryListStr}
|
|
|
5628
5672
|
];
|
|
5629
5673
|
finalItems.forEach((item, index) => {
|
|
5630
5674
|
const isLast = index === finalItems.length - 1;
|
|
5631
|
-
const filePath =
|
|
5675
|
+
const filePath = path16.join(dir, item.name);
|
|
5632
5676
|
const connector = isLast ? "\u2514\u2500\u2500 " : "\u251C\u2500\u2500 ";
|
|
5633
5677
|
const childPrefix = prefix + (isLast ? " " : "\u2502 ");
|
|
5634
5678
|
if (item.isCollapsed) {
|
|
@@ -5671,9 +5715,14 @@ ${newMemoryListStr}
|
|
|
5671
5715
|
else if (totalFolders > 128) dynamicMaxDepth = 8;
|
|
5672
5716
|
else if (totalFolders > 64) dynamicMaxDepth = 9;
|
|
5673
5717
|
else if (totalFolders > 32) dynamicMaxDepth = 10;
|
|
5718
|
+
const chatPaths = readEncryptedJson(PATHS_FILE, {});
|
|
5719
|
+
const lastCwd = chatPaths[chatId];
|
|
5720
|
+
const cwdMismatch = lastCwd ? lastCwd !== process.cwd() : false;
|
|
5721
|
+
chatPaths[chatId] = process.cwd();
|
|
5722
|
+
writeEncryptedJson(PATHS_FILE, chatPaths);
|
|
5674
5723
|
let dirStructure = process.cwd() + "\n" + getDirTree(process.cwd(), dynamicMaxDepth);
|
|
5675
5724
|
const firstUserMsg = `[SYSTEM METADATA (PRIORITY: DYNAMIC)] Time: ${dateTimeStr} | v${versionFluxflow2}
|
|
5676
|
-
CWD: ${process.cwd()}
|
|
5725
|
+
CWD: ${process.cwd()}${cwdMismatch ? ` (CWD Mismatch! Previous Path: ${lastCwd})` : ""}
|
|
5677
5726
|
**DIRECTORY STRUCTURE**
|
|
5678
5727
|
${dirStructure}
|
|
5679
5728
|
${memoryPrompt}
|
|
@@ -5888,12 +5937,12 @@ ${thinkingLevel != "Fast" ? "[SYSTEM] **STRICTLY FOLLOW THINKING POLICY AS CRITI
|
|
|
5888
5937
|
if (keyword) {
|
|
5889
5938
|
detail = keyword.replace(/["']/g, "");
|
|
5890
5939
|
} else if (filePath) {
|
|
5891
|
-
detail =
|
|
5940
|
+
detail = path16.basename(filePath.replace(/["']/g, "").replace(/\\/g, "/"));
|
|
5892
5941
|
} else {
|
|
5893
5942
|
const m = partialArgs.match(/(?:path|targetFile|TargetFile|directory|keyword)\s*=\s*\\?["']?([^\\"' \),]+)/);
|
|
5894
5943
|
if (m) {
|
|
5895
5944
|
const val = m[1].replace(/["']/g, "");
|
|
5896
|
-
detail = potentialTool === "search_keyword" ? val :
|
|
5945
|
+
detail = potentialTool === "search_keyword" ? val : path16.basename(val.replace(/\\/g, "/"));
|
|
5897
5946
|
}
|
|
5898
5947
|
}
|
|
5899
5948
|
}
|
|
@@ -6053,7 +6102,7 @@ ${thinkingLevel != "Fast" ? "[SYSTEM] **STRICTLY FOLLOW THINKING POLICY AS CRITI
|
|
|
6053
6102
|
let totalLines = "...";
|
|
6054
6103
|
let actualEndLine = eLine;
|
|
6055
6104
|
try {
|
|
6056
|
-
const absPath =
|
|
6105
|
+
const absPath = path16.resolve(process.cwd(), targetPath2);
|
|
6057
6106
|
if (fs16.existsSync(absPath)) {
|
|
6058
6107
|
const content = fs16.readFileSync(absPath, "utf8");
|
|
6059
6108
|
const lines = content.split("\n").length;
|
|
@@ -6075,8 +6124,8 @@ ${thinkingLevel != "Fast" ? "[SYSTEM] **STRICTLY FOLLOW THINKING POLICY AS CRITI
|
|
|
6075
6124
|
}
|
|
6076
6125
|
} else if (normToolName === "list_files" || normToolName === "read_folder") {
|
|
6077
6126
|
const action = normToolName === "list_files" ? "List" : "Viewed";
|
|
6078
|
-
const
|
|
6079
|
-
label = `\u{1F4C2} ${action}: ${
|
|
6127
|
+
const path18 = parseArgs(toolCall.args).path;
|
|
6128
|
+
label = `\u{1F4C2} ${action}: ${path18 === "." ? "./" : path18}`;
|
|
6080
6129
|
} else if (normToolName === "write_file" || normToolName === "update_file") {
|
|
6081
6130
|
const action = normToolName === "write_file" ? "Created" : "Edited";
|
|
6082
6131
|
label = `\u{1F4BE} ${action}: ${parseArgs(toolCall.args).path || "..."}`;
|
|
@@ -6098,7 +6147,7 @@ ${thinkingLevel != "Fast" ? "[SYSTEM] **STRICTLY FOLLOW THINKING POLICY AS CRITI
|
|
|
6098
6147
|
const { command } = parseArgs(toolCall.args);
|
|
6099
6148
|
if (command && settings.systemSettings && settings.systemSettings.allowExternalAccess === false) {
|
|
6100
6149
|
const riskyPatterns = [/[a-zA-Z]:[\\\/]/i, /^\//, /\.\.[\\\/]/, /\/etc\//, /\/var\//, /\/root\//, /\/bin\//, /\/usr\//];
|
|
6101
|
-
const currentDrive =
|
|
6150
|
+
const currentDrive = path16.resolve(process.cwd()).substring(0, 3).toLowerCase();
|
|
6102
6151
|
const isViolating = riskyPatterns.some((pattern) => {
|
|
6103
6152
|
if (pattern.source === "[a-zA-Z]:[\\\\\\/]") {
|
|
6104
6153
|
const driveMatch = command.match(/[a-zA-Z]:[\\\/]/i);
|
|
@@ -6127,8 +6176,8 @@ ${thinkingLevel != "Fast" ? "[SYSTEM] **STRICTLY FOLLOW THINKING POLICY AS CRITI
|
|
|
6127
6176
|
const targetPath = parsedArgs.path || parsedArgs.targetPath || null;
|
|
6128
6177
|
if (targetPath) {
|
|
6129
6178
|
const isExternalOff = settings.systemSettings && settings.systemSettings.allowExternalAccess === false;
|
|
6130
|
-
const absoluteTarget =
|
|
6131
|
-
const absoluteCwd =
|
|
6179
|
+
const absoluteTarget = path16.resolve(targetPath);
|
|
6180
|
+
const absoluteCwd = path16.resolve(process.cwd());
|
|
6132
6181
|
if (isExternalOff && !absoluteTarget.startsWith(absoluteCwd)) {
|
|
6133
6182
|
const denyMsg = `Access Denied. You are not allowed to access files outside the current workspace.`;
|
|
6134
6183
|
if (normToolName === "write_file" || normToolName === "update_file") {
|
|
@@ -6272,7 +6321,8 @@ ${boxBottom}` };
|
|
|
6272
6321
|
history,
|
|
6273
6322
|
onChunk: (chunk2) => settings.onExecChunk ? settings.onExecChunk(chunk2) : null,
|
|
6274
6323
|
onAskUser: settings.onAskUser,
|
|
6275
|
-
systemSettings: settings.systemSettings
|
|
6324
|
+
systemSettings: settings.systemSettings,
|
|
6325
|
+
mode
|
|
6276
6326
|
});
|
|
6277
6327
|
yield { type: "spinner", content: true };
|
|
6278
6328
|
if (process.stdout.isTTY) {
|
|
@@ -6398,9 +6448,9 @@ ${boxBottom}` };
|
|
|
6398
6448
|
const errMsg = err.status || err.error && err.error.message || String(err);
|
|
6399
6449
|
const errLog = String(err);
|
|
6400
6450
|
const date = (/* @__PURE__ */ new Date()).toLocaleString();
|
|
6401
|
-
const agentErrDir =
|
|
6451
|
+
const agentErrDir = path16.join(LOGS_DIR, "agent");
|
|
6402
6452
|
if (!fs16.existsSync(agentErrDir)) fs16.mkdirSync(agentErrDir, { recursive: true });
|
|
6403
|
-
fs16.appendFileSync(
|
|
6453
|
+
fs16.appendFileSync(path16.join(agentErrDir, "error.log"), `ERROR [${date}]: ${errLog}
|
|
6404
6454
|
|
|
6405
6455
|
----------------------------------------------------------------------
|
|
6406
6456
|
|
|
@@ -6444,7 +6494,7 @@ ${recoveryText}`
|
|
|
6444
6494
|
yield { type: "status", content: `Error Occured. Recovering Stream...` };
|
|
6445
6495
|
} else {
|
|
6446
6496
|
throw new Error(`Stream collapsed too many times. (Failed to resolve ${MAX_RETRIES} times)
|
|
6447
|
-
Error Log can be found in ${
|
|
6497
|
+
Error Log can be found in ${path16.join(LOGS_DIR, "agent", "error.log")}`);
|
|
6448
6498
|
}
|
|
6449
6499
|
} else {
|
|
6450
6500
|
if (retryCount <= MAX_RETRIES) {
|
|
@@ -6461,7 +6511,7 @@ Error Log can be found in ${path15.join(LOGS_DIR, "agent", "error.log")}`);
|
|
|
6461
6511
|
yield { type: "status", content: `Trying to reach ${modelName}...` };
|
|
6462
6512
|
} else {
|
|
6463
6513
|
throw new Error(`Model ${modelName} cannot be reached. (Failed ${MAX_RETRIES} times)
|
|
6464
|
-
Error Log can be found in ${
|
|
6514
|
+
Error Log can be found in ${path16.join(LOGS_DIR, "agent", "error.log")}`);
|
|
6465
6515
|
}
|
|
6466
6516
|
}
|
|
6467
6517
|
}
|
|
@@ -6987,7 +7037,7 @@ import os4 from "os";
|
|
|
6987
7037
|
import React13, { useState as useState10, useEffect as useEffect7, useRef as useRef3, useMemo as useMemo2 } from "react";
|
|
6988
7038
|
import { Box as Box13, Text as Text13, useInput as useInput7, useStdout } from "ink";
|
|
6989
7039
|
import fs18 from "fs-extra";
|
|
6990
|
-
import
|
|
7040
|
+
import path17 from "path";
|
|
6991
7041
|
import { exec as exec3 } from "child_process";
|
|
6992
7042
|
import { fileURLToPath } from "url";
|
|
6993
7043
|
import TextInput4 from "ink-text-input";
|
|
@@ -7041,6 +7091,16 @@ function App({ args = [] }) {
|
|
|
7041
7091
|
} else if (arg === "--external-access" && args[i + 1]) {
|
|
7042
7092
|
parsed.externalAccess = args[i + 1].toLowerCase();
|
|
7043
7093
|
i++;
|
|
7094
|
+
} else if (arg === "--mode" && args[i + 1]) {
|
|
7095
|
+
const val = args[i + 1];
|
|
7096
|
+
const lower = val.toLowerCase();
|
|
7097
|
+
if (["flux", "flow"].includes(lower)) {
|
|
7098
|
+
let mapped = "Flux";
|
|
7099
|
+
if (lower === "flux") mapped = "Flux";
|
|
7100
|
+
else if (lower === "flow") mapped = "Flow";
|
|
7101
|
+
parsed.mode = mapped;
|
|
7102
|
+
}
|
|
7103
|
+
i++;
|
|
7044
7104
|
} else if (arg === "--thinking" && args[i + 1]) {
|
|
7045
7105
|
const val = args[i + 1];
|
|
7046
7106
|
const lower = val.toLowerCase();
|
|
@@ -7446,7 +7506,11 @@ function App({ args = [] }) {
|
|
|
7446
7506
|
});
|
|
7447
7507
|
}
|
|
7448
7508
|
const saved = await loadSettings();
|
|
7449
|
-
|
|
7509
|
+
if (parsedArgs.mode) {
|
|
7510
|
+
setMode(parsedArgs.mode);
|
|
7511
|
+
} else {
|
|
7512
|
+
setMode(saved.mode);
|
|
7513
|
+
}
|
|
7450
7514
|
if (parsedArgs.thinking) {
|
|
7451
7515
|
setThinkingLevel(parsedArgs.thinking);
|
|
7452
7516
|
} else {
|
|
@@ -8062,7 +8126,7 @@ ${hintText}`, color: "magenta" }];
|
|
|
8062
8126
|
}
|
|
8063
8127
|
case "/export": {
|
|
8064
8128
|
const exportFile = `export-fluxflow-${chatId}.txt`;
|
|
8065
|
-
const exportPath =
|
|
8129
|
+
const exportPath = path17.join(process.cwd(), exportFile);
|
|
8066
8130
|
const exportLines = [];
|
|
8067
8131
|
let insideAgentBlock = false;
|
|
8068
8132
|
for (let i = 0; i < messages.length; i++) {
|
|
@@ -8223,7 +8287,7 @@ ${list || "No saved chats found."}`, isMeta: true }];
|
|
|
8223
8287
|
# SKILLS & WORKFLOWS
|
|
8224
8288
|
- [Define custom step-by-step recipes for this project here]
|
|
8225
8289
|
`;
|
|
8226
|
-
const filePath =
|
|
8290
|
+
const filePath = path17.join(process.cwd(), "FluxFlow.md");
|
|
8227
8291
|
if (fs18.pathExistsSync(filePath)) {
|
|
8228
8292
|
setMessages((prev) => {
|
|
8229
8293
|
setCompletedIndex(prev.length + 1);
|
|
@@ -9375,7 +9439,7 @@ var init_app = __esm({
|
|
|
9375
9439
|
CHANGELOG_URL = "https://fluxflow-cli.onrender.com/changelog.html";
|
|
9376
9440
|
linesAdded = 0;
|
|
9377
9441
|
linesRemoved = 0;
|
|
9378
|
-
packageJsonPath =
|
|
9442
|
+
packageJsonPath = path17.join(path17.dirname(fileURLToPath(import.meta.url)), "../package.json");
|
|
9379
9443
|
packageJson = JSON.parse(fs18.readFileSync(packageJsonPath, "utf8"));
|
|
9380
9444
|
versionFluxflow = packageJson.version;
|
|
9381
9445
|
updatedOn = packageJson.date || "2026-05-20";
|
|
@@ -9496,14 +9560,14 @@ var init_app = __esm({
|
|
|
9496
9560
|
if (["node_modules", ".git", ".gemini", "dist", "build", ".next", ".cache", "out"].includes(file)) {
|
|
9497
9561
|
continue;
|
|
9498
9562
|
}
|
|
9499
|
-
const filePath =
|
|
9563
|
+
const filePath = path17.join(currentDir, file);
|
|
9500
9564
|
const stat = fs18.statSync(filePath);
|
|
9501
9565
|
if (stat.isDirectory()) {
|
|
9502
9566
|
scan(filePath);
|
|
9503
9567
|
} else {
|
|
9504
9568
|
fileList.push({
|
|
9505
9569
|
name: file,
|
|
9506
|
-
relativePath:
|
|
9570
|
+
relativePath: path17.relative(process.cwd(), filePath)
|
|
9507
9571
|
});
|
|
9508
9572
|
}
|
|
9509
9573
|
}
|