fluxflow-cli 3.0.11 → 3.0.12

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 +130 -45
  2. package/package.json +1 -1
package/dist/fluxflow.js CHANGED
@@ -4829,36 +4829,78 @@ var init_ChatLayout = __esm({
4829
4829
  // src/components/StatusBar.jsx
4830
4830
  import React5 from "react";
4831
4831
  import { Box as Box4, Text as Text5 } from "ink";
4832
- import { useState as useState5, useEffect as useEffect4 } from "react";
4832
+ import { useState as useState5, useEffect as useEffect4, useRef as useRef3 } from "react";
4833
4833
  function getMemoryInfo() {
4834
4834
  if (activeGetMemoryInfo) {
4835
4835
  activeGetMemoryInfo();
4836
4836
  }
4837
4837
  }
4838
- var activeGetMemoryInfo, StatusBar, StatusBar_default;
4838
+ var activeGetMemoryInfo, getLatencyColor, StatusBar, StatusBar_default;
4839
4839
  var init_StatusBar = __esm({
4840
4840
  "src/components/StatusBar.jsx"() {
4841
4841
  init_text();
4842
4842
  activeGetMemoryInfo = null;
4843
+ getLatencyColor = (delay) => {
4844
+ if (delay <= 400) return "#00a564";
4845
+ if (delay >= 5e3) return "#ff0000";
4846
+ const points = [
4847
+ { t: 400, r: 0, g: 165, b: 100 },
4848
+ { t: 800, r: 120, g: 220, b: 80 },
4849
+ { t: 1500, r: 250, g: 210, b: 40 },
4850
+ { t: 3e3, r: 255, g: 120, b: 0 },
4851
+ { t: 5e3, r: 255, g: 0, b: 0 }
4852
+ ];
4853
+ for (let i = 0; i < points.length - 1; i++) {
4854
+ const p1 = points[i];
4855
+ const p2 = points[i + 1];
4856
+ if (delay >= p1.t && delay <= p2.t) {
4857
+ const ratio = (delay - p1.t) / (p2.t - p1.t);
4858
+ const r = Math.round(p1.r + (p2.r - p1.r) * ratio);
4859
+ const g = Math.round(p1.g + (p2.g - p1.g) * ratio);
4860
+ const b = Math.round(p1.b + (p2.b - p1.b) * ratio);
4861
+ return `#${((1 << 24) + (r << 16) + (g << 8) + b).toString(16).slice(1)}`;
4862
+ }
4863
+ }
4864
+ return "#ff0000";
4865
+ };
4843
4866
  StatusBar = React5.memo(({ mode, thinkingLevel, tokens = "0.0k", tokensTotal = "0.0k", chatId = "NEW-SESSION", isMemoryEnabled = true, apiTier = "Free", aiProvider = "Google", activeModel = "", isProcessing = false, lastChunkTime = 0 }) => {
4844
4867
  const modeIcon = mode === "Flux" ? "" : "";
4845
4868
  const [memoryUsage, setMemoryUsage] = useState5(0);
4846
4869
  const [memoryLimit, setMemoryLimit] = useState5(0);
4847
4870
  const [memoryUnit, setMemoryUnit] = useState5("MB");
4848
4871
  const [dotColor, setDotColor] = useState5("green");
4872
+ const chunkTimesRef = useRef3([]);
4849
4873
  useEffect4(() => {
4850
- if (!isProcessing) return;
4874
+ if (!isProcessing) {
4875
+ chunkTimesRef.current = [];
4876
+ return;
4877
+ }
4878
+ if (lastChunkTime > 0) {
4879
+ const times = chunkTimesRef.current;
4880
+ if (times.length === 0 || times[times.length - 1] !== lastChunkTime) {
4881
+ times.push(lastChunkTime);
4882
+ if (times.length > 5) {
4883
+ times.shift();
4884
+ }
4885
+ }
4886
+ }
4851
4887
  const checkLatency = () => {
4852
- const delay = Date.now() - lastChunkTime;
4853
- if (delay < 700) {
4854
- setDotColor("green");
4855
- } else if (delay <= 1200) {
4856
- setDotColor("yellow");
4857
- } else if (delay <= 2e3) {
4858
- setDotColor("#ff9f43");
4859
- } else {
4860
- setDotColor("#d63031");
4888
+ if (!lastChunkTime) {
4889
+ setDotColor("#00a564");
4890
+ return;
4891
+ }
4892
+ const times = chunkTimesRef.current;
4893
+ let averageInterval = 0;
4894
+ if (times.length > 1) {
4895
+ let sum = 0;
4896
+ for (let i = 1; i < times.length; i++) {
4897
+ sum += times[i] - times[i - 1];
4898
+ }
4899
+ averageInterval = sum / (times.length - 1);
4861
4900
  }
4901
+ const timeSinceLast = Date.now() - lastChunkTime;
4902
+ const delay = Math.max(averageInterval, timeSinceLast);
4903
+ setDotColor(getLatencyColor(delay));
4862
4904
  };
4863
4905
  checkLatency();
4864
4906
  const timer = setInterval(checkLatency, 100);
@@ -15001,7 +15043,7 @@ __export(app_exports, {
15001
15043
  default: () => App
15002
15044
  });
15003
15045
  import os4 from "os";
15004
- import React15, { useState as useState14, useEffect as useEffect11, useRef as useRef3, useMemo as useMemo2 } from "react";
15046
+ import React15, { useState as useState14, useEffect as useEffect11, useRef as useRef4, useMemo as useMemo2 } from "react";
15005
15047
  import { Box as Box14, Text as Text15, useInput as useInput9, useStdout as useStdout2, Static } from "ink";
15006
15048
  import fs22 from "fs-extra";
15007
15049
  import path20 from "path";
@@ -15027,8 +15069,8 @@ function App({ args = [] }) {
15027
15069
  const [isFilePickerDismissed, setIsFilePickerDismissed] = useState14(false);
15028
15070
  const [showBridgePromo, setShowBridgePromo] = useState14(false);
15029
15071
  const [promoSelectedIndex, setPromoSelectedIndex] = useState14(0);
15030
- const suggestionOffsetRef = useRef3(0);
15031
- const persistedModelRef = useRef3(null);
15072
+ const suggestionOffsetRef = useRef4(0);
15073
+ const persistedModelRef = useRef4(null);
15032
15074
  useEffect11(() => {
15033
15075
  const ideName = getIDEName();
15034
15076
  const isIDE = !["Terminal", "Windows Terminal"].includes(ideName) || !!process.env.VSC_TERMINAL_URL;
@@ -15242,7 +15284,7 @@ function App({ args = [] }) {
15242
15284
  const [janitorModel, setJanitorModel] = useState14("gemma-4-26b-a4b-it");
15243
15285
  const [isInitializing, setIsInitializing] = useState14(true);
15244
15286
  const [isAppFocused, setIsAppFocused] = useState14(true);
15245
- const lastFocusEventTime = useRef3(0);
15287
+ const lastFocusEventTime = useRef4(0);
15246
15288
  const [apiKey, setApiKey] = useState14(null);
15247
15289
  const [tempKey, setTempKey] = useState14("");
15248
15290
  const addShiftEnterBinding = async (ideName) => {
@@ -15313,7 +15355,7 @@ function App({ args = [] }) {
15313
15355
  const [sessionBackgroundCalls, setSessionBackgroundCalls] = useState14(0);
15314
15356
  const [sessionTotalTokens, setSessionTotalTokens] = useState14(0);
15315
15357
  const [chatTokens, setChatTokens] = useState14(0);
15316
- const chatTokenStartRef = useRef3(0);
15358
+ const chatTokenStartRef = useRef4(0);
15317
15359
  const [sessionTotalCachedTokens, setSessionTotalCachedTokens] = useState14(0);
15318
15360
  const [sessionTotalCandidateTokens, setSessionTotalCandidateTokens] = useState14(0);
15319
15361
  const [sessionToolSuccess, setSessionToolSuccess] = useState14(0);
@@ -15356,12 +15398,12 @@ function App({ args = [] }) {
15356
15398
  const [isTerminalFocused, setIsTerminalFocused] = useState14(false);
15357
15399
  const [activeSubagents, setActiveSubagents] = useState14([]);
15358
15400
  const [tick, setTick] = useState14(0);
15359
- const isFirstRender = useRef3(true);
15360
- const isSecondRender = useRef3(true);
15361
- const isThirdRender = useRef3(true);
15362
- const prevProviderRef = useRef3(aiProvider);
15363
- const originalAllowExternalAccessRef = useRef3(false);
15364
- const originalMemoryRef = useRef3(true);
15401
+ const isFirstRender = useRef4(true);
15402
+ const isSecondRender = useRef4(true);
15403
+ const isThirdRender = useRef4(true);
15404
+ const prevProviderRef = useRef4(aiProvider);
15405
+ const originalAllowExternalAccessRef = useRef4(false);
15406
+ const originalMemoryRef = useRef4(true);
15365
15407
  useEffect11(() => {
15366
15408
  if (prevProviderRef.current !== aiProvider) {
15367
15409
  prevProviderRef.current = aiProvider;
@@ -15447,8 +15489,8 @@ function App({ args = [] }) {
15447
15489
  }
15448
15490
  };
15449
15491
  }, []);
15450
- const activeCommandRef = useRef3(null);
15451
- const execOutputRef = useRef3("");
15492
+ const activeCommandRef = useRef4(null);
15493
+ const execOutputRef = useRef4("");
15452
15494
  useEffect11(() => {
15453
15495
  activeCommandRef.current = activeCommand;
15454
15496
  }, [activeCommand]);
@@ -15504,8 +15546,8 @@ function App({ args = [] }) {
15504
15546
  const [escTimer, setEscTimer] = useState14(null);
15505
15547
  const [escPressCount, setEscPressCount] = useState14(0);
15506
15548
  const [recentPrompts, setRecentPrompts] = useState14([]);
15507
- const escDoubleTimerRef = useRef3(null);
15508
- const chatLoadingRef = useRef3(false);
15549
+ const escDoubleTimerRef = useRef4(null);
15550
+ const chatLoadingRef = useRef4(false);
15509
15551
  useEffect11(() => {
15510
15552
  return () => {
15511
15553
  if (escDoubleTimerRef.current) {
@@ -15513,7 +15555,7 @@ function App({ args = [] }) {
15513
15555
  }
15514
15556
  };
15515
15557
  }, []);
15516
- const didSignalTerminationRef = useRef3(false);
15558
+ const didSignalTerminationRef = useRef4(false);
15517
15559
  const [queuedPrompt, setQueuedPrompt] = useState14(null);
15518
15560
  const [resolutionData, setResolutionData] = useState14(null);
15519
15561
  const [tempModelOverride, setTempModelOverride] = useState14(null);
@@ -15566,11 +15608,11 @@ function App({ args = [] }) {
15566
15608
  return next;
15567
15609
  });
15568
15610
  };
15569
- const queuedPromptRef = useRef3(null);
15611
+ const queuedPromptRef = useRef4(null);
15570
15612
  const [btwResponse, setBtwResponse] = useState14("");
15571
15613
  const [showBtwBox, setShowBtwBox] = useState14(false);
15572
- const btwResponseRef = useRef3("");
15573
- const btwClosedRef = useRef3(null);
15614
+ const btwResponseRef = useRef4("");
15615
+ const btwClosedRef = useRef4(null);
15574
15616
  useEffect11(() => {
15575
15617
  if (messages.length === 0) return;
15576
15618
  const lastMsg = messages[messages.length - 1];
@@ -15591,8 +15633,8 @@ function App({ args = [] }) {
15591
15633
  }, [messages]);
15592
15634
  const [completedIndex, setCompletedIndex] = useState14(messages.length);
15593
15635
  const [clearKey, setClearKey] = useState14(0);
15594
- const lastCompletedBlocksRef = useRef3([]);
15595
- const cachedHistoryRef = useRef3({
15636
+ const lastCompletedBlocksRef = useRef4([]);
15637
+ const cachedHistoryRef = useRef4({
15596
15638
  completedIndex: 0,
15597
15639
  columns: 0,
15598
15640
  historicalBlocks: [],
@@ -16234,7 +16276,7 @@ function App({ args = [] }) {
16234
16276
  setTempKey("");
16235
16277
  }
16236
16278
  };
16237
- const lastSavedTimeRef = useRef3(SESSION_START_TIME);
16279
+ const lastSavedTimeRef = useRef4(SESSION_START_TIME);
16238
16280
  useEffect11(() => {
16239
16281
  if (activeView === "exit") {
16240
16282
  const flush = async () => {
@@ -19243,7 +19285,7 @@ Selection: ${val}`,
19243
19285
  return /* @__PURE__ */ React15.createElement(Box14, { flexDirection: "column", borderStyle: "round", paddingX: 3, paddingY: 1, borderColor: "grey", width: Math.min(100, (stdout?.columns || 100) - 2), marginTop: 0, marginBottom: 0 }, /* @__PURE__ */ React15.createElement(Box14, { marginBottom: 1 }, /* @__PURE__ */ React15.createElement(Text15, { bold: true }, gradient2(["blue", "purple"])("Agent powering down. Goodbye!"))), /* @__PURE__ */ React15.createElement(Box14, { flexDirection: "column" }, /* @__PURE__ */ React15.createElement(Text15, { color: "white", bold: true, underline: true }, "Interaction Summary"), /* @__PURE__ */ React15.createElement(Box14, { marginTop: 1 }, /* @__PURE__ */ React15.createElement(Box14, { width: 20 }, /* @__PURE__ */ React15.createElement(Text15, { color: "blue" }, "Session ID:")), /* @__PURE__ */ React15.createElement(Text15, { color: "white" }, chatId)), /* @__PURE__ */ React15.createElement(Box14, null, /* @__PURE__ */ React15.createElement(Box14, { width: 20 }, /* @__PURE__ */ React15.createElement(Text15, { color: "blue" }, "Tool Calls:")), /* @__PURE__ */ React15.createElement(Text15, { color: "white" }, sessionToolSuccess + sessionToolFailure + sessionToolDenied, " ( ", /* @__PURE__ */ React15.createElement(Text15, { color: "green" }, "\u2713 ", sessionToolSuccess), " ", /* @__PURE__ */ React15.createElement(Text15, { color: "yellow" }, "\u2298 ", sessionToolDenied), " ", /* @__PURE__ */ React15.createElement(Text15, { color: "red" }, "\u2715 ", sessionToolFailure), " )")), /* @__PURE__ */ React15.createElement(Box14, null, /* @__PURE__ */ React15.createElement(Box14, { width: 20 }, /* @__PURE__ */ React15.createElement(Text15, { color: "blue" }, "Success Rate:")), /* @__PURE__ */ React15.createElement(Text15, { color: "white" }, successRate, "%")), /* @__PURE__ */ React15.createElement(Box14, null, /* @__PURE__ */ React15.createElement(Box14, { width: 20 }, /* @__PURE__ */ React15.createElement(Text15, { color: "blue" }, "Code Changes:")), /* @__PURE__ */ React15.createElement(Text15, { color: "white" }, /* @__PURE__ */ React15.createElement(Text15, { color: "green" }, "+", linesAdded), " ", /* @__PURE__ */ React15.createElement(Text15, { color: "red" }, "-", linesRemoved))), /* @__PURE__ */ React15.createElement(Box14, null, /* @__PURE__ */ React15.createElement(Box14, { width: 20 }, /* @__PURE__ */ React15.createElement(Text15, { color: "blue" }, "Tokens Consumed:")), /* @__PURE__ */ React15.createElement(Text15, { color: "white" }, formatTokens(sessionTotalTokens))), sessionTotalTokens > 0 && /* @__PURE__ */ React15.createElement(React15.Fragment, null, /* @__PURE__ */ React15.createElement(Box14, { marginLeft: 2 }, /* @__PURE__ */ React15.createElement(Box14, { width: 18 }, /* @__PURE__ */ React15.createElement(Text15, { color: "grey" }, "\xBB Input Tokens:")), /* @__PURE__ */ React15.createElement(Text15, { color: "white" }, formatTokens(sessionTotalTokens - sessionTotalCandidateTokens))), sessionTotalCachedTokens > 0 && /* @__PURE__ */ React15.createElement(Box14, { marginLeft: 4 }, /* @__PURE__ */ React15.createElement(Box14, { width: 16 }, /* @__PURE__ */ React15.createElement(Text15, { color: "grey" }, "\xBB Cached:")), /* @__PURE__ */ React15.createElement(Text15, { color: "white" }, formatTokens(sessionTotalCachedTokens))), sessionTotalCandidateTokens > 0 && /* @__PURE__ */ React15.createElement(Box14, { marginLeft: 2 }, /* @__PURE__ */ React15.createElement(Box14, { width: 18 }, /* @__PURE__ */ React15.createElement(Text15, { color: "grey" }, "\xBB Output Tokens:")), /* @__PURE__ */ React15.createElement(Text15, { color: "white" }, formatTokens(sessionTotalCandidateTokens)))), sessionImageCount > 0 && /* @__PURE__ */ React15.createElement(React15.Fragment, null, /* @__PURE__ */ React15.createElement(Box14, null, /* @__PURE__ */ React15.createElement(Box14, { width: 20 }, /* @__PURE__ */ React15.createElement(Text15, { color: "blue" }, "Images Made:")), /* @__PURE__ */ React15.createElement(Text15, { color: "white" }, sessionImageCount)), /* @__PURE__ */ React15.createElement(Box14, null, /* @__PURE__ */ React15.createElement(Box14, { width: 20 }, /* @__PURE__ */ React15.createElement(Text15, { color: "blue" }, "Image Credits:")), /* @__PURE__ */ React15.createElement(Text15, { color: "white" }, Number(((sessionImageCredits || 0) * 1e3).toFixed(0)), " credits")))), /* @__PURE__ */ React15.createElement(Box14, { flexDirection: "column", marginTop: 1 }, /* @__PURE__ */ React15.createElement(Text15, { color: "white", bold: true, underline: true }, "Performance"), /* @__PURE__ */ React15.createElement(Box14, { marginTop: 1 }, /* @__PURE__ */ React15.createElement(Box14, { width: 20 }, /* @__PURE__ */ React15.createElement(Text15, { color: "blue" }, "Wall Time:")), /* @__PURE__ */ React15.createElement(Text15, { color: "white" }, formatMsDuration(wallTimeMs))), /* @__PURE__ */ React15.createElement(Box14, null, /* @__PURE__ */ React15.createElement(Box14, { width: 20 }, /* @__PURE__ */ React15.createElement(Text15, { color: "blue" }, "Agent Active:")), /* @__PURE__ */ React15.createElement(Text15, { color: "white" }, formatMsDuration(agentActiveMs))), /* @__PURE__ */ React15.createElement(Box14, { marginLeft: 2 }, /* @__PURE__ */ React15.createElement(Box14, { width: 18 }, /* @__PURE__ */ React15.createElement(Text15, { color: "grey" }, "\xBB API Time:")), /* @__PURE__ */ React15.createElement(Text15, { color: "white" }, formatMsDuration(sessionApiTime), " (", apiPercent, "%)")), /* @__PURE__ */ React15.createElement(Box14, { marginLeft: 2 }, /* @__PURE__ */ React15.createElement(Box14, { width: 18 }, /* @__PURE__ */ React15.createElement(Text15, { color: "grey" }, "\xBB Tool Time:")), /* @__PURE__ */ React15.createElement(Text15, { color: "white" }, formatMsDuration(sessionToolTime), " (", toolPercent, "%)"))));
19244
19286
  })())));
19245
19287
  }
19246
- var shouldClearValue, getPrefilledValue, getIDEName, getIDEDirName, getKeybindingsPath, parseJsonc, hasShiftEnterBinding, getPromoOptions, BridgePromo, SESSION_START_TIME, CHANGELOG_URL, DOCS_URL, linesAdded, linesRemoved, packageJsonPath, packageJson, versionFluxflow, updatedOn, ResolutionModal, parseAgentText, getProjectFiles, cachedShortcut, SubagentRow;
19288
+ var shouldClearValue, getPrefilledValue, getIDEName, getIDEDirName, getKeybindingsPath, parseJsonc, hasShiftEnterBinding, getPromoOptions, BridgePromo, SESSION_START_TIME, CHANGELOG_URL, DOCS_URL, linesAdded, linesRemoved, packageJsonPath, packageJson, versionFluxflow, updatedOn, ResolutionModal, parseAgentText, getProjectFiles, cachedShortcut, getLatencyColor2, SubagentRow;
19247
19289
  var init_app = __esm({
19248
19290
  async "src/app.jsx"() {
19249
19291
  init_build();
@@ -19499,21 +19541,64 @@ var init_app = __esm({
19499
19541
  };
19500
19542
  })();
19501
19543
  cachedShortcut = "\\ + Enter";
19544
+ getLatencyColor2 = (delay) => {
19545
+ if (delay <= 400) return "#00a564";
19546
+ if (delay >= 5e3) return "#ff0000";
19547
+ const points = [
19548
+ { t: 400, r: 0, g: 165, b: 100 },
19549
+ { t: 800, r: 120, g: 220, b: 80 },
19550
+ { t: 1500, r: 250, g: 210, b: 40 },
19551
+ { t: 3e3, r: 255, g: 120, b: 0 },
19552
+ { t: 5e3, r: 255, g: 0, b: 0 }
19553
+ ];
19554
+ for (let i = 0; i < points.length - 1; i++) {
19555
+ const p1 = points[i];
19556
+ const p2 = points[i + 1];
19557
+ if (delay >= p1.t && delay <= p2.t) {
19558
+ const ratio = (delay - p1.t) / (p2.t - p1.t);
19559
+ const r = Math.round(p1.r + (p2.r - p1.r) * ratio);
19560
+ const g = Math.round(p1.g + (p2.g - p1.g) * ratio);
19561
+ const b = Math.round(p1.b + (p2.b - p1.b) * ratio);
19562
+ return `#${((1 << 24) + (r << 16) + (g << 8) + b).toString(16).slice(1)}`;
19563
+ }
19564
+ }
19565
+ return "#ff0000";
19566
+ };
19502
19567
  SubagentRow = React15.memo(({ sa }) => {
19503
19568
  const [dotColor, setDotColor] = useState14("green");
19569
+ const chunkTimesRef = useRef4([]);
19504
19570
  useEffect11(() => {
19505
- if (sa.status !== "running") return;
19571
+ if (sa.status !== "running") {
19572
+ chunkTimesRef.current = [];
19573
+ return;
19574
+ }
19575
+ const lastChunkTime = sa.lastChunkTime;
19576
+ if (lastChunkTime > 0) {
19577
+ const times = chunkTimesRef.current;
19578
+ if (times.length === 0 || times[times.length - 1] !== lastChunkTime) {
19579
+ times.push(lastChunkTime);
19580
+ if (times.length > 5) {
19581
+ times.shift();
19582
+ }
19583
+ }
19584
+ }
19506
19585
  const checkLatency = () => {
19507
- const delay = Date.now() - (sa.lastChunkTime || Date.now());
19508
- if (delay < 700) {
19509
- setDotColor("green");
19510
- } else if (delay <= 1200) {
19511
- setDotColor("yellow");
19512
- } else if (delay <= 2e3) {
19513
- setDotColor("#ff9f43");
19514
- } else {
19515
- setDotColor("#d63031");
19586
+ if (!lastChunkTime) {
19587
+ setDotColor("#00a564");
19588
+ return;
19589
+ }
19590
+ const times = chunkTimesRef.current;
19591
+ let averageInterval = 0;
19592
+ if (times.length > 1) {
19593
+ let sum = 0;
19594
+ for (let i = 1; i < times.length; i++) {
19595
+ sum += times[i] - times[i - 1];
19596
+ }
19597
+ averageInterval = sum / (times.length - 1);
19516
19598
  }
19599
+ const timeSinceLast = Date.now() - lastChunkTime;
19600
+ const delay = Math.max(averageInterval, timeSinceLast);
19601
+ setDotColor(getLatencyColor2(delay));
19517
19602
  };
19518
19603
  checkLatency();
19519
19604
  const timer = setInterval(checkLatency, 100);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "fluxflow-cli",
3
- "version": "3.0.11",
3
+ "version": "3.0.12",
4
4
  "date": "2026-07-04",
5
5
  "description": "A High-Fidelity Agentic CLI with Sub-Agents for the Flux Era.",
6
6
  "keywords": [