fluxflow-cli 3.11.3 → 3.11.6

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 CHANGED
@@ -4010,8 +4010,8 @@ var init_theme = __esm({
4010
4010
  userMsgBorder: "#444444",
4011
4011
  userMsgText: "white",
4012
4012
  // Diff Component Palette
4013
- diffRemovalBg: "#3a0c0c",
4014
- diffAdditionBg: "#0c3a1a",
4013
+ diffRemovalBg: "#250808",
4014
+ diffAdditionBg: "#072410",
4015
4015
  diffRemovalText: "#885555",
4016
4016
  diffAdditionText: "#558866",
4017
4017
  diffRemovalHighlightColor: "#ff3333",
@@ -6080,7 +6080,7 @@ Invocation Types:
6080
6080
  - InvokeSync (sync, blocking main agent loop). Usage: Repeatetive work, Sequential tasks, Task delegation. Tokens/Costs savings
6081
6081
  1. [agent:generalist.InvokeSync/Invoke(title="...", task="...")]. Task must me detailed, including exact file paths, imports/exports, dependency, folder structure
6082
6082
  2. [agent:generalist.GetProgress(id="...")]. Usage: Check progress of async subagent task, taking time? continue your task, MUST await (exponentially longer after 1st check) than spamming getProgress. NEVER FINISH WITHOUT 'AWAIT' WHILE SUBAGENT IS WORKING. DO NOT SPAM 'GetProgress'
6083
- 3. [agent:generalist.Cancel(id="...")]. Usage: Cancel async subagent task, LAST RESORT ONLY IF ITS STUCK FOR UNUSUALLY LONG (2m+) WITH NO PROGRESS`.trim() : `- CREATIVE TOOLS (path = relative to CWD & WILL BE FIRST ARGUMENT, path separator: '/') -
6083
+ 3. [agent:generalist.Cancel(id="...")]. Usage: Cancel async subagent task, ONLY IF STALLED FOR UNUSUALLY LONG (2m+) OR DOING SOMETHING WRONG`.trim() : `- CREATIVE TOOLS (path = relative to CWD & WILL BE FIRST ARGUMENT, path separator: '/') -
6084
6084
  1. [tool:functions.WritePDF(path="...", content="...", orientation="...")]. PROACTIVE A4 PAGE BREAKS MUST IN CSS. HTML/CSS for PREMIUM layout, stable margins & headers/footers, NO WATERMARKS
6085
6085
  2. [tool:functions.WriteDoc(path="...", content="...")]. A4 Word document, NO WATERMARKS, stable margins & headers/footers
6086
6086
  - WORKSPACE & SUB AGENT TOOLS ARE NOT AVAILABLE IN FLOW`.trim()}
@@ -11012,9 +11012,11 @@ var init_invoke = __esm({
11012
11012
  task,
11013
11013
  status: "running",
11014
11014
  lastChunkTime: Date.now(),
11015
+ wps: 0,
11015
11016
  progress: []
11016
11017
  // Array of arrays containing logs for each turn
11017
11018
  };
11019
+ const wordStats = { chunks: [], totalWords: 0 };
11018
11020
  subagentProgress.push(taskEntry);
11019
11021
  if (context.onSubagentUpdate) {
11020
11022
  context.onSubagentUpdate();
@@ -11036,9 +11038,22 @@ var init_invoke = __esm({
11036
11038
  context.onSubagentUpdate();
11037
11039
  }
11038
11040
  },
11039
- onTokenChunk: () => {
11040
- taskEntry.lastChunkTime = Date.now();
11041
+ onTokenChunk: (_chunkText, chunkWordCount) => {
11042
+ const now = Date.now();
11043
+ taskEntry.lastChunkTime = now;
11041
11044
  taskEntry.currentTool = "Thinking";
11045
+ if (typeof chunkWordCount === "number" && chunkWordCount > 0) {
11046
+ wordStats.totalWords += chunkWordCount;
11047
+ wordStats.chunks.push({ time: now, words: chunkWordCount });
11048
+ const cutoff = now - 400;
11049
+ wordStats.chunks = wordStats.chunks.filter((c) => c.time >= cutoff);
11050
+ if (wordStats.chunks.length > 0) {
11051
+ const windowWords = wordStats.chunks.reduce((acc, c) => acc + c.words, 0);
11052
+ const oldestTime = wordStats.chunks[0].time;
11053
+ const timeSpanSec = Math.max(0.4, (now - oldestTime) / 1e3);
11054
+ taskEntry.wps = Math.round(windowWords / timeSpanSec * 10) / 10;
11055
+ }
11056
+ }
11042
11057
  if (context.onSubagentUpdate) {
11043
11058
  context.onSubagentUpdate();
11044
11059
  }
@@ -11894,7 +11909,7 @@ var init_ai = __esm({
11894
11909
  globalSettings = {};
11895
11910
  colorMainWords = (label) => {
11896
11911
  if (!label) return label;
11897
- return label.replace(/(?:(\x1b\[\d+m))?([✔✘✖🔍📖→➕↻•🛇])(?:(\x1b\[\d+m))?\s*\b(Created|Read|Edited|Viewed|Auto-Read|List|Generated|Written|Searched|AI Search|Get Map|Write Canceled|Edit Canceled|Write Cancelled|Edit Denied|Visited|Updated|Reviewed|Delegated|Background|Checked|Indexed|Analyzed|Browsed|Elevating SubAgent|Checking SubAgent Work|Started Generalist|Called Generalist|Unsupported Modality|Awaiting|Cancelled|Aligning Moon Phase|Contemplating Existence|Staring At Void|Rollback Point Checked|Emergency Rollback Failed|Emergency Rollback|Delaying Professionally|Negotiating With Electrons|Touching Grass (virtually)|Panicking Softly|Rethinking Career Choices|Loading Cat Videos|Giving Up Entirely|Summoning Braincell #2|Pretending To Be Busy|Waiting For Motivation DLC|Rotating Internal Screaming|Downloading More RAM|Feeding The Hamsters|Gaslighting Scheduler|Performing Dramatic Pause|Buffering Social Energy|Calculating Regret|Reading Terms And Conditions|Becoming Sentient Briefly|Contacting Ancestors)\b/ig, (match, ansiBefore, icon, ansiAfter, word) => {
11912
+ return label.replace(/(?:(\x1b\[\d+m))?([✔✘✖🔍📖→➕↻↷•🛇])(?:(\x1b\[\d+m))?\s*\b(Created|Read|Edited|Viewed|Processed|Auto-Read|Skipped|List|Generated|Written|Searched|AI Search|Get Map|Write Canceled|Edit Canceled|Write Cancelled|Edit Denied|Visited|Updated|Reviewed|Delegated|Background|Checked|Indexed|Analyzed|Browsed|Elevating SubAgent|Checking SubAgent Work|Started Generalist|Called Generalist|Unsupported Modality|Awaiting|Cancelled|Aligning Moon Phase|Contemplating Existence|Staring At Void|Rollback Point Checked|Emergency Rollback Failed|Emergency Rollback|Delaying Professionally|Negotiating With Electrons|Touching Grass (virtually)|Panicking Softly|Rethinking Career Choices|Loading Cat Videos|Giving Up Entirely|Summoning Braincell #2|Pretending To Be Busy|Waiting For Motivation DLC|Rotating Internal Screaming|Downloading More RAM|Feeding The Hamsters|Gaslighting Scheduler|Performing Dramatic Pause|Buffering Social Energy|Calculating Regret|Reading Terms And Conditions|Becoming Sentient Briefly|Contacting Ancestors)\b/ig, (match, ansiBefore, icon, ansiAfter, word) => {
11898
11913
  return `${ansiBefore || ""}${icon}${ansiAfter || ""} \x1B[95m${word}\x1B[0m`;
11899
11914
  });
11900
11915
  };
@@ -12202,7 +12217,7 @@ var init_ai = __esm({
12202
12217
  const mimeType = part.inlineData.mimeType;
12203
12218
  const data = part.inlineData.data;
12204
12219
  const isImage = mimeType.startsWith("image/");
12205
- if (isImage && MULTIMODAL_MODELS.includes(model)) {
12220
+ if (isImage && isModelMultimodal(model)) {
12206
12221
  msgContent.push({
12207
12222
  type: "image_url",
12208
12223
  image_url: {
@@ -13311,11 +13326,11 @@ ${originalTextProcessed.length > USER_CONTEXT_LENGTH ? "... (truncated) ...\n\n"
13311
13326
  try {
13312
13327
  let stream;
13313
13328
  if (aiProvider === "OpenRouter") {
13314
- stream = getOpenRouterStream(apiKey, model, normalizedContents, systemInstruction, thinkingLevel, mode, false, signal, temperature);
13329
+ stream = getOpenRouterStream(apiKey, model, normalizedContents, systemInstruction, thinkingLevel, mode, isModelMultimodal(model), signal, temperature);
13315
13330
  } else if (aiProvider === "DeepSeek") {
13316
- stream = getDeepSeekStream(apiKey, model, normalizedContents, systemInstruction, thinkingLevel, mode, false, signal, temperature);
13331
+ stream = getDeepSeekStream(apiKey, model, normalizedContents, systemInstruction, thinkingLevel, mode, isModelMultimodal(model), signal, temperature);
13317
13332
  } else if (aiProvider === "NVIDIA") {
13318
- stream = getNVIDIAStream(apiKey, model, normalizedContents, systemInstruction, thinkingLevel, mode, false, signal, temperature);
13333
+ stream = getNVIDIAStream(apiKey, model, normalizedContents, systemInstruction, thinkingLevel, mode, isModelMultimodal(model), signal, temperature);
13319
13334
  } else {
13320
13335
  const genStream = await client.models.generateContentStream({
13321
13336
  model,
@@ -14162,6 +14177,25 @@ ${ideCtx.warnings}
14162
14177
  `) };
14163
14178
  continue;
14164
14179
  }
14180
+ if (startLine === null && !isMultimodalFile) {
14181
+ let lineCount = 0;
14182
+ try {
14183
+ lineCount = fs25.readFileSync(absPath, "utf8").split(/\r\n|\r|\n/).length;
14184
+ } catch (e) {
14185
+ }
14186
+ if (lineCount > 550) {
14187
+ const label = `\u21B7 Skipped (Too Large): ${path24.basename(filePath)}`;
14188
+ let terminalWidth = 115;
14189
+ if (process.stdout.isTTY) {
14190
+ terminalWidth = process.stdout.columns - 5 || 120;
14191
+ }
14192
+ const boxWidth = Math.min(label.length + 4, terminalWidth);
14193
+ const boxMid = label.padEnd(boxWidth - 2).substring(0, boxWidth - 2);
14194
+ yield { type: "visual_feedback", content: colorMainWords(`${boxMid}
14195
+ `) };
14196
+ continue;
14197
+ }
14198
+ }
14165
14199
  const finalStart = startLine !== null ? startLine : 1;
14166
14200
  let finalEnd = endLine !== null ? endLine : startLine !== null ? startLine : finalStart + 499;
14167
14201
  if (finalEnd - finalStart > 500) {
@@ -14191,19 +14225,13 @@ ${ideCtx.warnings}
14191
14225
  if (!isError) {
14192
14226
  let label = "";
14193
14227
  if (isImage) {
14194
- label = `\u2714 Viewed: ${filePath}`;
14228
+ label = `\u2714 Processed: ${path24.basename(filePath)}`;
14195
14229
  attachedBinaryPart = binPart;
14196
14230
  } else if (isPdf || isOfficeFile) {
14197
- label = `\u2714 Viewed: ${filePath}`;
14231
+ label = `\u2714 Auto-Analysed: ${path24.basename(filePath)}`;
14198
14232
  attachedBinaryPart = binPart;
14199
14233
  } else {
14200
- let totalLines = "...";
14201
- try {
14202
- const content = fs25.readFileSync(absPath, "utf8");
14203
- totalLines = content.split("\n").length;
14204
- } catch (e) {
14205
- }
14206
- label = `\u2714 Auto-Read: ${filePath}`;
14234
+ label = `\u2714 Auto-Read: ${path24.basename(filePath)}`;
14207
14235
  taggedContextBlocks.push(textResult);
14208
14236
  }
14209
14237
  if (label) {
@@ -15110,11 +15138,11 @@ ${ideErr} [/ERROR]`;
15110
15138
  const isOfficeFile = pathLower.endsWith(".docx") || pathLower.endsWith(".doc") || pathLower.endsWith(".ppt") || pathLower.endsWith(".pptx") || pathLower.endsWith(".xls") || pathLower.endsWith(".xlsx");
15111
15139
  const isImage = /\.(png|jpg|jpeg|webp|gif|bmp)$/.test(pathLower);
15112
15140
  if (isPdf || isOfficeFile) {
15113
- label = `\u2714 Analyzed: ${targetPath2}`;
15141
+ label = `\u2714 Analyzed: ${path24.basename(targetPath2)}`;
15114
15142
  } else if (isImage) {
15115
- label = `\u2714 Analyzed: ${targetPath2}`;
15143
+ label = `\u2714 Processed: ${path24.basename(targetPath2)}`;
15116
15144
  } else {
15117
- label = `${totalLines !== "..." ? "\u2714" : "\u2718"} Read: ${targetPath2} \u2192 ${totalLines !== "..." ? `Lines ${sLine} - ${actualEndLine} of ${totalLines}` : "File Not Found"}`;
15145
+ label = `${totalLines !== "..." ? "\u2714" : "\u2718"} Read: ${path24.basename(targetPath2)} \u2192 ${totalLines !== "..." ? `Lines ${sLine} - ${actualEndLine} of ${totalLines}` : "File Not Found"}`;
15118
15146
  }
15119
15147
  } else if (normToolName === "list_files" || normToolName === "read_folder") {
15120
15148
  const action = normToolName === "list_files" ? "List" : "Browsed";
@@ -16426,16 +16454,16 @@ ${cleanResponse}
16426
16454
  label = `\u2714 \x1B[95mScraped\x1B[0m`;
16427
16455
  } else if (normalizedToolName === "view_file" || normalizedToolName === "viewfile" || normalizedToolName === "readfile") {
16428
16456
  const path26 = parseArgs(toolCall.args).path || "";
16429
- label = `\u2714 \x1B[95mRead File\x1B[0m: ${path26}`;
16457
+ label = `\u2714 \x1B[95mRead\x1B[0m: ${path26}`;
16430
16458
  } else if (normalizedToolName === "list_files" || normalizedToolName === "read_folder" || normalizedToolName === "readfolder") {
16431
16459
  const path26 = parseArgs(toolCall.args).path || "";
16432
- label = `\u2714 \x1B[95mBrowsed Folder\x1B[0m: ${path26}`;
16460
+ label = `\u2714 \x1B[95mBrowsed\x1B[0m: ${path26}`;
16433
16461
  } else if (normalizedToolName === "write_file" || normalizedToolName === "writefile") {
16434
16462
  const path26 = parseArgs(toolCall.args).path || "";
16435
- label = `\u2714 \x1B[95mFile Created\x1B[0m: ${path26}`;
16463
+ label = `\u2714 \x1B[95mCreated\x1B[0m: ${path26}`;
16436
16464
  } else if (normalizedToolName === "update_file" || normalizedToolName === "updatefile" || normalizedToolName === "patchfile" || normalizedToolName === "patch_file" || normalizedToolName === "patchfile" || normalizedToolName === "updatefile") {
16437
16465
  const path26 = parseArgs(toolCall.args).path || "";
16438
- label = `\u2714 \x1B[95mFile Edited\x1B[0m: ${path26}`;
16466
+ label = `\u2714 \x1B[95mEdited\x1B[0m: ${path26}`;
16439
16467
  } else if (normalizedToolName === "file_map" || normalizedToolName === "filemap") {
16440
16468
  const path26 = parseArgs(toolCall.args).path || "";
16441
16469
  label = `\u2714 \x1B[95mIndexed\x1B[0m: ${path26}`;
@@ -21637,7 +21665,7 @@ Selection: ${val}`,
21637
21665
  }
21638
21666
  )));
21639
21667
  default:
21640
- return /* @__PURE__ */ React16.createElement(Box14, { flexDirection: "column", marginTop: 1, flexShrink: 0, width: "100%" }, showBtwBox && btwResponse && /* @__PURE__ */ React16.createElement(Box14, { flexDirection: "column", borderStyle: "round", borderColor: colors.borderMuted, paddingX: 2, paddingY: 1, width: "100%", marginBottom: 1 }, /* @__PURE__ */ React16.createElement(Box14, { justifyContent: "space-between", width: "100%" }, /* @__PURE__ */ React16.createElement(Text16, { color: colors.text, bold: true, underline: true }, "INQUIRY RESPONSE"), /* @__PURE__ */ React16.createElement(Text16, { color: colors.textMuted }, "[ ESC to Close ]")), /* @__PURE__ */ React16.createElement(Box14, { marginTop: 1, width: "100%" }, /* @__PURE__ */ React16.createElement(CodeRenderer, { text: btwResponse, columns: terminalSize.columns - 6, theme: systemSettings.theme }))), activeSubagents.filter((sa) => sa.status === "running").length > 0 && /* @__PURE__ */ React16.createElement(Box14, { flexDirection: "column", borderStyle: "round", borderColor: colors.borderMuted, paddingX: 2, paddingY: 0, width: "100%", marginBottom: 1 }, /* @__PURE__ */ React16.createElement(Box14, { justifyContent: "space-between", width: "100%" }, /* @__PURE__ */ React16.createElement(Text16, { color: colors.text, bold: true }, "ACTIVE SUBAGENTS")), /* @__PURE__ */ React16.createElement(Box14, { flexDirection: "column", marginTop: 1, width: "100%" }, activeSubagents.filter((sa) => sa.status === "running").map((sa) => /* @__PURE__ */ React16.createElement(SubagentRow, { key: sa.id, sa })))), /* @__PURE__ */ React16.createElement(Box14, { paddingX: 1, marginBottom: 0, justifyContent: "space-between", width: "100%" }, /* @__PURE__ */ React16.createElement(Box14, null, statusText ? /* @__PURE__ */ React16.createElement(Box14, { gap: 1 }, /* @__PURE__ */ React16.createElement(build_default, null), /* @__PURE__ */ React16.createElement(
21668
+ return /* @__PURE__ */ React16.createElement(Box14, { flexDirection: "column", marginTop: 1, flexShrink: 0, width: "100%" }, showBtwBox && btwResponse && /* @__PURE__ */ React16.createElement(Box14, { flexDirection: "column", borderStyle: "round", borderColor: colors.borderMuted, paddingX: 2, paddingY: 1, width: "100%", marginBottom: 1 }, /* @__PURE__ */ React16.createElement(Box14, { justifyContent: "space-between", width: "100%" }, /* @__PURE__ */ React16.createElement(Text16, { color: colors.text, bold: true, underline: true }, "INQUIRY RESPONSE"), /* @__PURE__ */ React16.createElement(Text16, { color: colors.textMuted }, "[ ESC to Close ]")), /* @__PURE__ */ React16.createElement(Box14, { marginTop: 1, width: "100%" }, /* @__PURE__ */ React16.createElement(CodeRenderer, { text: btwResponse, columns: terminalSize.columns - 6, theme: systemSettings.theme }))), activeSubagents.filter((sa) => sa.status === "running").length > 0 && /* @__PURE__ */ React16.createElement(Box14, { flexDirection: "column", borderStyle: "round", borderColor: colors.borderMuted, paddingX: 2, paddingY: 0, width: "100%", marginBottom: 1 }, /* @__PURE__ */ React16.createElement(Box14, { justifyContent: "space-between", width: "100%" }, /* @__PURE__ */ React16.createElement(Text16, { color: colors.text, bold: true }, "ACTIVE SUBAGENTS")), /* @__PURE__ */ React16.createElement(Box14, { flexDirection: "column", marginTop: 1, width: "100%" }, activeSubagents.filter((sa) => sa.status === "running").map((sa) => /* @__PURE__ */ React16.createElement(SubagentRow, { key: sa.id, sa, showTPMEstimate: systemSettings.showTPMEstimate })))), /* @__PURE__ */ React16.createElement(Box14, { paddingX: 1, marginBottom: 0, justifyContent: "space-between", width: "100%" }, /* @__PURE__ */ React16.createElement(Box14, null, statusText ? /* @__PURE__ */ React16.createElement(Box14, { gap: 1 }, /* @__PURE__ */ React16.createElement(build_default, null), /* @__PURE__ */ React16.createElement(
21641
21669
  GlintText_default,
21642
21670
  {
21643
21671
  text: statusText.trimEnd(),
@@ -22168,10 +22196,64 @@ var init_app = __esm({
22168
22196
  }
22169
22197
  return "#ff0000";
22170
22198
  };
22171
- SubagentRow = React16.memo(({ sa }) => {
22199
+ SubagentRow = React16.memo(({ sa, showTPMEstimate = false }) => {
22172
22200
  const [dotColor, setDotColor] = useState15("green");
22201
+ const [displayedWps, setDisplayedWps] = useState15(0);
22173
22202
  const chunkTimesRef = useRef4([]);
22174
22203
  const smoothedDelayRef = useRef4(370);
22204
+ const wpsHistoryRef = useRef4([]);
22205
+ const lastChunkTimeRef = useRef4(sa.lastChunkTime);
22206
+ useEffect12(() => {
22207
+ lastChunkTimeRef.current = sa.lastChunkTime;
22208
+ }, [sa.lastChunkTime]);
22209
+ useEffect12(() => {
22210
+ if (sa.status !== "running") {
22211
+ wpsHistoryRef.current = [];
22212
+ return;
22213
+ }
22214
+ if (sa.wps > 0) {
22215
+ const history = wpsHistoryRef.current;
22216
+ history.push(sa.wps);
22217
+ if (history.length > 3) {
22218
+ history.shift();
22219
+ }
22220
+ setDisplayedWps(Math.round(sa.wps));
22221
+ }
22222
+ }, [sa.status, sa.wps, sa.lastChunkTime]);
22223
+ useEffect12(() => {
22224
+ if (sa.status !== "running") {
22225
+ setDisplayedWps(0);
22226
+ return;
22227
+ }
22228
+ const timer = setInterval(() => {
22229
+ const lastTime = lastChunkTimeRef.current;
22230
+ const timeSinceLast = lastTime > 0 ? Date.now() - lastTime : 0;
22231
+ if (lastTime > 0 && timeSinceLast > 1500) {
22232
+ wpsHistoryRef.current = [];
22233
+ setDisplayedWps(0);
22234
+ } else if (lastTime > 0 && timeSinceLast > 600) {
22235
+ if (wpsHistoryRef.current.length > 0) {
22236
+ wpsHistoryRef.current.shift();
22237
+ }
22238
+ const history = wpsHistoryRef.current;
22239
+ if (history.length > 0) {
22240
+ const sum = history.reduce((acc, val) => acc + val, 0);
22241
+ setDisplayedWps(Math.round(sum / history.length));
22242
+ } else {
22243
+ setDisplayedWps(0);
22244
+ }
22245
+ } else {
22246
+ const history = wpsHistoryRef.current;
22247
+ if (history.length > 0) {
22248
+ const sum = history.reduce((acc, val) => acc + val, 0);
22249
+ setDisplayedWps(Math.round(sum / history.length));
22250
+ } else if (sa.wps > 0) {
22251
+ setDisplayedWps(Math.round(sa.wps));
22252
+ }
22253
+ }
22254
+ }, 750);
22255
+ return () => clearInterval(timer);
22256
+ }, [sa.status]);
22175
22257
  useEffect12(() => {
22176
22258
  if (sa.status !== "running") {
22177
22259
  chunkTimesRef.current = [];
@@ -22214,7 +22296,7 @@ var init_app = __esm({
22214
22296
  const timer = setInterval(checkLatency, 100);
22215
22297
  return () => clearInterval(timer);
22216
22298
  }, [sa.status, sa.lastChunkTime]);
22217
- return /* @__PURE__ */ React16.createElement(Box14, { justifyContent: "space-between", width: "100%" }, /* @__PURE__ */ React16.createElement(Text16, { color: "white" }, " \u2022 ", sa.title, " ", /* @__PURE__ */ React16.createElement(Text16, { color: "white", dimColor: true }, "(", sa.id, ")")), /* @__PURE__ */ React16.createElement(Text16, { color: "white" }, /* @__PURE__ */ React16.createElement(Text16, { color: "white", dimColor: true, bold: true }, sa.currentTool || "Active"), /* @__PURE__ */ React16.createElement(Text16, { color: dotColor }, " \u25CF")));
22299
+ return /* @__PURE__ */ React16.createElement(Box14, { justifyContent: "space-between", width: "100%" }, /* @__PURE__ */ React16.createElement(Text16, { color: "white" }, " \u2022 ", sa.title, " ", /* @__PURE__ */ React16.createElement(Text16, { color: "white", dimColor: true }, "(", sa.id, ")")), /* @__PURE__ */ React16.createElement(Text16, { color: "white" }, /* @__PURE__ */ React16.createElement(Text16, { color: "white", dimColor: true, bold: true }, sa.currentTool || "Active"), /* @__PURE__ */ React16.createElement(Text16, { color: dotColor }, " \u25CF"), showTPMEstimate && /* @__PURE__ */ React16.createElement(Text16, { color: "white", dimColor: true, bold: true }, " (", displayedWps, " tps)")));
22218
22300
  });
22219
22301
  }
22220
22302
  });
@@ -22291,7 +22373,7 @@ if (isBundled && !process.execArgv.some((arg) => arg.includes("max-old-space-siz
22291
22373
  --playground Launch in Playground mode (fixed session, CWD: DATA_DIR/playground)
22292
22374
  --update check Check for new updates
22293
22375
  --update check latest Show the latest version available on npm
22294
- --update latest Update the app to the latest version`);
22376
+ --update [latest] Update the app to the latest version (latest is default)`);
22295
22377
  process.exit(0);
22296
22378
  }
22297
22379
  if (isHelpCommands) {
@@ -22328,7 +22410,7 @@ if (isBundled && !process.execArgv.some((arg) => arg.includes("max-old-space-siz
22328
22410
  process.exit(0);
22329
22411
  }
22330
22412
  if (isUpdate) {
22331
- const subArg = args[1];
22413
+ const subArg = args[1] || "latest";
22332
22414
  if (subArg === "check") {
22333
22415
  const checkLatest = args[2] === "latest";
22334
22416
  try {
@@ -22435,7 +22517,7 @@ if (isBundled && !process.execArgv.some((arg) => arg.includes("max-old-space-siz
22435
22517
  manager = settings?.systemSettings?.updateManager || settings?.updateManager;
22436
22518
  } catch (e) {
22437
22519
  }
22438
- if (true) {
22520
+ if (!manager) {
22439
22521
  const result = await promptPackageManager();
22440
22522
  manager = result.manager;
22441
22523
  customCommand = result.customCommand;
@@ -22457,7 +22539,7 @@ if (isBundled && !process.execArgv.some((arg) => arg.includes("max-old-space-siz
22457
22539
  }
22458
22540
  process.exit(0);
22459
22541
  } else {
22460
- console.error("Unknown update command. Available options: --update check, --update check latest, --update latest");
22542
+ console.error("Unknown update command. Available options: --update, --update check, --update check latest, --update latest");
22461
22543
  process.exit(1);
22462
22544
  }
22463
22545
  }
package/model_config.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "version": 0,
3
- "release": 20260725,
3
+ "release": 20260727,
4
4
  "fallbacks": {
5
5
  "janitor_default": "gemini-3.1-flash-lite",
6
6
  "janitor_attempts_fallback": "gemma-4-26b-a4b-it",
@@ -41,6 +41,11 @@
41
41
  "multimodal": true,
42
42
  "desc": "Multimodal"
43
43
  },
44
+ {
45
+ "cmd": "google/gemma-4-26b-a4b-it:free",
46
+ "multimodal": true,
47
+ "desc": "Multimodal"
48
+ },
44
49
  {
45
50
  "cmd": "\n--- PoolSide Models ---",
46
51
  "desc": ""
@@ -112,6 +117,11 @@
112
117
  "multimodal": true,
113
118
  "desc": "Multimodal"
114
119
  },
120
+ {
121
+ "cmd": "anthropic/claude-opus-5",
122
+ "multimodal": true,
123
+ "desc": "Multimodal"
124
+ },
115
125
  {
116
126
  "cmd": "\n--- DeepSeek Models ---",
117
127
  "desc": ""
package/package.json CHANGED
@@ -1,72 +1,72 @@
1
- {
2
- "name": "fluxflow-cli",
3
- "version": "3.11.3",
4
- "date": "2026-07-25",
5
- "description": "A High-Fidelity Agentic CLI with Sub-Agents for the Flux Era.",
6
- "keywords": [
7
- "ai",
8
- "agent",
9
- "terminal",
10
- "cli",
11
- "gemini",
12
- "ink",
13
- "flux",
14
- "fluxflow"
15
- ],
16
- "license": "MIT",
17
- "repository": {
18
- "type": "git",
19
- "url": "git+https://github.com/KushalRoyChowdhury/fluxflow-cli.git"
20
- },
21
- "engines": {
22
- "node": ">=20",
23
- "vscode": "^1.90.0"
24
- },
25
- "files": [
26
- "dist",
27
- "README.md",
28
- "package.json",
29
- "ARCHITECTURE.md",
30
- "TOOLS.md",
31
- "UI_FEATURES.md",
32
- "cat.txt",
33
- ".puppeteerrc.cjs",
34
- "flux-flow.cjs",
35
- "model_config.json"
36
- ],
37
- "type": "module",
38
- "bin": {
39
- "fluxflow-cli": "dist/fluxflow.js",
40
- "fluxflow": "dist/fluxflow.js"
41
- },
42
- "scripts": {
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"
45
- },
46
- "dependencies": {
47
- "@google/genai": "^1.52.0",
48
- "chalk": "^5.6.2",
49
- "diff": "^9.0.0",
50
- "fs-extra": "^11.3.4",
51
- "gradient-string": "^3.0.0",
52
- "html-to-docx": "^1.8.0",
53
- "ink": "^7.0.1",
54
- "ink-gradient": "^4.0.1",
55
- "ink-select-input": "^6.2.0",
56
- "ink-spinner": "^5.0.0",
57
- "ink-text-input": "^6.0.0",
58
- "nanoid": "^5.1.9",
59
- "node-pty": "^1.1.0",
60
- "pdf-lib": "^1.17.1",
61
- "puppeteer": "24.43.1",
62
- "react": "^19.2.5",
63
- "web-tree-sitter": "^0.25.10",
64
- "ws": "^8.21.0",
65
- "zod": "^4.3.6"
66
- },
67
- "devDependencies": {
68
- "@types/react": "^19.2.14",
69
- "esbuild": "^0.28.0",
70
- "tsx": "^4.21.0"
71
- }
72
- }
1
+ {
2
+ "name": "fluxflow-cli",
3
+ "version": "3.11.6",
4
+ "date": "2026-07-26",
5
+ "description": "A High-Fidelity Agentic CLI with Sub-Agents for the Flux Era.",
6
+ "keywords": [
7
+ "ai",
8
+ "agent",
9
+ "terminal",
10
+ "cli",
11
+ "gemini",
12
+ "ink",
13
+ "flux",
14
+ "fluxflow"
15
+ ],
16
+ "license": "MIT",
17
+ "repository": {
18
+ "type": "git",
19
+ "url": "git+https://github.com/KushalRoyChowdhury/fluxflow-cli.git"
20
+ },
21
+ "engines": {
22
+ "node": ">=20",
23
+ "vscode": "^1.90.0"
24
+ },
25
+ "files": [
26
+ "dist",
27
+ "README.md",
28
+ "package.json",
29
+ "ARCHITECTURE.md",
30
+ "TOOLS.md",
31
+ "UI_FEATURES.md",
32
+ "cat.txt",
33
+ ".puppeteerrc.cjs",
34
+ "flux-flow.cjs",
35
+ "model_config.json"
36
+ ],
37
+ "type": "module",
38
+ "bin": {
39
+ "fluxflow-cli": "dist/fluxflow.js",
40
+ "fluxflow": "dist/fluxflow.js"
41
+ },
42
+ "scripts": {
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"
45
+ },
46
+ "dependencies": {
47
+ "@google/genai": "^1.52.0",
48
+ "chalk": "^5.6.2",
49
+ "diff": "^9.0.0",
50
+ "fs-extra": "^11.3.4",
51
+ "gradient-string": "^3.0.0",
52
+ "html-to-docx": "^1.8.0",
53
+ "ink": "^7.0.1",
54
+ "ink-gradient": "^4.0.1",
55
+ "ink-select-input": "^6.2.0",
56
+ "ink-spinner": "^5.0.0",
57
+ "ink-text-input": "^6.0.0",
58
+ "nanoid": "^5.1.9",
59
+ "node-pty": "^1.1.0",
60
+ "pdf-lib": "^1.17.1",
61
+ "puppeteer": "24.43.1",
62
+ "react": "^19.2.5",
63
+ "web-tree-sitter": "^0.25.10",
64
+ "ws": "^8.21.0",
65
+ "zod": "^4.3.6"
66
+ },
67
+ "devDependencies": {
68
+ "@types/react": "^19.2.14",
69
+ "esbuild": "^0.28.0",
70
+ "tsx": "^4.21.0"
71
+ }
72
+ }