fluxflow-cli 2.11.0 → 2.11.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 +156 -11
  2. package/package.json +1 -1
package/dist/fluxflow.js CHANGED
@@ -1898,6 +1898,7 @@ var init_ChatLayout = __esm({
1898
1898
  { cmd: "/chats", desc: "List all chat sessions" },
1899
1899
  { cmd: "/btw", desc: "Send raw inquiry mid-turn" },
1900
1900
  { cmd: "/image", desc: "Generate images" },
1901
+ { cmd: "/budget", desc: "Set or View budget limits" },
1901
1902
  { cmd: "/mode", desc: "Toggle Flux/Flow modes" },
1902
1903
  { cmd: "/thinking", desc: "Set AI reasoning depth" },
1903
1904
  { cmd: "/model", desc: "Switch AI model" },
@@ -2935,7 +2936,7 @@ function SettingsMenu({
2935
2936
  case "other":
2936
2937
  return [
2937
2938
  { label: "Current Provider", value: "aiProvider", status: aiProvider },
2938
- { label: "API Tier", value: "apiTier", status: apiTier === "Free" ? "Provider Limits" : "Custom Budget" },
2939
+ { label: "Budgets", value: "apiTier", status: apiTier === "Free" ? "Provider Limits" : "Custom Budget" },
2939
2940
  { label: "Download Language Parsers", value: "parserDownload", status: "ACTION" }
2940
2941
  ];
2941
2942
  default:
@@ -4394,11 +4395,31 @@ var init_usage = __esm({
4394
4395
  const tier = settings.apiTier || "Free";
4395
4396
  const quotas = settings.quotas || {};
4396
4397
  if (tier === "Free") {
4397
- if (key === "agent" || key === "background") {
4398
- const daily = await getDailyUsage();
4399
- return daily.agent + daily.background < 999999;
4398
+ if (key === "agent") {
4399
+ const reqLimit = quotas.agentLimit || 99999999;
4400
+ const tokenLimit = quotas.tokenLimit || 99999999999999;
4401
+ const monthlyTokenLimit = quotas.monthlyTokenLimit || 99999999999999;
4402
+ const dailyUsage = await getDailyUsage();
4403
+ if (dailyUsage.agent + dailyUsage.background >= 999999) return false;
4404
+ const dailyOk = dailyUsage.agent < reqLimit && (dailyUsage.tokens || 0) < tokenLimit;
4405
+ if (!dailyOk) return false;
4406
+ let monthlyUsage;
4407
+ if (quotas.resetMode === "Custom") {
4408
+ monthlyUsage = await getCustomPeriodUsage(quotas.resetDay || 1);
4409
+ } else {
4410
+ monthlyUsage = await getMonthlyUsage();
4411
+ }
4412
+ return (monthlyUsage.tokens || 0) < monthlyTokenLimit;
4413
+ }
4414
+ if (key === "background") {
4415
+ const dailyUsage = await getDailyUsage();
4416
+ if (dailyUsage.agent + dailyUsage.background >= 999999) return false;
4417
+ return dailyUsage.background < (quotas.backgroundLimit || 999999);
4418
+ }
4419
+ if (key === "search") {
4420
+ const dailyUsage = await getDailyUsage();
4421
+ return dailyUsage.search < (quotas.searchLimit || 100);
4400
4422
  }
4401
- if (key === "search") return true;
4402
4423
  }
4403
4424
  if (tier === "Paid" || tier === "Custom") {
4404
4425
  if (key === "agent") {
@@ -12292,6 +12313,14 @@ function App({ args = [] }) {
12292
12313
  { cmd: "init", desc: "Create FluxFlow.md template" }
12293
12314
  ]
12294
12315
  },
12316
+ {
12317
+ cmd: "/budget",
12318
+ desc: "Set or View budget limits",
12319
+ subs: [
12320
+ { cmd: "Set", desc: "Configure budgets (Daily/Monthly limits)" },
12321
+ { cmd: "View", desc: "View current usage budget bars" }
12322
+ ]
12323
+ },
12295
12324
  {
12296
12325
  cmd: "/update",
12297
12326
  desc: "Check/Install updates",
@@ -12823,6 +12852,50 @@ ${list || "No saved chats found."}`, isMeta: true }];
12823
12852
  });
12824
12853
  break;
12825
12854
  }
12855
+ case "/budget": {
12856
+ const sub = parts[1]?.toLowerCase();
12857
+ if (sub === "set") {
12858
+ setInputConfig({
12859
+ label: "Enter Agent daily budget (requests made):",
12860
+ key: "quotas",
12861
+ subKey: "agentLimit",
12862
+ value: getPrefilledValue(quotas.agentLimit),
12863
+ returnView: "chat",
12864
+ next: (newQuotas) => ({
12865
+ label: "Enter Agent daily budget (tokens used):",
12866
+ key: "quotas",
12867
+ subKey: "tokenLimit",
12868
+ value: getPrefilledValue(newQuotas.tokenLimit),
12869
+ returnView: "chat",
12870
+ next: (q2) => ({
12871
+ label: "Enter Agent monthly budget (tokens used):",
12872
+ key: "quotas",
12873
+ subKey: "monthlyTokenLimit",
12874
+ value: getPrefilledValue(q2.monthlyTokenLimit),
12875
+ returnView: "budgetResetMode"
12876
+ })
12877
+ })
12878
+ });
12879
+ setActiveView("input");
12880
+ } else if (sub === "view") {
12881
+ const run = async () => {
12882
+ const usage = await getDailyUsage();
12883
+ const mUsage = await getMonthlyUsage();
12884
+ const cUsage = await getCustomPeriodUsage(quotas.resetDay || 1);
12885
+ setDailyUsage(usage);
12886
+ setMonthlyUsage(mUsage);
12887
+ setCustomPeriodUsage(cUsage);
12888
+ setActiveView("budgetView");
12889
+ };
12890
+ run();
12891
+ } else {
12892
+ setMessages((prev) => {
12893
+ setCompletedIndex(prev.length + 1);
12894
+ return [...prev, { id: Date.now(), role: "system", text: `Usage: /budget <Set|View>`, isMeta: true }];
12895
+ });
12896
+ }
12897
+ break;
12898
+ }
12826
12899
  case "/fluxflow": {
12827
12900
  const args2 = parts.slice(1);
12828
12901
  if (args2[0] === "init") {
@@ -13569,7 +13642,10 @@ Selection: ${val}`,
13569
13642
  } else if (percent > 80) {
13570
13643
  barColor = "red";
13571
13644
  }
13572
- return /* @__PURE__ */ React14.createElement(Box14, { flexDirection: "row", paddingLeft: 4, key: label }, /* @__PURE__ */ React14.createElement(Box14, { width: 18 }, /* @__PURE__ */ React14.createElement(Text14, { color: "gray" }, label, ": ")), /* @__PURE__ */ React14.createElement(Text14, { color: barColor }, barStr), /* @__PURE__ */ React14.createElement(Text14, { color: "gray" }, " ", percent, "% (", current, "/", limit >= 99999999 ? "\u221E" : limit, ")"));
13645
+ const isTokens = label.toLowerCase().includes("token");
13646
+ const displayLimit = shouldClearValue(limit) ? "\u221E" : isTokens ? formatTokens(limit) : limit;
13647
+ const displayCurrent = isTokens ? formatTokens(current) : current;
13648
+ return /* @__PURE__ */ React14.createElement(Box14, { flexDirection: "row", paddingLeft: 4, key: label }, /* @__PURE__ */ React14.createElement(Box14, { width: 18 }, /* @__PURE__ */ React14.createElement(Text14, { color: "gray" }, label, ": ")), /* @__PURE__ */ React14.createElement(Text14, { color: barColor }, barStr), /* @__PURE__ */ React14.createElement(Text14, { color: "gray" }, " ", percent, "% (", displayCurrent, "/", displayLimit, ")"));
13573
13649
  };
13574
13650
  const renderActiveView = () => {
13575
13651
  switch (activeView) {
@@ -13683,19 +13759,19 @@ Selection: ${val}`,
13683
13759
  label: "Enter Agent daily budget (requests made):",
13684
13760
  key: "quotas",
13685
13761
  subKey: "agentLimit",
13686
- value: quotas.agentLimit >= 99999999 ? "" : String(quotas.agentLimit),
13762
+ value: getPrefilledValue(quotas.agentLimit),
13687
13763
  returnView: "settings",
13688
13764
  next: (newQuotas) => ({
13689
13765
  label: "Enter Agent daily budget (tokens used):",
13690
13766
  key: "quotas",
13691
13767
  subKey: "tokenLimit",
13692
- value: newQuotas.tokenLimit >= 99999999999999 || newQuotas.tokenLimit === 0 ? "" : String(newQuotas.tokenLimit),
13768
+ value: getPrefilledValue(newQuotas.tokenLimit),
13693
13769
  returnView: "settings",
13694
13770
  next: (q2) => ({
13695
13771
  label: "Enter Agent monthly budget (tokens used):",
13696
13772
  key: "quotas",
13697
13773
  subKey: "monthlyTokenLimit",
13698
- value: q2.monthlyTokenLimit >= 99999999999999 || q2.monthlyTokenLimit === 0 ? "" : String(q2.monthlyTokenLimit),
13774
+ value: getPrefilledValue(q2.monthlyTokenLimit),
13699
13775
  returnView: "resetMode"
13700
13776
  })
13701
13777
  })
@@ -13748,6 +13824,64 @@ Selection: ${val}`,
13748
13824
  onClose: () => setActiveView("apiTier")
13749
13825
  }
13750
13826
  );
13827
+ case "budgetResetMode":
13828
+ return /* @__PURE__ */ React14.createElement(
13829
+ CommandMenu,
13830
+ {
13831
+ title: "SELECT MONTHLY RESET MODE",
13832
+ items: [
13833
+ { label: "Default (Rolling 30-Day Window)", value: "Rolling" },
13834
+ { label: "Custom (Set reset day of month)", value: "Custom" },
13835
+ { label: "Back", value: "chat" }
13836
+ ],
13837
+ onSelect: (item) => {
13838
+ if (item.value === "chat" || item.value === "Back") {
13839
+ setActiveView("chat");
13840
+ return;
13841
+ }
13842
+ const selectedMode = item.value;
13843
+ const updatedQuotas = { ...quotas, resetMode: selectedMode };
13844
+ setQuotas(updatedQuotas);
13845
+ if (selectedMode === "Custom") {
13846
+ setInputConfig({
13847
+ label: "Enter monthly reset day (1-30):",
13848
+ key: "quotas",
13849
+ subKey: "resetDay",
13850
+ value: String(quotas.resetDay || 1),
13851
+ returnView: "chat"
13852
+ });
13853
+ setActiveView("input");
13854
+ } else {
13855
+ saveSettings({ apiTier, quotas: updatedQuotas });
13856
+ setActiveView("chat");
13857
+ }
13858
+ },
13859
+ onClose: () => setActiveView("chat")
13860
+ }
13861
+ );
13862
+ case "budgetView": {
13863
+ const reqCurrent = dailyUsage?.agent || 0;
13864
+ const reqLimit = quotas.agentLimit || 99999999;
13865
+ const tokenCurrent = dailyUsage?.tokens || 0;
13866
+ const tokenLimit = quotas.tokenLimit || 99999999999999;
13867
+ const monthlyCurrent = quotas.resetMode === "Custom" ? customPeriodUsage?.tokens || 0 : monthlyUsage?.tokens || 0;
13868
+ const monthlyLimit = quotas.monthlyTokenLimit || 99999999999999;
13869
+ const isFreeTier = apiTier !== "Paid";
13870
+ const limitsNotSet = isFreeTier && (shouldClearValue(reqLimit) || shouldClearValue(tokenLimit) || shouldClearValue(monthlyLimit));
13871
+ let resetInfo = "";
13872
+ if (quotas.resetMode === "Custom") {
13873
+ const today = /* @__PURE__ */ new Date();
13874
+ const resetDay = quotas.resetDay || 1;
13875
+ let resetMonth = today.getMonth();
13876
+ if (today.getDate() >= resetDay) {
13877
+ resetMonth += 1;
13878
+ }
13879
+ const resetDate = new Date(today.getFullYear(), resetMonth, resetDay);
13880
+ const monthName = resetDate.toLocaleString("default", { month: "short" });
13881
+ resetInfo = `Resets on: ${resetDay}-${monthName}`;
13882
+ }
13883
+ return /* @__PURE__ */ React14.createElement(Box14, { flexDirection: "column", borderStyle: "round", borderColor: "white", padding: 1, width: "100%" }, /* @__PURE__ */ React14.createElement(Box14, { marginBottom: 1, justifyContent: "space-between", width: "100%" }, /* @__PURE__ */ React14.createElement(Text14, { color: "white", bold: true, underline: true }, "BUDGET LIMIT STATUS", isFreeTier ? " (Isn't it fun to see numbers go BRRRR)" : ""), /* @__PURE__ */ React14.createElement(Text14, { color: "gray" }, "[ ESC to Close ]")), limitsNotSet ? /* @__PURE__ */ React14.createElement(Box14, { padding: 1, justifyContent: "center", alignItems: "center", width: "100%" }, /* @__PURE__ */ React14.createElement(Text14, { color: "yellow", bold: true }, "LIMITS NOT SET")) : /* @__PURE__ */ React14.createElement(Box14, { flexDirection: "column", borderStyle: "single", borderColor: "gray", paddingX: 1, width: "100%" }, renderProgressBar("Daily Requests", reqCurrent, reqLimit, "cyan"), renderProgressBar("Daily Tokens", tokenCurrent, tokenLimit, "green"), renderProgressBar("Monthly Tokens", monthlyCurrent, monthlyLimit, "yellow"), resetInfo ? /* @__PURE__ */ React14.createElement(Box14, { marginLeft: 4, marginTop: 1 }, /* @__PURE__ */ React14.createElement(Text14, { color: "gray" }, "Monthly Reset : "), /* @__PURE__ */ React14.createElement(Text14, { color: "magenta", bold: true }, resetInfo)) : /* @__PURE__ */ React14.createElement(Box14, { marginLeft: 4, marginTop: 1 }, /* @__PURE__ */ React14.createElement(Text14, { color: "gray" }, "Monthly Reset : "), /* @__PURE__ */ React14.createElement(Text14, { color: "blue", bold: true }, "Rolling 30-Day Window"))));
13884
+ }
13751
13885
  case "input":
13752
13886
  return /* @__PURE__ */ React14.createElement(Box14, { flexDirection: "column", borderStyle: "round", borderColor: "white", padding: 0, width: "100%" }, /* @__PURE__ */ React14.createElement(Box14, { paddingX: 1 }, /* @__PURE__ */ React14.createElement(Text14, { color: "white", bold: true }, "DATA CONFIGURATION")), inputConfig?.note && /* @__PURE__ */ React14.createElement(Box14, { paddingX: 1, marginBottom: 1 }, /* @__PURE__ */ React14.createElement(Text14, { color: "gray", italic: true }, inputConfig.note)), /* @__PURE__ */ React14.createElement(Box14, { paddingX: 1, flexDirection: "row" }, /* @__PURE__ */ React14.createElement(Text14, { color: "white", bold: true }, inputConfig?.label, " "), /* @__PURE__ */ React14.createElement(
13753
13887
  TextInput4,
@@ -14309,7 +14443,7 @@ Selection: ${val}`,
14309
14443
  setSetupStep(1);
14310
14444
  }
14311
14445
  }
14312
- ))) : /* @__PURE__ */ React14.createElement(React14.Fragment, null, /* @__PURE__ */ React14.createElement(Text14, { color: "white" }, "Please enter your ", aiProvider, " API Key to initialize the agent (If billing is enabled set Tier to paid in /settings \u2192 other \u2192 API Tier)."), /* @__PURE__ */ React14.createElement(Box14, { marginTop: 1 }, /* @__PURE__ */ React14.createElement(Text14, { color: "gray", bold: true }, " ", ">", " "), /* @__PURE__ */ React14.createElement(
14446
+ ))) : /* @__PURE__ */ React14.createElement(React14.Fragment, null, /* @__PURE__ */ React14.createElement(Text14, { color: "white" }, "Please enter your ", aiProvider, " API Key to initialize the agent (If billing is enabled set budgets in /settings \u2192 Others \u2192 Budgets to avoid runaway spending)."), /* @__PURE__ */ React14.createElement(Box14, { marginTop: 1 }, /* @__PURE__ */ React14.createElement(Text14, { color: "gray", bold: true }, " ", ">", " "), /* @__PURE__ */ React14.createElement(
14313
14447
  TextInput4,
14314
14448
  {
14315
14449
  value: tempKey,
@@ -14403,7 +14537,7 @@ Selection: ${val}`,
14403
14537
  return /* @__PURE__ */ React14.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__ */ React14.createElement(Box14, { marginBottom: 1 }, /* @__PURE__ */ React14.createElement(Text14, { bold: true }, gradient2(["blue", "purple"])("Agent powering down. Goodbye!"))), /* @__PURE__ */ React14.createElement(Box14, { flexDirection: "column" }, /* @__PURE__ */ React14.createElement(Text14, { color: "white", bold: true, underline: true }, "Interaction Summary"), /* @__PURE__ */ React14.createElement(Box14, { marginTop: 1 }, /* @__PURE__ */ React14.createElement(Box14, { width: 20 }, /* @__PURE__ */ React14.createElement(Text14, { color: "blue" }, "Session ID:")), /* @__PURE__ */ React14.createElement(Text14, { color: "white" }, chatId)), /* @__PURE__ */ React14.createElement(Box14, null, /* @__PURE__ */ React14.createElement(Box14, { width: 20 }, /* @__PURE__ */ React14.createElement(Text14, { color: "blue" }, "Tool Calls:")), /* @__PURE__ */ React14.createElement(Text14, { color: "white" }, sessionToolSuccess + sessionToolFailure + sessionToolDenied, " ( ", /* @__PURE__ */ React14.createElement(Text14, { color: "green" }, "\u2713 ", sessionToolSuccess), " ", /* @__PURE__ */ React14.createElement(Text14, { color: "yellow" }, "\u2298 ", sessionToolDenied), " ", /* @__PURE__ */ React14.createElement(Text14, { color: "red" }, "\u2715 ", sessionToolFailure), " )")), /* @__PURE__ */ React14.createElement(Box14, null, /* @__PURE__ */ React14.createElement(Box14, { width: 20 }, /* @__PURE__ */ React14.createElement(Text14, { color: "blue" }, "Success Rate:")), /* @__PURE__ */ React14.createElement(Text14, { color: "white" }, successRate, "%")), /* @__PURE__ */ React14.createElement(Box14, null, /* @__PURE__ */ React14.createElement(Box14, { width: 20 }, /* @__PURE__ */ React14.createElement(Text14, { color: "blue" }, "Code Changes:")), /* @__PURE__ */ React14.createElement(Text14, { color: "white" }, /* @__PURE__ */ React14.createElement(Text14, { color: "green" }, "+", linesAdded), " ", /* @__PURE__ */ React14.createElement(Text14, { color: "red" }, "-", linesRemoved))), /* @__PURE__ */ React14.createElement(Box14, null, /* @__PURE__ */ React14.createElement(Box14, { width: 20 }, /* @__PURE__ */ React14.createElement(Text14, { color: "blue" }, "Tokens Consumed:")), /* @__PURE__ */ React14.createElement(Text14, { color: "white" }, formatTokens(sessionTotalTokens))), sessionTotalTokens > 0 && /* @__PURE__ */ React14.createElement(React14.Fragment, null, /* @__PURE__ */ React14.createElement(Box14, { marginLeft: 2 }, /* @__PURE__ */ React14.createElement(Box14, { width: 18 }, /* @__PURE__ */ React14.createElement(Text14, { color: "grey" }, "\xBB Input Tokens:")), /* @__PURE__ */ React14.createElement(Text14, { color: "white" }, formatTokens(sessionTotalTokens - sessionTotalCandidateTokens))), sessionTotalCachedTokens > 0 && /* @__PURE__ */ React14.createElement(Box14, { marginLeft: 4 }, /* @__PURE__ */ React14.createElement(Box14, { width: 16 }, /* @__PURE__ */ React14.createElement(Text14, { color: "grey" }, "\xBB Cached:")), /* @__PURE__ */ React14.createElement(Text14, { color: "white" }, formatTokens(sessionTotalCachedTokens))), sessionTotalCandidateTokens > 0 && /* @__PURE__ */ React14.createElement(Box14, { marginLeft: 2 }, /* @__PURE__ */ React14.createElement(Box14, { width: 18 }, /* @__PURE__ */ React14.createElement(Text14, { color: "grey" }, "\xBB Output Tokens:")), /* @__PURE__ */ React14.createElement(Text14, { color: "white" }, formatTokens(sessionTotalCandidateTokens)))), sessionImageCount > 0 && /* @__PURE__ */ React14.createElement(React14.Fragment, null, /* @__PURE__ */ React14.createElement(Box14, null, /* @__PURE__ */ React14.createElement(Box14, { width: 20 }, /* @__PURE__ */ React14.createElement(Text14, { color: "blue" }, "Images Made:")), /* @__PURE__ */ React14.createElement(Text14, { color: "white" }, sessionImageCount)), /* @__PURE__ */ React14.createElement(Box14, null, /* @__PURE__ */ React14.createElement(Box14, { width: 20 }, /* @__PURE__ */ React14.createElement(Text14, { color: "blue" }, "Image Credits:")), /* @__PURE__ */ React14.createElement(Text14, { color: "white" }, Number(((sessionImageCredits || 0) * 1e3).toFixed(0)), " credits")))), /* @__PURE__ */ React14.createElement(Box14, { flexDirection: "column", marginTop: 1 }, /* @__PURE__ */ React14.createElement(Text14, { color: "white", bold: true, underline: true }, "Performance"), /* @__PURE__ */ React14.createElement(Box14, { marginTop: 1 }, /* @__PURE__ */ React14.createElement(Box14, { width: 20 }, /* @__PURE__ */ React14.createElement(Text14, { color: "blue" }, "Wall Time:")), /* @__PURE__ */ React14.createElement(Text14, { color: "white" }, formatMsDuration(wallTimeMs))), /* @__PURE__ */ React14.createElement(Box14, null, /* @__PURE__ */ React14.createElement(Box14, { width: 20 }, /* @__PURE__ */ React14.createElement(Text14, { color: "blue" }, "Agent Active:")), /* @__PURE__ */ React14.createElement(Text14, { color: "white" }, formatMsDuration(agentActiveMs))), /* @__PURE__ */ React14.createElement(Box14, { marginLeft: 2 }, /* @__PURE__ */ React14.createElement(Box14, { width: 18 }, /* @__PURE__ */ React14.createElement(Text14, { color: "grey" }, "\xBB API Time:")), /* @__PURE__ */ React14.createElement(Text14, { color: "white" }, formatMsDuration(sessionApiTime), " (", apiPercent, "%)")), /* @__PURE__ */ React14.createElement(Box14, { marginLeft: 2 }, /* @__PURE__ */ React14.createElement(Box14, { width: 18 }, /* @__PURE__ */ React14.createElement(Text14, { color: "grey" }, "\xBB Tool Time:")), /* @__PURE__ */ React14.createElement(Text14, { color: "white" }, formatMsDuration(sessionToolTime), " (", toolPercent, "%)"))));
14404
14538
  })())));
14405
14539
  }
14406
- var getIDEName, getIDEDirName, getKeybindingsPath, parseJsonc, hasShiftEnterBinding, getPromoOptions, BridgePromo, SESSION_START_TIME, CHANGELOG_URL, DOCS_URL, linesAdded, linesRemoved, packageJsonPath, packageJson, versionFluxflow, updatedOn, ResolutionModal, parseAgentText, getProjectFiles, cachedShortcut;
14540
+ 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;
14407
14541
  var init_app = __esm({
14408
14542
  async "src/app.jsx"() {
14409
14543
  init_MultilineInput();
@@ -14434,6 +14568,16 @@ var init_app = __esm({
14434
14568
  init_setup();
14435
14569
  init_text();
14436
14570
  init_editor();
14571
+ shouldClearValue = (val) => {
14572
+ const s = String(val);
14573
+ return s.startsWith("999") && s.endsWith("9");
14574
+ };
14575
+ getPrefilledValue = (val) => {
14576
+ if (val === void 0 || val === null || val === 0 || shouldClearValue(val)) {
14577
+ return "";
14578
+ }
14579
+ return String(val);
14580
+ };
14437
14581
  getIDEName = () => {
14438
14582
  const termProgram = (process.env.TERM_PROGRAM || "").toLowerCase();
14439
14583
  if (process.env.WT_SESSION) return "Windows Terminal";
@@ -14714,6 +14858,7 @@ if (isBundled && !process.execArgv.some((arg) => arg.includes("max-old-space-siz
14714
14858
  /chats List all chat sessions
14715
14859
  /btw <question> Send raw inquiry to the agent mid-turn
14716
14860
  /image setup key <default|custom> Configure image API key strategy
14861
+ /budget Set or View budget limits
14717
14862
  /image setup quality <low...premium> Configure default image generation quality
14718
14863
  /image stats Show image quota stats
14719
14864
  /mode <flux|flow> Toggle Flux/Flow modes
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "fluxflow-cli",
3
- "version": "2.11.0",
3
+ "version": "2.11.1",
4
4
  "date": "2026-06-22",
5
5
  "description": "A high-fidelity agentic terminal assistant for the Flux Era.",
6
6
  "keywords": [