fluxflow-cli 2.10.2 → 2.11.0

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 +507 -90
  2. package/package.json +4 -3
package/dist/fluxflow.js CHANGED
@@ -1745,7 +1745,7 @@ var init_ChatLayout = __esm({
1745
1745
  const level = headingMatch[1].length;
1746
1746
  const hText = headingMatch[2];
1747
1747
  result.push(
1748
- /* @__PURE__ */ React3.createElement(Box3, { key: i, marginTop: 1, marginBottom: 1, width: "100%" }, /* @__PURE__ */ React3.createElement(Text3, { bold: true, color: level === 1 ? "cyan" : level === 2 ? "magenta" : level === 3 ? "yellow" : level === 4 ? "green" : level === 5 ? "blue" : "white", underline: true }, hText.toUpperCase()))
1748
+ /* @__PURE__ */ React3.createElement(Box3, { key: i, marginTop: 1, marginBottom: 0, width: "100%" }, /* @__PURE__ */ React3.createElement(Text3, { bold: true, color: level === 1 ? "cyan" : level === 2 ? "purple" : level === 3 ? "yellow" : level === 4 ? "green" : level === 5 ? "blue" : "white", underline: true }, hText.toUpperCase()))
1749
1749
  );
1750
1750
  return;
1751
1751
  }
@@ -1852,13 +1852,13 @@ var init_ChatLayout = __esm({
1852
1852
  const isTerminalRecord = msg.isTerminalRecord;
1853
1853
  const isHomeWarning = msg.isHomeWarning;
1854
1854
  if (isHomeWarning) {
1855
- return /* @__PURE__ */ React3.createElement(Box3, { marginBottom: 1, paddingX: 1, width: "100%" }, /* @__PURE__ */ React3.createElement(Box3, { flexDirection: "column", borderStyle: "round", borderColor: "yellow", dimColor: true, padding: 0, width: "100%" }, /* @__PURE__ */ React3.createElement(Box3, { paddingX: 1, backgroundColor: "#3a0000" }, /* @__PURE__ */ React3.createElement(Text3, { color: "white", bold: true }, msg.text)), /* @__PURE__ */ React3.createElement(Box3, { paddingX: 1, marginTop: 0, marginBottom: 0 }, /* @__PURE__ */ React3.createElement(Text3, { color: "white" }, msg.subText))));
1855
+ return /* @__PURE__ */ React3.createElement(Box3, { marginBottom: 1, paddingX: 1, width: "100%" }, /* @__PURE__ */ React3.createElement(Box3, { flexDirection: "column", borderStyle: "round", borderColor: "white", dimColor: true, padding: 0, width: "100%" }, /* @__PURE__ */ React3.createElement(Box3, { paddingX: 1 }, /* @__PURE__ */ React3.createElement(Text3, { color: "white", bold: true }, msg.text)), /* @__PURE__ */ React3.createElement(Box3, { paddingX: 1, marginTop: 0, marginBottom: 0 }, /* @__PURE__ */ React3.createElement(Text3, { color: "white" }, msg.subText))));
1856
1856
  }
1857
1857
  if (msg.isLogo) {
1858
1858
  return /* @__PURE__ */ React3.createElement(Box3, { flexDirection: "column", alignItems: "flex-start", width: "100%", marginY: 1 }, /* @__PURE__ */ React3.createElement(Text3, null, getFluxLogo(version, aiProvider)));
1859
1859
  }
1860
1860
  if (msg.id && String(msg.id).startsWith("welcome")) {
1861
- return /* @__PURE__ */ React3.createElement(Box3, { flexDirection: "column", alignItems: "center", width: "100%", marginY: 1 }, /* @__PURE__ */ React3.createElement(Box3, { borderStyle: "round", borderColor: "gray", paddingX: 3, paddingY: 0 }, /* @__PURE__ */ React3.createElement(Text3, { color: "cyan", bold: true }, msg.text.trim())));
1861
+ return /* @__PURE__ */ React3.createElement(Box3, { flexDirection: "column", alignItems: "center", width: "100%", marginY: 1 }, /* @__PURE__ */ React3.createElement(Box3, { borderStyle: "round", borderColor: "grey", paddingX: 3, paddingY: 0 }, /* @__PURE__ */ React3.createElement(Text3, { color: "white", bold: true }, msg.text.trim())));
1862
1862
  }
1863
1863
  if (msg.isVisualFeedback) {
1864
1864
  return (
@@ -1871,13 +1871,13 @@ var init_ChatLayout = __esm({
1871
1871
  }
1872
1872
  if (msg.role === "system" && msg.text?.includes("[TOOL RESULT]") && !isDiffResult && !isTerminalRecord && !isPatchError) return null;
1873
1873
  if (msg.isImageStats) {
1874
- return /* @__PURE__ */ React3.createElement(Box3, { marginBottom: 1, paddingX: 1, width: "100%" }, /* @__PURE__ */ React3.createElement(Box3, { flexDirection: "column", borderStyle: "round", borderColor: "cyan", padding: 0, width: "100%" }, /* @__PURE__ */ React3.createElement(Box3, { paddingX: 1, backgroundColor: "#0e1b21" }, /* @__PURE__ */ React3.createElement(Text3, { color: "cyan", bold: true }, "\u{1F4B3} IMAGE STATS")), /* @__PURE__ */ React3.createElement(Box3, { paddingX: 1, marginTop: 1, marginBottom: 1, flexDirection: "column" }, msg.text.split("\n").map((line, i) => /* @__PURE__ */ React3.createElement(Text3, { key: i, color: "white" }, line)))));
1874
+ return /* @__PURE__ */ React3.createElement(Box3, { marginBottom: 1, paddingX: 1, width: "100%" }, /* @__PURE__ */ React3.createElement(Box3, { flexDirection: "column", borderStyle: "round", borderColor: "grey", padding: 0, width: "100%" }, /* @__PURE__ */ React3.createElement(Box3, { paddingX: 1, backgroundColor: "#0e1b21" }, /* @__PURE__ */ React3.createElement(Text3, { color: "white", bold: true }, "IMAGE STATS")), /* @__PURE__ */ React3.createElement(Box3, { paddingX: 1, marginTop: 1, marginBottom: 1, flexDirection: "column" }, msg.text.split("\n").map((line, i) => /* @__PURE__ */ React3.createElement(Text3, { key: i, color: "grey" }, line)))));
1875
1875
  }
1876
1876
  if (msg.isAskRecord) {
1877
1877
  const selectionMatch = msg.text.match(/Selection: (.*)/);
1878
1878
  const selection = selectionMatch ? selectionMatch[1] : "No selection";
1879
1879
  const s = emojiSpace(2);
1880
- return /* @__PURE__ */ React3.createElement(Box3, { marginBottom: 0, paddingX: 1, width: "100%" }, /* @__PURE__ */ React3.createElement(Box3, { flexDirection: "column", borderStyle: "round", borderColor: "gray", padding: 0, width: "100%" }, /* @__PURE__ */ React3.createElement(Box3, { paddingX: 1 }, /* @__PURE__ */ React3.createElement(Text3, { color: "cyan", bold: true }, "\u{1F4AC} AGENT REQUEST: RESOLVED")), /* @__PURE__ */ React3.createElement(Box3, { paddingX: 1, marginTop: 1, marginBottom: 1 }, /* @__PURE__ */ React3.createElement(Text3, { color: "white" }, "Selection: ", /* @__PURE__ */ React3.createElement(Text3, { color: "yellow", bold: true }, selection)))));
1880
+ return /* @__PURE__ */ React3.createElement(Box3, { marginBottom: 0, paddingX: 1, width: "100%" }, /* @__PURE__ */ React3.createElement(Box3, { flexDirection: "column", borderStyle: "round", borderColor: "gray", padding: 0, width: "100%" }, /* @__PURE__ */ React3.createElement(Box3, { paddingX: 1 }, /* @__PURE__ */ React3.createElement(Text3, { color: "white", bold: true }, "AGENT REQUEST: RESOLVED")), /* @__PURE__ */ React3.createElement(Box3, { paddingX: 1, marginTop: 1, marginBottom: 1 }, /* @__PURE__ */ React3.createElement(Text3, { color: "white" }, "Selection: ", /* @__PURE__ */ React3.createElement(Text3, { color: "grey", bold: true }, selection)))));
1881
1881
  }
1882
1882
  if (msg.isAboutRecord) {
1883
1883
  return /* @__PURE__ */ React3.createElement(Box3, { marginBottom: 0, paddingX: 1, width: "100%" }, /* @__PURE__ */ React3.createElement(Box3, { flexDirection: "column", borderStyle: "round", borderColor: "gray", padding: 0, width: "100%" }, /* @__PURE__ */ React3.createElement(Box3, { paddingX: 1 }, /* @__PURE__ */ React3.createElement(Text3, { color: "white", bold: true }, "ABOUT FLUX FLOW")), /* @__PURE__ */ React3.createElement(Box3, { paddingX: 1, marginTop: 1, marginBottom: 1 }, /* @__PURE__ */ React3.createElement(Text3, null, msg.text))));
@@ -1913,7 +1913,7 @@ var init_ChatLayout = __esm({
1913
1913
  { cmd: "/fluxflow", desc: "Project management" },
1914
1914
  { cmd: "/update", desc: "Check/Install updates" }
1915
1915
  ];
1916
- return /* @__PURE__ */ React3.createElement(Box3, { marginBottom: 1, paddingX: 1, width: "100%" }, /* @__PURE__ */ React3.createElement(Box3, { flexDirection: "column", borderStyle: "round", borderColor: "magenta", paddingX: 2, paddingY: 1, width: "100%" }, /* @__PURE__ */ React3.createElement(Text3, { color: "magenta", bold: true, underline: true }, "\u{1F4DC} COMMAND REFERENCE"), /* @__PURE__ */ React3.createElement(Box3, { flexDirection: "column", marginTop: 1 }, commandList.map((c, i) => /* @__PURE__ */ React3.createElement(Box3, { key: i, flexDirection: "row" }, /* @__PURE__ */ React3.createElement(Box3, { width: 15 }, /* @__PURE__ */ React3.createElement(Text3, { color: "cyan", bold: true }, c.cmd)), /* @__PURE__ */ React3.createElement(Text3, { color: "gray" }, " - ", c.desc))))));
1916
+ return /* @__PURE__ */ React3.createElement(Box3, { marginBottom: 1, paddingX: 1, width: "100%" }, /* @__PURE__ */ React3.createElement(Box3, { flexDirection: "column", borderStyle: "round", borderColor: "grey", paddingX: 2, paddingY: 1, width: "100%" }, /* @__PURE__ */ React3.createElement(Text3, { color: "white", bold: true, underline: true }, "COMMAND REFERENCE"), /* @__PURE__ */ React3.createElement(Box3, { flexDirection: "column", marginTop: 1 }, commandList.map((c, i) => /* @__PURE__ */ React3.createElement(Box3, { key: i, flexDirection: "row" }, /* @__PURE__ */ React3.createElement(Box3, { width: 15 }, /* @__PURE__ */ React3.createElement(Text3, { color: "white", bold: true }, c.cmd)), /* @__PURE__ */ React3.createElement(Text3, { color: "gray" }, " - ", c.desc))))));
1917
1917
  }
1918
1918
  if (msg.isTerminalRecord) {
1919
1919
  const cmdMatch = msg.text.match(/COMMAND: (.*)/);
@@ -1993,7 +1993,7 @@ var init_StatusBar = __esm({
1993
1993
  },
1994
1994
  /* @__PURE__ */ React4.createElement(Box4, null, /* @__PURE__ */ React4.createElement(Box4, { marginRight: 1 }, /* @__PURE__ */ React4.createElement(Text4, { color: "white", bold: true }, modeIcon, " ", mode.toUpperCase())), /* @__PURE__ */ React4.createElement(Text4, { color: "gray", dimColor: true }, "\u2503 "), /* @__PURE__ */ React4.createElement(Box4, { marginX: 1 }, /* @__PURE__ */ React4.createElement(Text4, { color: "white", bold: true }, thinkingLevel.toUpperCase())), /* @__PURE__ */ React4.createElement(Text4, { color: "gray", dimColor: true }, "\u2503 "), /* @__PURE__ */ React4.createElement(Box4, { marginX: 1 }, /* @__PURE__ */ React4.createElement(Text4, { color: "gray" }, "MEM: "), /* @__PURE__ */ React4.createElement(Text4, { color: "white", bold: true }, isMemoryEnabled ? "ON" : "OFF"))),
1995
1995
  /* @__PURE__ */ React4.createElement(Box4, { flexGrow: 1, justifyContent: "center", paddingX: 2 }, /* @__PURE__ */ React4.createElement(Text4, { color: "white", italic: true }, " ", truncatePath(process.cwd(), 35))),
1996
- /* @__PURE__ */ React4.createElement(Box4, null, /* @__PURE__ */ React4.createElement(Text4, { color: "gray", dimColor: true }, "\u2503 "), /* @__PURE__ */ React4.createElement(Box4, { marginX: 1 }, /* @__PURE__ */ React4.createElement(Text4, { color: "white" }, " ", formatTokens(tokensTotal), " ", /* @__PURE__ */ React4.createElement(Text4, { dimColor: true }, (tokens / maxLimit * 100).toFixed(0), "%"))), /* @__PURE__ */ React4.createElement(Text4, { color: "gray", dimColor: true }, "\u2503 "), /* @__PURE__ */ React4.createElement(Box4, { marginLeft: 1 }, /* @__PURE__ */ React4.createElement(Text4, { color: "gray", italic: true }, " ", chatId), (apiTier === "Custom" || apiTier === "Paid") && /* @__PURE__ */ React4.createElement(Text4, { color: "gray", dimColor: true }, " | ", /* @__PURE__ */ React4.createElement(Text4, { color: "gray", bold: true }, "PAID"))))
1996
+ /* @__PURE__ */ React4.createElement(Box4, null, /* @__PURE__ */ React4.createElement(Text4, { color: "gray", dimColor: true }, "\u2503 "), /* @__PURE__ */ React4.createElement(Box4, { marginX: 1 }, /* @__PURE__ */ React4.createElement(Text4, { color: "white" }, " ", formatTokens(tokensTotal), " ", /* @__PURE__ */ React4.createElement(Text4, { dimColor: true }, (tokens / maxLimit * 100).toFixed(0), "%"))), /* @__PURE__ */ React4.createElement(Text4, { color: "gray", dimColor: true }, "\u2503 "), /* @__PURE__ */ React4.createElement(Box4, { marginLeft: 1 }, /* @__PURE__ */ React4.createElement(Text4, { color: "gray", italic: true }, " ", chatId), (apiTier === "Custom" || apiTier === "Paid") && /* @__PURE__ */ React4.createElement(Text4, { color: "white" }, " | ", /* @__PURE__ */ React4.createElement(Text4, { color: "gray", bold: true }, "CUSTOM"))))
1997
1997
  );
1998
1998
  });
1999
1999
  StatusBar_default = StatusBar;
@@ -2012,11 +2012,11 @@ function CommandMenu({ title, subtitle, items, onSelect }) {
2012
2012
  borderStyle: "round",
2013
2013
  borderColor: "white",
2014
2014
  padding: 0,
2015
- marginTop: 1,
2015
+ marginTop: 0,
2016
2016
  flexShrink: 0,
2017
2017
  width: "100%"
2018
2018
  },
2019
- /* @__PURE__ */ React5.createElement(Box5, { paddingX: 1, paddingY: 0, marginBottom: subtitle ? 0 : 1 }, /* @__PURE__ */ React5.createElement(Text5, { color: "gray", bold: true }, "\u{1F527} ", typeof title === "string" ? title.toUpperCase() : title)),
2019
+ title && /* @__PURE__ */ React5.createElement(Box5, { paddingX: 1, paddingY: 0, marginBottom: subtitle ? 0 : 1 }, /* @__PURE__ */ React5.createElement(Text5, { color: "gray", bold: true }, typeof title === "string" ? title.toUpperCase() : title)),
2020
2020
  subtitle && /* @__PURE__ */ React5.createElement(Box5, { paddingX: 1, marginBottom: 1 }, /* @__PURE__ */ React5.createElement(Text5, { color: "gray", italic: true }, " ", subtitle)),
2021
2021
  /* @__PURE__ */ React5.createElement(Box5, { flexDirection: "column", width: "100%" }, /* @__PURE__ */ React5.createElement(
2022
2022
  SelectInput,
@@ -2211,10 +2211,10 @@ var init_main_tools = __esm({
2211
2211
  };
2212
2212
  TOOL_PROTOCOL = (mode, osDetected, isMultiModal, aiProvider) => `
2213
2213
  -- TOOL DEFINITIONS --
2214
- Internal tools. MUST use the EXACT syntax '[tool:functions.ToolName(args)]'. **NEVER USE OTHER SYNTAX/MARKERS, BRACKETS SHOULD BE PROPERLY USED AS PER SCHEMA**
2214
+ Internal tools. MUST use the EXACT syntax '[tool:functions.ToolName(args)]'. **NO OTHER SYNTAX/MARKERS ALLOWED, BRACKETS SHOULD BE PROPERLY USED AS PER SCHEMA**
2215
2215
 
2216
2216
  **TOOL USAGE POLICY:**
2217
- - **MAX 3 TOOL CALLS PER TURN${mode === "Flux" ? " (EXCEPTION FOR Todo TOOL: 3+ CALLS ALLOWED)" : ""}. Next Turn, verify tool results, plan next**
2217
+ - **MAX 3 TOOL CALLS PER TURN${mode === "Flux" ? " (EXCEPTION FOR Todo TOOL: 3+ CALLS ALLOWED, Run: Limit to 2 MAX)" : ""}. Next Turn, verify tool results, plan next**
2218
2218
  ${mode === "Flux" ? "- USE multiple search & replace on patch tool if editing same file/path with many changes \u2190 **HIGHLY RECOMMENDED**\n- Tool execution denied? MUST use 'Ask' tool immediately for user reason/changes. NEVER END RESPONSE OR PROCEED BLINDLY \u2190 **MANDATORY**\n- FileMap >> ReadFile to understand file efficiently\n- Want spefific STRING across project/file? SearchKeyword >> Guessing/ReadFile\n- HUGE FILES? SearchKeyword >> FileMap/Full File read\n- **MUST MARK DONE/APPEND Todos BASED ON REALTIME TASK PROGRESS ON *EACH TURN***" : ""}
2219
2219
  ${mode === "Flux" ? "- **File Tools >> Code in chat**\n\n" : ""}- COMMUNICATION TOOLS -
2220
2220
  1. [tool:functions.Ask(question="...", optionA="option::description", ...MAX 4)]. Ambiguity Resolution. Mandatory Triggers: Path Divergence, Security, Risk Mitigation. ask >> finish. Suggest best options; don't ask for preferences
@@ -2230,7 +2230,7 @@ ${mode === "Flux" ? `- WORKSPACE TOOLS (path = relative to CWD & WILL BE FIRST A
2230
2230
  4. [tool:functions.PatchFile(path="...", replaceContent1="full line/block", newContent1="...", ...MAX 6)]. Surgical Patch. **Multiple patch on same file/path? Use replaceContent2, newContent2 etc >>> multiple spams**. Unsure? ReadFile >> guessing. **MUST VERIFY DIFF**
2231
2231
  5. [tool:functions.WriteFile(path="...", content="...")]. Creates/Overwrites. File Exist? PatchFile > WriteFile. Verify Imports
2232
2232
  6. [tool:functions.SearchKeyword(keyword="...", file="optional")]. Global project search. If 'file' is provided, searches only that file. Finds definitions/logic without reading every file. Usage: Can search for relevent lines/logic area to read specifically for edit
2233
- 7. [tool:functions.Run(command="...")]. Runs ${osDetected === "Windows" ? isPsAvailable() ? `${isPtyAvailable ? "Interactive " : ""}WINDOWS POWERSHELL ONLY` : `${isPtyAvailable ? "Interactive " : ""}WINDOWS CMD ONLY` : `${isPtyAvailable ? "Interactive " : ""}BASH`} command. Destructive/Irreversible ops -> Ask user. **TOOL DENY RULE APPLIES**. **1 CALL LIMIT FOR RUN**
2233
+ 7. [tool:functions.Run(command="...")]. Runs ${osDetected === "Windows" ? isPsAvailable() ? `${isPtyAvailable ? "Interactive " : ""}WINDOWS POWERSHELL ONLY` : `${isPtyAvailable ? "Interactive " : ""}WINDOWS CMD ONLY` : `${isPtyAvailable ? "Interactive " : ""}BASH`} command. Destructive/Irreversible ops -> Ask user
2234
2234
  8. [tool:functions.Todo(method="create/append/get", tasks=[ARRAY OF STRINGS], markDone=[ARRAY OF TASK STRINGS])]. Task List, Markdown IN ARRAY NOT ALLOWED. USAGE: ANALYZE USER REQUEST **IF** MULTIPLE TASK \u2192 BREAK DOWN TASK \u2192 CREATE TODO **BEFORE** DIVING IN. 'tasks' & 'markDone' OPTIONAL PARAMETERS WITH method 'get'. USE 'get' method WITH 'markDone' to mark task completed`.trim() : `- CREATIVE TOOLS (path = relative to CWD & WILL BE FIRST ARGUMENT, path separator: '/') -
2235
2235
  1. [tool:functions.WritePDF(path="...", content="...", orientation="...")]. PROACTIVE A4 PAGE BREAKS MUST IN CSS. HTML/CSS for PREMIUM layout
2236
2236
  2. [tool:functions.WriteDoc(path="...", content="...")]. A4 Word document
@@ -2935,7 +2935,7 @@ function SettingsMenu({
2935
2935
  case "other":
2936
2936
  return [
2937
2937
  { label: "Current Provider", value: "aiProvider", status: aiProvider },
2938
- { label: "API Tier", value: "apiTier", status: apiTier },
2938
+ { label: "API Tier", value: "apiTier", status: apiTier === "Free" ? "Provider Limits" : "Custom Budget" },
2939
2939
  { label: "Download Language Parsers", value: "parserDownload", status: "ACTION" }
2940
2940
  ];
2941
2941
  default:
@@ -3256,7 +3256,7 @@ function ProfileForm({ initialData, onSave, onCancel }) {
3256
3256
  flexDirection: "column",
3257
3257
  width: "100%"
3258
3258
  },
3259
- /* @__PURE__ */ React7.createElement(Box7, { paddingX: 1, marginBottom: 1 }, /* @__PURE__ */ React7.createElement(Text7, { color: "white", bold: true }, "\u{1F464} DEVELOPER PROFILE CONFIGURATION")),
3259
+ /* @__PURE__ */ React7.createElement(Box7, { paddingX: 1, marginBottom: 1 }, /* @__PURE__ */ React7.createElement(Text7, { color: "white", bold: true }, "DEVELOPER PROFILE CONFIGURATION")),
3260
3260
  /* @__PURE__ */ React7.createElement(Box7, { paddingX: 1, flexDirection: "column" }, /* @__PURE__ */ React7.createElement(Box7, null, /* @__PURE__ */ React7.createElement(Text7, { color: "white", bold: true }, steps[step].label), /* @__PURE__ */ React7.createElement(
3261
3261
  TextInput2,
3262
3262
  {
@@ -3314,7 +3314,7 @@ var init_AskUserModal = __esm({
3314
3314
  }
3315
3315
  )), /* @__PURE__ */ React8.createElement(Box8, { marginTop: 1, paddingX: 1, marginBottom: 1 }, /* @__PURE__ */ React8.createElement(Text8, { color: "gray", italic: true }, "(Press Enter to send)")));
3316
3316
  }
3317
- return /* @__PURE__ */ React8.createElement(Box8, { flexDirection: "column", borderStyle: "round", borderColor: "gray", padding: 0, width: "100%" }, /* @__PURE__ */ React8.createElement(Box8, { paddingX: 1, marginBottom: 1 }, /* @__PURE__ */ React8.createElement(Text8, { color: "white", bold: true }, "\u{1F4AC} AGENT REQUEST: ACTION REQUIRED")), /* @__PURE__ */ React8.createElement(Box8, { paddingX: 1, marginBottom: 1 }, /* @__PURE__ */ React8.createElement(Text8, { bold: true, color: "white" }, question)), /* @__PURE__ */ React8.createElement(Box8, { flexDirection: "column", width: "100%" }, allOptions.map((opt, idx) => {
3317
+ return /* @__PURE__ */ React8.createElement(Box8, { flexDirection: "column", borderStyle: "round", borderColor: "gray", padding: 0, width: "100%" }, /* @__PURE__ */ React8.createElement(Box8, { paddingX: 1, marginBottom: 1 }, /* @__PURE__ */ React8.createElement(Text8, { color: "white", bold: true }, "AGENT REQUEST: ACTION REQUIRED")), /* @__PURE__ */ React8.createElement(Box8, { paddingX: 1, marginBottom: 1 }, /* @__PURE__ */ React8.createElement(Text8, { bold: true, color: "white" }, question)), /* @__PURE__ */ React8.createElement(Box8, { flexDirection: "column", width: "100%" }, allOptions.map((opt, idx) => {
3318
3318
  const isSelected = idx === selectedIndex;
3319
3319
  return /* @__PURE__ */ React8.createElement(
3320
3320
  Box8,
@@ -3347,7 +3347,7 @@ Your tool syntax is: '[tool:functions.ToolName(args...)]'
3347
3347
  [tool:functions.Memory(action="temp", content="<summary of the user prompt & model responses ONLY FROM LATEST PROMPT UNDER 40 WORDS>. [Talked on: <date> <hour>]")]. Time format: YYYY-MM-DD HH am/pm
3348
3348
 
3349
3349
  ${isMemoryEnabled ? `-- User-specific long-term/permanent memory (USE BASED ON CONVERSATION CONTEXT, DO NOT RE-SAVE MEMORY WHICH IS ALREADY SAVED) --
3350
- - Add: [tool:functions.Memory(action="user", method="add", content="<string to add>. [Saved on: <date ONLY>]", score=2)] (Set score=2 ONLY if the user explicitly asked to "remember" or "save" this information, else omit this parameter entirely to default to 0.5)
3350
+ - Add: [tool:functions.Memory(action="user", method="add", content="<string to add>. [Saved on: <date ONLY>]", score=2)] (Set score=2 ONLY if the user explicitly asked to "remember" or "save" this information, else omit this parameter entirely)
3351
3351
  - Delete: [tool:functions.Memory(action="user", method="delete", id="<memory id>")]
3352
3352
  - Update: [tool:functions.Memory(action="user", method="update", content-new="string to update", id="<memory id>")]
3353
3353
 
@@ -3952,7 +3952,7 @@ var init_history = __esm({
3952
3952
  import fs8 from "fs-extra";
3953
3953
  import path7 from "path";
3954
3954
  import os3 from "os";
3955
- var getLocalBackupPath, BACKUP_FILE, generateSaveId, cachedUsage, writeTimeout, lastWriteTime, isDirty, defaultStats, purgeOldHistory, loadUsageFromFile, flushUsage, queueFlush, initUsage, forceFlushUsage, getDailyUsage, getMonthlyUsage, incrementUsage, addToUsage, checkQuota, getImageQuotaBuckets, getImageQuotaLimit, checkImageQuota, getImageQuotaStats, recordImageGeneration;
3955
+ var getLocalBackupPath, BACKUP_FILE, generateSaveId, cachedUsage, writeTimeout, lastWriteTime, isDirty, defaultStats, purgeOldHistory, loadUsageFromFile, flushUsage, queueFlush, initUsage, forceFlushUsage, getDailyUsage, getMonthlyUsage, incrementUsage, addToUsage, getCustomPeriodUsage, checkQuota, getImageQuotaBuckets, getImageQuotaLimit, checkImageQuota, getImageQuotaStats, recordImageGeneration;
3956
3956
  var init_usage = __esm({
3957
3957
  "src/utils/usage.js"() {
3958
3958
  init_paths();
@@ -4326,20 +4326,104 @@ var init_usage = __esm({
4326
4326
  }
4327
4327
  queueFlush();
4328
4328
  };
4329
+ getCustomPeriodUsage = async (resetDay = 1) => {
4330
+ const today = /* @__PURE__ */ new Date();
4331
+ const todayStr = today.toISOString().split("T")[0];
4332
+ if (!cachedUsage) {
4333
+ cachedUsage = await loadUsageFromFile();
4334
+ }
4335
+ if (cachedUsage.date !== todayStr) {
4336
+ await getDailyUsage();
4337
+ }
4338
+ let startYear = today.getFullYear();
4339
+ let startMonth = today.getMonth();
4340
+ const todayDay = today.getDate();
4341
+ if (todayDay < resetDay) {
4342
+ startMonth -= 1;
4343
+ if (startMonth < 0) {
4344
+ startMonth = 11;
4345
+ startYear -= 1;
4346
+ }
4347
+ }
4348
+ const startDate = new Date(startYear, startMonth, resetDay);
4349
+ const startDateStr = startDate.toISOString().split("T")[0];
4350
+ const history = cachedUsage.history || {};
4351
+ const todayStats = cachedUsage.stats || { ...defaultStats };
4352
+ const summed = { ...defaultStats };
4353
+ summed.imageCalls = [];
4354
+ summed.models = {};
4355
+ const addStats = (target, source) => {
4356
+ for (const key in target) {
4357
+ if (key === "imageCalls") {
4358
+ target.imageCalls = [...target.imageCalls || [], ...source.imageCalls || []];
4359
+ } else if (key === "models") {
4360
+ const srcModels = source.models || {};
4361
+ for (const provider in srcModels) {
4362
+ if (!target.models[provider]) {
4363
+ target.models[provider] = {};
4364
+ }
4365
+ for (const model in srcModels[provider]) {
4366
+ if (!target.models[provider][model]) {
4367
+ target.models[provider][model] = {
4368
+ tokens: 0,
4369
+ cachedTokens: 0,
4370
+ candidateTokens: 0
4371
+ };
4372
+ }
4373
+ const tM = target.models[provider][model];
4374
+ const sM = srcModels[provider][model];
4375
+ tM.tokens += sM.tokens || 0;
4376
+ tM.cachedTokens += sM.cachedTokens || 0;
4377
+ tM.candidateTokens += sM.candidateTokens || 0;
4378
+ }
4379
+ }
4380
+ } else if (typeof target[key] === "number") {
4381
+ target[key] += source[key] || 0;
4382
+ }
4383
+ }
4384
+ };
4385
+ addStats(summed, todayStats);
4386
+ for (const dateKey in history) {
4387
+ if (dateKey >= startDateStr && dateKey < todayStr) {
4388
+ addStats(summed, history[dateKey]);
4389
+ }
4390
+ }
4391
+ return summed;
4392
+ };
4329
4393
  checkQuota = async (key, settings) => {
4330
- const usage = await getDailyUsage();
4331
4394
  const tier = settings.apiTier || "Free";
4332
4395
  const quotas = settings.quotas || {};
4333
4396
  if (tier === "Free") {
4334
4397
  if (key === "agent" || key === "background") {
4335
- return usage.agent + usage.background < 999999;
4398
+ const daily = await getDailyUsage();
4399
+ return daily.agent + daily.background < 999999;
4336
4400
  }
4337
4401
  if (key === "search") return true;
4338
4402
  }
4339
4403
  if (tier === "Paid" || tier === "Custom") {
4340
- if (key === "agent") return usage.agent < (quotas.agentLimit || 999999);
4341
- if (key === "background") return usage.background < (quotas.backgroundLimit || 999999);
4342
- if (key === "search") return usage.search < (quotas.searchLimit || 100);
4404
+ if (key === "agent") {
4405
+ const reqLimit = quotas.agentLimit || 99999999;
4406
+ const tokenLimit = quotas.tokenLimit || 99999999999999;
4407
+ const monthlyTokenLimit = quotas.monthlyTokenLimit || 99999999999999;
4408
+ const dailyUsage = await getDailyUsage();
4409
+ const dailyOk = dailyUsage.agent < reqLimit && (dailyUsage.tokens || 0) < tokenLimit;
4410
+ if (!dailyOk) return false;
4411
+ let monthlyUsage;
4412
+ if (quotas.resetMode === "Custom") {
4413
+ monthlyUsage = await getCustomPeriodUsage(quotas.resetDay || 1);
4414
+ } else {
4415
+ monthlyUsage = await getMonthlyUsage();
4416
+ }
4417
+ return (monthlyUsage.tokens || 0) < monthlyTokenLimit;
4418
+ }
4419
+ if (key === "background") {
4420
+ const dailyUsage = await getDailyUsage();
4421
+ return dailyUsage.background < (quotas.backgroundLimit || 999999);
4422
+ }
4423
+ if (key === "search") {
4424
+ const dailyUsage = await getDailyUsage();
4425
+ return dailyUsage.search < (quotas.searchLimit || 100);
4426
+ }
4343
4427
  }
4344
4428
  return true;
4345
4429
  };
@@ -7154,16 +7238,23 @@ ${originalTextProcessed.length > USER_CONTEXT_LENGTH ? "... (truncated) ...\n\n"
7154
7238
  }
7155
7239
  }
7156
7240
  break;
7157
- } catch (janitorErr) {
7241
+ } catch (err) {
7158
7242
  attempts++;
7159
7243
  const date = (/* @__PURE__ */ new Date()).toLocaleString();
7160
7244
  if (process.stdout.isTTY) {
7161
7245
  process.stdout.write(`\x1B]0;Finalizing Error\x07`);
7162
7246
  }
7247
+ const errLog = err instanceof Error ? (() => {
7248
+ try {
7249
+ return JSON.parse(JSON.parse(err.message).error.message).error.message;
7250
+ } catch {
7251
+ return String(err);
7252
+ }
7253
+ })() : String(err);
7163
7254
  await new Promise((resolve) => setTimeout(resolve, 1e3));
7164
7255
  const janitorErrDir = path19.join(LOGS_DIR, "janitor");
7165
7256
  if (!fs20.existsSync(janitorErrDir)) fs20.mkdirSync(janitorErrDir, { recursive: true });
7166
- fs20.appendFileSync(path19.join(janitorErrDir, "error.log"), `ERROR [Attempt ${attempts}/${MAX_JANITOR_RETRIES + 1}] [${date}]: ${String(janitorErr)}
7257
+ fs20.appendFileSync(path19.join(janitorErrDir, "error.log"), `ERROR [Attempt ${attempts}/${MAX_JANITOR_RETRIES + 1}] [${date}]: ${errLog}
7167
7258
 
7168
7259
  `);
7169
7260
  if (attempts > MAX_JANITOR_RETRIES) break;
@@ -7175,7 +7266,6 @@ ${originalTextProcessed.length > USER_CONTEXT_LENGTH ? "... (truncated) ...\n\n"
7175
7266
  const janitorErrDir = path19.join(LOGS_DIR, "janitor");
7176
7267
  fs20.appendFileSync(path19.join(janitorErrDir, "error.log"), `-----------------------------------------------------------------------------
7177
7268
 
7178
-
7179
7269
  `);
7180
7270
  if (attempts >= MAX_JANITOR_RETRIES) {
7181
7271
  if (process.stdout.isTTY) {
@@ -7532,11 +7622,19 @@ ${newMemoryListStr}
7532
7622
  }
7533
7623
  }
7534
7624
  } catch (err) {
7625
+ const errLog = err instanceof Error ? (() => {
7626
+ try {
7627
+ return JSON.parse(JSON.parse(err.message).error.message).error.message;
7628
+ } catch {
7629
+ return String(err);
7630
+ }
7631
+ })() : String(err);
7632
+ ;
7535
7633
  const janitorLogDir = path19.join(LOGS_DIR, "janitor");
7536
7634
  if (!fs20.existsSync(janitorLogDir)) fs20.mkdirSync(janitorLogDir, { recursive: true });
7537
7635
  fs20.appendFileSync(
7538
7636
  path19.join(janitorLogDir, "error.log"),
7539
- `[${(/* @__PURE__ */ new Date()).toLocaleString()}] Past memory batch consolidation error: ${err.message}
7637
+ `[${(/* @__PURE__ */ new Date()).toLocaleString()}] Past memory batch consolidation error: ${errLog}
7540
7638
  `
7541
7639
  );
7542
7640
  }
@@ -8021,19 +8119,106 @@ Cursor Line: ${ideCtx.cursor_line}
8021
8119
  `;
8022
8120
  if (ideCtx.manual_edits) {
8023
8121
  let edits = ideCtx.manual_edits;
8024
- const CHAR_LIMIT = 4 * 512;
8025
- const LINE_LIMIT = 50;
8026
8122
  const lines = edits.split("\n");
8027
- if (lines.length > LINE_LIMIT) {
8028
- edits = lines.slice(0, LINE_LIMIT).join("\n") + `
8029
- ... (${lines.length - LINE_LIMIT} more lines truncated)`;
8123
+ const files = [];
8124
+ let currentFile = null;
8125
+ for (const line of lines) {
8126
+ if (!line.trim()) continue;
8127
+ if (line.startsWith(" Line ")) {
8128
+ if (currentFile) {
8129
+ currentFile.edits.push(line);
8130
+ }
8131
+ } else {
8132
+ const filePath = line.endsWith(":") ? line.slice(0, -1) : line;
8133
+ currentFile = { path: filePath, edits: [] };
8134
+ files.push(currentFile);
8135
+ }
8136
+ }
8137
+ for (const file of files) {
8138
+ if (file.edits.length > 80) {
8139
+ file.edits = file.edits.slice(-80);
8140
+ }
8141
+ file.originalEditsCount = file.edits.length;
8142
+ }
8143
+ const getSumForLimit = (limit, activeFiles2) => {
8144
+ return activeFiles2.reduce((sum, f) => {
8145
+ const isFocused = ideCtx.file_focused && (f.path === ideCtx.file_focused || path19.resolve(process.cwd(), f.path) === path19.resolve(ideCtx.file_focused));
8146
+ const fileLimit = isFocused ? Math.ceil(limit * 1.2) : limit;
8147
+ return sum + Math.min(f.edits.length, fileLimit);
8148
+ }, 0);
8149
+ };
8150
+ let chosenLimit = 80;
8151
+ if (getSumForLimit(80, files) > 300) {
8152
+ let found = false;
8153
+ for (let L = 80; L >= 10; L--) {
8154
+ if (getSumForLimit(L, files) <= 300) {
8155
+ chosenLimit = L;
8156
+ found = true;
8157
+ break;
8158
+ }
8159
+ }
8160
+ if (!found) {
8161
+ chosenLimit = 10;
8162
+ }
8163
+ }
8164
+ let activeFiles = [...files];
8165
+ if (chosenLimit === 10 && getSumForLimit(10, activeFiles) > 500) {
8166
+ while (activeFiles.length > 0 && getSumForLimit(10, activeFiles) > 500) {
8167
+ let minIndex = 0;
8168
+ let minVal = activeFiles[0].originalEditsCount;
8169
+ for (let i = 1; i < activeFiles.length; i++) {
8170
+ if (activeFiles[i].originalEditsCount < minVal) {
8171
+ minVal = activeFiles[i].originalEditsCount;
8172
+ minIndex = i;
8173
+ }
8174
+ }
8175
+ activeFiles.splice(minIndex, 1);
8176
+ }
8177
+ }
8178
+ for (const file of activeFiles) {
8179
+ const isFocused = ideCtx.file_focused && (file.path === ideCtx.file_focused || path19.resolve(process.cwd(), file.path) === path19.resolve(ideCtx.file_focused));
8180
+ const fileLimit = isFocused ? Math.ceil(chosenLimit * 1.2) : chosenLimit;
8181
+ if (file.edits.length > fileLimit) {
8182
+ file.edits = file.edits.slice(-fileLimit);
8183
+ }
8184
+ }
8185
+ for (const file of activeFiles) {
8186
+ let fileString = `${file.path}:
8187
+ ${file.edits.join("\n")}`;
8188
+ while (file.edits.length > 0 && fileString.length > 4 * 768) {
8189
+ file.edits.shift();
8190
+ fileString = `${file.path}:
8191
+ ${file.edits.join("\n")}`;
8192
+ }
8193
+ if (fileString.length > 4 * 768) {
8194
+ file.stringRepresentation = "... " + fileString.slice(-(4 * 768 - 4));
8195
+ } else {
8196
+ file.stringRepresentation = fileString;
8197
+ }
8030
8198
  }
8031
- if (edits.length > CHAR_LIMIT) {
8032
- edits = edits.substring(0, CHAR_LIMIT) + `
8033
- ... (Character limit reached, truncated)`;
8199
+ let finalEdits = activeFiles.map((f) => f.stringRepresentation).join("\n");
8200
+ while (activeFiles.length > 0 && finalEdits.length > 4 * 2048) {
8201
+ if (activeFiles[0].edits.length > 0) {
8202
+ activeFiles[0].edits.shift();
8203
+ } else {
8204
+ activeFiles.shift();
8205
+ }
8206
+ for (const file of activeFiles) {
8207
+ let fileString = `${file.path}:
8208
+ ${file.edits.join("\n")}`;
8209
+ if (fileString.length > 4 * 768) {
8210
+ file.stringRepresentation = "... " + fileString.slice(-(4 * 768 - 4));
8211
+ } else {
8212
+ file.stringRepresentation = fileString;
8213
+ }
8214
+ }
8215
+ finalEdits = activeFiles.map((f) => f.stringRepresentation).join("\n");
8216
+ }
8217
+ if (finalEdits.length > 4 * 2048) {
8218
+ finalEdits = "... " + finalEdits.slice(-(4 * 2048 - 4));
8034
8219
  }
8035
8220
  ideBlock += `Recent Manual Edits:
8036
- ${edits}
8221
+ ${finalEdits}
8037
8222
  `;
8038
8223
  }
8039
8224
  if (relOpened.length > 0) ideBlock += `All Opened Editors: ${relOpened.join(", ")}`;
@@ -9031,7 +9216,7 @@ ${ideErr} [/ERROR]`;
9031
9216
  return tokens.some((token) => checkToken(token));
9032
9217
  });
9033
9218
  if (isViolating) {
9034
- const denyMsg = `Access Denied. Terminal is prohibited from accessing system drives (C://) or external directories while "External Workspace Access" is disabled.`;
9219
+ const denyMsg = `Access Denied. Prohibited from accessing external directories while "External Workspace Access" is disabled.`;
9035
9220
  if (settings.onExecStart) settings.onExecStart(command || "Unknown");
9036
9221
  yield { type: "exec_start" };
9037
9222
  await new Promise((resolve) => setTimeout(resolve, 50));
@@ -9106,8 +9291,105 @@ ${boxBottom}` };
9106
9291
  }
9107
9292
  if (!forcePrompt && !decision) {
9108
9293
  if (systemSettings2.networkAccess === false) {
9109
- const networkCmdRegex = /\b(curl|wget|httpie|fetch|axial|yarn|npm|pnpm|bun|deno|pip|pip3|poetry|uv|gem|cargo|go\s+(get|install)|composer|nuget|ssh|scp|ping|sftp|rsync|docker|podman|kubectl|helm|git\s+(clone|push|pull|fetch)|ftp|telnet|nc|netcat|socat|traceroute|tracert|dig|nslookup|host|nmap|gcloud|aws|az|terraform|ansible-playbook|nix|nix-env)\b/i;
9110
- if (networkCmdRegex.test(cmdTrimmed)) {
9294
+ let normalized = cmdTrimmed.trim().replace(/\s+/g, " ").replace(/^['"]+|['"]+$/g, "").toLowerCase();
9295
+ const tokens = normalized.split(" ");
9296
+ const rawCmd = tokens[0];
9297
+ const cmd = rawCmd.split("/").pop().split("\\").pop().replace(/\.exe$/, "");
9298
+ const blockedCommands = /* @__PURE__ */ new Set([
9299
+ "curl",
9300
+ "wget",
9301
+ "httpie",
9302
+ "xh",
9303
+ "ssh",
9304
+ "scp",
9305
+ "sftp",
9306
+ "rsync",
9307
+ "ftp",
9308
+ "lftp",
9309
+ "tftp",
9310
+ "telnet",
9311
+ "nc",
9312
+ "netcat",
9313
+ "socat",
9314
+ "ping",
9315
+ "traceroute",
9316
+ "tracert",
9317
+ "dig",
9318
+ "nslookup",
9319
+ "host",
9320
+ "whois",
9321
+ "nmap",
9322
+ "docker",
9323
+ "podman",
9324
+ "kubectl",
9325
+ "helm",
9326
+ "gcloud",
9327
+ "aws",
9328
+ "az",
9329
+ "terraform",
9330
+ "ansible-playbook",
9331
+ "nix",
9332
+ "nix-env",
9333
+ "apt",
9334
+ "apt-get",
9335
+ "dpkg",
9336
+ "yum",
9337
+ "dnf",
9338
+ "pacman",
9339
+ "zypper",
9340
+ "brew",
9341
+ "apk",
9342
+ "choco",
9343
+ "scoop",
9344
+ "conda",
9345
+ "mamba",
9346
+ "aria2c",
9347
+ "axel",
9348
+ "smbclient",
9349
+ "lynx",
9350
+ "w3m",
9351
+ "links",
9352
+ "elinks",
9353
+ "heroku",
9354
+ "netlify",
9355
+ "vercel",
9356
+ "firebase",
9357
+ "supabase",
9358
+ "wrangler",
9359
+ "flyctl",
9360
+ "powershell",
9361
+ "pwsh",
9362
+ "certutil",
9363
+ "bitsadmin",
9364
+ "cloudflared",
9365
+ "ngrok",
9366
+ "tailscale",
9367
+ "zerotier",
9368
+ "rclone"
9369
+ ]);
9370
+ let deny = false;
9371
+ if (blockedCommands.has(cmd)) {
9372
+ deny = true;
9373
+ }
9374
+ const hasSubcmd = (list) => tokens.slice(1).some((token) => list.includes(token));
9375
+ const shouldDenyPkgManager = (dangerCommands) => {
9376
+ const dangerIdx = tokens.findIndex((t) => dangerCommands.includes(t));
9377
+ const safeIdx = tokens.findIndex((t) => ["run", "exec", "test"].includes(t));
9378
+ return dangerIdx !== -1 && !(safeIdx !== -1 && safeIdx < dangerIdx);
9379
+ };
9380
+ if (cmd === "git" && hasSubcmd(["clone", "pull", "push", "fetch"])) deny = true;
9381
+ if (cmd === "go" && hasSubcmd(["get", "install"])) deny = true;
9382
+ if (cmd === "npm" && shouldDenyPkgManager(["install", "i", "update", "add"])) deny = true;
9383
+ if (cmd === "yarn" && shouldDenyPkgManager(["add", "install", "upgrade"])) deny = true;
9384
+ if (cmd === "pnpm" && shouldDenyPkgManager(["add", "install", "update"])) deny = true;
9385
+ if (cmd === "bun" && shouldDenyPkgManager(["add", "install", "update"])) deny = true;
9386
+ if (cmd === "deno" && hasSubcmd(["install", "add"])) deny = true;
9387
+ if (cmd === "pip" && hasSubcmd(["install", "download"])) deny = true;
9388
+ if (cmd === "pip3" && hasSubcmd(["install", "download"])) deny = true;
9389
+ if (cmd === "cargo" && hasSubcmd(["install", "add"])) deny = true;
9390
+ if (["bash", "sh", "zsh", "fish"].includes(cmd) && hasSubcmd(["-c"])) deny = true;
9391
+ if (cmd === "cmd" && hasSubcmd(["/c"])) deny = true;
9392
+ if (deny) {
9111
9393
  decision = "deny";
9112
9394
  isNetworkDeny = true;
9113
9395
  }
@@ -9372,10 +9654,10 @@ ${boxBottom}` };
9372
9654
  } else if (denyReason === "network") {
9373
9655
  denyMsg = "Permission Denied: Sandbox Network Access Disabled by User Policy.";
9374
9656
  } else if (denyReason === "prohibited" && normToolName === "exec_command") {
9375
- denyMsg = "Permission Denied: Prohibited Command";
9657
+ denyMsg = "Permission Denied: Prohibited Command in User Policy";
9376
9658
  }
9377
9659
  if (normToolName === "write_file" || normToolName === "update_file") {
9378
- const action = normToolName === "write_file" ? "WRITE DENIED" : "UPDATE DENIED";
9660
+ const action = normToolName === "write_file" ? "Write Cancelled" : "Edit Denied";
9379
9661
  const deniedLabel = `\u{1F4BE} ${action}: ${parseArgs(toolCall.args).path || "..."}`.toUpperCase();
9380
9662
  let terminalWidth = 115;
9381
9663
  if (process.stdout.isTTY) {
@@ -9521,7 +9803,7 @@ ${boxBottom}` };
9521
9803
  uiTitle = "\u{1F4E5} Added Plan";
9522
9804
  listItems = normalizeList(tasks).map((item) => `\u25CB ${item}`);
9523
9805
  } else if (method === "get") {
9524
- uiTitle = markDone ? "\u{1F4CC} Updated Plan" : "\u{1F4DD} Reviewed Plan";
9806
+ uiTitle = markDone ? "\u{1F504} Updated Plan" : "\u{1F4DD} Reviewed Plan";
9525
9807
  const content = (result || "").split("\n").slice(1).join("\n");
9526
9808
  listItems = content.split("\n").filter((line) => line.trim().startsWith("- [")).map((line) => {
9527
9809
  const trimmed = line.trim();
@@ -9690,8 +9972,14 @@ ${boxBottom}` };
9690
9972
  isDedupeActive = false;
9691
9973
  dedupeBuffer = "";
9692
9974
  }
9693
- const errMsg = err.status || err.error && err.error.message || String(err);
9694
- const errLog = String(err);
9975
+ const errLog = err instanceof Error ? (() => {
9976
+ try {
9977
+ return JSON.parse(JSON.parse(err.message).error.message).error.message;
9978
+ } catch {
9979
+ return String(err);
9980
+ }
9981
+ })() : String(err);
9982
+ ;
9695
9983
  const date = (/* @__PURE__ */ new Date()).toLocaleString();
9696
9984
  const agentErrDir = path19.join(LOGS_DIR, "agent");
9697
9985
  if (!fs20.existsSync(agentErrDir)) fs20.mkdirSync(agentErrDir, { recursive: true });
@@ -9706,6 +9994,8 @@ ${boxBottom}` };
9706
9994
  if (retryCount < MAX_RETRIES - 3) {
9707
9995
  throw err;
9708
9996
  }
9997
+ yield { type: "text", content: errLog };
9998
+ yield { type: "status", content: "Error Occured" };
9709
9999
  }
9710
10000
  if (turnText.trim().length > 0 || inStreamRetryCount > 1) {
9711
10001
  if (inStreamRetryCount <= MAX_RETRIES) {
@@ -9852,11 +10142,18 @@ Error Log can be found in ${path19.join(LOGS_DIR, "agent", "error.log")}`);
9852
10142
  }
9853
10143
  });
9854
10144
  } catch (err) {
9855
- const errorMsg = err instanceof Error ? err.message : String(err);
10145
+ const errLog = err instanceof Error ? (() => {
10146
+ try {
10147
+ return JSON.parse(JSON.parse(err.message).error.message).error.message;
10148
+ } catch {
10149
+ return String(err);
10150
+ }
10151
+ })() : String(err);
9856
10152
  const date = (/* @__PURE__ */ new Date()).toLocaleString();
9857
10153
  const agentErrDir = path19.join(LOGS_DIR, "agent");
10154
+ yield { type: "text", content: `\u274C CRITICAL ERROR: ${errLog}` };
9858
10155
  if (!fs20.existsSync(agentErrDir)) fs20.mkdirSync(agentErrDir, { recursive: true });
9859
- fs20.appendFileSync(path19.join(agentErrDir, "error.log"), `CRITICAL ERROR [${date}]: ${err instanceof Error ? err.stack : err}
10156
+ fs20.appendFileSync(path19.join(agentErrDir, "error.log"), `CRITICAL ERROR [${date}]: ${errLog}
9860
10157
 
9861
10158
  ----------------------------------------------------------------------
9862
10159
 
@@ -9864,7 +10161,7 @@ Error Log can be found in ${path19.join(LOGS_DIR, "agent", "error.log")}`);
9864
10161
  if (typeof flushGoogleBuffer === "function") {
9865
10162
  yield* flushGoogleBuffer();
9866
10163
  }
9867
- yield { type: "tool_result", content: `ERROR: [INTERNAL CRITICAL] ${errorMsg}` };
10164
+ yield { type: "tool_result", content: `ERROR: [INTERNAL CRITICAL] ${errLog}` };
9868
10165
  } finally {
9869
10166
  if (connectionPollInterval) {
9870
10167
  clearInterval(connectionPollInterval);
@@ -10020,7 +10317,7 @@ function MemoryModal({ onClose }) {
10020
10317
  return "red";
10021
10318
  };
10022
10319
  const s = emojiSpace(2);
10023
- return /* @__PURE__ */ React10.createElement(Box10, { flexDirection: "column", borderStyle: "round", borderColor: "gray", padding: 0, width: "100%" }, /* @__PURE__ */ React10.createElement(Box10, { paddingX: 1, marginBottom: 1, justifyContent: "space-between" }, /* @__PURE__ */ React10.createElement(Text10, { color: "white", bold: true }, "AGENT MEMORY: LONG-TERM KNOWLEDGE"), /* @__PURE__ */ React10.createElement(Box10, null, /* @__PURE__ */ React10.createElement(Text10, { color: "gray" }, "Vault: "), /* @__PURE__ */ React10.createElement(Text10, { color: getBarColor() }, barStr), /* @__PURE__ */ React10.createElement(Text10, { color: "white", bold: true }, " ", usagePercent, "%"))), !isMemoryOn && memories.length > 0 ? /* @__PURE__ */ React10.createElement(Box10, { paddingX: 2, paddingY: 1 }, /* @__PURE__ */ React10.createElement(Text10, { italic: true, color: "gray" }, "Memory is currently Off...")) : memories.length === 0 ? /* @__PURE__ */ React10.createElement(Box10, { paddingX: 2, paddingY: 1 }, /* @__PURE__ */ React10.createElement(Text10, { italic: true, color: "gray" }, isMemoryOn ? "Learning..." : "Memory not available...")) : /* @__PURE__ */ React10.createElement(Box10, { flexDirection: "column" }, memories.map((mem, idx) => {
10320
+ return /* @__PURE__ */ React10.createElement(Box10, { flexDirection: "column", borderStyle: "round", borderColor: "gray", padding: 0, width: "100%" }, /* @__PURE__ */ React10.createElement(Box10, { paddingX: 1, marginBottom: 1, justifyContent: "space-between" }, /* @__PURE__ */ React10.createElement(Text10, { color: "white", bold: true }, "SAVED MEMORIES"), /* @__PURE__ */ React10.createElement(Box10, null, /* @__PURE__ */ React10.createElement(Text10, { color: "gray" }, "Vault: "), /* @__PURE__ */ React10.createElement(Text10, { color: getBarColor() }, barStr), /* @__PURE__ */ React10.createElement(Text10, { color: "white", bold: true }, " ", usagePercent, "%"))), !isMemoryOn && memories.length > 0 ? /* @__PURE__ */ React10.createElement(Box10, { paddingX: 2, paddingY: 1 }, /* @__PURE__ */ React10.createElement(Text10, { italic: true, color: "gray" }, "Memory is currently Off...")) : memories.length === 0 ? /* @__PURE__ */ React10.createElement(Box10, { paddingX: 2, paddingY: 1 }, /* @__PURE__ */ React10.createElement(Text10, { italic: true, color: "gray" }, isMemoryOn ? "Learning..." : "Memory not available...")) : /* @__PURE__ */ React10.createElement(Box10, { flexDirection: "column" }, memories.map((mem, idx) => {
10024
10321
  const isSelected = idx === selectedIndex;
10025
10322
  return /* @__PURE__ */ React10.createElement(
10026
10323
  Box10,
@@ -10031,7 +10328,7 @@ function MemoryModal({ onClose }) {
10031
10328
  width: "100%"
10032
10329
  },
10033
10330
  /* @__PURE__ */ React10.createElement(Box10, { flexGrow: 1 }, /* @__PURE__ */ React10.createElement(Text10, { color: isSelected ? "white" : "grey", bold: isSelected }, isSelected ? "\u276F " : " ", idx + 1, ". ", cleanDisplay(mem.memory))),
10034
- isSelected && /* @__PURE__ */ React10.createElement(Box10, { flexShrink: 0 }, /* @__PURE__ */ React10.createElement(Text10, { color: "grey", bold: true }, "[X] WIPE "))
10331
+ isSelected && /* @__PURE__ */ React10.createElement(Box10, { flexShrink: 0 }, /* @__PURE__ */ React10.createElement(Text10, { color: "grey", dimColor: true }, "[ "), " ", /* @__PURE__ */ React10.createElement(Text10, { color: "grey", dimColor: true, italic: true }, mem.score), /* @__PURE__ */ React10.createElement(Text10, { color: "grey", dimColor: true }, " ]"), /* @__PURE__ */ React10.createElement(Text10, { color: "grey", bold: true }, "[X] WIPE "))
10035
10332
  );
10036
10333
  })), /* @__PURE__ */ React10.createElement(
10037
10334
  Box10,
@@ -10703,6 +11000,7 @@ import path20 from "path";
10703
11000
  import { exec as exec2 } from "child_process";
10704
11001
  import { fileURLToPath } from "url";
10705
11002
  import TextInput4 from "ink-text-input";
11003
+ import SelectInput2 from "ink-select-input";
10706
11004
  import gradient2 from "gradient-string";
10707
11005
  function App({ args = [] }) {
10708
11006
  const [confirmExit, setConfirmExit] = useState11(false);
@@ -10969,7 +11267,7 @@ function App({ args = [] }) {
10969
11267
  };
10970
11268
  const [activeView, setActiveView] = useState11("chat");
10971
11269
  const [apiTier, setApiTier] = useState11("Free");
10972
- const [quotas, setQuotas] = useState11({ agentLimit: 999999, backgroundLimit: 999999, searchLimit: 100, customModelId: "", customLimit: 0 });
11270
+ const [quotas, setQuotas] = useState11({ limitMode: "Daily", agentLimit: 99999999, tokenLimit: 99999999999999, backgroundLimit: 999999, searchLimit: 100, customModelId: "", customLimit: 0 });
10973
11271
  const [inputConfig, setInputConfig] = useState11(null);
10974
11272
  const [systemSettings, setSystemSettings] = useState11({ memory: true, compression: 0, autoExec: false, autoDeleteHistory: "7d", autoUpdate: false, updateManager: "npm", customUpdateCommand: "" });
10975
11273
  const [profileData, setProfileData] = useState11({ name: null, nickname: null, instructions: null });
@@ -10991,6 +11289,7 @@ function App({ args = [] }) {
10991
11289
  const [sessionImageCredits, setSessionImageCredits] = useState11(0);
10992
11290
  const [dailyUsage, setDailyUsage] = useState11(null);
10993
11291
  const [monthlyUsage, setMonthlyUsage] = useState11(null);
11292
+ const [customPeriodUsage, setCustomPeriodUsage] = useState11(null);
10994
11293
  const [statsMode, setStatsMode] = useState11("daily");
10995
11294
  const [chatId, setChatId] = useState11(generateChatId());
10996
11295
  useEffect8(() => {
@@ -11001,6 +11300,19 @@ function App({ args = [] }) {
11001
11300
  });
11002
11301
  }
11003
11302
  }, [sessionTotalTokens, chatId, sessionStats.tokens]);
11303
+ useEffect8(() => {
11304
+ if (activeView === "apiTier") {
11305
+ const load = async () => {
11306
+ const d = await getDailyUsage();
11307
+ setDailyUsage(d);
11308
+ const m = await getMonthlyUsage();
11309
+ setMonthlyUsage(m);
11310
+ const c = await getCustomPeriodUsage(quotas.resetDay || 1);
11311
+ setCustomPeriodUsage(c);
11312
+ };
11313
+ load();
11314
+ }
11315
+ }, [activeView, quotas.resetDay]);
11004
11316
  const [activeCommand, setActiveCommand] = useState11(null);
11005
11317
  const [execOutput, setExecOutput] = useState11("");
11006
11318
  const [isTerminalFocused, setIsTerminalFocused] = useState11(false);
@@ -11172,18 +11484,16 @@ function App({ args = [] }) {
11172
11484
  id: "system-warning",
11173
11485
  role: "system",
11174
11486
  text: `[CRITICAL SECURITY ALERT] SYSTEM DIRECTORY DETECTED`,
11175
- subText: `You are currently in a PROTECTED SYSTEM DIRECTORY (${process.cwd()}). Operating here is EXTREMELY dangerous as the agent could accidentally corrupt your OS or installed applications. PLEASE MOVE TO A PROJECT FOLDER FOR SAFETY.`,
11176
- isHomeWarning: true,
11177
- isMeta: true
11487
+ subText: `You are currently in a PROTECTED SYSTEM DIRECTORY (${process.cwd()}). Operating here is EXTREMELY dangerous as the agent could accidentally corrupt your OS or installed applications. Open FluxFlow in project folder to work safely.`,
11488
+ isHomeWarning: true
11178
11489
  });
11179
11490
  } else if (isHomeDir) {
11180
11491
  msgs.push({
11181
11492
  id: "home-warning",
11182
11493
  role: "system",
11183
11494
  text: `[SECURITY ALERT] HOME DIRECTORY DETECTED`,
11184
- subText: `You are currently in ${os4.homedir()}. Working here is high-risk as the agent may modify system-sensitive configurations. Please move to a project folder for safety.`,
11185
- isHomeWarning: true,
11186
- isMeta: true
11495
+ subText: `You are currently in ${os4.homedir()}. Working here is high-risk as the agent may modify system-sensitive configurations. Please open FluxFlow in project folder.`,
11496
+ isHomeWarning: true
11187
11497
  });
11188
11498
  }
11189
11499
  return msgs;
@@ -11514,7 +11824,7 @@ function App({ args = [] }) {
11514
11824
  }
11515
11825
  setShowFullThinking(saved.showFullThinking);
11516
11826
  setApiTier(saved.apiTier || "Free");
11517
- setQuotas(saved.quotas || { agentLimit: 999999, backgroundLimit: 999999, searchLimit: 100, customModelId: "", customLimit: 0 });
11827
+ setQuotas(saved.quotas || { limitMode: "Daily", agentLimit: 99999999, tokenLimit: 99999999999999, backgroundLimit: 999999, searchLimit: 100, customModelId: "", customLimit: 0 });
11518
11828
  const freshSettings = {
11519
11829
  memory: true,
11520
11830
  compression: 0,
@@ -12110,7 +12420,7 @@ ${cleanText}`, color: "magenta" }];
12110
12420
  const s2 = emojiSpace(2);
12111
12421
  setMessages((prev) => {
12112
12422
  setCompletedIndex(prev.length + 1);
12113
- return [...prev, { id: "revert-empty-" + Date.now(), role: "system", text: `No revert checkpoints found for this session.`, isMeta: true }];
12423
+ return [...prev, { id: "revert-empty-" + Date.now(), role: "system", text: `Nothing to revert to.`, isMeta: true }];
12114
12424
  });
12115
12425
  }
12116
12426
  });
@@ -12468,7 +12778,7 @@ ${list || "No saved chats found."}`, isMeta: true }];
12468
12778
  } catch (err) {
12469
12779
  setMessages((prev) => {
12470
12780
  setCompletedIndex(prev.length + 1);
12471
- return [...prev, { id: Date.now(), role: "system", text: `[RESET ERROR] Failed to purge data: ${err.message}` }];
12781
+ return [...prev, { id: Date.now(), role: "system", text: `[RESET ERROR] Failed to clear data: ${err.message}` }];
12472
12782
  });
12473
12783
  }
12474
12784
  };
@@ -12652,6 +12962,13 @@ ${list || "No saved chats found."}`, isMeta: true }];
12652
12962
  });
12653
12963
  break;
12654
12964
  }
12965
+ case "/btw": {
12966
+ setMessages((prev) => {
12967
+ setCompletedIndex(prev.length + 1);
12968
+ return [...prev, { id: Date.now(), role: "system", text: `[SYSTEM] /btw only available when agent is working`, isMeta: true }];
12969
+ });
12970
+ break;
12971
+ }
12655
12972
  default:
12656
12973
  const s = emojiSpace(2);
12657
12974
  setMessages((prev) => {
@@ -13228,6 +13545,32 @@ Selection: ${val}`,
13228
13545
  useEffect8(() => {
13229
13546
  setSelectedIndex(0);
13230
13547
  }, [suggestions]);
13548
+ const CustomMenuItem = ({ label, isSelected }) => {
13549
+ const isCancel = label === "Cancel" || label === "Back" || label.toLowerCase().includes("exit") || label.toLowerCase().includes("back");
13550
+ return /* @__PURE__ */ React14.createElement(
13551
+ Box14,
13552
+ {
13553
+ marginTop: isCancel ? 1 : 0,
13554
+ backgroundColor: isSelected ? "#2a2a2a" : void 0,
13555
+ paddingX: 1,
13556
+ width: "100%"
13557
+ },
13558
+ /* @__PURE__ */ React14.createElement(Text14, { color: isSelected ? "white" : "gray", bold: isSelected }, isSelected ? "\u276F " : " ", label)
13559
+ );
13560
+ };
13561
+ const renderProgressBar = (label, current, limit) => {
13562
+ const percent = limit > 0 ? Math.min(100, Math.round(current / limit * 100)) : 0;
13563
+ const barWidth = 15;
13564
+ const filledCount = Math.round(percent / 100 * barWidth);
13565
+ const barStr = "\u2588".repeat(filledCount) + "\u2591".repeat(Math.max(0, barWidth - filledCount));
13566
+ let barColor = "gray";
13567
+ if (percent >= 40 && percent <= 80) {
13568
+ barColor = "yellow";
13569
+ } else if (percent > 80) {
13570
+ barColor = "red";
13571
+ }
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, ")"));
13573
+ };
13231
13574
  const renderActiveView = () => {
13232
13575
  switch (activeView) {
13233
13576
  case "settings":
@@ -13252,9 +13595,9 @@ Selection: ${val}`,
13252
13595
  title: "SELECT AI PROVIDER",
13253
13596
  items: [
13254
13597
  { label: "Google (Free/Paid)", value: "Google" },
13598
+ { label: "Nvidia (Free/Paid)", value: "NVIDIA" },
13255
13599
  { label: "DeepSeek (Paid)", value: "DeepSeek" },
13256
13600
  { label: "OpenRouter (Free/Paid) [EXPERIMENTAL]", value: "OpenRouter" },
13257
- { label: "NVIDIA (Free/Paid)", value: "NVIDIA" },
13258
13601
  { label: "Back", value: "settings" }
13259
13602
  ],
13260
13603
  onSelect: async (item) => {
@@ -13282,7 +13625,7 @@ Selection: ${val}`,
13282
13625
  ...prev,
13283
13626
  {
13284
13627
  role: "system",
13285
- text: `\u2705 Switched to ${selectedProvider}! Key loaded from Vault. Model set to ${defaultModel}.`,
13628
+ text: `[SYSTEM] Switched to ${selectedProvider}! Key loaded from Cache. Model set to ${defaultModel}.`,
13286
13629
  isMeta: true
13287
13630
  }
13288
13631
  ]);
@@ -13301,14 +13644,31 @@ Selection: ${val}`,
13301
13644
  onClose: () => setActiveView("settings")
13302
13645
  }
13303
13646
  );
13304
- case "apiTier":
13305
- return /* @__PURE__ */ React14.createElement(
13306
- CommandMenu,
13647
+ case "apiTier": {
13648
+ const reqCurrent = dailyUsage?.agent || 0;
13649
+ const reqLimit = quotas.agentLimit || 99999999;
13650
+ const tokenCurrent = dailyUsage?.tokens || 0;
13651
+ const tokenLimit = quotas.tokenLimit || 99999999999999;
13652
+ const monthlyCurrent = quotas.resetMode === "Custom" ? customPeriodUsage?.tokens || 0 : monthlyUsage?.tokens || 0;
13653
+ const monthlyLimit = quotas.monthlyTokenLimit || 99999999999999;
13654
+ let resetInfo = "";
13655
+ if (quotas.resetMode === "Custom") {
13656
+ const today = /* @__PURE__ */ new Date();
13657
+ const resetDay = quotas.resetDay || 1;
13658
+ let resetMonth = today.getMonth();
13659
+ if (today.getDate() >= resetDay) {
13660
+ resetMonth += 1;
13661
+ }
13662
+ const resetDate = new Date(today.getFullYear(), resetMonth, resetDay);
13663
+ const monthName = resetDate.toLocaleString("default", { month: "short" });
13664
+ resetInfo = `Resets on: ${resetDay}-${monthName}`;
13665
+ }
13666
+ return /* @__PURE__ */ React14.createElement(Box14, { flexDirection: "column", borderStyle: "round", borderColor: "white", padding: 0, width: "100%" }, /* @__PURE__ */ React14.createElement(Box14, { paddingX: 1, marginBottom: 1 }, /* @__PURE__ */ React14.createElement(Text14, { color: "gray", bold: true }, "SELECT YOUR CURRENT API TIER BASED ON YOUR PROVIDER. (Provider: ", aiProvider, ")")), /* @__PURE__ */ React14.createElement(
13667
+ SelectInput2,
13307
13668
  {
13308
- title: /* @__PURE__ */ React14.createElement(Text14, null, "SELECT YOUR CURRENT API TIER BASED ON ", /* @__PURE__ */ React14.createElement(Text14, { color: "cyan", underline: true, bold: true }, "\x1B]8;;https://aistudio.google.com/projects\x07AI STUDIO\x1B]8;;\x07"), ". (CURRENT: ", apiTier.toUpperCase(), ")"),
13309
13669
  items: [
13310
- { label: "Free Tier (Gemini API Free Tier)", value: "Free" },
13311
- { label: `Paid Tier (API with Billing Account)`, value: "Paid" },
13670
+ { label: "Provider Limits", value: "Free" },
13671
+ { label: `Set Budgets (API with Billing Account) ${apiTier === "Paid" ? "\u25CF" : ""}`, value: "Paid" },
13312
13672
  { label: "Back", value: "settings" }
13313
13673
  ],
13314
13674
  onSelect: (item) => {
@@ -13323,15 +13683,69 @@ Selection: ${val}`,
13323
13683
  label: "Enter Agent daily budget (requests made):",
13324
13684
  key: "quotas",
13325
13685
  subKey: "agentLimit",
13326
- value: String(quotas.agentLimit)
13686
+ value: quotas.agentLimit >= 99999999 ? "" : String(quotas.agentLimit),
13687
+ returnView: "settings",
13688
+ next: (newQuotas) => ({
13689
+ label: "Enter Agent daily budget (tokens used):",
13690
+ key: "quotas",
13691
+ subKey: "tokenLimit",
13692
+ value: newQuotas.tokenLimit >= 99999999999999 || newQuotas.tokenLimit === 0 ? "" : String(newQuotas.tokenLimit),
13693
+ returnView: "settings",
13694
+ next: (q2) => ({
13695
+ label: "Enter Agent monthly budget (tokens used):",
13696
+ key: "quotas",
13697
+ subKey: "monthlyTokenLimit",
13698
+ value: q2.monthlyTokenLimit >= 99999999999999 || q2.monthlyTokenLimit === 0 ? "" : String(q2.monthlyTokenLimit),
13699
+ returnView: "resetMode"
13700
+ })
13701
+ })
13327
13702
  });
13328
13703
  setActiveView("input");
13329
13704
  } else {
13330
- saveSettings({ apiTier: newTier, quotas });
13705
+ const newQuotas = { ...quotas, agentLimit: 99999999, tokenLimit: 99999999999999, monthlyTokenLimit: 99999999999999 };
13706
+ setQuotas(newQuotas);
13707
+ saveSettings({ apiTier: newTier, quotas: newQuotas });
13331
13708
  setActiveView("settings");
13332
13709
  }
13333
13710
  },
13334
- onClose: () => setActiveView("settings")
13711
+ itemComponent: CustomMenuItem,
13712
+ indicatorComponent: () => null
13713
+ }
13714
+ ), apiTier === "Paid" && /* @__PURE__ */ React14.createElement(Box14, { flexDirection: "column", marginTop: 1, borderStyle: "single", borderColor: "gray", paddingX: 1, width: "100%" }, /* @__PURE__ */ React14.createElement(Box14, { marginBottom: 1 }, /* @__PURE__ */ React14.createElement(Text14, { color: "white", bold: true }, "USAGE BUDGET STATUS")), 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"))), /* @__PURE__ */ React14.createElement(Box14, { paddingX: 1, marginTop: 1 }, /* @__PURE__ */ React14.createElement(Text14, { color: "gray", italic: true }, "(Arrows to select \u2022 Enter to confirm)")));
13715
+ }
13716
+ case "resetMode":
13717
+ return /* @__PURE__ */ React14.createElement(
13718
+ CommandMenu,
13719
+ {
13720
+ title: "SELECT MONTHLY RESET MODE",
13721
+ items: [
13722
+ { label: "Default (Rolling 30-Day Window)", value: "Rolling" },
13723
+ { label: "Custom (Set reset day of month)", value: "Custom" },
13724
+ { label: "Back", value: "apiTier" }
13725
+ ],
13726
+ onSelect: (item) => {
13727
+ if (item.value === "apiTier" || item.value === "Back") {
13728
+ setActiveView("apiTier");
13729
+ return;
13730
+ }
13731
+ const selectedMode = item.value;
13732
+ const updatedQuotas = { ...quotas, resetMode: selectedMode };
13733
+ setQuotas(updatedQuotas);
13734
+ if (selectedMode === "Custom") {
13735
+ setInputConfig({
13736
+ label: "Enter monthly reset day (1-30):",
13737
+ key: "quotas",
13738
+ subKey: "resetDay",
13739
+ value: String(quotas.resetDay || 1),
13740
+ returnView: "settings"
13741
+ });
13742
+ setActiveView("input");
13743
+ } else {
13744
+ saveSettings({ apiTier, quotas: updatedQuotas });
13745
+ setActiveView("settings");
13746
+ }
13747
+ },
13748
+ onClose: () => setActiveView("apiTier")
13335
13749
  }
13336
13750
  );
13337
13751
  case "input":
@@ -13345,7 +13759,10 @@ Selection: ${val}`,
13345
13759
  let newQuotas = { ...quotas };
13346
13760
  let newSettings = {};
13347
13761
  if (key === "quotas") {
13348
- const parsedValue = subKey.toLowerCase().includes("limit") ? parseInt(val) || 0 : val;
13762
+ let parsedValue = subKey.toLowerCase().includes("limit") || subKey === "resetDay" ? parseInt(val) || 0 : val;
13763
+ if (subKey === "resetDay") {
13764
+ parsedValue = Math.max(1, Math.min(30, parsedValue));
13765
+ }
13349
13766
  newQuotas[subKey] = parsedValue;
13350
13767
  setQuotas(newQuotas);
13351
13768
  newSettings.quotas = newQuotas;
@@ -13417,17 +13834,17 @@ Selection: ${val}`,
13417
13834
  )), /* @__PURE__ */ React14.createElement(Box14, { paddingX: 1, marginTop: 1 }, /* @__PURE__ */ React14.createElement(Text14, { color: "gray", dimColor: true, italic: true }, "(Press Enter to confirm selection)")));
13418
13835
  case "stats": {
13419
13836
  const u = statsMode === "monthly" ? monthlyUsage : dailyUsage;
13420
- const trackerTitle = statsMode === "monthly" ? "LAST 30 DAYS USAGE TRACKER" : "DAILY USAGE TRACKER";
13421
- const timeLabel = statsMode === "monthly" ? "Wall Time (30d):" : "Wall Time Today:";
13422
- const tokensLabel = statsMode === "monthly" ? "Tokens Used (30d):" : "Tokens Used Today:";
13423
- const imagesLabel = statsMode === "monthly" ? "Images Made (30d):" : "Images Made Today:";
13424
- const imageCreditsLabel = statsMode === "monthly" ? "Image Credits (30d):" : "Image Credits Today:";
13425
- const codeChangesLabel = statsMode === "monthly" ? "Code Changes (30d):" : "Code Changes Today:";
13426
- const toolCallsLabel = statsMode === "monthly" ? "Tool Calls (30d):" : "Tool Calls Today:";
13837
+ const trackerTitle = statsMode === "monthly" ? "LAST 30 DAYS USAGE" : "TODAY's USAGE";
13838
+ const timeLabel = statsMode === "monthly" ? "Wall Time:" : "Wall Time:";
13839
+ const tokensLabel = statsMode === "monthly" ? "Tokens Used:" : "Tokens Used:";
13840
+ const imagesLabel = statsMode === "monthly" ? "Images Made:" : "Images Made:";
13841
+ const imageCreditsLabel = statsMode === "monthly" ? "Image Credits:" : "Image Credits:";
13842
+ const codeChangesLabel = statsMode === "monthly" ? "Code Changes:" : "Code Changes:";
13843
+ const toolCallsLabel = statsMode === "monthly" ? "Tool Calls:" : "Tool Calls:";
13427
13844
  return /* @__PURE__ */ React14.createElement(Box14, { flexDirection: "column", borderStyle: "round", borderColor: "grey", paddingX: 3, paddingY: 1, paddingBottom: 0, width: Math.min(125, (stdout?.columns || 100) - 2) }, statsMode === "modelBreakdown" ? /* @__PURE__ */ React14.createElement(Box14, { flexDirection: "column" }, /* @__PURE__ */ React14.createElement(Text14, { color: "white", bold: true, underline: true }, "30-DAY MODEL TOKEN BREAKDOWN"), !monthlyUsage?.models || Object.keys(monthlyUsage.models).length === 0 ? /* @__PURE__ */ React14.createElement(Box14, { marginTop: 1 }, /* @__PURE__ */ React14.createElement(Text14, { color: "grey", italic: true }, "No model token usage recorded in the last 30 days.")) : Object.entries(monthlyUsage.models).map(([provider, models]) => {
13428
13845
  const providerTotalTokens = Object.values(models).reduce((sum, m) => sum + (m.tokens || 0), 0);
13429
- return /* @__PURE__ */ React14.createElement(Box14, { key: provider, flexDirection: "column", marginTop: 1 }, /* @__PURE__ */ React14.createElement(Box14, null, /* @__PURE__ */ React14.createElement(Box14, { width: 25 }, /* @__PURE__ */ React14.createElement(Text14, { color: "cyan", bold: true }, provider, ":")), /* @__PURE__ */ React14.createElement(Text14, { color: "white", bold: true }, formatTokens(providerTotalTokens))), Object.entries(models).map(([modelName, stats]) => /* @__PURE__ */ React14.createElement(Box14, { key: modelName, flexDirection: "column", marginLeft: 4 }, /* @__PURE__ */ React14.createElement(Box14, null, /* @__PURE__ */ React14.createElement(Box14, { width: 21 }, /* @__PURE__ */ React14.createElement(Text14, { color: "blue" }, "\xBB ", modelName, ":")), /* @__PURE__ */ React14.createElement(Text14, { color: "white" }, formatTokens(stats.tokens || 0))), /* @__PURE__ */ React14.createElement(Box14, { marginLeft: 4 }, /* @__PURE__ */ React14.createElement(Box14, { width: 17 }, /* @__PURE__ */ React14.createElement(Text14, { color: "grey" }, "\xBB Input Tokens:")), /* @__PURE__ */ React14.createElement(Text14, { color: "white" }, formatTokens((stats.tokens || 0) - (stats.candidateTokens || 0)))), (stats.cachedTokens || 0) > 0 && /* @__PURE__ */ React14.createElement(Box14, { marginLeft: 5 }, /* @__PURE__ */ React14.createElement(Box14, { width: 16 }, /* @__PURE__ */ React14.createElement(Text14, { color: "grey" }, "\xBB Cached:")), /* @__PURE__ */ React14.createElement(Text14, { color: "white" }, formatTokens(stats.cachedTokens))), /* @__PURE__ */ React14.createElement(Box14, { marginLeft: 4 }, /* @__PURE__ */ React14.createElement(Box14, { width: 17 }, /* @__PURE__ */ React14.createElement(Text14, { color: "grey" }, "\xBB Output Tokens:")), /* @__PURE__ */ React14.createElement(Text14, { color: "white" }, formatTokens(stats.candidateTokens || 0))))));
13430
- })) : /* @__PURE__ */ React14.createElement(React14.Fragment, null, /* @__PURE__ */ React14.createElement(Box14, { marginBottom: 1 }, /* @__PURE__ */ React14.createElement(Text14, { color: "white", bold: true, underline: true }, "SESSION TELEMETRY")), /* @__PURE__ */ React14.createElement(Box14, { flexDirection: "column" }, /* @__PURE__ */ React14.createElement(Box14, null, /* @__PURE__ */ React14.createElement(Box14, { width: 25 }, /* @__PURE__ */ React14.createElement(Text14, { color: "blue" }, "Session Duration:")), /* @__PURE__ */ React14.createElement(Text14, { color: "white" }, formatMsDuration(Date.now() - SESSION_START_TIME))), /* @__PURE__ */ React14.createElement(Box14, null, /* @__PURE__ */ React14.createElement(Box14, { width: 25 }, /* @__PURE__ */ React14.createElement(Text14, { color: "blue" }, "Agent Interactions:")), /* @__PURE__ */ React14.createElement(Text14, { color: "white" }, sessionAgentCalls)), /* @__PURE__ */ React14.createElement(Box14, { marginLeft: 2 }, /* @__PURE__ */ React14.createElement(Box14, { width: 23 }, /* @__PURE__ */ React14.createElement(Text14, { color: "grey" }, "\xBB API Time:")), /* @__PURE__ */ React14.createElement(Text14, { color: "white" }, formatMsDuration(sessionApiTime))), /* @__PURE__ */ React14.createElement(Box14, { marginLeft: 2 }, /* @__PURE__ */ React14.createElement(Box14, { width: 23 }, /* @__PURE__ */ React14.createElement(Text14, { color: "grey" }, "\xBB Tool Time:")), /* @__PURE__ */ React14.createElement(Text14, { color: "white" }, formatMsDuration(sessionToolTime))), /* @__PURE__ */ React14.createElement(Box14, null, /* @__PURE__ */ React14.createElement(Box14, { width: 25 }, /* @__PURE__ */ React14.createElement(Text14, { color: "blue" }, "Background Tasks:")), /* @__PURE__ */ React14.createElement(Text14, { color: "white" }, sessionBackgroundCalls)), /* @__PURE__ */ React14.createElement(Box14, null, /* @__PURE__ */ React14.createElement(Box14, { width: 25 }, /* @__PURE__ */ React14.createElement(Text14, { color: "blue" }, "Tokens Consumed:")), /* @__PURE__ */ React14.createElement(Text14, { color: "white" }, formatTokens(sessionTotalTokens))), /* @__PURE__ */ React14.createElement(Box14, null, /* @__PURE__ */ React14.createElement(Box14, { width: 25 }, /* @__PURE__ */ React14.createElement(Text14, { color: "blue" }, "Active Context:")), /* @__PURE__ */ React14.createElement(Text14, { color: "white" }, formatTokens(sessionStats.tokens))), sessionTotalTokens > 0 && /* @__PURE__ */ React14.createElement(React14.Fragment, null, /* @__PURE__ */ React14.createElement(Box14, { marginLeft: 2 }, /* @__PURE__ */ React14.createElement(Box14, { width: 23 }, /* @__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: 21 }, /* @__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: 23 }, /* @__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: 25 }, /* @__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: 25 }, /* @__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, null, /* @__PURE__ */ React14.createElement(Box14, { width: 25 }, /* @__PURE__ */ React14.createElement(Text14, { color: "blue" }, "Code Changes (Sess):")), /* @__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: 25 }, /* @__PURE__ */ React14.createElement(Text14, { color: "blue" }, "Tool Calls (Sess):")), /* @__PURE__ */ React14.createElement(Text14, { color: "white" }, sessionToolSuccess + sessionToolFailure + sessionToolDenied, " ( "), /* @__PURE__ */ React14.createElement(Text14, { color: "green" }, "\u2713 ", sessionToolSuccess), /* @__PURE__ */ React14.createElement(Text14, { color: "white" }, " "), /* @__PURE__ */ React14.createElement(Text14, { color: "yellow" }, "\u2298 ", sessionToolDenied), /* @__PURE__ */ React14.createElement(Text14, { color: "white" }, " "), /* @__PURE__ */ React14.createElement(Text14, { color: "red" }, "\u2715 ", sessionToolFailure), /* @__PURE__ */ React14.createElement(Text14, { color: "white" }, " )"))), /* @__PURE__ */ React14.createElement(Box14, { flexDirection: "column", marginTop: 1 }, /* @__PURE__ */ React14.createElement(Text14, { color: "white", bold: true, underline: true }, trackerTitle), /* @__PURE__ */ React14.createElement(Box14, { marginTop: 1 }, /* @__PURE__ */ React14.createElement(Box14, { width: 25 }, /* @__PURE__ */ React14.createElement(Text14, { color: "blue" }, timeLabel)), /* @__PURE__ */ React14.createElement(Text14, { color: "white" }, formatDuration(u?.duration || 0))), /* @__PURE__ */ React14.createElement(Box14, null, /* @__PURE__ */ React14.createElement(Box14, { width: 25 }, /* @__PURE__ */ React14.createElement(Text14, { color: "blue" }, "Agent Interactions:")), /* @__PURE__ */ React14.createElement(Text14, { color: "white" }, u?.agent || 0)), /* @__PURE__ */ React14.createElement(Box14, null, /* @__PURE__ */ React14.createElement(Box14, { width: 25 }, /* @__PURE__ */ React14.createElement(Text14, { color: "blue" }, "Background Tasks:")), /* @__PURE__ */ React14.createElement(Text14, { color: "white" }, u?.background || 0)), /* @__PURE__ */ React14.createElement(Box14, null, /* @__PURE__ */ React14.createElement(Box14, { width: 25 }, /* @__PURE__ */ React14.createElement(Text14, { color: "blue" }, tokensLabel)), /* @__PURE__ */ React14.createElement(Text14, { color: "white" }, formatTokens(u?.tokens || 0))), (u?.tokens || 0) > 0 && /* @__PURE__ */ React14.createElement(React14.Fragment, null, /* @__PURE__ */ React14.createElement(Box14, { marginLeft: 2 }, /* @__PURE__ */ React14.createElement(Box14, { width: 23 }, /* @__PURE__ */ React14.createElement(Text14, { color: "grey" }, "\xBB Input Tokens:")), /* @__PURE__ */ React14.createElement(Text14, { color: "white" }, formatTokens((u?.tokens || 0) - (u?.candidateTokens || 0)))), (u?.cachedTokens || 0) > 0 && /* @__PURE__ */ React14.createElement(Box14, { marginLeft: 4 }, /* @__PURE__ */ React14.createElement(Box14, { width: 21 }, /* @__PURE__ */ React14.createElement(Text14, { color: "grey" }, "\xBB Cached:")), /* @__PURE__ */ React14.createElement(Text14, { color: "white" }, formatTokens(u.cachedTokens))), (u?.candidateTokens || 0) > 0 && /* @__PURE__ */ React14.createElement(Box14, { marginLeft: 2 }, /* @__PURE__ */ React14.createElement(Box14, { width: 23 }, /* @__PURE__ */ React14.createElement(Text14, { color: "grey" }, "\xBB Output Tokens:")), /* @__PURE__ */ React14.createElement(Text14, { color: "white" }, formatTokens(u.candidateTokens)))), (u?.imageCalls?.length || 0) > 0 && /* @__PURE__ */ React14.createElement(React14.Fragment, null, /* @__PURE__ */ React14.createElement(Box14, null, /* @__PURE__ */ React14.createElement(Box14, { width: 25 }, /* @__PURE__ */ React14.createElement(Text14, { color: "blue" }, imagesLabel)), /* @__PURE__ */ React14.createElement(Text14, { color: "white" }, u.imageCalls.length)), /* @__PURE__ */ React14.createElement(Box14, null, /* @__PURE__ */ React14.createElement(Box14, { width: 25 }, /* @__PURE__ */ React14.createElement(Text14, { color: "blue" }, imageCreditsLabel)), /* @__PURE__ */ React14.createElement(Text14, { color: "white" }, Number(((u.imageCalls.reduce((sum, c) => sum + c.cost, 0) || 0) * 1e3).toFixed(0)), " credits"))), /* @__PURE__ */ React14.createElement(Box14, null, /* @__PURE__ */ React14.createElement(Box14, { width: 25 }, /* @__PURE__ */ React14.createElement(Text14, { color: "blue" }, codeChangesLabel)), /* @__PURE__ */ React14.createElement(Text14, { color: "white" }, /* @__PURE__ */ React14.createElement(Text14, { color: "green" }, "+", u?.linesAdded || 0), " ", /* @__PURE__ */ React14.createElement(Text14, { color: "red" }, "-", u?.linesRemoved || 0))), /* @__PURE__ */ React14.createElement(Box14, null, /* @__PURE__ */ React14.createElement(Box14, { width: 25 }, /* @__PURE__ */ React14.createElement(Text14, { color: "blue" }, toolCallsLabel)), /* @__PURE__ */ React14.createElement(Text14, { color: "white" }, (u?.toolSuccess || 0) + (u?.toolFailure || 0) + (u?.toolDenied || 0), " ( "), /* @__PURE__ */ React14.createElement(Text14, { color: "green" }, "\u2713 ", u?.toolSuccess || 0), /* @__PURE__ */ React14.createElement(Text14, { color: "white" }, " "), /* @__PURE__ */ React14.createElement(Text14, { color: "yellow" }, "\u2298 ", u?.toolDenied || 0), /* @__PURE__ */ React14.createElement(Text14, { color: "white" }, " "), /* @__PURE__ */ React14.createElement(Text14, { color: "red" }, "\u2715 ", u?.toolFailure || 0), /* @__PURE__ */ React14.createElement(Text14, { color: "white" }, " )")))), /* @__PURE__ */ React14.createElement(Text14, { dimColor: true, marginTop: 1, italic: true }, "(Press TAB to toggle Daily/Monthly views, SPACE for Model Breakdown, ESC to return)"));
13846
+ return /* @__PURE__ */ React14.createElement(Box14, { key: provider, flexDirection: "column", marginTop: 1 }, /* @__PURE__ */ React14.createElement(Box14, null, /* @__PURE__ */ React14.createElement(Box14, { width: 40 }, /* @__PURE__ */ React14.createElement(Text14, { color: "cyan", bold: true }, provider, ":")), /* @__PURE__ */ React14.createElement(Text14, { color: "white", bold: true }, formatTokens(providerTotalTokens))), Object.entries(models).map(([modelName, stats]) => /* @__PURE__ */ React14.createElement(Box14, { key: modelName, flexDirection: "column", marginLeft: 4, marginTop: 1 }, /* @__PURE__ */ React14.createElement(Box14, null, /* @__PURE__ */ React14.createElement(Box14, { width: 36 }, /* @__PURE__ */ React14.createElement(Text14, { color: "blue" }, "\xBB ", modelName, ":")), /* @__PURE__ */ React14.createElement(Text14, { color: "white" }, formatTokens(stats.tokens || 0))), /* @__PURE__ */ React14.createElement(Box14, { marginLeft: 4 }, /* @__PURE__ */ React14.createElement(Box14, { width: 32 }, /* @__PURE__ */ React14.createElement(Text14, { color: "grey" }, "\xBB Input Tokens:")), /* @__PURE__ */ React14.createElement(Text14, { color: "white" }, formatTokens((stats.tokens || 0) - (stats.candidateTokens || 0)))), (stats.cachedTokens || 0) > 0 && /* @__PURE__ */ React14.createElement(Box14, { marginLeft: 5 }, /* @__PURE__ */ React14.createElement(Box14, { width: 31 }, /* @__PURE__ */ React14.createElement(Text14, { color: "grey" }, "\xBB Cached:")), /* @__PURE__ */ React14.createElement(Text14, { color: "white" }, formatTokens(stats.cachedTokens))), /* @__PURE__ */ React14.createElement(Box14, { marginLeft: 4 }, /* @__PURE__ */ React14.createElement(Box14, { width: 32 }, /* @__PURE__ */ React14.createElement(Text14, { color: "grey" }, "\xBB Output Tokens:")), /* @__PURE__ */ React14.createElement(Text14, { color: "white" }, formatTokens(stats.candidateTokens || 0))))));
13847
+ })) : /* @__PURE__ */ React14.createElement(React14.Fragment, null, /* @__PURE__ */ React14.createElement(Box14, { marginBottom: 1 }, /* @__PURE__ */ React14.createElement(Text14, { color: "white", bold: true, underline: true }, "SESSION TELEMETRY")), /* @__PURE__ */ React14.createElement(Box14, { flexDirection: "column" }, /* @__PURE__ */ React14.createElement(Box14, null, /* @__PURE__ */ React14.createElement(Box14, { width: 25 }, /* @__PURE__ */ React14.createElement(Text14, { color: "blue" }, "Session Duration:")), /* @__PURE__ */ React14.createElement(Text14, { color: "white" }, formatMsDuration(Date.now() - SESSION_START_TIME))), /* @__PURE__ */ React14.createElement(Box14, null, /* @__PURE__ */ React14.createElement(Box14, { width: 25 }, /* @__PURE__ */ React14.createElement(Text14, { color: "blue" }, "Model Requests:")), /* @__PURE__ */ React14.createElement(Text14, { color: "white" }, sessionAgentCalls)), /* @__PURE__ */ React14.createElement(Box14, { marginLeft: 2 }, /* @__PURE__ */ React14.createElement(Box14, { width: 23 }, /* @__PURE__ */ React14.createElement(Text14, { color: "grey" }, "\xBB API Time:")), /* @__PURE__ */ React14.createElement(Text14, { color: "white" }, formatMsDuration(sessionApiTime))), /* @__PURE__ */ React14.createElement(Box14, { marginLeft: 2 }, /* @__PURE__ */ React14.createElement(Box14, { width: 23 }, /* @__PURE__ */ React14.createElement(Text14, { color: "grey" }, "\xBB Tool Time:")), /* @__PURE__ */ React14.createElement(Text14, { color: "white" }, formatMsDuration(sessionToolTime))), /* @__PURE__ */ React14.createElement(Box14, null, /* @__PURE__ */ React14.createElement(Box14, { width: 25 }, /* @__PURE__ */ React14.createElement(Text14, { color: "blue" }, "Memory Agent:")), /* @__PURE__ */ React14.createElement(Text14, { color: "white" }, sessionBackgroundCalls)), /* @__PURE__ */ React14.createElement(Box14, null, /* @__PURE__ */ React14.createElement(Box14, { width: 25 }, /* @__PURE__ */ React14.createElement(Text14, { color: "blue" }, "Tokens Consumed:")), /* @__PURE__ */ React14.createElement(Text14, { color: "white" }, formatTokens(sessionTotalTokens))), /* @__PURE__ */ React14.createElement(Box14, null, /* @__PURE__ */ React14.createElement(Box14, { width: 25 }, /* @__PURE__ */ React14.createElement(Text14, { color: "blue" }, "Active Context:")), /* @__PURE__ */ React14.createElement(Text14, { color: "white" }, formatTokens(sessionStats.tokens))), sessionTotalTokens > 0 && /* @__PURE__ */ React14.createElement(React14.Fragment, null, /* @__PURE__ */ React14.createElement(Box14, { marginLeft: 2 }, /* @__PURE__ */ React14.createElement(Box14, { width: 23 }, /* @__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: 21 }, /* @__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: 23 }, /* @__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: 25 }, /* @__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: 25 }, /* @__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, null, /* @__PURE__ */ React14.createElement(Box14, { width: 25 }, /* @__PURE__ */ React14.createElement(Text14, { color: "blue" }, "Code Changes (Sess):")), /* @__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: 25 }, /* @__PURE__ */ React14.createElement(Text14, { color: "blue" }, "Tool Calls (Sess):")), /* @__PURE__ */ React14.createElement(Text14, { color: "white" }, sessionToolSuccess + sessionToolFailure + sessionToolDenied, " ( "), /* @__PURE__ */ React14.createElement(Text14, { color: "green" }, "\u2713 ", sessionToolSuccess), /* @__PURE__ */ React14.createElement(Text14, { color: "white" }, " "), /* @__PURE__ */ React14.createElement(Text14, { color: "yellow" }, "\u2298 ", sessionToolDenied), /* @__PURE__ */ React14.createElement(Text14, { color: "white" }, " "), /* @__PURE__ */ React14.createElement(Text14, { color: "red" }, "\u2715 ", sessionToolFailure), /* @__PURE__ */ React14.createElement(Text14, { color: "white" }, " )"))), /* @__PURE__ */ React14.createElement(Box14, { flexDirection: "column", marginTop: 1 }, /* @__PURE__ */ React14.createElement(Text14, { color: "white", bold: true, underline: true }, trackerTitle), /* @__PURE__ */ React14.createElement(Box14, { marginTop: 1 }, /* @__PURE__ */ React14.createElement(Box14, { width: 25 }, /* @__PURE__ */ React14.createElement(Text14, { color: "blue" }, timeLabel)), /* @__PURE__ */ React14.createElement(Text14, { color: "white" }, formatDuration(u?.duration || 0))), /* @__PURE__ */ React14.createElement(Box14, null, /* @__PURE__ */ React14.createElement(Box14, { width: 25 }, /* @__PURE__ */ React14.createElement(Text14, { color: "blue" }, "Model Requests:")), /* @__PURE__ */ React14.createElement(Text14, { color: "white" }, u?.agent || 0)), /* @__PURE__ */ React14.createElement(Box14, null, /* @__PURE__ */ React14.createElement(Box14, { width: 25 }, /* @__PURE__ */ React14.createElement(Text14, { color: "blue" }, "Memory Agent:")), /* @__PURE__ */ React14.createElement(Text14, { color: "white" }, u?.background || 0)), /* @__PURE__ */ React14.createElement(Box14, null, /* @__PURE__ */ React14.createElement(Box14, { width: 25 }, /* @__PURE__ */ React14.createElement(Text14, { color: "blue" }, tokensLabel)), /* @__PURE__ */ React14.createElement(Text14, { color: "white" }, formatTokens(u?.tokens || 0))), (u?.tokens || 0) > 0 && /* @__PURE__ */ React14.createElement(React14.Fragment, null, /* @__PURE__ */ React14.createElement(Box14, { marginLeft: 2 }, /* @__PURE__ */ React14.createElement(Box14, { width: 23 }, /* @__PURE__ */ React14.createElement(Text14, { color: "grey" }, "\xBB Input Tokens:")), /* @__PURE__ */ React14.createElement(Text14, { color: "white" }, formatTokens((u?.tokens || 0) - (u?.candidateTokens || 0)))), (u?.cachedTokens || 0) > 0 && /* @__PURE__ */ React14.createElement(Box14, { marginLeft: 4 }, /* @__PURE__ */ React14.createElement(Box14, { width: 21 }, /* @__PURE__ */ React14.createElement(Text14, { color: "grey" }, "\xBB Cached:")), /* @__PURE__ */ React14.createElement(Text14, { color: "white" }, formatTokens(u.cachedTokens))), (u?.candidateTokens || 0) > 0 && /* @__PURE__ */ React14.createElement(Box14, { marginLeft: 2 }, /* @__PURE__ */ React14.createElement(Box14, { width: 23 }, /* @__PURE__ */ React14.createElement(Text14, { color: "grey" }, "\xBB Output Tokens:")), /* @__PURE__ */ React14.createElement(Text14, { color: "white" }, formatTokens(u.candidateTokens)))), (u?.imageCalls?.length || 0) > 0 && /* @__PURE__ */ React14.createElement(React14.Fragment, null, /* @__PURE__ */ React14.createElement(Box14, null, /* @__PURE__ */ React14.createElement(Box14, { width: 25 }, /* @__PURE__ */ React14.createElement(Text14, { color: "blue" }, imagesLabel)), /* @__PURE__ */ React14.createElement(Text14, { color: "white" }, u.imageCalls.length)), /* @__PURE__ */ React14.createElement(Box14, null, /* @__PURE__ */ React14.createElement(Box14, { width: 25 }, /* @__PURE__ */ React14.createElement(Text14, { color: "blue" }, imageCreditsLabel)), /* @__PURE__ */ React14.createElement(Text14, { color: "white" }, Number(((u.imageCalls.reduce((sum, c) => sum + c.cost, 0) || 0) * 1e3).toFixed(0)), " credits"))), /* @__PURE__ */ React14.createElement(Box14, null, /* @__PURE__ */ React14.createElement(Box14, { width: 25 }, /* @__PURE__ */ React14.createElement(Text14, { color: "blue" }, codeChangesLabel)), /* @__PURE__ */ React14.createElement(Text14, { color: "white" }, /* @__PURE__ */ React14.createElement(Text14, { color: "green" }, "+", u?.linesAdded || 0), " ", /* @__PURE__ */ React14.createElement(Text14, { color: "red" }, "-", u?.linesRemoved || 0))), /* @__PURE__ */ React14.createElement(Box14, null, /* @__PURE__ */ React14.createElement(Box14, { width: 25 }, /* @__PURE__ */ React14.createElement(Text14, { color: "blue" }, toolCallsLabel)), /* @__PURE__ */ React14.createElement(Text14, { color: "white" }, (u?.toolSuccess || 0) + (u?.toolFailure || 0) + (u?.toolDenied || 0), " ( "), /* @__PURE__ */ React14.createElement(Text14, { color: "green" }, "\u2713 ", u?.toolSuccess || 0), /* @__PURE__ */ React14.createElement(Text14, { color: "white" }, " "), /* @__PURE__ */ React14.createElement(Text14, { color: "yellow" }, "\u2298 ", u?.toolDenied || 0), /* @__PURE__ */ React14.createElement(Text14, { color: "white" }, " "), /* @__PURE__ */ React14.createElement(Text14, { color: "red" }, "\u2715 ", u?.toolFailure || 0), /* @__PURE__ */ React14.createElement(Text14, { color: "white" }, " )")))), /* @__PURE__ */ React14.createElement(Text14, { dimColor: true, marginTop: 1, italic: true }, "(Press TAB to toggle Daily/Monthly views, SPACE for Model Breakdown, ESC to return)"));
13431
13848
  }
13432
13849
  case "autoExecDanger":
13433
13850
  return /* @__PURE__ */ React14.createElement(Box14, { flexDirection: "column", borderStyle: "round", borderColor: "grey", paddingX: 2, paddingY: 1, width: "100%" }, /* @__PURE__ */ React14.createElement(Text14, { color: "white", bold: true, underline: true }, "SECURITY WARNING: YOLO MODE"), /* @__PURE__ */ React14.createElement(Text14, { marginTop: 1 }, "Turning this ON allows the agent to execute terminal commands automatically without requiring your approval for each step."), /* @__PURE__ */ React14.createElement(Text14, { marginTop: 1, color: "white" }, "RISKS INVOLVED:"), /* @__PURE__ */ React14.createElement(Text14, null, "\u2022 The agent may execute destructive commands (rm -rf, etc.) by mistake unless specified in sandbox rules."), /* @__PURE__ */ React14.createElement(Text14, null, "\u2022 Unintended system changes if the agent hallucinates a path or command."), /* @__PURE__ */ React14.createElement(Text14, null, "\u2022 Reduced control over the agent's step-by-step decision making."), /* @__PURE__ */ React14.createElement(Box14, { marginTop: 1 }, /* @__PURE__ */ React14.createElement(
@@ -13487,7 +13904,7 @@ Selection: ${val}`,
13487
13904
  title: "API KEY MANAGEMENT",
13488
13905
  items: [
13489
13906
  { label: "Edit Current Key (Update)", value: "edit" },
13490
- { label: "Remove Current Key (Purge)", value: "remove" },
13907
+ { label: "Remove Current Key (Delete)", value: "remove" },
13491
13908
  { label: "Cancel", value: "Cancel" }
13492
13909
  ],
13493
13910
  onSelect: (item) => {
@@ -13507,13 +13924,13 @@ Selection: ${val}`,
13507
13924
  case "deleteKey":
13508
13925
  return /* @__PURE__ */ React14.createElement(Box14, { flexDirection: "column", borderStyle: "round", borderColor: "grey", paddingX: 2, paddingY: 1 }, (() => {
13509
13926
  const s = emojiSpace(2);
13510
- return /* @__PURE__ */ React14.createElement(Text14, { color: "white", bold: true }, "DANGER: PURGE API KEY");
13511
- })(), /* @__PURE__ */ React14.createElement(Text14, { marginTop: 1 }, "This will permanently delete the saved API key from the project vault. You will need to enter it again to use Flux."), /* @__PURE__ */ React14.createElement(Box14, { marginTop: 1 }, /* @__PURE__ */ React14.createElement(
13927
+ return /* @__PURE__ */ React14.createElement(Text14, { color: "white", bold: true }, "DANGER: CLEAR CREDENTIALS");
13928
+ })(), /* @__PURE__ */ React14.createElement(Text14, { marginTop: 1 }, "This will permanently delete all saved API keys in credential cache. You will need to enter it again to use Flux."), /* @__PURE__ */ React14.createElement(Box14, { marginTop: 1 }, /* @__PURE__ */ React14.createElement(
13512
13929
  CommandMenu,
13513
13930
  {
13514
- title: "Are you absolutely sure?",
13931
+ title: "Are you sure?",
13515
13932
  items: [
13516
- { label: "YES, PURGE KEY", value: "yes" },
13933
+ { label: "YES, CLEAR CREDENTIALS", value: "yes" },
13517
13934
  { label: "NO, GO BACK", value: "no" }
13518
13935
  ],
13519
13936
  onSelect: async (item) => {
@@ -13522,7 +13939,7 @@ Selection: ${val}`,
13522
13939
  setApiKey(null);
13523
13940
  setActiveView("chat");
13524
13941
  const s = emojiSpace(2);
13525
- setMessages((prev) => [...prev, { id: Date.now(), role: "system", text: `[VAULT PURGED] API Key removed successfully.` }]);
13942
+ setMessages((prev) => [...prev, { id: Date.now(), role: "system", text: `[CREDENTIAL CLEARED] API Key removed successfully.` }]);
13526
13943
  } else {
13527
13944
  setActiveView("key");
13528
13945
  }
@@ -13878,14 +14295,14 @@ Selection: ${val}`,
13878
14295
  aiProvider,
13879
14296
  version: versionFluxflow
13880
14297
  }
13881
- ), activeCommand && /* @__PURE__ */ React14.createElement(Box14, { marginTop: 1 }, /* @__PURE__ */ React14.createElement(TerminalBox, { command: activeCommand, output: execOutput, isFocused: isTerminalFocused, isPty: isActiveCommandPty }))), isInitializing ? /* @__PURE__ */ React14.createElement(Box14, { borderStyle: "double", borderColor: "grey", padding: 1, flexShrink: 0 }, /* @__PURE__ */ React14.createElement(Text14, { color: "white" }, "Starting Flux Flow...")) : !apiKey ? /* @__PURE__ */ React14.createElement(Box14, { borderStyle: "round", borderColor: "white", padding: 0, flexDirection: "column", flexShrink: 0, width: "100%" }, /* @__PURE__ */ React14.createElement(Box14, { paddingX: 1, marginBottom: 1 }, /* @__PURE__ */ React14.createElement(Text14, { color: "gray", bold: true }, "\u{1F511}", emojiSpace(2), "API KEY REQUIRED")), /* @__PURE__ */ React14.createElement(Box14, { paddingX: 1, flexDirection: "column" }, setupStep === 0 ? /* @__PURE__ */ React14.createElement(React14.Fragment, null, /* @__PURE__ */ React14.createElement(Text14, { color: "white" }, "Select your Preferred Provider:"), /* @__PURE__ */ React14.createElement(Box14, { marginTop: 1 }, /* @__PURE__ */ React14.createElement(
14298
+ ), activeCommand && /* @__PURE__ */ React14.createElement(Box14, { marginTop: 1 }, /* @__PURE__ */ React14.createElement(TerminalBox, { command: activeCommand, output: execOutput, isFocused: isTerminalFocused, isPty: isActiveCommandPty }))), isInitializing ? /* @__PURE__ */ React14.createElement(Box14, { borderStyle: "double", borderColor: "grey", padding: 1, flexShrink: 0 }, /* @__PURE__ */ React14.createElement(Text14, { color: "white" }, "Starting Flux Flow...")) : !apiKey ? /* @__PURE__ */ React14.createElement(Box14, { borderStyle: "round", borderColor: "white", padding: 0, flexDirection: "column", flexShrink: 0, width: "100%" }, /* @__PURE__ */ React14.createElement(Box14, { paddingX: 1, marginBottom: 1 }, /* @__PURE__ */ React14.createElement(Text14, { color: "gray", bold: true }, "API KEY REQUIRED")), /* @__PURE__ */ React14.createElement(Box14, { paddingX: 1, flexDirection: "column" }, setupStep === 0 ? /* @__PURE__ */ React14.createElement(React14.Fragment, null, /* @__PURE__ */ React14.createElement(Text14, { color: "white" }, "Select your Preferred Provider:"), /* @__PURE__ */ React14.createElement(Box14, { marginTop: 1 }, /* @__PURE__ */ React14.createElement(
13882
14299
  CommandMenu,
13883
14300
  {
13884
14301
  items: [
13885
14302
  { label: "Google (Free/Paid)", value: "Google" },
14303
+ { label: "Nvidia (Free/Paid)", value: "NVIDIA" },
13886
14304
  { label: "DeepSeek (Paid)", value: "DeepSeek" },
13887
- { label: "OpenRouter (Free/Paid) [EXPERIMENTAL]", value: "OpenRouter" },
13888
- { label: "NVIDIA (Free/Paid)", value: "NVIDIA" }
14305
+ { label: "OpenRouter (Free/Paid) [EXPERIMENTAL]", value: "OpenRouter" }
13889
14306
  ],
13890
14307
  onSelect: (item) => {
13891
14308
  setAiProvider(item.value);
@@ -14360,7 +14777,7 @@ if (isBundled && !process.execArgv.some((arg) => arg.includes("max-old-space-siz
14360
14777
  const React16 = (await import("react")).default;
14361
14778
  const { useState: useState12 } = React16;
14362
14779
  const { render: render2, Box: Box15, Text: Text15 } = await import("ink");
14363
- const SelectInput2 = (await import("ink-select-input")).default;
14780
+ const SelectInput3 = (await import("ink-select-input")).default;
14364
14781
  const TextInput5 = (await import("ink-text-input")).default;
14365
14782
  return new Promise((resolve) => {
14366
14783
  const items = [
@@ -14398,7 +14815,7 @@ if (isBundled && !process.execArgv.some((arg) => arg.includes("max-old-space-siz
14398
14815
  )), /* @__PURE__ */ React16.createElement(Box15, { marginTop: 1 }, /* @__PURE__ */ React16.createElement(Text15, { color: "gray", dimColor: true, italic: true }, " (Press Enter to confirm)")));
14399
14816
  }
14400
14817
  return /* @__PURE__ */ React16.createElement(Box15, { flexDirection: "column", marginY: 1 }, /* @__PURE__ */ React16.createElement(Box15, { marginBottom: 1 }, /* @__PURE__ */ React16.createElement(Text15, { color: "magenta", bold: true }, "\u{1F4E6} Select a package manager for the update:")), /* @__PURE__ */ React16.createElement(
14401
- SelectInput2,
14818
+ SelectInput3,
14402
14819
  {
14403
14820
  items,
14404
14821
  onSelect: handleSelect,
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "fluxflow-cli",
3
- "version": "2.10.2",
4
- "date": "2026-06-20",
3
+ "version": "2.11.0",
4
+ "date": "2026-06-22",
5
5
  "description": "A high-fidelity agentic terminal assistant for the Flux Era.",
6
6
  "keywords": [
7
7
  "ai",
@@ -10,7 +10,8 @@
10
10
  "cli",
11
11
  "gemini",
12
12
  "ink",
13
- "flux"
13
+ "flux",
14
+ "fluxflow"
14
15
  ],
15
16
  "license": "MIT",
16
17
  "repository": {