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.
Files changed (2) hide show
  1. package/dist/fluxflow.js +123 -59
  2. 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 endMatch = argsString.substring(i).match(/([^,\s\)]+)/);
1127
- if (endMatch) {
1128
- value = endMatch[1];
1129
- i += value.length;
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
- STRICT POLICY
1167
- - **MAX 3 TOOL CALLS PER TURN. Next Turn, verify results, plan next**${mode === "Flux" ? "\n- **File Tools >> Code in chat**" : ""}
1168
- - Use contextually BEST tool, no brute force, no spamming
1169
- - Use multiple search & replace on patch tool if same file/path
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 { $rel = Resolve-Path $_.Path -Relative; '{0}:{1}:' -f $rel, $_.LineNumber } } else { Write-Error 'File not found: ${file}' }"`;
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 { $rel = Resolve-Path $_.Path -Relative; '{0}:{1}:' -f $rel, $_.LineNumber }"`;
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
- const firstColon = line.indexOf(":");
4331
- const secondColon = line.indexOf(":", firstColon + 1);
4332
- if (firstColon === -1 || secondColon === -1) return null;
4333
- const filePath = line.substring(0, firstColon).replace(/^(\.\/|\.\\)/, "");
4334
- const lineNum = line.substring(firstColon + 1, secondColon);
4335
- return `${filePath} ${lineNum}`;
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 path13 from "path";
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 = path13.join(FLUXFLOW_DIR2, folder);
4441
- const dest = path13.join(newPath, folder);
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(path13.dirname(SETTINGS_FILE));
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 path14 from "path";
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 = path14.resolve(process.cwd(), outputPath);
4673
- await fs15.ensureDir(path14.dirname(absolutePath));
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 = path14.extname(outputPath).toLowerCase();
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 path15 from "path";
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 ? path15.basename(filePath.replace(/["']/g, "").replace(/\\/g, "/")) : null;
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 = path15.join(LOGS_DIR, "janitor");
5113
+ const janitorErrDir = path16.join(LOGS_DIR, "janitor");
5070
5114
  if (!fs16.existsSync(janitorErrDir)) fs16.mkdirSync(janitorErrDir, { recursive: true });
5071
- fs16.appendFileSync(path15.join(janitorErrDir, "error.log"), `ERROR [Attempt ${attempts}/${MAX_JANITOR_RETRIES + 1}] [${date}]: ${String(janitorErr)}
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 = path15.join(LOGS_DIR, "janitor");
5081
- fs16.appendFileSync(path15.join(janitorErrDir, "error.log"), `-----------------------------------------------------------------------------
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 = path15.join(LOGS_DIR, "janitor");
5441
+ const janitorLogDir = path16.join(LOGS_DIR, "janitor");
5398
5442
  if (!fs16.existsSync(janitorLogDir)) fs16.mkdirSync(janitorLogDir, { recursive: true });
5399
5443
  fs16.appendFileSync(
5400
- path15.join(janitorLogDir, "error.log"),
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(path15.join(dir, entry.name), currentCount, depth + 1);
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 = path15.sep;
5655
+ const sep = path16.sep;
5612
5656
  if (entries.length > 100) {
5613
- return `${prefix}\u2514\u2500\u2500 ${path15.basename(dir)}${sep} ...100+ files...
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 = path15.join(dir, item.name);
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 = path15.basename(filePath.replace(/["']/g, "").replace(/\\/g, "/"));
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 : path15.basename(val.replace(/\\/g, "/"));
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 = path15.resolve(process.cwd(), targetPath2);
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 path17 = parseArgs(toolCall.args).path;
6079
- label = `\u{1F4C2} ${action}: ${path17 === "." ? "./" : path17}`;
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 = path15.resolve(process.cwd()).substring(0, 3).toLowerCase();
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 = path15.resolve(targetPath);
6131
- const absoluteCwd = path15.resolve(process.cwd());
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 = path15.join(LOGS_DIR, "agent");
6451
+ const agentErrDir = path16.join(LOGS_DIR, "agent");
6402
6452
  if (!fs16.existsSync(agentErrDir)) fs16.mkdirSync(agentErrDir, { recursive: true });
6403
- fs16.appendFileSync(path15.join(agentErrDir, "error.log"), `ERROR [${date}]: ${errLog}
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 ${path15.join(LOGS_DIR, "agent", "error.log")}`);
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 ${path15.join(LOGS_DIR, "agent", "error.log")}`);
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 path16 from "path";
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
- setMode(saved.mode);
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 = path16.join(process.cwd(), exportFile);
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 = path16.join(process.cwd(), "FluxFlow.md");
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 = path16.join(path16.dirname(fileURLToPath(import.meta.url)), "../package.json");
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 = path16.join(currentDir, file);
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: path16.relative(process.cwd(), filePath)
9570
+ relativePath: path17.relative(process.cwd(), filePath)
9507
9571
  });
9508
9572
  }
9509
9573
  }
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "fluxflow-cli",
3
- "version": "1.18.19",
4
- "date": "2026-06-01",
3
+ "version": "1.18.21",
4
+ "date": "2026-06-02",
5
5
  "description": "A high-fidelity agentic terminal assistant for the Flux Era.",
6
6
  "keywords": [
7
7
  "ai",