fluxflow-cli 2.14.0 → 2.14.1

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 +165 -82
  2. package/package.json +1 -1
package/dist/fluxflow.js CHANGED
@@ -2091,7 +2091,7 @@ var init_build = __esm({
2091
2091
 
2092
2092
  // src/utils/text.js
2093
2093
  import os2 from "os";
2094
- var wrapText, formatTokens, truncatePath, parsePatchPairs, applyPatches, generateHighFidelityDiff, parseLineInfo, getSimilarity, alignChangeGroup, blocksCache, streamingBlocksCache, MAX_CACHE_SIZE, parseMessageToBlocks, TOOL_LABELS, REGEX_INITIAL_THINK, REGEX_INITIAL_TOOL, REGEX_SYSTEM, REGEX_THINK, REGEX_ANSWER, REGEX_TOOL_RES, REGEX_SUCCESS_ERROR, REGEX_TURN_1, REGEX_END, REGEX_TURN_2, REGEX_TURN_3, REGEX_OPEN_BRACKET, REGEX_RESPONDED, REGEX_PROMPTED, REGEX_ARROWS, REGEX_ARROWS_L, REGEX_ARROWS_U, REGEX_ARROWS_D, REGEX_ARROWS_LR, REGEX_TERMINAL, REGEX_TOOLS, cleanSignals, clearBlocksCache;
2094
+ var wrapText, formatTokens, truncatePath, parsePatchPairs, applyPatches, generateHighFidelityDiff, parseLineInfo, getSimilarity, alignChangeGroup, blocksCache, streamingBlocksCache, MAX_CACHE_SIZE, CHUNK_SIZE, indexBlockIntoMap, parseMessageToBlocks, TOOL_LABELS, REGEX_INITIAL_THINK, REGEX_INITIAL_TOOL, REGEX_SYSTEM, REGEX_THINK, REGEX_ANSWER, REGEX_TOOL_RES, REGEX_SUCCESS_ERROR, REGEX_TURN_1, REGEX_END, REGEX_TURN_2, REGEX_TURN_3, REGEX_OPEN_BRACKET, REGEX_RESPONDED, REGEX_PROMPTED, REGEX_ARROWS, REGEX_ARROWS_L, REGEX_ARROWS_U, REGEX_ARROWS_D, REGEX_ARROWS_LR, REGEX_TERMINAL, REGEX_TOOLS, cleanSignals, clearBlocksCache;
2095
2095
  var init_text = __esm({
2096
2096
  "src/utils/text.js"() {
2097
2097
  init_paths();
@@ -2533,6 +2533,11 @@ var init_text = __esm({
2533
2533
  blocksCache = /* @__PURE__ */ new Map();
2534
2534
  streamingBlocksCache = /* @__PURE__ */ new Map();
2535
2535
  MAX_CACHE_SIZE = 200;
2536
+ CHUNK_SIZE = 6;
2537
+ indexBlockIntoMap = (b, map) => {
2538
+ map.set(b.key, b);
2539
+ if (b.type === "chunk" && b.blocks) b.blocks.forEach((sub) => indexBlockIntoMap(sub, map));
2540
+ };
2536
2541
  parseMessageToBlocks = (msg, columns) => {
2537
2542
  if (!msg) return { completed: [], active: [] };
2538
2543
  const cacheKey = `${msg.id}-${msg.text?.length || 0}-${columns}-${msg.isStreaming}`;
@@ -2563,16 +2568,25 @@ var init_text = __esm({
2563
2568
  };
2564
2569
  if (text.includes("- Content Preview:")) {
2565
2570
  const mainParts = text.split("- Content Preview:");
2566
- const headerText = mainParts[0] || "";
2567
2571
  const contentPart = mainParts[1] || "";
2568
2572
  const footerMarker = "[SYSTEM] Check the content preview for verification [/SYSTEM]";
2569
- const contentAndFooter = contentPart.split(footerMarker);
2570
- const content = contentAndFooter[0]?.trim() || "";
2571
- const footer = contentAndFooter[1] ? `${footerMarker}${contentAndFooter[1]}` : "";
2573
+ const content = contentPart.split(footerMarker)[0]?.trim() || "";
2572
2574
  const codeLines = content.split("\n").map((l) => l.replace(/\r$/, ""));
2573
2575
  const gutterWidth = String(codeLines.length).length;
2574
2576
  const completedBlocks2 = [];
2575
2577
  let activeBlock2 = null;
2578
+ let writeChunk = [];
2579
+ const flushWrite = () => {
2580
+ if (!writeChunk.length) return;
2581
+ const batch = writeChunk;
2582
+ writeChunk = [];
2583
+ completedBlocks2.push(batch.length === 1 ? batch[0] : {
2584
+ key: `${batch[0].key}-chunk`,
2585
+ msg,
2586
+ type: "chunk",
2587
+ blocks: batch
2588
+ });
2589
+ };
2576
2590
  codeLines.forEach((line, idx) => {
2577
2591
  const isLast = idx === codeLines.length - 1;
2578
2592
  const block = getBlock(`${msg.id || Date.now()}-write-line-${idx}`, "write-line", line, {
@@ -2582,27 +2596,21 @@ var init_text = __esm({
2582
2596
  isLastLine: isLast
2583
2597
  });
2584
2598
  if (isLast && msg.isStreaming) {
2599
+ flushWrite();
2585
2600
  activeBlock2 = block;
2586
2601
  } else {
2587
- completedBlocks2.push(block);
2602
+ writeChunk.push(block);
2603
+ if (writeChunk.length >= CHUNK_SIZE) flushWrite();
2588
2604
  }
2589
2605
  });
2590
- return {
2591
- completed: completedBlocks2,
2592
- active: activeBlock2 ? [activeBlock2] : []
2593
- };
2606
+ flushWrite();
2607
+ return { completed: completedBlocks2, active: activeBlock2 ? [activeBlock2] : [] };
2594
2608
  }
2595
2609
  if (text.includes("[DIFF_START]")) {
2596
2610
  const match = text.match(/\[DIFF_START\]([\s\S]*?)(?:\[DIFF_END\]|$)/);
2597
2611
  const diffBody = match ? match[1].trim() : "";
2598
2612
  const diffLines = diffBody.split("\n").map((l) => l.replace(/\r$/, ""));
2599
- const parsedLines = diffLines.map((line) => {
2600
- return {
2601
- line,
2602
- parsed: parseLineInfo(line),
2603
- pairContent: null
2604
- };
2605
- });
2613
+ const parsedLines = diffLines.map((line) => ({ line, parsed: parseLineInfo(line), pairContent: null }));
2606
2614
  let currentGroup = [];
2607
2615
  for (let i = 0; i < parsedLines.length; i++) {
2608
2616
  const item = parsedLines[i];
@@ -2615,11 +2623,21 @@ var init_text = __esm({
2615
2623
  }
2616
2624
  }
2617
2625
  }
2618
- if (currentGroup.length > 0) {
2619
- alignChangeGroup(currentGroup);
2620
- }
2626
+ if (currentGroup.length > 0) alignChangeGroup(currentGroup);
2621
2627
  const completedBlocks2 = [];
2622
2628
  let activeBlock2 = null;
2629
+ let diffChunk = [];
2630
+ const flushDiff = () => {
2631
+ if (!diffChunk.length) return;
2632
+ const batch = diffChunk;
2633
+ diffChunk = [];
2634
+ completedBlocks2.push(batch.length === 1 ? batch[0] : {
2635
+ key: `${batch[0].key}-chunk`,
2636
+ msg,
2637
+ type: "chunk",
2638
+ blocks: batch
2639
+ });
2640
+ };
2623
2641
  diffLines.forEach((line, i) => {
2624
2642
  const isLast = i === diffLines.length - 1;
2625
2643
  const block = getBlock(`${msg.id || Date.now()}-diff-${i}`, "diff-line", line, {
@@ -2628,15 +2646,15 @@ var init_text = __esm({
2628
2646
  pairContent: parsedLines[i].pairContent
2629
2647
  });
2630
2648
  if (isLast && msg.isStreaming) {
2649
+ flushDiff();
2631
2650
  activeBlock2 = block;
2632
2651
  } else {
2633
- completedBlocks2.push(block);
2652
+ diffChunk.push(block);
2653
+ if (diffChunk.length >= CHUNK_SIZE) flushDiff();
2634
2654
  }
2635
2655
  });
2636
- return {
2637
- completed: completedBlocks2,
2638
- active: activeBlock2 ? [activeBlock2] : []
2639
- };
2656
+ flushDiff();
2657
+ return { completed: completedBlocks2, active: activeBlock2 ? [activeBlock2] : [] };
2640
2658
  }
2641
2659
  if (msg.role === "system" || msg.isLogo || msg.isHelpRecord || msg.isTerminalRecord || msg.isHomeWarning || msg.isImageStats || msg.isAskRecord || msg.isAboutRecord || msg.isUpdateNotification || msg.role === "user") {
2642
2660
  return {
@@ -2646,89 +2664,97 @@ var init_text = __esm({
2646
2664
  }
2647
2665
  const completedBlocks = [];
2648
2666
  let activeBlock = null;
2667
+ let pendingChunk = [];
2668
+ let pendingChunkType = null;
2669
+ const flushPending = () => {
2670
+ if (!pendingChunk.length) return;
2671
+ const batch = pendingChunk;
2672
+ pendingChunk = [];
2673
+ pendingChunkType = null;
2674
+ completedBlocks.push(batch.length === 1 ? batch[0] : {
2675
+ key: `${msg.id || "x"}-chunk-${batch[0].key}`,
2676
+ msg,
2677
+ type: "chunk",
2678
+ blocks: batch
2679
+ });
2680
+ };
2681
+ const enqueue = (block) => {
2682
+ if (pendingChunkType !== null && pendingChunkType !== block.type) flushPending();
2683
+ pendingChunk.push(block);
2684
+ pendingChunkType = block.type;
2685
+ if (pendingChunk.length >= CHUNK_SIZE) flushPending();
2686
+ };
2649
2687
  if (msg.role === "think") {
2650
2688
  completedBlocks.push(getBlock(`${msg.id}-header`, "think-header", ""));
2651
2689
  const lines = text.split("\n");
2652
2690
  lines.forEach((line, idx) => {
2653
- const isLast = idx === lines.length - 1;
2654
- const block = getBlock(`${msg.id}-${idx}`, "think-line", line, isLast && msg.isStreaming ? { isActiveBlock: true } : {});
2655
- if (isLast && msg.isStreaming) {
2656
- activeBlock = block;
2657
- } else {
2658
- completedBlocks.push(block);
2659
- }
2691
+ enqueue(getBlock(`${msg.id}-${idx}`, "think-line", line, {}));
2660
2692
  });
2661
2693
  if (!msg.isStreaming) {
2662
- completedBlocks.push({
2663
- key: `${msg.id}-footer-padding`,
2664
- msg,
2665
- type: "think-footer-padding",
2666
- text: ""
2667
- });
2694
+ flushPending();
2695
+ completedBlocks.push({ key: `${msg.id}-footer-padding`, msg, type: "think-footer-padding", text: "" });
2668
2696
  }
2669
2697
  } else {
2670
2698
  const lines = text.split("\n");
2671
2699
  let inTable = false;
2672
2700
  let tableLines = [];
2673
2701
  let inCodeBlock = false;
2674
- let codeLines = [];
2702
+ let codeLineNum = 0;
2703
+ let codeStartIdx = 0;
2675
2704
  lines.forEach((line, idx) => {
2676
2705
  const isLast = idx === lines.length - 1;
2677
2706
  const isTableRow = line.trim().startsWith("|");
2678
2707
  const isCodeBlockMarker = line.trim().startsWith("```");
2679
2708
  if (inCodeBlock) {
2680
- codeLines.push(line);
2681
- if (isCodeBlockMarker || isLast) {
2682
- inCodeBlock = !isCodeBlockMarker;
2683
- if (!inCodeBlock || isLast) {
2684
- const block = getBlock(`${msg.id}-code-${idx}`, "agent-line", codeLines.join("\n"), isLast && msg.isStreaming && inCodeBlock ? { isActiveBlock: true } : {});
2685
- if (isLast && msg.isStreaming && inCodeBlock) {
2686
- activeBlock = block;
2687
- } else {
2688
- completedBlocks.push(block);
2689
- }
2690
- codeLines = [];
2691
- }
2709
+ if (isCodeBlockMarker) {
2710
+ inCodeBlock = false;
2711
+ enqueue(getBlock(`${msg.id}-code-close-${codeStartIdx}`, "code-fence-close", "", {}));
2712
+ } else {
2713
+ codeLineNum++;
2714
+ enqueue(getBlock(`${msg.id}-code-line-${idx}`, "code-line", line, { lineNum: codeLineNum }));
2692
2715
  }
2693
2716
  } else if (isCodeBlockMarker) {
2694
2717
  inCodeBlock = true;
2695
- codeLines.push(line);
2696
- if (isLast) {
2697
- const block = getBlock(`${msg.id}-code-${idx}`, "agent-line", codeLines.join("\n"), msg.isStreaming ? { isActiveBlock: true } : {});
2698
- if (msg.isStreaming) {
2699
- activeBlock = block;
2700
- } else {
2701
- completedBlocks.push(block);
2702
- }
2703
- }
2718
+ codeStartIdx = idx;
2719
+ codeLineNum = 0;
2720
+ const lang = line.trim().replace(/^```/, "").trim();
2721
+ enqueue(getBlock(`${msg.id}-code-open-${idx}`, "code-fence-open", lang, {}));
2704
2722
  } else if (isTableRow) {
2705
2723
  inTable = true;
2706
2724
  tableLines.push(line);
2707
2725
  if (isLast) {
2726
+ flushPending();
2708
2727
  if (msg.isStreaming) {
2709
- activeBlock = getBlock(`${msg.id}-table-${idx}`, "table", tableLines.join("\n"), { isStreaming: true, isActiveBlock: true });
2728
+ activeBlock = getBlock(`${msg.id}-table-${idx}`, "table", tableLines.join("\n"), { isStreaming: true });
2710
2729
  } else {
2711
2730
  completedBlocks.push(getBlock(`${msg.id}-table-${idx}`, "table", tableLines.join("\n"), { isStreaming: false }));
2712
2731
  }
2713
2732
  }
2714
2733
  } else {
2715
2734
  if (inTable) {
2735
+ flushPending();
2716
2736
  completedBlocks.push(getBlock(`${msg.id}-table-${idx}`, "table", tableLines.join("\n"), { isStreaming: false }));
2717
2737
  inTable = false;
2718
2738
  tableLines = [];
2719
2739
  }
2720
- const block = getBlock(`${msg.id}-${idx}`, "agent-line", line, isLast && msg.isStreaming ? { isActiveBlock: true } : {});
2721
- if (isLast && msg.isStreaming) {
2722
- activeBlock = block;
2723
- } else {
2724
- completedBlocks.push(block);
2725
- }
2740
+ enqueue(getBlock(`${msg.id}-${idx}`, "agent-line", line, {}));
2726
2741
  }
2727
2742
  });
2728
2743
  if (!msg.isStreaming && msg.workedDuration) {
2744
+ flushPending();
2729
2745
  completedBlocks.push(getBlock(`${msg.id}-worked-duration`, "worked-duration", ""));
2730
2746
  }
2731
2747
  }
2748
+ if (msg.isStreaming && pendingChunk.length > 0) {
2749
+ activeBlock = pendingChunk.length === 1 ? pendingChunk[0] : {
2750
+ key: `${msg.id || "x"}-chunk-active-${pendingChunk[0].key}`,
2751
+ msg,
2752
+ type: "chunk",
2753
+ blocks: pendingChunk
2754
+ };
2755
+ } else {
2756
+ flushPending();
2757
+ }
2732
2758
  const result = {
2733
2759
  completed: completedBlocks,
2734
2760
  active: activeBlock ? [activeBlock] : []
@@ -2742,14 +2768,9 @@ var init_text = __esm({
2742
2768
  streamingBlocksCache.delete(streamCacheKey);
2743
2769
  } else {
2744
2770
  const blocksMap = /* @__PURE__ */ new Map();
2745
- completedBlocks.forEach((b) => blocksMap.set(b.key, b));
2746
- if (activeBlock) {
2747
- blocksMap.set(activeBlock.key, activeBlock);
2748
- }
2749
- streamingBlocksCache.set(streamCacheKey, {
2750
- text,
2751
- blocksMap
2752
- });
2771
+ completedBlocks.forEach((b) => indexBlockIntoMap(b, blocksMap));
2772
+ if (activeBlock) indexBlockIntoMap(activeBlock, blocksMap);
2773
+ streamingBlocksCache.set(streamCacheKey, { text, blocksMap });
2753
2774
  if (streamingBlocksCache.size > MAX_CACHE_SIZE) {
2754
2775
  const firstKey = streamingBlocksCache.keys().next().value;
2755
2776
  streamingBlocksCache.delete(firstKey);
@@ -4520,6 +4541,19 @@ var init_ChatLayout = __esm({
4520
4541
  });
4521
4542
  BlockItem = React4.memo(({ block, columns = 80, showFullThinking, aiProvider, version }) => {
4522
4543
  const { msg, type, text, isStreaming } = block;
4544
+ if (type === "chunk") {
4545
+ return /* @__PURE__ */ React4.createElement(Box3, { flexDirection: "column", width: "100%" }, block.blocks.map((b) => /* @__PURE__ */ React4.createElement(
4546
+ BlockItem,
4547
+ {
4548
+ key: b.key,
4549
+ block: b,
4550
+ columns,
4551
+ showFullThinking,
4552
+ aiProvider,
4553
+ version
4554
+ }
4555
+ )));
4556
+ }
4523
4557
  if (type === "full-message") {
4524
4558
  return /* @__PURE__ */ React4.createElement(
4525
4559
  MessageItem,
@@ -4583,6 +4617,56 @@ var init_ChatLayout = __esm({
4583
4617
  }
4584
4618
  ), isLastLine && renderPaddingLine(true));
4585
4619
  }
4620
+ if (type === "code-fence-open") {
4621
+ const borderProps = {
4622
+ borderStyle: "single",
4623
+ borderLeft: true,
4624
+ borderRight: false,
4625
+ borderTop: false,
4626
+ borderBottom: false,
4627
+ borderColor: "#444444",
4628
+ paddingLeft: 2,
4629
+ width: "100%"
4630
+ };
4631
+ return /* @__PURE__ */ React4.createElement(Box3, { flexDirection: "column", marginTop: 1, width: "100%" }, /* @__PURE__ */ React4.createElement(Box3, { flexDirection: "row", ...borderProps }, /* @__PURE__ */ React4.createElement(Text4, null, " ")), /* @__PURE__ */ React4.createElement(Box3, { flexDirection: "row", ...borderProps }, /* @__PURE__ */ React4.createElement(Text4, { color: "gray", bold: true }, "\u25B6_ ", (text || "CODE").toUpperCase())));
4632
+ }
4633
+ if (type === "code-line") {
4634
+ const { lineNum } = block;
4635
+ return /* @__PURE__ */ React4.createElement(
4636
+ Box3,
4637
+ {
4638
+ flexDirection: "row",
4639
+ borderStyle: "single",
4640
+ borderLeft: true,
4641
+ borderRight: false,
4642
+ borderTop: false,
4643
+ borderBottom: false,
4644
+ borderColor: "#444444",
4645
+ paddingLeft: 2,
4646
+ width: "100%"
4647
+ },
4648
+ /* @__PURE__ */ React4.createElement(Box3, { width: 4, flexShrink: 0 }, /* @__PURE__ */ React4.createElement(Text4, { color: "gray", dimColor: true }, String(lineNum).padStart(3, " "), " ")),
4649
+ /* @__PURE__ */ React4.createElement(Box3, { flexGrow: 1 }, /* @__PURE__ */ React4.createElement(Text4, { color: "#fcfca4ff" }, text))
4650
+ );
4651
+ }
4652
+ if (type === "code-fence-close") {
4653
+ return /* @__PURE__ */ React4.createElement(
4654
+ Box3,
4655
+ {
4656
+ flexDirection: "row",
4657
+ borderStyle: "single",
4658
+ borderLeft: true,
4659
+ borderRight: false,
4660
+ borderTop: false,
4661
+ borderBottom: false,
4662
+ borderColor: "#444444",
4663
+ paddingLeft: 2,
4664
+ marginBottom: 1,
4665
+ width: "100%"
4666
+ },
4667
+ /* @__PURE__ */ React4.createElement(Text4, null, " ")
4668
+ );
4669
+ }
4586
4670
  if (type === "write-header") {
4587
4671
  return /* @__PURE__ */ React4.createElement(Box3, { flexDirection: "column", paddingX: 1, width: columns }, /* @__PURE__ */ React4.createElement(MarkdownText, { text, columns }));
4588
4672
  }
@@ -6246,6 +6330,7 @@ ${projectContextBlock}
6246
6330
  -- FORMATTING --
6247
6331
  - GFM Supported
6248
6332
  - NO CHAT **AFTER** FIRING TOOLS IN CURRENT TURN
6333
+ - Short headsup about actions before firing tools
6249
6334
  - Task Complete & Results Verified? End response with summary of changes made and files edited
6250
6335
  - Basic LaTeX${mode === "Flux" ? "" : ". Kaomojis"}
6251
6336
  === END SYSTEM PROMPT ===`.trim();
@@ -15391,7 +15476,7 @@ function App({ args = [] }) {
15391
15476
  ] : aiProvider === "NVIDIA" ? [
15392
15477
  { cmd: "Fast", desc: "Reasoning Disabled" },
15393
15478
  { cmd: "Standard", desc: "Balanced Reasoning" },
15394
- { cmd: "High", desc: "Reasoning Enabled" }
15479
+ { cmd: "High", desc: "Deep Reasoning" }
15395
15480
  ] : aiProvider === "OpenRouter" ? [
15396
15481
  { cmd: "Fast", desc: "Fastest" },
15397
15482
  { cmd: "Low", desc: "Quick Reasoning" },
@@ -18326,14 +18411,12 @@ var _allocIdx = _rawArgs.indexOf("--allocation");
18326
18411
  var _allocValue = _allocIdx !== -1 ? parseInt(_rawArgs[_allocIdx + 1], 10) : NaN;
18327
18412
  var _maxAllowed = Math.floor(totalSystemRamMB * 0.75);
18328
18413
  var HEAP_LIMIT = !isNaN(_allocValue) && _allocValue > 0 ? Math.min(_allocValue, _maxAllowed) : Math.max(1536, Math.min(32768, calculatedLimit));
18329
- if (!Number.isNaN(_allocValue)) {
18330
- console.log("\n[MEMORY] Using custom memory allocation: " + _allocValue + " MB" + (_allocValue > _maxAllowed ? " (Max allowed: " + _maxAllowed + "MB)" : ""));
18331
- await new Promise((resolve) => setTimeout(resolve, 2e3));
18332
- } else {
18333
- console.log("\n[MEMORY] Using auto-detected memory allocation: " + calculatedLimit + " MB");
18334
- }
18335
18414
  var isBundled = fileURLToPath2(import.meta.url).endsWith(".js");
18336
18415
  if (isBundled && !process.execArgv.some((arg) => arg.includes("max-old-space-size"))) {
18416
+ if (!Number.isNaN(_allocValue)) {
18417
+ console.log("\n[MEMORY] Using custom memory allocation: " + _allocValue + " MB" + (_allocValue > _maxAllowed ? " (Max allowed: " + _maxAllowed + "MB)" : ""));
18418
+ await new Promise((resolve) => setTimeout(resolve, 2e3));
18419
+ }
18337
18420
  const cp = spawn3(process.execPath, [
18338
18421
  `--max-old-space-size=${HEAP_LIMIT}`,
18339
18422
  fileURLToPath2(import.meta.url),
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "fluxflow-cli",
3
- "version": "2.14.0",
3
+ "version": "2.14.1",
4
4
  "date": "2026-06-29",
5
5
  "description": "A high-fidelity agentic terminal assistant for the Flux Era.",
6
6
  "keywords": [