fluxflow-cli 1.15.5 → 1.16.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (3) hide show
  1. package/README.md +4 -2
  2. package/dist/fluxflow.js +718 -270
  3. package/package.json +2 -2
package/dist/fluxflow.js CHANGED
@@ -138,7 +138,7 @@ var init_terminal = __esm({
138
138
  // src/components/ChatLayout.jsx
139
139
  import React2, { useState, useEffect, useRef } from "react";
140
140
  import { Box as Box2, Text as Text2 } from "ink";
141
- var TOOL_LABELS, cleanSignals, formatThinkText, parseMathSymbols, InlineMarkdown, TableRenderer, MarkdownText, DiffLine, DiffBlock, CodeRenderer, MessageItem, ChatLayout, ChatLayout_default;
141
+ var TOOL_LABELS, cleanSignals, formatThinkText, parseMathSymbols, InlineMarkdown, TableRenderer, MarkdownText, DiffLine, DiffBlock, CodeRenderer, formatThinkingDuration, MessageItem, ChatLayout, ChatLayout_default;
142
142
  var init_ChatLayout = __esm({
143
143
  "src/components/ChatLayout.jsx"() {
144
144
  init_TerminalBox();
@@ -225,7 +225,7 @@ var init_ChatLayout = __esm({
225
225
  }
226
226
  }
227
227
  }
228
- return result.replace(/^\[TOOL_RESULT\]:\s*/gi, "").split("\n").filter((line) => !line.trim().startsWith("SUCCESS:") && !line.trim().startsWith("ERROR:")).join("\n").replace(/\[\s*turn\s*:\s*(continue|finish)\s*\]/gi, "").replace(/\[\s*turn\s*:?.*?$/gi, "").replace(/\n\s*turn\s*:?.*?$/gi, "").replace(/\[\s*$/gi, "").replace(/\n\nResponded on .*/g, "").replace(/\n\n\[Prompted on: .*\]/g, "").replace(/(\$?\\?\/?\\rightarrow\$?|\$\\rightarrow\$)/gi, "\u2192").replace(/(\$?\\?\/?\\leftarrow\$?|\$\\leftarrow\$)/gi, "\u2190").replace(/(\$?\\?\/?\\uparrow\$?|\$\\uparrow\$)/gi, "\u2191").replace(/(\$?\\?\/?\\downarrow\$?|\$\\downarrow\$)/gi, "\u2193").replace(/(\$?\\?\/?\\leftrightarrow\$?|\$\\leftrightarrow\$)/gi, "\u2194").replace(/@\[TerminalName:.*?, ProcessId:.*?\]/gi, "").replace(/\b(write_file|update_file|read_folder|view_file|exec_command|web_search|web_scrape|search_keyword|write_pdf|write_docx|generate_image)\b/gi, (match) => TOOL_LABELS[match.toLowerCase()] || match).trim();
228
+ return result.replace(/\[TOOL RESULT\]:?\s*/gi, "").split("\n").filter((line) => !line.trim().startsWith("SUCCESS:") && !line.trim().startsWith("ERROR:")).join("\n").replace(/\[\s*turn\s*:\s*(continue|finish)\s*\]/gi, "").replace(/\[\s*turn\s*:?.*?$/gi, "").replace(/\n\s*turn\s*:?.*?$/gi, "").replace(/\[\s*$/gi, "").replace(/\n\nResponded on .*/g, "").replace(/\n\n\[Prompted on: .*\]/g, "").replace(/(\$?\\?\/?\\rightarrow\$?|\$\\rightarrow\$)/gi, "\u2192").replace(/(\$?\\?\/?\\leftarrow\$?|\$\\leftarrow\$)/gi, "\u2190").replace(/(\$?\\?\/?\\uparrow\$?|\$\\uparrow\$)/gi, "\u2191").replace(/(\$?\\?\/?\\downarrow\$?|\$\\downarrow\$)/gi, "\u2193").replace(/(\$?\\?\/?\\leftrightarrow\$?|\$\\leftrightarrow\$)/gi, "\u2194").replace(/@\[TerminalName:.*?, ProcessId:.*?\]/gi, "").replace(/\b(write_file|update_file|read_folder|view_file|exec_command|web_search|web_scrape|search_keyword|write_pdf|write_docx|generate_image)\b/gi, (match) => TOOL_LABELS[match.toLowerCase()] || match).trim();
229
229
  };
230
230
  formatThinkText = (cleaned, columns = 80) => {
231
231
  if (!cleaned) return null;
@@ -421,6 +421,16 @@ var init_ChatLayout = __esm({
421
421
  }
422
422
  return /* @__PURE__ */ React2.createElement(MarkdownText, { text, columns });
423
423
  });
424
+ formatThinkingDuration = (ms) => {
425
+ const totalSecs = Math.round(ms / 1e3);
426
+ if (totalSecs <= 0) return "0s";
427
+ const m = Math.floor(totalSecs / 60);
428
+ const s = totalSecs % 60;
429
+ if (m > 0) {
430
+ return `${m}m ${s}s`;
431
+ }
432
+ return `${totalSecs}s`;
433
+ };
424
434
  MessageItem = React2.memo(({ msg, showFullThinking, columns = 80 }) => {
425
435
  const isDiffResult = msg.role === "system" && (msg.text?.includes("[DIFF_START]") || msg.text?.includes("- Content Preview:"));
426
436
  const isPatchError = msg.role === "system" && msg.text?.includes("[TOOL RESULT]: ERROR:") && (msg.toolName === "update_file" || msg.text?.includes("Could not find exact match"));
@@ -520,7 +530,7 @@ var init_ChatLayout = __esm({
520
530
  finalContent.replace(/\r\n/g, "\n").replace(/\r/g, "\n").replace(/\\\n/g, "\n").replace(/\\$/, ""),
521
531
  columns - 6
522
532
  ).split("\n").map((line, lineIdx) => /* @__PURE__ */ React2.createElement(Box2, { key: lineIdx, flexDirection: "row", width: "100%" }, /* @__PURE__ */ React2.createElement(Box2, { flexShrink: 0, width: 2 }, /* @__PURE__ */ React2.createElement(Text2, { bold: true, color: "white" }, lineIdx === 0 ? "\u276F" : " ")), /* @__PURE__ */ React2.createElement(Box2, { flexGrow: 1, marginLeft: 1 }, /* @__PURE__ */ React2.createElement(Text2, { color: msg.color || "white", wrap: "anywhere" }, line))))
523
- ) : msg.role === "think" ? /* @__PURE__ */ React2.createElement(Box2, { flexDirection: "column", marginTop: 0, marginBottom: 0, paddingX: 1, width: "100%" }, /* @__PURE__ */ React2.createElement(Text2, { bold: true, color: "white" }, "Thinking..."), /* @__PURE__ */ React2.createElement(Box2, { borderStyle: "single", borderLeft: true, borderRight: false, borderTop: false, borderBottom: false, paddingLeft: 2, paddingTop: 1, paddingBottom: 1, flexDirection: "column", width: "100%" }, formatThinkText(finalContent, columns))) : /* @__PURE__ */ React2.createElement(Box2, { flexDirection: "column", paddingX: 1, marginTop: 0, width: "100%" }, /* @__PURE__ */ React2.createElement(CodeRenderer, { text: finalContent.replace(/ \|\n\n/g, " |\n"), columns }), msg.memoryUpdated && /* @__PURE__ */ React2.createElement(Box2, { marginTop: 1, width: "100%" }, /* @__PURE__ */ React2.createElement(Text2, { color: "yellow", italic: true }, "\u2728 [Memory Updated]"))))
533
+ ) : msg.role === "think" ? /* @__PURE__ */ React2.createElement(Box2, { flexDirection: "column", marginTop: 0, marginBottom: 0, paddingX: 1, width: "100%" }, msg.isStreaming && !msg.duration ? /* @__PURE__ */ React2.createElement(Text2, { bold: true, color: "white" }, "\u2727 Thinking...") : /* @__PURE__ */ React2.createElement(Text2, { bold: true, color: "white" }, "\u2726 Thought", msg.duration ? /* @__PURE__ */ React2.createElement(Text2, { dimColor: true, color: "gray" }, " for ", /* @__PURE__ */ React2.createElement(Text2, { bold: true, color: "cyan" }, formatThinkingDuration(msg.duration))) : ""), /* @__PURE__ */ React2.createElement(Box2, { borderStyle: "single", borderLeft: true, borderRight: false, borderTop: false, borderBottom: false, paddingLeft: 2, paddingTop: 1, paddingBottom: 1, flexDirection: "column", width: "100%" }, formatThinkText(finalContent, columns))) : /* @__PURE__ */ React2.createElement(Box2, { flexDirection: "column", paddingX: 1, marginTop: 0, width: "100%" }, /* @__PURE__ */ React2.createElement(CodeRenderer, { text: finalContent.replace(/ \|\n\n/g, " |\n"), columns }), msg.memoryUpdated && /* @__PURE__ */ React2.createElement(Box2, { marginTop: 1, width: "100%" }, /* @__PURE__ */ React2.createElement(Text2, { color: "yellow", italic: true }, "\u2728 [Memory Updated]"))))
524
534
  );
525
535
  });
526
536
  ChatLayout = React2.memo(({ messages, showFullThinking, columns = 80 }) => {
@@ -616,14 +626,319 @@ var init_CommandMenu = __esm({
616
626
  }
617
627
  });
618
628
 
619
- // src/components/ProfileForm.jsx
620
- import React5, { useState as useState2, useEffect as useEffect2 } from "react";
621
- import { Box as Box5, Text as Text5 } from "ink";
629
+ // src/components/SettingsMenu.jsx
630
+ import React5, { useState as useState2 } from "react";
631
+ import { Box as Box5, Text as Text5, useInput } from "ink";
622
632
  import TextInput from "ink-text-input";
633
+ function SettingsMenu({
634
+ systemSettings,
635
+ setSystemSettings,
636
+ apiTier,
637
+ setActiveView,
638
+ setInputConfig,
639
+ saveSettings: saveSettings2,
640
+ quotas,
641
+ setMessages
642
+ }) {
643
+ const [activeColumn, setActiveColumn] = useState2("categories");
644
+ const [selectedCategoryIndex, setSelectedCategoryIndex] = useState2(0);
645
+ const [selectedItemIndex, setSelectedItemIndex] = useState2(0);
646
+ const [editingItem, setEditingItem] = useState2(null);
647
+ const [editValue, setEditValue] = useState2("");
648
+ const getCategoryItems = (catId) => {
649
+ switch (catId) {
650
+ case "memory":
651
+ return [
652
+ { label: "Toggle Memory", value: "memory", status: systemSettings.memory ? "ON" : "OFF" }
653
+ ];
654
+ case "security":
655
+ const activePreset = getActivePreset(systemSettings);
656
+ return [
657
+ { label: "Sandbox Preset", value: "sandboxPreset", status: activePreset, section: "Sandbox" },
658
+ { label: "Auto Execute", value: "autoExec", status: systemSettings.autoExec ? "ON" : "OFF", section: "Sandbox" },
659
+ { label: "External Workspace Access", value: "externalAccess", status: systemSettings.allowExternalAccess ? "ON" : "OFF", section: "Sandbox" },
660
+ { label: "Network Access (Terminal)", value: "networkAccess", status: systemSettings.networkAccess !== false ? "ON" : "OFF", section: "Sandbox" },
661
+ { label: "Always Ask Commands", value: "alwaysAsk", status: truncateCSV(systemSettings.alwaysAskCommands), section: "Sandbox" },
662
+ { label: "Auto Approve Commands", value: "autoApprove", status: truncateCSV(systemSettings.autoApproveCommands), section: "Sandbox" },
663
+ { label: "Auto Disapprove Commands", value: "autoDisallow", status: truncateCSV(systemSettings.autoDisallowCommands), section: "Sandbox" },
664
+ { label: "Auto Approve Git Commits", value: "autoApproveGit", status: systemSettings.autoApproveGit ? "ON" : "OFF", section: "Sandbox" },
665
+ { label: "Auto-Delete History", value: "autoDelete", status: systemSettings.autoDeleteHistory || "30d", section: "Other" },
666
+ { label: "Save AppData Externally", value: "externalData", status: systemSettings.useExternalData ? "ON" : "OFF", section: "Other" }
667
+ ];
668
+ case "updater":
669
+ return [
670
+ { label: "Auto-Update", value: "autoUpdate", status: systemSettings.autoUpdate ? "ON" : "OFF" },
671
+ { label: "Preferred Updater", value: "updateManager", status: (systemSettings.updateManager || "npm") === "custom" ? "Custom" : (systemSettings.updateManager || "npm").toUpperCase() }
672
+ ];
673
+ case "other":
674
+ return [
675
+ { label: "API Tier", value: "apiTier", status: apiTier }
676
+ ];
677
+ default:
678
+ return [];
679
+ }
680
+ };
681
+ const currentCatId = CATEGORIES[selectedCategoryIndex].id;
682
+ const currentItems = getCategoryItems(currentCatId);
683
+ useInput((input, key) => {
684
+ if (editingItem) {
685
+ if (key.escape) {
686
+ setEditingItem(null);
687
+ }
688
+ return;
689
+ }
690
+ if (activeColumn === "categories") {
691
+ if (key.upArrow) {
692
+ setSelectedCategoryIndex((prev) => (prev - 1 + CATEGORIES.length) % CATEGORIES.length);
693
+ } else if (key.downArrow) {
694
+ setSelectedCategoryIndex((prev) => (prev + 1) % CATEGORIES.length);
695
+ } else if (key.return || key.rightArrow) {
696
+ const targetCat = CATEGORIES[selectedCategoryIndex];
697
+ if (targetCat.id === "exit") {
698
+ setActiveView("chat");
699
+ } else {
700
+ setActiveColumn("items");
701
+ setSelectedItemIndex(0);
702
+ }
703
+ } else if (key.escape) {
704
+ setActiveView("chat");
705
+ }
706
+ } else if (activeColumn === "items") {
707
+ if (key.upArrow) {
708
+ setSelectedItemIndex((prev) => (prev - 1 + currentItems.length) % currentItems.length);
709
+ } else if (key.downArrow) {
710
+ setSelectedItemIndex((prev) => (prev + 1) % currentItems.length);
711
+ } else if (key.leftArrow || key.escape) {
712
+ setActiveColumn("categories");
713
+ } else if (key.return) {
714
+ const item = currentItems[selectedItemIndex];
715
+ handleSelect(item);
716
+ }
717
+ }
718
+ });
719
+ const handleSelect = (item) => {
720
+ if (item.value === "memory") {
721
+ setSystemSettings((s) => ({ ...s, memory: !s.memory }));
722
+ } else if (item.value === "sandboxPreset") {
723
+ const activePreset = getActivePreset(systemSettings);
724
+ const presets = ["Autonomous", "Balanced", "Strict"];
725
+ const curIndex = presets.indexOf(activePreset);
726
+ const nextIndex = (curIndex + 1) % presets.length;
727
+ const nextPreset = presets[nextIndex];
728
+ setSystemSettings((s) => {
729
+ const updated = { ...s, sandboxPreset: nextPreset };
730
+ if (nextPreset === "Strict") {
731
+ updated.autoExec = false;
732
+ updated.allowExternalAccess = false;
733
+ updated.networkAccess = false;
734
+ updated.autoApproveCommands = "";
735
+ updated.autoDisallowCommands = "rm -rf, rm -f, del /f, rd /s, rmdir /s, format";
736
+ updated.alwaysAskCommands = "";
737
+ updated.autoApproveGit = false;
738
+ } else if (nextPreset === "Balanced") {
739
+ updated.autoExec = true;
740
+ updated.allowExternalAccess = false;
741
+ updated.networkAccess = true;
742
+ updated.autoApproveCommands = "ls, dir, cat, type, echo, pwd, cd, git status, git log, git diff, help, mkdir, touch, md";
743
+ updated.autoDisallowCommands = "rm -rf, rm -f, del /f, rd /s, rmdir /s, format";
744
+ updated.alwaysAskCommands = "";
745
+ updated.autoApproveGit = false;
746
+ } else if (nextPreset === "Autonomous") {
747
+ updated.autoExec = true;
748
+ updated.allowExternalAccess = true;
749
+ updated.networkAccess = true;
750
+ updated.autoApproveCommands = "";
751
+ updated.autoDisallowCommands = "";
752
+ updated.alwaysAskCommands = "";
753
+ updated.autoApproveGit = true;
754
+ }
755
+ return updated;
756
+ });
757
+ } else if (item.value === "autoExec") {
758
+ if (!systemSettings.autoExec) {
759
+ if (systemSettings.allowExternalAccess) {
760
+ setActiveView("doubleDanger");
761
+ } else {
762
+ setActiveView("autoExecDanger");
763
+ }
764
+ } else {
765
+ setSystemSettings((s) => ({ ...s, autoExec: false, sandboxPreset: "Custom" }));
766
+ }
767
+ } else if (item.value === "externalAccess") {
768
+ if (!systemSettings.allowExternalAccess) {
769
+ if (systemSettings.autoExec) {
770
+ setActiveView("doubleDanger");
771
+ } else {
772
+ setActiveView("externalDanger");
773
+ }
774
+ } else {
775
+ setSystemSettings((s) => ({ ...s, allowExternalAccess: false, sandboxPreset: "Custom" }));
776
+ }
777
+ } else if (item.value === "networkAccess") {
778
+ setSystemSettings((s) => ({ ...s, networkAccess: s.networkAccess === false, sandboxPreset: "Custom" }));
779
+ } else if (item.value === "alwaysAsk") {
780
+ setEditingItem("alwaysAskCommands");
781
+ setEditValue(systemSettings.alwaysAskCommands || "");
782
+ } else if (item.value === "autoApprove") {
783
+ setEditingItem("autoApproveCommands");
784
+ setEditValue(systemSettings.autoApproveCommands || "");
785
+ } else if (item.value === "autoApproveGit") {
786
+ setSystemSettings((s) => ({ ...s, autoApproveGit: !s.autoApproveGit, sandboxPreset: "Custom" }));
787
+ } else if (item.value === "autoDisallow") {
788
+ setEditingItem("autoDisallowCommands");
789
+ setEditValue(systemSettings.autoDisallowCommands || "");
790
+ } else if (item.value === "apiTier") {
791
+ setActiveView("apiTier");
792
+ } else if (item.value === "autoDelete") {
793
+ const options = ["1d", "7d", "30d"];
794
+ const currentIndex = options.indexOf(systemSettings.autoDeleteHistory || "30d");
795
+ const nextIndex = (currentIndex + 1) % options.length;
796
+ setSystemSettings((s) => ({ ...s, autoDeleteHistory: options[nextIndex] }));
797
+ } else if (item.value === "autoUpdate") {
798
+ setSystemSettings((s) => ({ ...s, autoUpdate: !s.autoUpdate }));
799
+ } else if (item.value === "externalData") {
800
+ if (!systemSettings.useExternalData) {
801
+ setInputConfig({
802
+ label: "Enter absolute path for External AppData:",
803
+ note: "All history, logs and secrets will be stored here. ~/.fluxflow/settings.json stays as anchor.",
804
+ key: "externalDataPath",
805
+ value: systemSettings.externalDataPath || ""
806
+ });
807
+ setActiveView("input");
808
+ } else {
809
+ const newSettings = { ...systemSettings, useExternalData: false };
810
+ setSystemSettings(newSettings);
811
+ saveSettings2({ systemSettings: newSettings, apiTier, quotas });
812
+ setMessages((prev) => [...prev, { id: Date.now(), role: "system", text: "\u{1F3E0} [STORAGE RESET] Flux Flow will return to default ~/.fluxflow after restart." }]);
813
+ setActiveView("chat");
814
+ }
815
+ } else if (item.value === "updateManager") {
816
+ setActiveView("updateManager");
817
+ }
818
+ };
819
+ return /* @__PURE__ */ React5.createElement(Box5, { flexDirection: "column", borderStyle: "round", borderColor: "gray", padding: 0, width: "100%" }, /* @__PURE__ */ React5.createElement(Box5, { paddingX: 1, paddingY: 0, marginBottom: 1, borderStyle: "single", borderColor: "magenta", width: "100%" }, /* @__PURE__ */ React5.createElement(Text5, { color: "magenta", bold: true }, "\u{1F527} SYSTEM CONFIGURATION")), /* @__PURE__ */ React5.createElement(Box5, { flexDirection: "row", width: "100%", minHeight: 8 }, /* @__PURE__ */ React5.createElement(Box5, { flexDirection: "column", width: "30%", borderStyle: "round", borderColor: activeColumn === "categories" ? "cyan" : "gray", padding: 1 }, /* @__PURE__ */ React5.createElement(Box5, { marginBottom: 1 }, /* @__PURE__ */ React5.createElement(Text5, { color: activeColumn === "categories" ? "cyan" : "white", bold: true, underline: true }, "CATEGORIES")), CATEGORIES.map((cat, index) => {
820
+ const isSelected = selectedCategoryIndex === index;
821
+ const isExit = cat.id === "exit";
822
+ return /* @__PURE__ */ React5.createElement(
823
+ Box5,
824
+ {
825
+ key: cat.id,
826
+ marginTop: isExit ? 1 : 0,
827
+ backgroundColor: isSelected ? activeColumn === "categories" ? "#2a2a2a" : "#1e1e1e" : void 0,
828
+ paddingX: 1
829
+ },
830
+ /* @__PURE__ */ React5.createElement(
831
+ Text5,
832
+ {
833
+ color: isSelected ? activeColumn === "categories" ? "cyan" : "yellow" : "white",
834
+ bold: isSelected
835
+ },
836
+ isSelected ? "\u276F " : " ",
837
+ cat.label
838
+ )
839
+ );
840
+ })), /* @__PURE__ */ React5.createElement(Box5, { flexDirection: "column", width: "70%", borderStyle: "round", borderColor: activeColumn === "items" ? "cyan" : "gray", padding: 1, marginLeft: 1 }, /* @__PURE__ */ React5.createElement(Box5, { marginBottom: 1 }, /* @__PURE__ */ React5.createElement(Text5, { color: activeColumn === "items" ? "cyan" : "white", bold: true, underline: true }, CATEGORIES[selectedCategoryIndex].label.toUpperCase(), " SETTINGS")), currentItems.length > 0 ? (() => {
841
+ let lastSection = null;
842
+ const elements = [];
843
+ const getListItems = (val) => (val || "").split(",").map((s) => s.trim().toLowerCase()).filter(Boolean);
844
+ const approveList = getListItems(systemSettings.autoApproveCommands);
845
+ const disallowList = getListItems(systemSettings.autoDisallowCommands);
846
+ const askList = getListItems(systemSettings.alwaysAskCommands);
847
+ const allLists = [...approveList, ...disallowList, ...askList];
848
+ const uniqueLists = new Set(allLists);
849
+ const hasConflict = currentCatId === "security" && allLists.length !== uniqueLists.size;
850
+ currentItems.forEach((item, index) => {
851
+ const isSelected = activeColumn === "items" && selectedItemIndex === index;
852
+ const labelLength = item.label.length;
853
+ const dotsCount = Math.max(2, 35 - labelLength);
854
+ const dots = ".".repeat(dotsCount);
855
+ const getStatusColor = (item2) => {
856
+ if (currentCatId === "security") {
857
+ if ((item2.value === "autoExec" || item2.value === "externalAccess") && item2.status === "ON") {
858
+ return "red";
859
+ }
860
+ return "yellow";
861
+ }
862
+ return item2.status === "ON" ? "green" : item2.status === "OFF" ? "red" : "yellow";
863
+ };
864
+ if (item.section && item.section !== lastSection) {
865
+ lastSection = item.section;
866
+ elements.push(
867
+ /* @__PURE__ */ React5.createElement(Box5, { key: `sec-hdr-${item.section}`, marginTop: elements.length > 0 ? 1 : 0, marginBottom: 0, paddingX: 1 }, /* @__PURE__ */ React5.createElement(Text5, { color: "magenta", bold: true, underline: true }, "\u{1F4C2} ", item.section.toUpperCase()))
868
+ );
869
+ }
870
+ const isEditingThis = isSelected && editingItem && (editingItem === "alwaysAskCommands" && item.value === "alwaysAsk" || editingItem === "autoApproveCommands" && item.value === "autoApprove" || editingItem === "autoDisallowCommands" && item.value === "autoDisallow");
871
+ const isCommandListItem = item.value === "alwaysAsk" || item.value === "autoApprove" || item.value === "autoDisallow";
872
+ elements.push(
873
+ /* @__PURE__ */ React5.createElement(Box5, { key: item.value, flexDirection: "column" }, /* @__PURE__ */ React5.createElement(Box5, { backgroundColor: isSelected && !isEditingThis ? "#2a2a2a" : void 0, paddingX: 2 }, /* @__PURE__ */ React5.createElement(
874
+ Text5,
875
+ {
876
+ color: isSelected ? "cyan" : "white",
877
+ bold: isSelected
878
+ },
879
+ isSelected ? "\u276F " : " ",
880
+ item.label
881
+ ), !isCommandListItem && /* @__PURE__ */ React5.createElement(React5.Fragment, null, /* @__PURE__ */ React5.createElement(Text5, { color: "gray", dimColor: true }, dots), /* @__PURE__ */ React5.createElement(Text5, { color: getStatusColor(item), bold: true }, "[ ", item.status, " ]"))), isCommandListItem && !isEditingThis && item.status !== "None" && /* @__PURE__ */ React5.createElement(Box5, { paddingX: 4, marginBottom: 1 }, /* @__PURE__ */ React5.createElement(Text5, { color: "gray", dimColor: true }, "\u21B3 ", item.status)), isEditingThis && /* @__PURE__ */ React5.createElement(Box5, { flexDirection: "column", marginLeft: 4, marginBottom: 1 }, /* @__PURE__ */ React5.createElement(Box5, { paddingX: 1, borderStyle: "single", borderColor: "cyan", flexDirection: "row" }, /* @__PURE__ */ React5.createElement(Text5, { color: "cyan", bold: true }, "> ", " "), /* @__PURE__ */ React5.createElement(
882
+ TextInput,
883
+ {
884
+ value: editValue,
885
+ onChange: setEditValue,
886
+ onSubmit: (val) => {
887
+ const newSysSettings = { ...systemSettings, [editingItem]: val.trim(), sandboxPreset: "Custom" };
888
+ setSystemSettings(newSysSettings);
889
+ saveSettings2({ systemSettings: newSysSettings, apiTier, quotas });
890
+ setEditingItem(null);
891
+ }
892
+ }
893
+ )), /* @__PURE__ */ React5.createElement(Text5, { color: "gray", dimColor: true, italic: true }, " Comma separated \u2022 Press Enter to save, Esc to cancel")))
894
+ );
895
+ });
896
+ if (hasConflict) {
897
+ elements.push(
898
+ /* @__PURE__ */ React5.createElement(Box5, { key: "conflict-warning", marginTop: 1, paddingX: 1 }, /* @__PURE__ */ React5.createElement(Text5, { color: "red", dimColor: true, italic: true }, "* Conflicting commands will be ignored and defaulted to highest priority"))
899
+ );
900
+ }
901
+ return elements;
902
+ })() : /* @__PURE__ */ React5.createElement(Box5, { paddingX: 1 }, /* @__PURE__ */ React5.createElement(Text5, { color: "gray", italic: true }, CATEGORIES[selectedCategoryIndex].desc)))), /* @__PURE__ */ React5.createElement(Box5, { paddingX: 1, marginTop: 1, flexDirection: "row", justifyContent: "space-between" }, /* @__PURE__ */ React5.createElement(Text5, { color: "gray", dimColor: true, italic: true }, activeColumn === "categories" ? "\u25B2\u25BC Select Category \u2022 Enter/\u25BA to configure" : "\u25B2\u25BC Select Option \u2022 Enter to Toggle \u2022 \u25C4/ESC to go back"), activeColumn === "categories" && /* @__PURE__ */ React5.createElement(Text5, { color: "gray", dimColor: true }, CATEGORIES[selectedCategoryIndex].desc)));
903
+ }
904
+ var CATEGORIES, getActivePreset, truncateCSV;
905
+ var init_SettingsMenu = __esm({
906
+ "src/components/SettingsMenu.jsx"() {
907
+ CATEGORIES = [
908
+ { id: "memory", label: "\u{1F9E0} Memory", desc: "Manage system context & agent's memory" },
909
+ { id: "security", label: "\u{1F512} Security", desc: "Configure permissions & data safety" },
910
+ { id: "updater", label: "\u{1F504} Updater", desc: "Manage application updates" },
911
+ { id: "other", label: "\u{1F4CB} Other", desc: "Miscellaneous preferences" },
912
+ { id: "exit", label: "\u{1F6AA} Exit Settings", desc: "Return to chat view" }
913
+ ];
914
+ getActivePreset = (settings) => {
915
+ const approve = settings.autoApproveCommands || "";
916
+ const disallow = settings.autoDisallowCommands || "";
917
+ const alwaysAsk = settings.alwaysAskCommands || "";
918
+ const isStrict = settings.autoExec === false && settings.allowExternalAccess === false && settings.networkAccess === false && approve === "" && disallow === "rm -rf, rm -f, del /f, rd /s, rmdir /s, format" && alwaysAsk === "" && settings.autoApproveGit === false;
919
+ const isBalanced = settings.autoExec === true && settings.allowExternalAccess === false && settings.networkAccess !== false && approve === "ls, dir, cat, type, echo, pwd, cd, git status, git log, git diff, help, mkdir, touch, md" && disallow === "rm -rf, rm -f, del /f, rd /s, rmdir /s, format" && alwaysAsk === "" && settings.autoApproveGit === false;
920
+ const isAutonomous = settings.autoExec === true && settings.allowExternalAccess === true && settings.networkAccess !== false && approve === "" && disallow === "" && alwaysAsk === "" && settings.autoApproveGit === true;
921
+ if (isStrict) return "Strict";
922
+ if (isBalanced) return "Balanced";
923
+ if (isAutonomous) return "Autonomous";
924
+ return settings.sandboxPreset || "Custom";
925
+ };
926
+ truncateCSV = (val) => {
927
+ if (!val || val.trim() === "") return "None";
928
+ if (val.length > 20) return val.substring(0, 17) + "...";
929
+ return val;
930
+ };
931
+ }
932
+ });
933
+
934
+ // src/components/ProfileForm.jsx
935
+ import React6, { useState as useState3, useEffect as useEffect2 } from "react";
936
+ import { Box as Box6, Text as Text6 } from "ink";
937
+ import TextInput2 from "ink-text-input";
623
938
  function ProfileForm({ initialData, onSave, onCancel }) {
624
- const [step, setStep] = useState2(0);
625
- const [currentInput, setCurrentInput] = useState2("");
626
- const [profile, setProfile] = useState2(() => ({
939
+ const [step, setStep] = useState3(0);
940
+ const [currentInput, setCurrentInput] = useState3("");
941
+ const [profile, setProfile] = useState3(() => ({
627
942
  name: initialData?.name || "",
628
943
  nickname: initialData?.nickname || "",
629
944
  instructions: initialData?.instructions || ""
@@ -652,8 +967,8 @@ function ProfileForm({ initialData, onSave, onCancel }) {
652
967
  onSave(newProfile);
653
968
  }
654
969
  };
655
- return /* @__PURE__ */ React5.createElement(
656
- Box5,
970
+ return /* @__PURE__ */ React6.createElement(
971
+ Box6,
657
972
  {
658
973
  borderStyle: "round",
659
974
  borderColor: "gray",
@@ -663,16 +978,16 @@ function ProfileForm({ initialData, onSave, onCancel }) {
663
978
  flexDirection: "column",
664
979
  width: "100%"
665
980
  },
666
- /* @__PURE__ */ React5.createElement(Box5, { paddingX: 1, marginBottom: 1 }, /* @__PURE__ */ React5.createElement(Text5, { color: "magenta", bold: true }, "\u{1F464} DEVELOPER PROFILE CONFIGURATION")),
667
- /* @__PURE__ */ React5.createElement(Box5, { paddingX: 1, flexDirection: "column" }, /* @__PURE__ */ React5.createElement(Box5, null, /* @__PURE__ */ React5.createElement(Text5, { color: "cyan", bold: true }, steps[step].label), /* @__PURE__ */ React5.createElement(
668
- TextInput,
981
+ /* @__PURE__ */ React6.createElement(Box6, { paddingX: 1, marginBottom: 1 }, /* @__PURE__ */ React6.createElement(Text6, { color: "magenta", bold: true }, "\u{1F464} DEVELOPER PROFILE CONFIGURATION")),
982
+ /* @__PURE__ */ React6.createElement(Box6, { paddingX: 1, flexDirection: "column" }, /* @__PURE__ */ React6.createElement(Box6, null, /* @__PURE__ */ React6.createElement(Text6, { color: "cyan", bold: true }, steps[step].label), /* @__PURE__ */ React6.createElement(
983
+ TextInput2,
669
984
  {
670
985
  value: currentInput,
671
986
  onChange: setCurrentInput,
672
987
  onSubmit: handleSubmit
673
988
  }
674
- )), /* @__PURE__ */ React5.createElement(Box5, { marginTop: 1 }, /* @__PURE__ */ React5.createElement(Text5, { color: "gray", dimColor: true, italic: true }, "Step ", step + 1, " of ", steps.length))),
675
- /* @__PURE__ */ React5.createElement(Box5, { paddingX: 1, marginTop: 1 }, /* @__PURE__ */ React5.createElement(Text5, { color: "gray", dimColor: true, italic: true }, "(Enter to submit \u2022 Type /cancel to abort)"))
989
+ )), /* @__PURE__ */ React6.createElement(Box6, { marginTop: 1 }, /* @__PURE__ */ React6.createElement(Text6, { color: "gray", dimColor: true, italic: true }, "Step ", step + 1, " of ", steps.length))),
990
+ /* @__PURE__ */ React6.createElement(Box6, { paddingX: 1, marginTop: 1 }, /* @__PURE__ */ React6.createElement(Text6, { color: "gray", dimColor: true, italic: true }, "(Enter to submit \u2022 Type /cancel to abort)"))
676
991
  );
677
992
  }
678
993
  var init_ProfileForm = __esm({
@@ -681,19 +996,19 @@ var init_ProfileForm = __esm({
681
996
  });
682
997
 
683
998
  // src/components/AskUserModal.jsx
684
- import React6, { useState as useState3 } from "react";
685
- import { Box as Box6, Text as Text6, useInput } from "ink";
686
- import TextInput2 from "ink-text-input";
999
+ import React7, { useState as useState4 } from "react";
1000
+ import { Box as Box7, Text as Text7, useInput as useInput2 } from "ink";
1001
+ import TextInput3 from "ink-text-input";
687
1002
  var AskUserModal, AskUserModal_default;
688
1003
  var init_AskUserModal = __esm({
689
1004
  "src/components/AskUserModal.jsx"() {
690
1005
  init_terminal();
691
1006
  AskUserModal = ({ question, options, onResolve }) => {
692
- const [isSuggestingElse, setIsSuggestingElse] = useState3(false);
693
- const [customInput, setCustomInput] = useState3("");
694
- const [selectedIndex, setSelectedIndex] = useState3(0);
1007
+ const [isSuggestingElse, setIsSuggestingElse] = useState4(false);
1008
+ const [customInput, setCustomInput] = useState4("");
1009
+ const [selectedIndex, setSelectedIndex] = useState4(0);
695
1010
  const allOptions = [...options, { id: "CUSTOM", label: "Suggest something else...", description: "Provide a custom response" }];
696
- useInput((input, key) => {
1011
+ useInput2((input, key) => {
697
1012
  if (isSuggestingElse) return;
698
1013
  if (key.leftArrow || key.upArrow) {
699
1014
  setSelectedIndex((prev) => Math.max(0, prev - 1));
@@ -712,19 +1027,19 @@ var init_AskUserModal = __esm({
712
1027
  });
713
1028
  const s = emojiSpace(2);
714
1029
  if (isSuggestingElse) {
715
- return /* @__PURE__ */ React6.createElement(Box6, { flexDirection: "column", borderStyle: "round", borderColor: "gray", padding: 0, width: "100%" }, /* @__PURE__ */ React6.createElement(Box6, { paddingX: 1 }, /* @__PURE__ */ React6.createElement(Text6, { color: "cyan", bold: true }, "\u{1F4AC} SUGGEST SOMETHING ELSE")), /* @__PURE__ */ React6.createElement(Box6, { marginTop: 1, paddingX: 1 }, /* @__PURE__ */ React6.createElement(Text6, { italic: true, color: "gray" }, "Replying to: ", question)), /* @__PURE__ */ React6.createElement(Box6, { marginTop: 1, paddingX: 1, flexDirection: "row" }, /* @__PURE__ */ React6.createElement(Text6, { color: "cyan", bold: true }, "\u{1F4A0} "), /* @__PURE__ */ React6.createElement(
716
- TextInput2,
1030
+ return /* @__PURE__ */ React7.createElement(Box7, { flexDirection: "column", borderStyle: "round", borderColor: "gray", padding: 0, width: "100%" }, /* @__PURE__ */ React7.createElement(Box7, { paddingX: 1 }, /* @__PURE__ */ React7.createElement(Text7, { color: "cyan", bold: true }, "\u{1F4AC} SUGGEST SOMETHING ELSE")), /* @__PURE__ */ React7.createElement(Box7, { marginTop: 1, paddingX: 1 }, /* @__PURE__ */ React7.createElement(Text7, { italic: true, color: "gray" }, "Replying to: ", question)), /* @__PURE__ */ React7.createElement(Box7, { marginTop: 1, paddingX: 1, flexDirection: "row" }, /* @__PURE__ */ React7.createElement(Text7, { color: "cyan", bold: true }, "\u{1F4A0} "), /* @__PURE__ */ React7.createElement(
1031
+ TextInput3,
717
1032
  {
718
1033
  value: customInput,
719
1034
  onChange: setCustomInput,
720
1035
  onSubmit: () => onResolve(customInput)
721
1036
  }
722
- )), /* @__PURE__ */ React6.createElement(Box6, { marginTop: 1, paddingX: 1, marginBottom: 1 }, /* @__PURE__ */ React6.createElement(Text6, { color: "gray", dimColor: true, italic: true }, "(Press Enter to send)")));
1037
+ )), /* @__PURE__ */ React7.createElement(Box7, { marginTop: 1, paddingX: 1, marginBottom: 1 }, /* @__PURE__ */ React7.createElement(Text7, { color: "gray", dimColor: true, italic: true }, "(Press Enter to send)")));
723
1038
  }
724
- return /* @__PURE__ */ React6.createElement(Box6, { flexDirection: "column", borderStyle: "round", borderColor: "gray", padding: 0, width: "100%" }, /* @__PURE__ */ React6.createElement(Box6, { paddingX: 1, marginBottom: 1 }, /* @__PURE__ */ React6.createElement(Text6, { color: "cyan", bold: true }, "\u{1F4AC} AGENT REQUEST: ACTION REQUIRED")), /* @__PURE__ */ React6.createElement(Box6, { paddingX: 1, marginBottom: 1 }, /* @__PURE__ */ React6.createElement(Text6, { bold: true, color: "white" }, question)), /* @__PURE__ */ React6.createElement(Box6, { flexDirection: "column", width: "100%" }, allOptions.map((opt, idx) => {
1039
+ return /* @__PURE__ */ React7.createElement(Box7, { flexDirection: "column", borderStyle: "round", borderColor: "gray", padding: 0, width: "100%" }, /* @__PURE__ */ React7.createElement(Box7, { paddingX: 1, marginBottom: 1 }, /* @__PURE__ */ React7.createElement(Text7, { color: "cyan", bold: true }, "\u{1F4AC} AGENT REQUEST: ACTION REQUIRED")), /* @__PURE__ */ React7.createElement(Box7, { paddingX: 1, marginBottom: 1 }, /* @__PURE__ */ React7.createElement(Text7, { bold: true, color: "white" }, question)), /* @__PURE__ */ React7.createElement(Box7, { flexDirection: "column", width: "100%" }, allOptions.map((opt, idx) => {
725
1040
  const isSelected = idx === selectedIndex;
726
- return /* @__PURE__ */ React6.createElement(
727
- Box6,
1041
+ return /* @__PURE__ */ React7.createElement(
1042
+ Box7,
728
1043
  {
729
1044
  key: opt.id,
730
1045
  flexDirection: "column",
@@ -733,10 +1048,10 @@ var init_AskUserModal = __esm({
733
1048
  paddingX: 1,
734
1049
  marginBottom: idx === allOptions.length - 1 ? 0 : 1
735
1050
  },
736
- /* @__PURE__ */ React6.createElement(Text6, { color: isSelected ? "cyan" : "white", bold: isSelected }, isSelected ? "\u276F " : " ", opt.label),
737
- opt.description && /* @__PURE__ */ React6.createElement(Box6, { marginLeft: 4 }, /* @__PURE__ */ React6.createElement(Text6, { color: "gray", italic: true, dimColor: true }, opt.description))
1051
+ /* @__PURE__ */ React7.createElement(Text7, { color: isSelected ? "cyan" : "white", bold: isSelected }, isSelected ? "\u276F " : " ", opt.label),
1052
+ opt.description && /* @__PURE__ */ React7.createElement(Box7, { marginLeft: 4 }, /* @__PURE__ */ React7.createElement(Text7, { color: "gray", italic: true, dimColor: true }, opt.description))
738
1053
  );
739
- })), /* @__PURE__ */ React6.createElement(Box6, { paddingX: 1, marginTop: 1, marginBottom: 1 }, /* @__PURE__ */ React6.createElement(Text6, { color: "gray", dimColor: true, italic: true }, "(Use Arrows to navigate, Enter to confirm)")));
1054
+ })), /* @__PURE__ */ React7.createElement(Box7, { paddingX: 1, marginTop: 1, marginBottom: 1 }, /* @__PURE__ */ React7.createElement(Text7, { color: "gray", dimColor: true, italic: true }, "(Use Arrows to navigate, Enter to confirm)")));
740
1055
  };
741
1056
  AskUserModal_default = AskUserModal;
742
1057
  }
@@ -1572,6 +1887,8 @@ var init_usage = __esm({
1572
1887
  toolDenied: 0,
1573
1888
  duration: 0,
1574
1889
  tokens: 0,
1890
+ linesAdded: 0,
1891
+ linesRemoved: 0,
1575
1892
  imageCalls: []
1576
1893
  };
1577
1894
  loadUsageFromFile = async () => {
@@ -2821,6 +3138,17 @@ var init_exec_command = __esm({
2821
3138
  const { onChunk } = options;
2822
3139
  if (!rawCommand) return 'ERROR: Missing "command" argument for exec_command.';
2823
3140
  const command = adjustWindowsCommand(rawCommand);
3141
+ const systemSettings = options.systemSettings || {};
3142
+ const netEnv = {};
3143
+ if (systemSettings.networkAccess === false) {
3144
+ netEnv.HTTP_PROXY = "http://127.0.0.1:9999";
3145
+ netEnv.HTTPS_PROXY = "http://127.0.0.1:9999";
3146
+ netEnv.ALL_PROXY = "socks5://127.0.0.1:9999";
3147
+ netEnv.http_proxy = "http://127.0.0.1:9999";
3148
+ netEnv.https_proxy = "http://127.0.0.1:9999";
3149
+ netEnv.all_proxy = "socks5://127.0.0.1:9999";
3150
+ netEnv.NO_PROXY = "localhost,127.0.0.1";
3151
+ }
2824
3152
  return new Promise((resolve) => {
2825
3153
  const child = spawn(command, {
2826
3154
  shell: true,
@@ -2829,7 +3157,8 @@ var init_exec_command = __esm({
2829
3157
  ...process.env,
2830
3158
  CI: "false",
2831
3159
  TERM: "xterm-256color",
2832
- FORCE_COLOR: "1"
3160
+ FORCE_COLOR: "1",
3161
+ ...netEnv
2833
3162
  }
2834
3163
  });
2835
3164
  activeChildProcess = child;
@@ -4705,7 +5034,7 @@ ${thinkingLevel != "Fast" ? "[SYSTEM] **STRICTLY FOLLOW THINKING POLICY AS CORE
4705
5034
  const action = normToolName === "list_files" ? "LIST" : "ANALYSED";
4706
5035
  label = `\u{1F4C2} ${action} FOLDER: ${parseArgs(toolCall.args).path || "."}`.toUpperCase();
4707
5036
  } else if (normToolName === "write_file" || normToolName === "update_file") {
4708
- const action = normToolName === "write_file" ? "WRITTEN" : "UPDATED FILE";
5037
+ const action = normToolName === "write_file" ? "WRITTEN" : "PATCHED";
4709
5038
  label = `\u{1F4BE} ${action}: ${parseArgs(toolCall.args).path || "..."}`.toUpperCase();
4710
5039
  } else if (normToolName === "write_pdf") {
4711
5040
  label = `\u{1F4D1} PDF CREATED: ${parseArgs(toolCall.args).path || "..."}`.toUpperCase();
@@ -4722,15 +5051,6 @@ ${thinkingLevel != "Fast" ? "[SYSTEM] **STRICTLY FOLLOW THINKING POLICY AS CORE
4722
5051
  } else {
4723
5052
  label = `EXECUTED: ${toolCall.toolName}`.toUpperCase();
4724
5053
  }
4725
- if (label) {
4726
- const boxWidth = Math.min(label.length + 4, 115);
4727
- const boxTop = `\u256D${"\u2500".repeat(boxWidth)}\u256E`;
4728
- const boxMid = `\u2502 ${label.padEnd(boxWidth - 2).substring(0, boxWidth - 2)} \u2502`;
4729
- const boxBottom = `\u2570${"\u2500".repeat(boxWidth)}\u256F`;
4730
- yield { type: "visual_feedback", content: `${boxTop}
4731
- ${boxMid}
4732
- ${boxBottom}` };
4733
- }
4734
5054
  if (normToolName === "exec_command") {
4735
5055
  const { command } = parseArgs(toolCall.args);
4736
5056
  if (command && settings.systemSettings && settings.systemSettings.allowExternalAccess === false) {
@@ -4745,6 +5065,12 @@ ${boxBottom}` };
4745
5065
  });
4746
5066
  if (isViolating) {
4747
5067
  const denyMsg = `Access Denied. Terminal is prohibited from accessing system drives (C://) or external directories while "External Workspace Access" is disabled.`;
5068
+ if (settings.onExecStart) settings.onExecStart(command || "Unknown");
5069
+ yield { type: "exec_start" };
5070
+ await new Promise((resolve) => setTimeout(resolve, 50));
5071
+ if (settings.onExecChunk) settings.onExecChunk(`ERROR: ${denyMsg}`);
5072
+ await new Promise((resolve) => setTimeout(resolve, 50));
5073
+ if (settings.onExecEnd) settings.onExecEnd();
4748
5074
  toolResults.push({ role: "user", text: `[TOOL RESULT]: ERROR: ${denyMsg}` });
4749
5075
  yield { type: "tool_result", content: `[TOOL RESULT]: ERROR: ${denyMsg}` };
4750
5076
  toolCallPointer++;
@@ -4761,7 +5087,18 @@ ${boxBottom}` };
4761
5087
  const absoluteTarget = path15.resolve(targetPath);
4762
5088
  const absoluteCwd = path15.resolve(process.cwd());
4763
5089
  if (isExternalOff && !absoluteTarget.startsWith(absoluteCwd)) {
4764
- const denyMsg = `Access Denied. You are not allowed to access files outside the current workspace. To enable this, ask the user to turn on "External Workspace Access" in /settings.`;
5090
+ const denyMsg = `Access Denied. You are not allowed to access files outside the current workspace.`;
5091
+ if (normToolName === "write_file" || normToolName === "update_file") {
5092
+ const action = normToolName === "write_file" ? "WRITE DENIED" : "UPDATE DENIED";
5093
+ const deniedLabel = `\u{1F4BE} ${action}: ${parsedArgs.path || "..."}`.toUpperCase();
5094
+ const boxWidth = Math.min(deniedLabel.length + 4, 115);
5095
+ const boxTop = `\u256D${"\u2500".repeat(boxWidth)}\u256E`;
5096
+ const boxMid = `\u2502 ${deniedLabel.padEnd(boxWidth - 2).substring(0, boxWidth - 2)} \u2502`;
5097
+ const boxBottom = `\u2570${"\u2500".repeat(boxWidth)}\u256F`;
5098
+ yield { type: "visual_feedback", content: `${boxTop}
5099
+ ${boxMid}
5100
+ ${boxBottom}` };
5101
+ }
4765
5102
  toolResults.push({ role: "user", text: `[TOOL RESULT]: ERROR: ${denyMsg}` });
4766
5103
  yield { type: "tool_result", content: `[TOOL RESULT]: ERROR: ${denyMsg}` };
4767
5104
  toolCallPointer++;
@@ -4771,10 +5108,96 @@ ${boxBottom}` };
4771
5108
  if (settings.onToolApproval) {
4772
5109
  let shouldPrompt = normToolName === "write_file" || normToolName === "update_file" || normToolName === "exec_command";
4773
5110
  if (shouldPrompt) {
4774
- const approval = await settings.onToolApproval(normToolName, toolCall.args);
5111
+ const systemSettings2 = settings.systemSettings || {};
5112
+ const autoExec = systemSettings2.autoExec;
5113
+ let decision = null;
5114
+ let forcePrompt = false;
5115
+ let disallowMatch = false;
5116
+ let isNetworkDeny = false;
5117
+ if (normToolName === "exec_command") {
5118
+ const { command } = parseArgs(toolCall.args);
5119
+ const cmdTrimmed = (command || "").trim();
5120
+ const matchesList = (cmd, csv) => {
5121
+ if (!csv) return false;
5122
+ const list = csv.split(",").map((s) => s.trim().toLowerCase()).filter(Boolean);
5123
+ const lowerCmd = cmd.toLowerCase();
5124
+ return list.some((item) => lowerCmd.startsWith(item));
5125
+ };
5126
+ const askMatch = matchesList(cmdTrimmed, systemSettings2.alwaysAskCommands);
5127
+ const approveMatch = matchesList(cmdTrimmed, systemSettings2.autoApproveCommands);
5128
+ disallowMatch = matchesList(cmdTrimmed, systemSettings2.autoDisallowCommands);
5129
+ if (askMatch) {
5130
+ forcePrompt = true;
5131
+ } else if (approveMatch) {
5132
+ decision = "allow";
5133
+ } else if (systemSettings2.autoApproveGit && /^git\s+commit\b/i.test(cmdTrimmed)) {
5134
+ decision = "allow";
5135
+ }
5136
+ if (!forcePrompt && !decision) {
5137
+ if (systemSettings2.networkAccess === false) {
5138
+ const networkCmdRegex = /\b(curl|wget|npm|yarn|pnpm|pip|pip3|ssh|docker|git\s+(clone|push|pull|fetch))\b/i;
5139
+ if (networkCmdRegex.test(cmdTrimmed)) {
5140
+ decision = "deny";
5141
+ isNetworkDeny = true;
5142
+ }
5143
+ }
5144
+ if (!decision && disallowMatch) {
5145
+ decision = "deny";
5146
+ }
5147
+ }
5148
+ if (!forcePrompt && !decision && autoExec) {
5149
+ decision = "allow";
5150
+ }
5151
+ } else {
5152
+ if (autoExec) {
5153
+ decision = "allow";
5154
+ }
5155
+ }
5156
+ let approval = decision;
5157
+ let denyReason = "";
5158
+ if (decision === "deny") {
5159
+ if (isNetworkDeny) {
5160
+ denyReason = "network";
5161
+ } else if (disallowMatch) {
5162
+ denyReason = "settings";
5163
+ } else {
5164
+ denyReason = "prohibited";
5165
+ }
5166
+ }
5167
+ if (!approval) {
5168
+ approval = await settings.onToolApproval(normToolName, toolCall.args);
5169
+ if (approval === "deny") {
5170
+ denyReason = "user";
5171
+ }
5172
+ }
4775
5173
  if (approval === "deny") {
4776
- if (normToolName === "exec_command" && settings.onExecEnd) settings.onExecEnd();
4777
- const denyMsg = `Permission Denied: User rejected the ${normToolName === "exec_command" ? "terminal execution" : "file edit"}.`;
5174
+ let denyMsg = `Permission Denied: Prohibited ${normToolName === "exec_command" ? "Command" : "file edit"}.`;
5175
+ if (denyReason === "user") {
5176
+ denyMsg = "Permission Denied by User";
5177
+ } else if (denyReason === "settings") {
5178
+ denyMsg = "Permission Denied by User Policy";
5179
+ } else if (denyReason === "network") {
5180
+ denyMsg = "Permission Denied: Sandbox Network Access Disabled by User Policy.";
5181
+ } else if (denyReason === "prohibited" && normToolName === "exec_command") {
5182
+ denyMsg = "Permission Denied: Prohibited Command";
5183
+ }
5184
+ if (normToolName === "write_file" || normToolName === "update_file") {
5185
+ const action = normToolName === "write_file" ? "WRITE DENIED" : "UPDATE DENIED";
5186
+ const deniedLabel = `\u{1F4BE} ${action}: ${parseArgs(toolCall.args).path || "..."}`.toUpperCase();
5187
+ const boxWidth = Math.min(deniedLabel.length + 4, 115);
5188
+ const boxTop = `\u256D${"\u2500".repeat(boxWidth)}\u256E`;
5189
+ const boxMid = `\u2502 ${deniedLabel.padEnd(boxWidth - 2).substring(0, boxWidth - 2)} \u2502`;
5190
+ const boxBottom = `\u2570${"\u2500".repeat(boxWidth)}\u256F`;
5191
+ yield { type: "visual_feedback", content: `${boxTop}
5192
+ ${boxMid}
5193
+ ${boxBottom}` };
5194
+ }
5195
+ if (normToolName === "exec_command") {
5196
+ await new Promise((resolve) => setTimeout(resolve, 50));
5197
+ if (settings.onExecChunk) settings.onExecChunk(`ERROR: ${denyMsg}`);
5198
+ await new Promise((resolve) => setTimeout(resolve, 50));
5199
+ if (settings.onExecEnd) settings.onExecEnd();
5200
+ }
4778
5201
  toolResults.push({ role: "user", text: `[TOOL RESULT]: DENIED: ${denyMsg}` });
4779
5202
  yield { type: "tool_result", content: `[TOOL RESULT]: DENIED: ${denyMsg}` };
4780
5203
  await incrementUsage("toolDenied");
@@ -4784,6 +5207,15 @@ ${boxBottom}` };
4784
5207
  }
4785
5208
  }
4786
5209
  }
5210
+ if (label) {
5211
+ const boxWidth = Math.min(label.length + 4, 115);
5212
+ const boxTop = `\u256D${"\u2500".repeat(boxWidth)}\u256E`;
5213
+ const boxMid = `\u2502 ${label.padEnd(boxWidth - 2).substring(0, boxWidth - 2)} \u2502`;
5214
+ const boxBottom = `\u2570${"\u2500".repeat(boxWidth)}\u256F`;
5215
+ yield { type: "visual_feedback", content: `${boxTop}
5216
+ ${boxMid}
5217
+ ${boxBottom}` };
5218
+ }
4787
5219
  if (lastToolFinishedAt > 0) {
4788
5220
  const timeSinceLastTool = Date.now() - lastToolFinishedAt;
4789
5221
  if (timeSinceLastTool < 1e3) {
@@ -4796,7 +5228,8 @@ ${boxBottom}` };
4796
5228
  chatId,
4797
5229
  history,
4798
5230
  onChunk: (chunk2) => settings.onExecChunk ? settings.onExecChunk(chunk2) : null,
4799
- onAskUser: settings.onAskUser
5231
+ onAskUser: settings.onAskUser,
5232
+ systemSettings: settings.systemSettings
4800
5233
  });
4801
5234
  yield { type: "spinner", content: true };
4802
5235
  if (process.stdout.isTTY) {
@@ -5036,12 +5469,12 @@ ${timestamp}`;
5036
5469
  });
5037
5470
 
5038
5471
  // src/components/ResumeModal.jsx
5039
- import React7, { useState as useState4, useEffect as useEffect3 } from "react";
5040
- import { Box as Box7, Text as Text7, useInput as useInput2 } from "ink";
5472
+ import React8, { useState as useState5, useEffect as useEffect3 } from "react";
5473
+ import { Box as Box8, Text as Text8, useInput as useInput3 } from "ink";
5041
5474
  function ResumeModal({ onSelect, onDelete, onClose }) {
5042
- const [history, setHistory] = useState4({});
5043
- const [keys, setKeys] = useState4([]);
5044
- const [selectedIndex, setSelectedIndex] = useState4(0);
5475
+ const [history, setHistory] = useState5({});
5476
+ const [keys, setKeys] = useState5([]);
5477
+ const [selectedIndex, setSelectedIndex] = useState5(0);
5045
5478
  useEffect3(() => {
5046
5479
  const fetchHistory = async () => {
5047
5480
  const h = await loadHistory();
@@ -5050,7 +5483,7 @@ function ResumeModal({ onSelect, onDelete, onClose }) {
5050
5483
  };
5051
5484
  fetchHistory();
5052
5485
  }, []);
5053
- useInput2((input, key) => {
5486
+ useInput3((input, key) => {
5054
5487
  if (key.escape) onClose();
5055
5488
  if (key.upArrow) setSelectedIndex((prev) => Math.max(0, prev - 1));
5056
5489
  if (key.downArrow) setSelectedIndex((prev) => Math.min(keys.length - 1, prev + 1));
@@ -5079,24 +5512,24 @@ function ResumeModal({ onSelect, onDelete, onClose }) {
5079
5512
  }
5080
5513
  }
5081
5514
  const visibleKeys = keys.slice(startIndex, startIndex + MAX_VISIBLE);
5082
- return /* @__PURE__ */ React7.createElement(Box7, { flexDirection: "column", borderStyle: "round", borderColor: "gray", padding: 0, width: "100%" }, /* @__PURE__ */ React7.createElement(Box7, { paddingX: 1, marginBottom: 1 }, /* @__PURE__ */ React7.createElement(Text7, { color: "cyan", bold: true }, "\u{1F4A0} CHAT HISTORY: RESUME CONVERSATION")), keys.length === 0 ? /* @__PURE__ */ React7.createElement(Box7, { paddingX: 2, paddingY: 1 }, /* @__PURE__ */ React7.createElement(Text7, { italic: true, color: "gray" }, "No saved chats found.")) : /* @__PURE__ */ React7.createElement(Box7, { flexDirection: "column", width: "100%" }, startIndex > 0 && /* @__PURE__ */ React7.createElement(Box7, { paddingX: 2, marginBottom: 1 }, /* @__PURE__ */ React7.createElement(Text7, { color: "gray", dimColor: true }, "\u25B2 (+", startIndex, " more chats above)")), visibleKeys.map((id, index) => {
5515
+ 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: "cyan", bold: true }, "\u{1F4A0} CHAT HISTORY: RESUME CONVERSATION")), keys.length === 0 ? /* @__PURE__ */ React8.createElement(Box8, { paddingX: 2, paddingY: 1 }, /* @__PURE__ */ React8.createElement(Text8, { italic: true, color: "gray" }, "No saved chats found.")) : /* @__PURE__ */ React8.createElement(Box8, { flexDirection: "column", width: "100%" }, startIndex > 0 && /* @__PURE__ */ React8.createElement(Box8, { paddingX: 2, marginBottom: 1 }, /* @__PURE__ */ React8.createElement(Text8, { color: "gray", dimColor: true }, "\u25B2 (+", startIndex, " more chats above)")), visibleKeys.map((id, index) => {
5083
5516
  const chat2 = history[id];
5084
5517
  const actualIndex = startIndex + index;
5085
5518
  const isSelected = actualIndex === selectedIndex;
5086
5519
  const dateStr = formatDate(chat2?.updatedAt);
5087
- return /* @__PURE__ */ React7.createElement(
5088
- Box7,
5520
+ return /* @__PURE__ */ React8.createElement(
5521
+ Box8,
5089
5522
  {
5090
5523
  key: id,
5091
5524
  paddingX: 1,
5092
5525
  backgroundColor: isSelected ? "#2a2a2a" : void 0,
5093
5526
  width: "100%"
5094
5527
  },
5095
- /* @__PURE__ */ React7.createElement(Box7, { flexGrow: 1 }, /* @__PURE__ */ React7.createElement(Text7, { color: isSelected ? "cyan" : "white", bold: isSelected }, isSelected ? "\u276F " : " ", chat2?.name || id, /* @__PURE__ */ React7.createElement(Text7, { color: "gray", dimColor: !isSelected }, " [", dateStr, " \u2022 ", id.slice(5), "]"))),
5096
- isSelected && /* @__PURE__ */ React7.createElement(Box7, { flexShrink: 0 }, /* @__PURE__ */ React7.createElement(Text7, { color: "red", bold: true }, "[X] DELETE "))
5528
+ /* @__PURE__ */ React8.createElement(Box8, { flexGrow: 1 }, /* @__PURE__ */ React8.createElement(Text8, { color: isSelected ? "cyan" : "white", bold: isSelected }, isSelected ? "\u276F " : " ", chat2?.name || id, /* @__PURE__ */ React8.createElement(Text8, { color: "gray", dimColor: !isSelected }, " [", dateStr, " \u2022 ", id.slice(5), "]"))),
5529
+ isSelected && /* @__PURE__ */ React8.createElement(Box8, { flexShrink: 0 }, /* @__PURE__ */ React8.createElement(Text8, { color: "red", bold: true }, "[X] DELETE "))
5097
5530
  );
5098
- }), startIndex + MAX_VISIBLE < keys.length && /* @__PURE__ */ React7.createElement(Box7, { paddingX: 2, marginTop: 1 }, /* @__PURE__ */ React7.createElement(Text7, { color: "gray", dimColor: true }, "\u25BC (+", keys.length - (startIndex + MAX_VISIBLE), " more chats below)"))), /* @__PURE__ */ React7.createElement(
5099
- Box7,
5531
+ }), startIndex + MAX_VISIBLE < keys.length && /* @__PURE__ */ React8.createElement(Box8, { paddingX: 2, marginTop: 1 }, /* @__PURE__ */ React8.createElement(Text8, { color: "gray", dimColor: true }, "\u25BC (+", keys.length - (startIndex + MAX_VISIBLE), " more chats below)"))), /* @__PURE__ */ React8.createElement(
5532
+ Box8,
5100
5533
  {
5101
5534
  marginTop: 1,
5102
5535
  paddingX: 1,
@@ -5106,7 +5539,7 @@ function ResumeModal({ onSelect, onDelete, onClose }) {
5106
5539
  borderBottom: false,
5107
5540
  borderColor: "gray"
5108
5541
  },
5109
- /* @__PURE__ */ React7.createElement(Text7, { dimColor: true, italic: true }, "\u2191\u2193 navigate \u2022 Enter select \u2022 x delete \u2022 Esc close")
5542
+ /* @__PURE__ */ React8.createElement(Text8, { dimColor: true, italic: true }, "\u2191\u2193 navigate \u2022 Enter select \u2022 x delete \u2022 Esc close")
5110
5543
  ));
5111
5544
  }
5112
5545
  function formatDate(timestamp) {
@@ -5128,12 +5561,12 @@ var init_ResumeModal = __esm({
5128
5561
  });
5129
5562
 
5130
5563
  // src/components/MemoryModal.jsx
5131
- import React8, { useState as useState5, useEffect as useEffect4 } from "react";
5132
- import { Box as Box8, Text as Text8, useInput as useInput3 } from "ink";
5564
+ import React9, { useState as useState6, useEffect as useEffect4 } from "react";
5565
+ import { Box as Box9, Text as Text9, useInput as useInput4 } from "ink";
5133
5566
  function MemoryModal({ onClose }) {
5134
- const [memories, setMemories] = useState5([]);
5135
- const [selectedIndex, setSelectedIndex] = useState5(0);
5136
- const [isMemoryOn, setIsMemoryOn] = useState5(true);
5567
+ const [memories, setMemories] = useState6([]);
5568
+ const [selectedIndex, setSelectedIndex] = useState6(0);
5569
+ const [isMemoryOn, setIsMemoryOn] = useState6(true);
5137
5570
  const loadMemories = () => {
5138
5571
  const data = readEncryptedJson(MEMORIES_FILE, []);
5139
5572
  setMemories(data);
@@ -5148,7 +5581,7 @@ function MemoryModal({ onClose }) {
5148
5581
  useEffect4(() => {
5149
5582
  loadMemories();
5150
5583
  }, []);
5151
- useInput3((input, key) => {
5584
+ useInput4((input, key) => {
5152
5585
  if (key.escape) onClose();
5153
5586
  if (key.upArrow) setSelectedIndex((prev) => Math.max(0, prev - 1));
5154
5587
  if (key.downArrow) setSelectedIndex((prev) => Math.min(memories.length - 1, prev + 1));
@@ -5178,21 +5611,21 @@ function MemoryModal({ onClose }) {
5178
5611
  return "red";
5179
5612
  };
5180
5613
  const s = emojiSpace(2);
5181
- return /* @__PURE__ */ React8.createElement(Box8, { flexDirection: "column", borderStyle: "round", borderColor: "gray", padding: 0, width: "100%" }, /* @__PURE__ */ React8.createElement(Box8, { paddingX: 1, marginBottom: 1, justifyContent: "space-between" }, /* @__PURE__ */ React8.createElement(Text8, { color: "cyan", bold: true }, "\u{1F9E0} AGENT MEMORY: LONG-TERM KNOWLEDGE"), /* @__PURE__ */ React8.createElement(Box8, null, /* @__PURE__ */ React8.createElement(Text8, { color: "gray" }, "Vault: "), /* @__PURE__ */ React8.createElement(Text8, { color: getBarColor() }, barStr), /* @__PURE__ */ React8.createElement(Text8, { color: "white", bold: true }, " ", usagePercent, "%"))), !isMemoryOn && memories.length > 0 ? /* @__PURE__ */ React8.createElement(Box8, { paddingX: 2, paddingY: 1 }, /* @__PURE__ */ React8.createElement(Text8, { italic: true, color: "gray" }, "Memory is currently Off...")) : memories.length === 0 ? /* @__PURE__ */ React8.createElement(Box8, { paddingX: 2, paddingY: 1 }, /* @__PURE__ */ React8.createElement(Text8, { italic: true, color: "gray" }, isMemoryOn ? "Learning..." : "Memory not available...")) : /* @__PURE__ */ React8.createElement(Box8, { flexDirection: "column" }, memories.map((mem, idx) => {
5614
+ return /* @__PURE__ */ React9.createElement(Box9, { flexDirection: "column", borderStyle: "round", borderColor: "gray", padding: 0, width: "100%" }, /* @__PURE__ */ React9.createElement(Box9, { paddingX: 1, marginBottom: 1, justifyContent: "space-between" }, /* @__PURE__ */ React9.createElement(Text9, { color: "cyan", bold: true }, "\u{1F9E0} AGENT MEMORY: LONG-TERM KNOWLEDGE"), /* @__PURE__ */ React9.createElement(Box9, null, /* @__PURE__ */ React9.createElement(Text9, { color: "gray" }, "Vault: "), /* @__PURE__ */ React9.createElement(Text9, { color: getBarColor() }, barStr), /* @__PURE__ */ React9.createElement(Text9, { color: "white", bold: true }, " ", usagePercent, "%"))), !isMemoryOn && memories.length > 0 ? /* @__PURE__ */ React9.createElement(Box9, { paddingX: 2, paddingY: 1 }, /* @__PURE__ */ React9.createElement(Text9, { italic: true, color: "gray" }, "Memory is currently Off...")) : memories.length === 0 ? /* @__PURE__ */ React9.createElement(Box9, { paddingX: 2, paddingY: 1 }, /* @__PURE__ */ React9.createElement(Text9, { italic: true, color: "gray" }, isMemoryOn ? "Learning..." : "Memory not available...")) : /* @__PURE__ */ React9.createElement(Box9, { flexDirection: "column" }, memories.map((mem, idx) => {
5182
5615
  const isSelected = idx === selectedIndex;
5183
- return /* @__PURE__ */ React8.createElement(
5184
- Box8,
5616
+ return /* @__PURE__ */ React9.createElement(
5617
+ Box9,
5185
5618
  {
5186
5619
  key: mem.id,
5187
5620
  paddingX: 1,
5188
5621
  backgroundColor: isSelected ? "#2a2a2a" : void 0,
5189
5622
  width: "100%"
5190
5623
  },
5191
- /* @__PURE__ */ React8.createElement(Box8, { flexGrow: 1 }, /* @__PURE__ */ React8.createElement(Text8, { color: isSelected ? "cyan" : "white", bold: isSelected }, isSelected ? "\u276F " : " ", idx + 1, ". ", cleanDisplay(mem.memory))),
5192
- isSelected && /* @__PURE__ */ React8.createElement(Box8, { flexShrink: 0 }, /* @__PURE__ */ React8.createElement(Text8, { color: "red", bold: true }, "[X] WIPE "))
5624
+ /* @__PURE__ */ React9.createElement(Box9, { flexGrow: 1 }, /* @__PURE__ */ React9.createElement(Text9, { color: isSelected ? "cyan" : "white", bold: isSelected }, isSelected ? "\u276F " : " ", idx + 1, ". ", cleanDisplay(mem.memory))),
5625
+ isSelected && /* @__PURE__ */ React9.createElement(Box9, { flexShrink: 0 }, /* @__PURE__ */ React9.createElement(Text9, { color: "red", bold: true }, "[X] WIPE "))
5193
5626
  );
5194
- })), /* @__PURE__ */ React8.createElement(
5195
- Box8,
5627
+ })), /* @__PURE__ */ React9.createElement(
5628
+ Box9,
5196
5629
  {
5197
5630
  marginTop: 1,
5198
5631
  paddingX: 1,
@@ -5202,7 +5635,7 @@ function MemoryModal({ onClose }) {
5202
5635
  borderBottom: false,
5203
5636
  borderColor: "gray"
5204
5637
  },
5205
- /* @__PURE__ */ React8.createElement(Text8, { dimColor: true, italic: true }, "\u2191\u2193 navigate \u2022 x wipe memory \u2022 Esc close")
5638
+ /* @__PURE__ */ React9.createElement(Text9, { dimColor: true, italic: true }, "\u2191\u2193 navigate \u2022 x wipe memory \u2022 Esc close")
5206
5639
  ));
5207
5640
  }
5208
5641
  var init_MemoryModal = __esm({
@@ -5214,17 +5647,17 @@ var init_MemoryModal = __esm({
5214
5647
  });
5215
5648
 
5216
5649
  // src/components/UpdateProcessor.jsx
5217
- import React9, { useState as useState6, useEffect as useEffect5 } from "react";
5218
- import { Box as Box9, Text as Text9 } from "ink";
5650
+ import React10, { useState as useState7, useEffect as useEffect5 } from "react";
5651
+ import { Box as Box10, Text as Text10 } from "ink";
5219
5652
  import Spinner from "ink-spinner";
5220
5653
  import { exec as exec2 } from "child_process";
5221
5654
  var UpdateProcessor, UpdateProcessor_default;
5222
5655
  var init_UpdateProcessor = __esm({
5223
5656
  "src/components/UpdateProcessor.jsx"() {
5224
5657
  UpdateProcessor = ({ latest, current, settings, onClose, onUpdateSettings, onSuccess }) => {
5225
- const [status, setStatus] = useState6("initializing");
5226
- const [log, setLog] = useState6("");
5227
- const [error, setError] = useState6(null);
5658
+ const [status, setStatus] = useState7("initializing");
5659
+ const [log, setLog] = useState7("");
5660
+ const [error, setError] = useState7(null);
5228
5661
  useEffect5(() => {
5229
5662
  let child;
5230
5663
  const runUpdate = async () => {
@@ -5265,13 +5698,13 @@ var init_UpdateProcessor = __esm({
5265
5698
  };
5266
5699
  }, []);
5267
5700
  if (status === "initializing" || status === "downloading") {
5268
- return /* @__PURE__ */ React9.createElement(Box9, { flexDirection: "column", borderStyle: "round", borderColor: "cyan", paddingX: 2, paddingY: 1 }, /* @__PURE__ */ React9.createElement(Box9, null, /* @__PURE__ */ React9.createElement(Text9, { color: "cyan" }, /* @__PURE__ */ React9.createElement(Spinner, { type: "dots" })), /* @__PURE__ */ React9.createElement(Text9, { marginLeft: 1, bold: true }, " Updating Flux Flow to v", latest, "...")), /* @__PURE__ */ React9.createElement(Box9, { marginTop: 1, paddingX: 1, borderStyle: "single", borderColor: "#333" }, /* @__PURE__ */ React9.createElement(Text9, { color: "gray", dimColor: true, italic: true }, log || "Preparing environment...")), /* @__PURE__ */ React9.createElement(Text9, { marginTop: 1, dimColor: true }, "(Please do not close the terminal)"));
5701
+ return /* @__PURE__ */ React10.createElement(Box10, { flexDirection: "column", borderStyle: "round", borderColor: "cyan", paddingX: 2, paddingY: 1 }, /* @__PURE__ */ React10.createElement(Box10, null, /* @__PURE__ */ React10.createElement(Text10, { color: "cyan" }, /* @__PURE__ */ React10.createElement(Spinner, { type: "dots" })), /* @__PURE__ */ React10.createElement(Text10, { marginLeft: 1, bold: true }, " Updating Flux Flow to v", latest, "...")), /* @__PURE__ */ React10.createElement(Box10, { marginTop: 1, paddingX: 1, borderStyle: "single", borderColor: "#333" }, /* @__PURE__ */ React10.createElement(Text10, { color: "gray", dimColor: true, italic: true }, log || "Preparing environment...")), /* @__PURE__ */ React10.createElement(Text10, { marginTop: 1, dimColor: true }, "(Please do not close the terminal)"));
5269
5702
  }
5270
5703
  if (status === "success") {
5271
- return /* @__PURE__ */ React9.createElement(Box9, { flexDirection: "column", borderStyle: "round", borderColor: "green", paddingX: 2, paddingY: 1 }, /* @__PURE__ */ React9.createElement(Text9, { color: "green", bold: true }, "\u2705 UPDATE SUCCESSFUL!"), /* @__PURE__ */ React9.createElement(Text9, { marginTop: 1 }, "Flux Flow has been updated to ", /* @__PURE__ */ React9.createElement(Text9, { color: "cyan" }, "v", latest), "."), /* @__PURE__ */ React9.createElement(Text9, { marginTop: 1, color: "yellow", bold: true }, "CRITICAL: Please restart your terminal session to apply changes."), /* @__PURE__ */ React9.createElement(Box9, { marginTop: 1 }, /* @__PURE__ */ React9.createElement(Text9, { dimColor: true }, "(Press ESC to return to chat)")));
5704
+ return /* @__PURE__ */ React10.createElement(Box10, { flexDirection: "column", borderStyle: "round", borderColor: "green", paddingX: 2, paddingY: 1 }, /* @__PURE__ */ React10.createElement(Text10, { color: "green", bold: true }, "\u2705 UPDATE SUCCESSFUL!"), /* @__PURE__ */ React10.createElement(Text10, { marginTop: 1 }, "Flux Flow has been updated to ", /* @__PURE__ */ React10.createElement(Text10, { color: "cyan" }, "v", latest), "."), /* @__PURE__ */ React10.createElement(Text10, { marginTop: 1, color: "yellow", bold: true }, "CRITICAL: Please restart your terminal session to apply changes."), /* @__PURE__ */ React10.createElement(Box10, { marginTop: 1 }, /* @__PURE__ */ React10.createElement(Text10, { dimColor: true }, "(Press ESC to return to chat)")));
5272
5705
  }
5273
5706
  if (status === "error") {
5274
- return /* @__PURE__ */ React9.createElement(Box9, { flexDirection: "column", borderStyle: "round", borderColor: "red", paddingX: 2, paddingY: 1 }, /* @__PURE__ */ React9.createElement(Text9, { color: "red", bold: true }, "\u274C UPDATE FAILED"), /* @__PURE__ */ React9.createElement(Box9, { marginTop: 1, paddingX: 1, borderStyle: "single", borderColor: "red" }, /* @__PURE__ */ React9.createElement(Text9, { color: "red" }, error)), /* @__PURE__ */ React9.createElement(Text9, { marginTop: 1 }, "Possible causes:"), /* @__PURE__ */ React9.createElement(Text9, null, "\u2022 Missing permissions (Try running as Administrator/Sudo)"), /* @__PURE__ */ React9.createElement(Text9, null, "\u2022 Package manager (", settings.updateManager, ") not found"), /* @__PURE__ */ React9.createElement(Text9, null, "\u2022 Network failure"), /* @__PURE__ */ React9.createElement(Box9, { marginTop: 1 }, /* @__PURE__ */ React9.createElement(Text9, { dimColor: true }, "(Press ESC to return to chat)")));
5707
+ return /* @__PURE__ */ React10.createElement(Box10, { flexDirection: "column", borderStyle: "round", borderColor: "red", paddingX: 2, paddingY: 1 }, /* @__PURE__ */ React10.createElement(Text10, { color: "red", bold: true }, "\u274C UPDATE FAILED"), /* @__PURE__ */ React10.createElement(Box10, { marginTop: 1, paddingX: 1, borderStyle: "single", borderColor: "red" }, /* @__PURE__ */ React10.createElement(Text10, { color: "red" }, error)), /* @__PURE__ */ React10.createElement(Text10, { marginTop: 1 }, "Possible causes:"), /* @__PURE__ */ React10.createElement(Text10, null, "\u2022 Missing permissions (Try running as Administrator/Sudo)"), /* @__PURE__ */ React10.createElement(Text10, null, "\u2022 Package manager (", settings.updateManager, ") not found"), /* @__PURE__ */ React10.createElement(Text10, null, "\u2022 Network failure"), /* @__PURE__ */ React10.createElement(Box10, { marginTop: 1 }, /* @__PURE__ */ React10.createElement(Text10, { dimColor: true }, "(Press ESC to return to chat)")));
5275
5708
  }
5276
5709
  return null;
5277
5710
  };
@@ -5280,11 +5713,11 @@ var init_UpdateProcessor = __esm({
5280
5713
  });
5281
5714
 
5282
5715
  // src/components/RevertModal.jsx
5283
- import React10, { useState as useState7 } from "react";
5284
- import { Box as Box10, Text as Text10, useInput as useInput4 } from "ink";
5716
+ import React11, { useState as useState8 } from "react";
5717
+ import { Box as Box11, Text as Text11, useInput as useInput5 } from "ink";
5285
5718
  function RevertModal({ prompts, onSelect, onClose }) {
5286
- const [selectedIndex, setSelectedIndex] = useState7(0);
5287
- useInput4((input, key) => {
5719
+ const [selectedIndex, setSelectedIndex] = useState8(0);
5720
+ useInput5((input, key) => {
5288
5721
  if (key.escape) onClose();
5289
5722
  if (key.upArrow) setSelectedIndex((prev) => Math.max(0, prev - 1));
5290
5723
  if (key.downArrow) setSelectedIndex((prev) => Math.min(prompts.length - 1, prev + 1));
@@ -5303,23 +5736,23 @@ function RevertModal({ prompts, onSelect, onClose }) {
5303
5736
  }
5304
5737
  }
5305
5738
  const visiblePrompts = prompts.slice(startIndex, startIndex + MAX_VISIBLE);
5306
- return /* @__PURE__ */ React10.createElement(Box10, { flexDirection: "column", borderStyle: "round", borderColor: "cyan", padding: 0, width: "100%" }, /* @__PURE__ */ React10.createElement(Box10, { paddingX: 1, marginBottom: 1 }, /* @__PURE__ */ React10.createElement(Text10, { color: "cyan", bold: true }, "\u{1F504} CODEBASE TIME TRAVEL: SELECT UNDO POINT")), /* @__PURE__ */ React10.createElement(Box10, { paddingX: 2, marginBottom: 1 }, /* @__PURE__ */ React10.createElement(Text10, null, "Select a prompt to revert the codebase back to the state ", /* @__PURE__ */ React10.createElement(Text10, { bold: true, color: "blue" }, "immediately before"), " it was executed:")), prompts.length === 0 ? /* @__PURE__ */ React10.createElement(Box10, { paddingX: 2, paddingY: 1 }, /* @__PURE__ */ React10.createElement(Text10, { italic: true, color: "gray" }, "No prompt checkpoints found for this session.")) : /* @__PURE__ */ React10.createElement(Box10, { flexDirection: "column", width: "100%" }, startIndex > 0 && /* @__PURE__ */ React10.createElement(Box10, { paddingX: 2, marginBottom: 1 }, /* @__PURE__ */ React10.createElement(Text10, { color: "gray", dimColor: true }, "\u25B2 (+", startIndex, " more prompts above)")), visiblePrompts.map((p, index) => {
5739
+ return /* @__PURE__ */ React11.createElement(Box11, { flexDirection: "column", borderStyle: "round", borderColor: "cyan", padding: 0, width: "100%" }, /* @__PURE__ */ React11.createElement(Box11, { paddingX: 1, marginBottom: 1 }, /* @__PURE__ */ React11.createElement(Text11, { color: "cyan", bold: true }, "\u{1F504} CODEBASE TIME TRAVEL: SELECT UNDO POINT")), /* @__PURE__ */ React11.createElement(Box11, { paddingX: 2, marginBottom: 1 }, /* @__PURE__ */ React11.createElement(Text11, null, "Select a prompt to revert the codebase back to the state ", /* @__PURE__ */ React11.createElement(Text11, { bold: true, color: "blue" }, "immediately before"), " it was executed:")), prompts.length === 0 ? /* @__PURE__ */ React11.createElement(Box11, { paddingX: 2, paddingY: 1 }, /* @__PURE__ */ React11.createElement(Text11, { italic: true, color: "gray" }, "No prompt checkpoints found for this session.")) : /* @__PURE__ */ React11.createElement(Box11, { flexDirection: "column", width: "100%" }, startIndex > 0 && /* @__PURE__ */ React11.createElement(Box11, { paddingX: 2, marginBottom: 1 }, /* @__PURE__ */ React11.createElement(Text11, { color: "gray", dimColor: true }, "\u25B2 (+", startIndex, " more prompts above)")), visiblePrompts.map((p, index) => {
5307
5740
  const actualIndex = startIndex + index;
5308
5741
  const isSelected = actualIndex === selectedIndex;
5309
5742
  const dateStr = formatDate2(p.timestamp);
5310
5743
  const fileCount = p.changes ? p.changes.length : 0;
5311
- return /* @__PURE__ */ React10.createElement(
5312
- Box10,
5744
+ return /* @__PURE__ */ React11.createElement(
5745
+ Box11,
5313
5746
  {
5314
5747
  key: p.id,
5315
5748
  paddingX: 1,
5316
5749
  backgroundColor: isSelected ? "#1a2a3a" : void 0,
5317
5750
  width: "100%"
5318
5751
  },
5319
- /* @__PURE__ */ React10.createElement(Box10, { flexGrow: 1 }, /* @__PURE__ */ React10.createElement(Text10, { color: isSelected ? "cyan" : "white", bold: isSelected }, isSelected ? "\u276F " : " ", '"', formatPromptPreview(p.prompt), '"', /* @__PURE__ */ React10.createElement(Text10, { color: "gray", dimColor: !isSelected }, " [", dateStr, " \u2022 ", fileCount, " file(s) changed]")))
5752
+ /* @__PURE__ */ React11.createElement(Box11, { flexGrow: 1 }, /* @__PURE__ */ React11.createElement(Text11, { color: isSelected ? "cyan" : "white", bold: isSelected }, isSelected ? "\u276F " : " ", '"', formatPromptPreview(p.prompt), '"', /* @__PURE__ */ React11.createElement(Text11, { color: "gray", dimColor: !isSelected }, " [", dateStr, " \u2022 ", fileCount, " file(s) changed]")))
5320
5753
  );
5321
- }), startIndex + MAX_VISIBLE < prompts.length && /* @__PURE__ */ React10.createElement(Box10, { paddingX: 2, marginTop: 1 }, /* @__PURE__ */ React10.createElement(Text10, { color: "gray", dimColor: true }, "\u25BC (+", prompts.length - (startIndex + MAX_VISIBLE), " more prompts below)"))), /* @__PURE__ */ React10.createElement(
5322
- Box10,
5754
+ }), startIndex + MAX_VISIBLE < prompts.length && /* @__PURE__ */ React11.createElement(Box11, { paddingX: 2, marginTop: 1 }, /* @__PURE__ */ React11.createElement(Text11, { color: "gray", dimColor: true }, "\u25BC (+", prompts.length - (startIndex + MAX_VISIBLE), " more prompts below)"))), /* @__PURE__ */ React11.createElement(
5755
+ Box11,
5323
5756
  {
5324
5757
  marginTop: 1,
5325
5758
  paddingX: 1,
@@ -5329,7 +5762,7 @@ function RevertModal({ prompts, onSelect, onClose }) {
5329
5762
  borderBottom: false,
5330
5763
  borderColor: "cyan"
5331
5764
  },
5332
- /* @__PURE__ */ React10.createElement(Text10, { dimColor: true, italic: true }, "\u2191\u2193 navigate \u2022 Enter select undo point \u2022 Esc close")
5765
+ /* @__PURE__ */ React11.createElement(Text11, { dimColor: true, italic: true }, "\u2191\u2193 navigate \u2022 Enter select undo point \u2022 Esc close")
5333
5766
  ));
5334
5767
  }
5335
5768
  function formatPromptPreview(prompt) {
@@ -5403,28 +5836,28 @@ __export(app_exports, {
5403
5836
  default: () => App
5404
5837
  });
5405
5838
  import os4 from "os";
5406
- import React11, { useState as useState8, useEffect as useEffect6, useRef as useRef2, useMemo } from "react";
5407
- import { Box as Box11, Text as Text11, useInput as useInput5, useStdout } from "ink";
5839
+ import React12, { useState as useState9, useEffect as useEffect6, useRef as useRef2, useMemo } from "react";
5840
+ import { Box as Box12, Text as Text12, useInput as useInput6, useStdout } from "ink";
5408
5841
  import Spinner2 from "ink-spinner";
5409
5842
  import fs18 from "fs-extra";
5410
5843
  import path16 from "path";
5411
5844
  import { exec as exec4 } from "child_process";
5412
5845
  import { fileURLToPath } from "url";
5413
5846
  import { MultilineInput } from "ink-multiline-input";
5414
- import TextInput3 from "ink-text-input";
5847
+ import TextInput4 from "ink-text-input";
5415
5848
  import gradient from "gradient-string";
5416
5849
  function App({ args = [] }) {
5417
- const [confirmExit, setConfirmExit] = useState8(false);
5418
- const [exitCountdown, setExitCountdown] = useState8(10);
5850
+ const [confirmExit, setConfirmExit] = useState9(false);
5851
+ const [exitCountdown, setExitCountdown] = useState9(10);
5419
5852
  const { stdout } = useStdout();
5420
- const [input, setInput] = useState8("");
5421
- const [isExpanded, setIsExpanded] = useState8(false);
5422
- const [mode, setMode] = useState8("Flux");
5423
- const [terminalSize, setTerminalSize] = useState8({
5853
+ const [input, setInput] = useState9("");
5854
+ const [isExpanded, setIsExpanded] = useState9(false);
5855
+ const [mode, setMode] = useState9("Flux");
5856
+ const [terminalSize, setTerminalSize] = useState9({
5424
5857
  columns: stdout?.columns || 80,
5425
5858
  rows: stdout?.rows || 24
5426
5859
  });
5427
- const [selectedIndex, setSelectedIndex] = useState8(0);
5860
+ const [selectedIndex, setSelectedIndex] = useState9(0);
5428
5861
  const persistedModelRef = useRef2(null);
5429
5862
  const parsedArgs = useMemo(() => {
5430
5863
  const parsed = {};
@@ -5528,37 +5961,37 @@ function App({ args = [] }) {
5528
5961
  stdout.off("resize", handleResize);
5529
5962
  };
5530
5963
  }, [stdout]);
5531
- const [thinkingLevel, setThinkingLevel] = useState8("Medium");
5532
- const [latestVer, setLatestVer] = useState8(null);
5533
- const [showFullThinking, setShowFullThinking] = useState8(false);
5534
- const [activeModel, setActiveModel] = useState8("gemma-4-31b-it");
5535
- const [janitorModel, setJanitorModel] = useState8("gemma-4-26b-a4b-it");
5536
- const [isInitializing, setIsInitializing] = useState8(true);
5537
- const [apiKey, setApiKey] = useState8(null);
5538
- const [tempKey, setTempKey] = useState8("");
5539
- const [activeView, setActiveView] = useState8("chat");
5540
- const [apiTier, setApiTier] = useState8("Free");
5541
- const [quotas, setQuotas] = useState8({ agentLimit: 1500, backgroundLimit: 1500, searchLimit: 100, customModelId: "", customLimit: 0 });
5542
- const [inputConfig, setInputConfig] = useState8(null);
5543
- const [systemSettings, setSystemSettings] = useState8({ memory: true, compression: 0, autoExec: false, autoDeleteHistory: "7d", autoUpdate: false, updateManager: "npm", customUpdateCommand: "" });
5544
- const [profileData, setProfileData] = useState8({ name: null, nickname: null, instructions: null });
5545
- const [imageSettings, setImageSettings] = useState8({ keyType: "Default", quality: "Low-High", apiKey: "" });
5546
- const [sessionStats, setSessionStats] = useState8({ tokens: 0 });
5547
- const [sessionAgentCalls, setSessionAgentCalls] = useState8(0);
5548
- const [sessionBackgroundCalls, setSessionBackgroundCalls] = useState8(0);
5549
- const [sessionTotalTokens, setSessionTotalTokens] = useState8(0);
5550
- const [sessionToolSuccess, setSessionToolSuccess] = useState8(0);
5551
- const [sessionToolFailure, setSessionToolFailure] = useState8(0);
5552
- const [sessionToolDenied, setSessionToolDenied] = useState8(0);
5553
- const [sessionApiTime, setSessionApiTime] = useState8(0);
5554
- const [sessionToolTime, setSessionToolTime] = useState8(0);
5555
- const [sessionImageCount, setSessionImageCount] = useState8(0);
5556
- const [sessionImageCredits, setSessionImageCredits] = useState8(0);
5557
- const [dailyUsage, setDailyUsage] = useState8(null);
5558
- const [chatId, setChatId] = useState8(generateChatId());
5559
- const [activeCommand, setActiveCommand] = useState8(null);
5560
- const [execOutput, setExecOutput] = useState8("");
5561
- const [isTerminalFocused, setIsTerminalFocused] = useState8(false);
5964
+ const [thinkingLevel, setThinkingLevel] = useState9("Medium");
5965
+ const [latestVer, setLatestVer] = useState9(null);
5966
+ const [showFullThinking, setShowFullThinking] = useState9(false);
5967
+ const [activeModel, setActiveModel] = useState9("gemma-4-31b-it");
5968
+ const [janitorModel, setJanitorModel] = useState9("gemma-4-26b-a4b-it");
5969
+ const [isInitializing, setIsInitializing] = useState9(true);
5970
+ const [apiKey, setApiKey] = useState9(null);
5971
+ const [tempKey, setTempKey] = useState9("");
5972
+ const [activeView, setActiveView] = useState9("chat");
5973
+ const [apiTier, setApiTier] = useState9("Free");
5974
+ const [quotas, setQuotas] = useState9({ agentLimit: 1500, backgroundLimit: 1500, searchLimit: 100, customModelId: "", customLimit: 0 });
5975
+ const [inputConfig, setInputConfig] = useState9(null);
5976
+ const [systemSettings, setSystemSettings] = useState9({ memory: true, compression: 0, autoExec: false, autoDeleteHistory: "7d", autoUpdate: false, updateManager: "npm", customUpdateCommand: "" });
5977
+ const [profileData, setProfileData] = useState9({ name: null, nickname: null, instructions: null });
5978
+ const [imageSettings, setImageSettings] = useState9({ keyType: "Default", quality: "Low-High", apiKey: "" });
5979
+ const [sessionStats, setSessionStats] = useState9({ tokens: 0 });
5980
+ const [sessionAgentCalls, setSessionAgentCalls] = useState9(0);
5981
+ const [sessionBackgroundCalls, setSessionBackgroundCalls] = useState9(0);
5982
+ const [sessionTotalTokens, setSessionTotalTokens] = useState9(0);
5983
+ const [sessionToolSuccess, setSessionToolSuccess] = useState9(0);
5984
+ const [sessionToolFailure, setSessionToolFailure] = useState9(0);
5985
+ const [sessionToolDenied, setSessionToolDenied] = useState9(0);
5986
+ const [sessionApiTime, setSessionApiTime] = useState9(0);
5987
+ const [sessionToolTime, setSessionToolTime] = useState9(0);
5988
+ const [sessionImageCount, setSessionImageCount] = useState9(0);
5989
+ const [sessionImageCredits, setSessionImageCredits] = useState9(0);
5990
+ const [dailyUsage, setDailyUsage] = useState9(null);
5991
+ const [chatId, setChatId] = useState9(generateChatId());
5992
+ const [activeCommand, setActiveCommand] = useState9(null);
5993
+ const [execOutput, setExecOutput] = useState9("");
5994
+ const [isTerminalFocused, setIsTerminalFocused] = useState9(false);
5562
5995
  useEffect6(() => {
5563
5996
  if (apiTier !== "Free" && activeModel === "gemma-4-31b-it") {
5564
5997
  setActiveModel("gemini-3-flash-preview");
@@ -5588,9 +6021,9 @@ function App({ args = [] }) {
5588
6021
  useEffect6(() => {
5589
6022
  execOutputRef.current = execOutput;
5590
6023
  }, [execOutput]);
5591
- const [autoAcceptWrites, setAutoAcceptWrites] = useState8(false);
5592
- const [pendingApproval, setPendingApproval] = useState8(null);
5593
- const [pendingAsk, setPendingAsk] = useState8(null);
6024
+ const [autoAcceptWrites, setAutoAcceptWrites] = useState9(false);
6025
+ const [pendingApproval, setPendingApproval] = useState9(null);
6026
+ const [pendingAsk, setPendingAsk] = useState9(null);
5594
6027
  const formatDuration = (totalSecs) => {
5595
6028
  const h = Math.floor(totalSecs / 3600);
5596
6029
  const m = Math.floor(totalSecs % 3600 / 60);
@@ -5605,18 +6038,18 @@ function App({ args = [] }) {
5605
6038
  if (ms < 1e3) return `${ms}ms`;
5606
6039
  return formatDuration(Math.floor(ms / 1e3));
5607
6040
  };
5608
- const [statusText, setStatusText] = useState8(null);
5609
- const [isSpinnerActive, setIsSpinnerActive] = useState8(true);
5610
- const [isProcessing, setIsProcessing] = useState8(false);
5611
- const [escPressed, setEscPressed] = useState8(false);
5612
- const [escTimer, setEscTimer] = useState8(null);
5613
- const [escPressCount, setEscPressCount] = useState8(0);
5614
- const [recentPrompts, setRecentPrompts] = useState8([]);
6041
+ const [statusText, setStatusText] = useState9(null);
6042
+ const [isSpinnerActive, setIsSpinnerActive] = useState9(true);
6043
+ const [isProcessing, setIsProcessing] = useState9(false);
6044
+ const [escPressed, setEscPressed] = useState9(false);
6045
+ const [escTimer, setEscTimer] = useState9(null);
6046
+ const [escPressCount, setEscPressCount] = useState9(0);
6047
+ const [recentPrompts, setRecentPrompts] = useState9([]);
5615
6048
  const escDoubleTimerRef = useRef2(null);
5616
- const [queuedPrompt, setQueuedPrompt] = useState8(null);
5617
- const [resolutionData, setResolutionData] = useState8(null);
5618
- const [tempModelOverride, setTempModelOverride] = useState8(null);
5619
- const [messages, setMessages] = useState8(() => {
6049
+ const [queuedPrompt, setQueuedPrompt] = useState9(null);
6050
+ const [resolutionData, setResolutionData] = useState9(null);
6051
+ const [tempModelOverride, setTempModelOverride] = useState9(null);
6052
+ const [messages, setMessages] = useState9(() => {
5620
6053
  const logoMsg = { id: "logo-" + Date.now(), role: "system", text: FLUX_LOGO, isLogo: true, isMeta: true };
5621
6054
  const welcomeMsg = { id: "welcome", role: "system", text: "\u{1F30A}\u26A1 Welcome to Flux Flow! Type /help for commands.", isMeta: true };
5622
6055
  const isHomeDir = process.cwd() === os4.homedir();
@@ -5655,7 +6088,7 @@ function App({ args = [] }) {
5655
6088
  return msgs;
5656
6089
  });
5657
6090
  const queuedPromptRef = useRef2(null);
5658
- const [completedIndex, setCompletedIndex] = useState8(messages.length);
6091
+ const [completedIndex, setCompletedIndex] = useState9(messages.length);
5659
6092
  const windowedHistory = useMemo(() => {
5660
6093
  const MAX_HISTORY_LINES = 2e3;
5661
6094
  const width = terminalSize.columns || 80;
@@ -5690,7 +6123,7 @@ function App({ args = [] }) {
5690
6123
  return acc + Math.max(1, Math.ceil(line.length / wrapWidth));
5691
6124
  }, 0);
5692
6125
  const maxLines = Math.max(1, wrappedLinesCount);
5693
- useInput5((inputText, key) => {
6126
+ useInput6((inputText, key) => {
5694
6127
  if (key.tab && activeCommand) {
5695
6128
  setIsTerminalFocused((prev) => !prev);
5696
6129
  return;
@@ -5739,7 +6172,7 @@ function App({ args = [] }) {
5739
6172
  if (activeView === "revert") {
5740
6173
  setActiveView("chat");
5741
6174
  setEscPressCount(0);
5742
- } else if (activeView !== "chat") {
6175
+ } else if (activeView !== "chat" && activeView !== "settings") {
5743
6176
  setActiveView("chat");
5744
6177
  } else {
5745
6178
  setEscPressCount((prev) => {
@@ -6166,6 +6599,8 @@ ${hintText}`, color: "magenta" }];
6166
6599
  setChatId(generateChatId());
6167
6600
  setSessionStats({ tokens: 0 });
6168
6601
  setIsExpanded(false);
6602
+ linesAdded = 0;
6603
+ linesRemoved = 0;
6169
6604
  break;
6170
6605
  }
6171
6606
  case "/revert": {
@@ -6653,6 +7088,7 @@ ${timestamp}` };
6653
7088
  },
6654
7089
  onExecEnd: () => {
6655
7090
  setMessages((prev) => {
7091
+ if (!activeCommandRef.current) return prev;
6656
7092
  const finalStatus = `[TERMINAL_RECORD]
6657
7093
  COMMAND: ${activeCommandRef.current}
6658
7094
  OUTPUT: ${execOutputRef.current}`;
@@ -6840,6 +7276,58 @@ Selection: ${val}`,
6840
7276
  // v1.5.0 Multimodal Support
6841
7277
  toolName: packet.toolName
6842
7278
  }]);
7279
+ if (packet.toolName === "update_file" && packet.aiContent) {
7280
+ const diffLines = packet.aiContent.split("\n");
7281
+ let added = 0;
7282
+ let removed = 0;
7283
+ let insideDiff = false;
7284
+ for (const line of diffLines) {
7285
+ if (line.includes("[DIFF_START]")) {
7286
+ insideDiff = true;
7287
+ continue;
7288
+ }
7289
+ if (line.includes("[DIFF_END]")) {
7290
+ insideDiff = false;
7291
+ continue;
7292
+ }
7293
+ if (insideDiff) {
7294
+ if (/^\+\d+/.test(line)) {
7295
+ added++;
7296
+ } else if (/^\-\d+/.test(line)) {
7297
+ removed++;
7298
+ }
7299
+ }
7300
+ }
7301
+ linesAdded += added;
7302
+ linesRemoved += removed;
7303
+ addToUsage("linesAdded", added);
7304
+ addToUsage("linesRemoved", removed);
7305
+ } else if (packet.toolName === "write_file" && packet.aiContent) {
7306
+ const statsMatch = packet.aiContent.match(/- Stats: \[(\d+) lines/);
7307
+ const verifiedLinesCount = statsMatch ? parseInt(statsMatch[1]) : 0;
7308
+ let oldLinesCount = 0;
7309
+ if (packet.aiContent.includes("Old File contents:")) {
7310
+ const ancestryLines = packet.aiContent.split("\n");
7311
+ let insideOldFile = false;
7312
+ for (const line of ancestryLines) {
7313
+ if (line.includes("Old File contents:")) {
7314
+ insideOldFile = true;
7315
+ continue;
7316
+ }
7317
+ if (insideOldFile) {
7318
+ if (line.trim() === "") {
7319
+ insideOldFile = false;
7320
+ } else if (/^\d+ \|/.test(line)) {
7321
+ oldLinesCount++;
7322
+ }
7323
+ }
7324
+ }
7325
+ }
7326
+ linesAdded += verifiedLinesCount;
7327
+ linesRemoved += oldLinesCount;
7328
+ addToUsage("linesAdded", verifiedLinesCount);
7329
+ addToUsage("linesRemoved", oldLinesCount);
7330
+ }
6843
7331
  continue;
6844
7332
  }
6845
7333
  let chunkText = packet.content;
@@ -6875,16 +7363,21 @@ Selection: ${val}`,
6875
7363
  thinkConsumedInTurn = true;
6876
7364
  chunkText = chunkText.replace(/<(think|thought)>[\s\S]*?<\/(think|thought)>/gi, "").replace(/<(think|thought)>/gi, "");
6877
7365
  currentThinkId = "think-" + Date.now();
6878
- setMessages((prev) => [...prev, { id: currentThinkId, role: "think", text: "", isStreaming: true }]);
7366
+ setMessages((prev) => [...prev, { id: currentThinkId, role: "think", text: "", isStreaming: true, startTime: Date.now() }]);
6879
7367
  }
6880
7368
  if (chunkLower.includes("</think>") || chunkLower.includes("</thought>")) {
6881
7369
  const parts = chunkText.split(/<\/(think|thought)>/gi);
6882
7370
  const thinkPart = parts[0] || "";
6883
7371
  const agentPart = parts.slice(2).join("").replace(/<\/?(think|thought)>/gi, "");
6884
7372
  setMessages((prev) => {
6885
- const newMsgs = prev.map(
6886
- (m) => m.id === currentThinkId ? { ...m, text: m.text + thinkPart, isStreaming: true } : m
6887
- );
7373
+ const newMsgs = prev.map((m) => {
7374
+ if (m.id === currentThinkId) {
7375
+ const startTime = m.startTime || parseInt(m.id.split("-")[1]) || Date.now();
7376
+ const duration = Date.now() - startTime;
7377
+ return { ...m, text: m.text + thinkPart, isStreaming: false, duration };
7378
+ }
7379
+ return m;
7380
+ });
6888
7381
  inThinkMode = false;
6889
7382
  currentAgentId = "agent-" + Date.now();
6890
7383
  return [...newMsgs, { id: currentAgentId, role: "agent", text: agentPart, isStreaming: true }];
@@ -6902,7 +7395,9 @@ Selection: ${val}`,
6902
7395
  transitioning = true;
6903
7396
  const parts = newText.split(/<\/think>/gi);
6904
7397
  transitionContent = parts.slice(1).join("</think>") || "";
6905
- return { ...m, text: parts[0] };
7398
+ const startTime = m.startTime || parseInt(m.id.split("-")[1]) || Date.now();
7399
+ const duration = Date.now() - startTime;
7400
+ return { ...m, text: parts[0], isStreaming: false, duration };
6906
7401
  }
6907
7402
  return { ...m, text: newText, isStreaming: true };
6908
7403
  }
@@ -7003,75 +7498,21 @@ Selection: ${val}`,
7003
7498
  const renderActiveView = () => {
7004
7499
  switch (activeView) {
7005
7500
  case "settings":
7006
- return /* @__PURE__ */ React11.createElement(
7007
- CommandMenu,
7501
+ return /* @__PURE__ */ React12.createElement(
7502
+ SettingsMenu,
7008
7503
  {
7009
- title: "System Settings",
7010
- items: [
7011
- { label: `Toggle Memory [ ${systemSettings.memory ? "ON" : "OFF"} ]`, value: "memory" },
7012
- { label: `Toggle Auto-Exec [ ${systemSettings.autoExec ? "ON" : "OFF"} ]`, value: "autoExec" },
7013
- { label: `External Workspace Access [ ${systemSettings.allowExternalAccess ? "ON" : "OFF"} ]`, value: "externalAccess" },
7014
- { label: `API Tier [ ${apiTier} ]`, value: "apiTier" },
7015
- { label: `Auto-Delete History [ ${systemSettings.autoDeleteHistory || "30d"} ]`, value: "autoDelete" },
7016
- { label: `Auto-Update [ ${systemSettings.autoUpdate ? "ON" : "OFF"} ]`, value: "autoUpdate" },
7017
- { label: `Preferred Updater [ ${(systemSettings.updateManager || "npm") === "custom" ? "Custom" : (systemSettings.updateManager || "npm").toUpperCase()} ]`, value: "updateManager" },
7018
- { label: `Save AppData Externally [ ${systemSettings.useExternalData ? "ON" : "OFF"} ]`, value: "externalData" },
7019
- { label: "Exit Settings", value: "Cancel" }
7020
- ],
7021
- onSelect: (item) => {
7022
- if (item.value === "memory") setSystemSettings((s) => ({ ...s, memory: !s.memory }));
7023
- else if (item.value === "autoExec") {
7024
- if (!systemSettings.autoExec) {
7025
- if (systemSettings.allowExternalAccess) {
7026
- setActiveView("doubleDanger");
7027
- } else {
7028
- setActiveView("autoExecDanger");
7029
- }
7030
- } else {
7031
- setSystemSettings((s) => ({ ...s, autoExec: false }));
7032
- }
7033
- } else if (item.value === "externalAccess") {
7034
- if (!systemSettings.allowExternalAccess) {
7035
- if (systemSettings.autoExec) {
7036
- setActiveView("doubleDanger");
7037
- } else {
7038
- setActiveView("externalDanger");
7039
- }
7040
- } else {
7041
- setSystemSettings((s) => ({ ...s, allowExternalAccess: false }));
7042
- }
7043
- } else if (item.value === "apiTier") setActiveView("apiTier");
7044
- else if (item.value === "autoDelete") {
7045
- const options = ["1d", "7d", "30d"];
7046
- const currentIndex = options.indexOf(systemSettings.autoDeleteHistory || "30d");
7047
- const nextIndex = (currentIndex + 1) % options.length;
7048
- setSystemSettings((s) => ({ ...s, autoDeleteHistory: options[nextIndex] }));
7049
- } else if (item.value === "autoUpdate") {
7050
- setSystemSettings((s) => ({ ...s, autoUpdate: !s.autoUpdate }));
7051
- } else if (item.value === "externalData") {
7052
- if (!systemSettings.useExternalData) {
7053
- setInputConfig({
7054
- label: "Enter absolute path for External AppData:",
7055
- note: "All history, logs and secrets will be stored here. ~/.fluxflow/settings.json stays as anchor.",
7056
- key: "externalDataPath",
7057
- value: systemSettings.externalDataPath || ""
7058
- });
7059
- setActiveView("input");
7060
- } else {
7061
- const newSettings = { ...systemSettings, useExternalData: false };
7062
- setSystemSettings(newSettings);
7063
- saveSettings({ systemSettings: newSettings, apiTier, quotas });
7064
- setMessages((prev) => [...prev, { id: Date.now(), role: "system", text: "\u{1F3E0} [STORAGE RESET] Flux Flow will return to default ~/.fluxflow after restart." }]);
7065
- setActiveView("chat");
7066
- }
7067
- } else if (item.value === "updateManager") {
7068
- setActiveView("updateManager");
7069
- } else if (item.value === "Cancel") setActiveView("chat");
7070
- }
7504
+ systemSettings,
7505
+ setSystemSettings,
7506
+ apiTier,
7507
+ setActiveView,
7508
+ setInputConfig,
7509
+ saveSettings,
7510
+ quotas,
7511
+ setMessages
7071
7512
  }
7072
7513
  );
7073
7514
  case "apiTier":
7074
- return /* @__PURE__ */ React11.createElement(
7515
+ return /* @__PURE__ */ React12.createElement(
7075
7516
  CommandMenu,
7076
7517
  {
7077
7518
  title: `API Tier: ${apiTier}`,
@@ -7104,8 +7545,8 @@ Selection: ${val}`,
7104
7545
  }
7105
7546
  );
7106
7547
  case "input":
7107
- return /* @__PURE__ */ React11.createElement(Box11, { flexDirection: "column", borderStyle: "round", borderColor: "gray", padding: 0, width: "100%" }, /* @__PURE__ */ React11.createElement(Box11, { paddingX: 1 }, /* @__PURE__ */ React11.createElement(Text11, { color: "magenta", bold: true }, "\u{1F527} DATA CONFIGURATION")), inputConfig?.note && /* @__PURE__ */ React11.createElement(Box11, { paddingX: 1, marginBottom: 1 }, /* @__PURE__ */ React11.createElement(Text11, { color: "yellow", dimColor: true, italic: true }, inputConfig.note)), /* @__PURE__ */ React11.createElement(Box11, { paddingX: 1, flexDirection: "row" }, /* @__PURE__ */ React11.createElement(Text11, { color: "cyan", bold: true }, inputConfig?.label, " "), /* @__PURE__ */ React11.createElement(
7108
- TextInput3,
7548
+ return /* @__PURE__ */ React12.createElement(Box12, { flexDirection: "column", borderStyle: "round", borderColor: "gray", padding: 0, width: "100%" }, /* @__PURE__ */ React12.createElement(Box12, { paddingX: 1 }, /* @__PURE__ */ React12.createElement(Text12, { color: "magenta", bold: true }, "\u{1F527} DATA CONFIGURATION")), inputConfig?.note && /* @__PURE__ */ React12.createElement(Box12, { paddingX: 1, marginBottom: 1 }, /* @__PURE__ */ React12.createElement(Text12, { color: "yellow", dimColor: true, italic: true }, inputConfig.note)), /* @__PURE__ */ React12.createElement(Box12, { paddingX: 1, flexDirection: "row" }, /* @__PURE__ */ React12.createElement(Text12, { color: "cyan", bold: true }, inputConfig?.label, " "), /* @__PURE__ */ React12.createElement(
7549
+ TextInput4,
7109
7550
  {
7110
7551
  value: inputConfig?.value || "",
7111
7552
  onChange: (val) => setInputConfig((prev) => ({ ...prev, value: val })),
@@ -7124,6 +7565,10 @@ Selection: ${val}`,
7124
7565
  } else if (key === "janitorModel") {
7125
7566
  setJanitorModel(val);
7126
7567
  newSettings.janitorModel = val;
7568
+ } else if (key === "autoApproveCommands" || key === "autoDisallowCommands" || key === "alwaysAskCommands") {
7569
+ const newSysSettings = { ...systemSettings, [key]: val.trim(), sandboxPreset: "Custom" };
7570
+ setSystemSettings(newSysSettings);
7571
+ newSettings.systemSettings = newSysSettings;
7127
7572
  } else if (key === "externalDataPath") {
7128
7573
  const newSysSettings = { ...systemSettings, useExternalData: true, externalDataPath: val.trim() };
7129
7574
  setSystemSettings(newSysSettings);
@@ -7157,11 +7602,11 @@ Selection: ${val}`,
7157
7602
  }
7158
7603
  }
7159
7604
  }
7160
- )), /* @__PURE__ */ React11.createElement(Box11, { paddingX: 1, marginTop: 1 }, /* @__PURE__ */ React11.createElement(Text11, { color: "gray", dimColor: true, italic: true }, "(Press Enter to confirm selection)")));
7605
+ )), /* @__PURE__ */ React12.createElement(Box12, { paddingX: 1, marginTop: 1 }, /* @__PURE__ */ React12.createElement(Text12, { color: "gray", dimColor: true, italic: true }, "(Press Enter to confirm selection)")));
7161
7606
  case "stats":
7162
- return /* @__PURE__ */ React11.createElement(Box11, { flexDirection: "column", borderStyle: "round", paddingX: 3, paddingY: 1, width: Math.min(100, (stdout?.columns || 100) - 2) }, /* @__PURE__ */ React11.createElement(Box11, { marginBottom: 1 }, /* @__PURE__ */ React11.createElement(Text11, { color: "white", bold: true, underline: true }, "SESSION TELEMETRY")), /* @__PURE__ */ React11.createElement(Box11, { flexDirection: "column" }, /* @__PURE__ */ React11.createElement(Box11, null, /* @__PURE__ */ React11.createElement(Box11, { width: 25 }, /* @__PURE__ */ React11.createElement(Text11, { color: "blue" }, "Session Duration:")), /* @__PURE__ */ React11.createElement(Text11, { color: "white" }, formatMsDuration(Date.now() - SESSION_START_TIME))), /* @__PURE__ */ React11.createElement(Box11, null, /* @__PURE__ */ React11.createElement(Box11, { width: 25 }, /* @__PURE__ */ React11.createElement(Text11, { color: "blue" }, "Agent Interactions:")), /* @__PURE__ */ React11.createElement(Text11, { color: "white" }, sessionAgentCalls)), /* @__PURE__ */ React11.createElement(Box11, { marginLeft: 2 }, /* @__PURE__ */ React11.createElement(Box11, { width: 23 }, /* @__PURE__ */ React11.createElement(Text11, { color: "blue", dimColor: true }, "\xBB API Time:")), /* @__PURE__ */ React11.createElement(Text11, { color: "white" }, formatMsDuration(sessionApiTime))), /* @__PURE__ */ React11.createElement(Box11, { marginLeft: 2 }, /* @__PURE__ */ React11.createElement(Box11, { width: 23 }, /* @__PURE__ */ React11.createElement(Text11, { color: "blue", dimColor: true }, "\xBB Tool Time:")), /* @__PURE__ */ React11.createElement(Text11, { color: "white" }, formatMsDuration(sessionToolTime))), /* @__PURE__ */ React11.createElement(Box11, null, /* @__PURE__ */ React11.createElement(Box11, { width: 25 }, /* @__PURE__ */ React11.createElement(Text11, { color: "blue" }, "Background Tasks:")), /* @__PURE__ */ React11.createElement(Text11, { color: "white" }, sessionBackgroundCalls)), /* @__PURE__ */ React11.createElement(Box11, null, /* @__PURE__ */ React11.createElement(Box11, { width: 25 }, /* @__PURE__ */ React11.createElement(Text11, { color: "blue" }, "Tokens Consumed:")), /* @__PURE__ */ React11.createElement(Text11, { color: "white" }, formatTokens(sessionTotalTokens))), /* @__PURE__ */ React11.createElement(Box11, null, /* @__PURE__ */ React11.createElement(Box11, { width: 25 }, /* @__PURE__ */ React11.createElement(Text11, { color: "blue" }, "Images Made:")), /* @__PURE__ */ React11.createElement(Text11, { color: "white" }, sessionImageCount || 0)), /* @__PURE__ */ React11.createElement(Box11, null, /* @__PURE__ */ React11.createElement(Box11, { width: 25 }, /* @__PURE__ */ React11.createElement(Text11, { color: "blue" }, "Image Credits:")), /* @__PURE__ */ React11.createElement(Text11, { color: "white" }, Number(((sessionImageCredits || 0) * 1e3).toFixed(0)), " credits")), /* @__PURE__ */ React11.createElement(Box11, null, /* @__PURE__ */ React11.createElement(Box11, { width: 25 }, /* @__PURE__ */ React11.createElement(Text11, { color: "blue" }, "Tool Calls (Sess):")), /* @__PURE__ */ React11.createElement(Text11, { color: "white" }, sessionToolSuccess + sessionToolFailure + sessionToolDenied, " ( "), /* @__PURE__ */ React11.createElement(Text11, { color: "green" }, "\u2713 ", sessionToolSuccess), /* @__PURE__ */ React11.createElement(Text11, { color: "white" }, " "), /* @__PURE__ */ React11.createElement(Text11, { color: "yellow" }, "\u2298 ", sessionToolDenied), /* @__PURE__ */ React11.createElement(Text11, { color: "white" }, " "), /* @__PURE__ */ React11.createElement(Text11, { color: "red" }, "\u2715 ", sessionToolFailure), /* @__PURE__ */ React11.createElement(Text11, { color: "white" }, " )"))), /* @__PURE__ */ React11.createElement(Box11, { flexDirection: "column", marginTop: 1 }, /* @__PURE__ */ React11.createElement(Text11, { color: "white", bold: true, underline: true }, "DAILY USAGE TRACKER"), /* @__PURE__ */ React11.createElement(Box11, { marginTop: 1 }, /* @__PURE__ */ React11.createElement(Box11, { width: 25 }, /* @__PURE__ */ React11.createElement(Text11, { color: "blue" }, "Wall Time Today:")), /* @__PURE__ */ React11.createElement(Text11, { color: "white" }, formatDuration(dailyUsage?.duration || 0))), /* @__PURE__ */ React11.createElement(Box11, null, /* @__PURE__ */ React11.createElement(Box11, { width: 25 }, /* @__PURE__ */ React11.createElement(Text11, { color: "blue" }, "Agent Interactions:")), /* @__PURE__ */ React11.createElement(Text11, { color: "white" }, dailyUsage?.agent || 0)), /* @__PURE__ */ React11.createElement(Box11, null, /* @__PURE__ */ React11.createElement(Box11, { width: 25 }, /* @__PURE__ */ React11.createElement(Text11, { color: "blue" }, "Background Tasks:")), /* @__PURE__ */ React11.createElement(Text11, { color: "white" }, dailyUsage?.background || 0)), /* @__PURE__ */ React11.createElement(Box11, null, /* @__PURE__ */ React11.createElement(Box11, { width: 25 }, /* @__PURE__ */ React11.createElement(Text11, { color: "blue" }, "Tokens Used Today:")), /* @__PURE__ */ React11.createElement(Text11, { color: "white" }, formatTokens(dailyUsage?.tokens || 0))), /* @__PURE__ */ React11.createElement(Box11, null, /* @__PURE__ */ React11.createElement(Box11, { width: 25 }, /* @__PURE__ */ React11.createElement(Text11, { color: "blue" }, "Images Made Today:")), /* @__PURE__ */ React11.createElement(Text11, { color: "white" }, dailyUsage?.imageCalls?.length || 0)), /* @__PURE__ */ React11.createElement(Box11, null, /* @__PURE__ */ React11.createElement(Box11, { width: 25 }, /* @__PURE__ */ React11.createElement(Text11, { color: "blue" }, "Image Credits Today:")), /* @__PURE__ */ React11.createElement(Text11, { color: "white" }, Number(((dailyUsage?.imageCalls?.reduce((sum, c) => sum + c.cost, 0) || 0) * 1e3).toFixed(0)), " credits")), /* @__PURE__ */ React11.createElement(Box11, null, /* @__PURE__ */ React11.createElement(Box11, { width: 25 }, /* @__PURE__ */ React11.createElement(Text11, { color: "blue" }, "Tool Calls Today:")), /* @__PURE__ */ React11.createElement(Text11, { color: "white" }, (dailyUsage?.toolSuccess || 0) + (dailyUsage?.toolFailure || 0) + (dailyUsage?.toolDenied || 0), " ( "), /* @__PURE__ */ React11.createElement(Text11, { color: "green" }, "\u2713 ", dailyUsage?.toolSuccess || 0), /* @__PURE__ */ React11.createElement(Text11, { color: "white" }, " "), /* @__PURE__ */ React11.createElement(Text11, { color: "yellow" }, "\u2298 ", dailyUsage?.toolDenied || 0), /* @__PURE__ */ React11.createElement(Text11, { color: "white" }, " "), /* @__PURE__ */ React11.createElement(Text11, { color: "red" }, "\u2715 ", dailyUsage?.toolFailure || 0), /* @__PURE__ */ React11.createElement(Text11, { color: "white" }, " )"))), /* @__PURE__ */ React11.createElement(Text11, { dimColor: true, marginTop: 1, italic: true }, "(Press ESC to return to chat)"));
7607
+ return /* @__PURE__ */ React12.createElement(Box12, { flexDirection: "column", borderStyle: "round", paddingX: 3, paddingY: 1, width: Math.min(100, (stdout?.columns || 100) - 2) }, /* @__PURE__ */ React12.createElement(Box12, { marginBottom: 1 }, /* @__PURE__ */ React12.createElement(Text12, { color: "white", bold: true, underline: true }, "SESSION TELEMETRY")), /* @__PURE__ */ React12.createElement(Box12, { flexDirection: "column" }, /* @__PURE__ */ React12.createElement(Box12, null, /* @__PURE__ */ React12.createElement(Box12, { width: 25 }, /* @__PURE__ */ React12.createElement(Text12, { color: "blue" }, "Session Duration:")), /* @__PURE__ */ React12.createElement(Text12, { color: "white" }, formatMsDuration(Date.now() - SESSION_START_TIME))), /* @__PURE__ */ React12.createElement(Box12, null, /* @__PURE__ */ React12.createElement(Box12, { width: 25 }, /* @__PURE__ */ React12.createElement(Text12, { color: "blue" }, "Agent Interactions:")), /* @__PURE__ */ React12.createElement(Text12, { color: "white" }, sessionAgentCalls)), /* @__PURE__ */ React12.createElement(Box12, { marginLeft: 2 }, /* @__PURE__ */ React12.createElement(Box12, { width: 23 }, /* @__PURE__ */ React12.createElement(Text12, { color: "blue", dimColor: true }, "\xBB API Time:")), /* @__PURE__ */ React12.createElement(Text12, { color: "white" }, formatMsDuration(sessionApiTime))), /* @__PURE__ */ React12.createElement(Box12, { marginLeft: 2 }, /* @__PURE__ */ React12.createElement(Box12, { width: 23 }, /* @__PURE__ */ React12.createElement(Text12, { color: "blue", dimColor: true }, "\xBB Tool Time:")), /* @__PURE__ */ React12.createElement(Text12, { color: "white" }, formatMsDuration(sessionToolTime))), /* @__PURE__ */ React12.createElement(Box12, null, /* @__PURE__ */ React12.createElement(Box12, { width: 25 }, /* @__PURE__ */ React12.createElement(Text12, { color: "blue" }, "Background Tasks:")), /* @__PURE__ */ React12.createElement(Text12, { color: "white" }, sessionBackgroundCalls)), /* @__PURE__ */ React12.createElement(Box12, null, /* @__PURE__ */ React12.createElement(Box12, { width: 25 }, /* @__PURE__ */ React12.createElement(Text12, { color: "blue" }, "Tokens Consumed:")), /* @__PURE__ */ React12.createElement(Text12, { color: "white" }, formatTokens(sessionTotalTokens))), /* @__PURE__ */ React12.createElement(Box12, null, /* @__PURE__ */ React12.createElement(Box12, { width: 25 }, /* @__PURE__ */ React12.createElement(Text12, { color: "blue" }, "Images Made:")), /* @__PURE__ */ React12.createElement(Text12, { color: "white" }, sessionImageCount || 0)), /* @__PURE__ */ React12.createElement(Box12, null, /* @__PURE__ */ React12.createElement(Box12, { width: 25 }, /* @__PURE__ */ React12.createElement(Text12, { color: "blue" }, "Image Credits:")), /* @__PURE__ */ React12.createElement(Text12, { color: "white" }, Number(((sessionImageCredits || 0) * 1e3).toFixed(0)), " credits")), /* @__PURE__ */ React12.createElement(Box12, null, /* @__PURE__ */ React12.createElement(Box12, { width: 25 }, /* @__PURE__ */ React12.createElement(Text12, { color: "blue" }, "Code Changes (Sess):")), /* @__PURE__ */ React12.createElement(Text12, { color: "white" }, /* @__PURE__ */ React12.createElement(Text12, { color: "green" }, "+", linesAdded), " ", /* @__PURE__ */ React12.createElement(Text12, { color: "red" }, "-", linesRemoved))), /* @__PURE__ */ React12.createElement(Box12, null, /* @__PURE__ */ React12.createElement(Box12, { width: 25 }, /* @__PURE__ */ React12.createElement(Text12, { color: "blue" }, "Tool Calls (Sess):")), /* @__PURE__ */ React12.createElement(Text12, { color: "white" }, sessionToolSuccess + sessionToolFailure + sessionToolDenied, " ( "), /* @__PURE__ */ React12.createElement(Text12, { color: "green" }, "\u2713 ", sessionToolSuccess), /* @__PURE__ */ React12.createElement(Text12, { color: "white" }, " "), /* @__PURE__ */ React12.createElement(Text12, { color: "yellow" }, "\u2298 ", sessionToolDenied), /* @__PURE__ */ React12.createElement(Text12, { color: "white" }, " "), /* @__PURE__ */ React12.createElement(Text12, { color: "red" }, "\u2715 ", sessionToolFailure), /* @__PURE__ */ React12.createElement(Text12, { color: "white" }, " )"))), /* @__PURE__ */ React12.createElement(Box12, { flexDirection: "column", marginTop: 1 }, /* @__PURE__ */ React12.createElement(Text12, { color: "white", bold: true, underline: true }, "DAILY USAGE TRACKER"), /* @__PURE__ */ React12.createElement(Box12, { marginTop: 1 }, /* @__PURE__ */ React12.createElement(Box12, { width: 25 }, /* @__PURE__ */ React12.createElement(Text12, { color: "blue" }, "Wall Time Today:")), /* @__PURE__ */ React12.createElement(Text12, { color: "white" }, formatDuration(dailyUsage?.duration || 0))), /* @__PURE__ */ React12.createElement(Box12, null, /* @__PURE__ */ React12.createElement(Box12, { width: 25 }, /* @__PURE__ */ React12.createElement(Text12, { color: "blue" }, "Agent Interactions:")), /* @__PURE__ */ React12.createElement(Text12, { color: "white" }, dailyUsage?.agent || 0)), /* @__PURE__ */ React12.createElement(Box12, null, /* @__PURE__ */ React12.createElement(Box12, { width: 25 }, /* @__PURE__ */ React12.createElement(Text12, { color: "blue" }, "Background Tasks:")), /* @__PURE__ */ React12.createElement(Text12, { color: "white" }, dailyUsage?.background || 0)), /* @__PURE__ */ React12.createElement(Box12, null, /* @__PURE__ */ React12.createElement(Box12, { width: 25 }, /* @__PURE__ */ React12.createElement(Text12, { color: "blue" }, "Tokens Used Today:")), /* @__PURE__ */ React12.createElement(Text12, { color: "white" }, formatTokens(dailyUsage?.tokens || 0))), /* @__PURE__ */ React12.createElement(Box12, null, /* @__PURE__ */ React12.createElement(Box12, { width: 25 }, /* @__PURE__ */ React12.createElement(Text12, { color: "blue" }, "Images Made Today:")), /* @__PURE__ */ React12.createElement(Text12, { color: "white" }, dailyUsage?.imageCalls?.length || 0)), /* @__PURE__ */ React12.createElement(Box12, null, /* @__PURE__ */ React12.createElement(Box12, { width: 25 }, /* @__PURE__ */ React12.createElement(Text12, { color: "blue" }, "Image Credits Today:")), /* @__PURE__ */ React12.createElement(Text12, { color: "white" }, Number(((dailyUsage?.imageCalls?.reduce((sum, c) => sum + c.cost, 0) || 0) * 1e3).toFixed(0)), " credits")), /* @__PURE__ */ React12.createElement(Box12, null, /* @__PURE__ */ React12.createElement(Box12, { width: 25 }, /* @__PURE__ */ React12.createElement(Text12, { color: "blue" }, "Code Changes Today:")), /* @__PURE__ */ React12.createElement(Text12, { color: "white" }, /* @__PURE__ */ React12.createElement(Text12, { color: "green" }, "+", dailyUsage?.linesAdded || 0), " ", /* @__PURE__ */ React12.createElement(Text12, { color: "red" }, "-", dailyUsage?.linesRemoved || 0))), /* @__PURE__ */ React12.createElement(Box12, null, /* @__PURE__ */ React12.createElement(Box12, { width: 25 }, /* @__PURE__ */ React12.createElement(Text12, { color: "blue" }, "Tool Calls Today:")), /* @__PURE__ */ React12.createElement(Text12, { color: "white" }, (dailyUsage?.toolSuccess || 0) + (dailyUsage?.toolFailure || 0) + (dailyUsage?.toolDenied || 0), " ( "), /* @__PURE__ */ React12.createElement(Text12, { color: "green" }, "\u2713 ", dailyUsage?.toolSuccess || 0), /* @__PURE__ */ React12.createElement(Text12, { color: "white" }, " "), /* @__PURE__ */ React12.createElement(Text12, { color: "yellow" }, "\u2298 ", dailyUsage?.toolDenied || 0), /* @__PURE__ */ React12.createElement(Text12, { color: "white" }, " "), /* @__PURE__ */ React12.createElement(Text12, { color: "red" }, "\u2715 ", dailyUsage?.toolFailure || 0), /* @__PURE__ */ React12.createElement(Text12, { color: "white" }, " )"))), /* @__PURE__ */ React12.createElement(Text12, { dimColor: true, marginTop: 1, italic: true }, "(Press ESC to return to chat)"));
7163
7608
  case "autoExecDanger":
7164
- return /* @__PURE__ */ React11.createElement(Box11, { flexDirection: "column", borderStyle: "round", borderColor: "yellow", paddingX: 2, paddingY: 1, width: "100%" }, /* @__PURE__ */ React11.createElement(Text11, { color: "yellow", bold: true, underline: true }, "\u26A0\uFE0F SECURITY WARNING: AUTO-EXEC MODE"), /* @__PURE__ */ React11.createElement(Text11, { marginTop: 1 }, "Turning this ON allows the agent to execute terminal commands automatically without requiring your approval for each step."), /* @__PURE__ */ React11.createElement(Text11, { marginTop: 1, color: "yellow" }, "RISKS INVOLVED:"), /* @__PURE__ */ React11.createElement(Text11, null, "\u2022 The agent may execute destructive commands (rm -rf, etc.) by mistake."), /* @__PURE__ */ React11.createElement(Text11, null, "\u2022 Unintended system changes if the agent hallucinates a path or command."), /* @__PURE__ */ React11.createElement(Text11, null, "\u2022 Reduced control over the agent's step-by-step decision making."), /* @__PURE__ */ React11.createElement(Box11, { marginTop: 1 }, /* @__PURE__ */ React11.createElement(
7609
+ return /* @__PURE__ */ React12.createElement(Box12, { flexDirection: "column", borderStyle: "round", borderColor: "yellow", paddingX: 2, paddingY: 1, width: "100%" }, /* @__PURE__ */ React12.createElement(Text12, { color: "yellow", bold: true, underline: true }, "\u26A0\uFE0F SECURITY WARNING: AUTO EXECUTE MODE"), /* @__PURE__ */ React12.createElement(Text12, { marginTop: 1 }, "Turning this ON allows the agent to execute terminal commands automatically without requiring your approval for each step."), /* @__PURE__ */ React12.createElement(Text12, { marginTop: 1, color: "yellow" }, "RISKS INVOLVED:"), /* @__PURE__ */ React12.createElement(Text12, null, "\u2022 The agent may execute destructive commands (rm -rf, etc.) by mistake."), /* @__PURE__ */ React12.createElement(Text12, null, "\u2022 Unintended system changes if the agent hallucinates a path or command."), /* @__PURE__ */ React12.createElement(Text12, null, "\u2022 Reduced control over the agent's step-by-step decision making."), /* @__PURE__ */ React12.createElement(Box12, { marginTop: 1 }, /* @__PURE__ */ React12.createElement(
7165
7610
  CommandMenu,
7166
7611
  {
7167
7612
  title: "Confirm Intent",
@@ -7178,7 +7623,7 @@ Selection: ${val}`,
7178
7623
  }
7179
7624
  )));
7180
7625
  case "externalDanger":
7181
- return /* @__PURE__ */ React11.createElement(Box11, { flexDirection: "column", borderStyle: "round", borderColor: "red", paddingX: 2, paddingY: 1, width: "100%" }, /* @__PURE__ */ React11.createElement(Text11, { color: "red", bold: true, underline: true }, "\u26A0\uFE0F SECURITY WARNING: EXTERNAL WORKSPACE ACCESS"), /* @__PURE__ */ React11.createElement(Text11, { marginTop: 1 }, "Turning this ON allows the agent to execute tools (Read/Write/Exec) outside of the current active workspace directory."), /* @__PURE__ */ React11.createElement(Text11, { marginTop: 1, color: "yellow" }, "RISKS INVOLVED:"), /* @__PURE__ */ React11.createElement(Text11, null, "\u2022 Access to sensitive system files (SSH keys, Browser data, etc.)"), /* @__PURE__ */ React11.createElement(Text11, null, "\u2022 Potential for accidental or malicious deletion of OS-critical files."), /* @__PURE__ */ React11.createElement(Text11, null, "\u2022 Unauthorized script execution across your entire file system."), /* @__PURE__ */ React11.createElement(Box11, { marginTop: 1 }, /* @__PURE__ */ React11.createElement(
7626
+ return /* @__PURE__ */ React12.createElement(Box12, { flexDirection: "column", borderStyle: "round", borderColor: "red", paddingX: 2, paddingY: 1, width: "100%" }, /* @__PURE__ */ React12.createElement(Text12, { color: "red", bold: true, underline: true }, "\u26A0\uFE0F SECURITY WARNING: EXTERNAL WORKSPACE ACCESS"), /* @__PURE__ */ React12.createElement(Text12, { marginTop: 1 }, "Turning this ON allows the agent to execute tools (Read/Write/Exec) outside of the current active workspace directory."), /* @__PURE__ */ React12.createElement(Text12, { marginTop: 1, color: "yellow" }, "RISKS INVOLVED:"), /* @__PURE__ */ React12.createElement(Text12, null, "\u2022 Access to sensitive system files (SSH keys, Browser data, etc.)"), /* @__PURE__ */ React12.createElement(Text12, null, "\u2022 Potential for accidental or malicious deletion of OS-critical files."), /* @__PURE__ */ React12.createElement(Text12, null, "\u2022 Unauthorized script execution across your entire file system."), /* @__PURE__ */ React12.createElement(Box12, { marginTop: 1 }, /* @__PURE__ */ React12.createElement(
7182
7627
  CommandMenu,
7183
7628
  {
7184
7629
  title: "Confirm Intent",
@@ -7195,7 +7640,7 @@ Selection: ${val}`,
7195
7640
  }
7196
7641
  )));
7197
7642
  case "doubleDanger":
7198
- return /* @__PURE__ */ React11.createElement(Box11, { flexDirection: "column", borderStyle: "round", borderColor: "red", paddingX: 2, paddingY: 1, width: "100%" }, /* @__PURE__ */ React11.createElement(Text11, { color: "red", bold: true, underline: true }, "\u26D4 CRITICAL SECURITY WARNING: COMBINED SYSTEM RISK"), /* @__PURE__ */ React11.createElement(Text11, { marginTop: 1 }, "You are attempting to enable BOTH [Auto-Exec] and [External Workspace Access] simultaneously."), /* @__PURE__ */ React11.createElement(Text11, { marginTop: 1, color: "red", bold: true }, "THIS IS NOT RECOMMENDED."), /* @__PURE__ */ React11.createElement(Text11, { marginTop: 1, color: "yellow" }, "THE CRITICAL RISK:"), /* @__PURE__ */ React11.createElement(Text11, null, "The agent will have the power to execute any command across your entire system WITHOUT your approval or supervision."), /* @__PURE__ */ React11.createElement(Text11, { color: "red", italic: true, marginTop: 1 }, "A single hallucination or error could result in full system wipe or data theft."), /* @__PURE__ */ React11.createElement(Box11, { marginTop: 1 }, /* @__PURE__ */ React11.createElement(
7643
+ return /* @__PURE__ */ React12.createElement(Box12, { flexDirection: "column", borderStyle: "round", borderColor: "red", paddingX: 2, paddingY: 1, width: "100%" }, /* @__PURE__ */ React12.createElement(Text12, { color: "red", bold: true, underline: true }, "\u26D4 CRITICAL SECURITY WARNING: COMBINED SYSTEM RISK"), /* @__PURE__ */ React12.createElement(Text12, { marginTop: 1 }, "You are attempting to enable BOTH [Auto Execute] and [External Workspace Access] simultaneously."), /* @__PURE__ */ React12.createElement(Text12, { marginTop: 1, color: "red", bold: true }, "THIS IS NOT RECOMMENDED."), /* @__PURE__ */ React12.createElement(Text12, { marginTop: 1, color: "yellow" }, "THE CRITICAL RISK:"), /* @__PURE__ */ React12.createElement(Text12, null, "The agent will have the power to execute any command across your entire system WITHOUT your approval or supervision."), /* @__PURE__ */ React12.createElement(Text12, { color: "red", italic: true, marginTop: 1 }, "A single hallucination or error could result in full system wipe or data theft."), /* @__PURE__ */ React12.createElement(Box12, { marginTop: 1 }, /* @__PURE__ */ React12.createElement(
7199
7644
  CommandMenu,
7200
7645
  {
7201
7646
  title: "Final Confirmation",
@@ -7212,7 +7657,7 @@ Selection: ${val}`,
7212
7657
  }
7213
7658
  )));
7214
7659
  case "key":
7215
- return /* @__PURE__ */ React11.createElement(
7660
+ return /* @__PURE__ */ React12.createElement(
7216
7661
  CommandMenu,
7217
7662
  {
7218
7663
  title: "\u{1F511} API KEY MANAGEMENT",
@@ -7236,10 +7681,10 @@ Selection: ${val}`,
7236
7681
  }
7237
7682
  );
7238
7683
  case "deleteKey":
7239
- return /* @__PURE__ */ React11.createElement(Box11, { flexDirection: "column", borderStyle: "round", borderColor: "red", paddingX: 2, paddingY: 1 }, (() => {
7684
+ return /* @__PURE__ */ React12.createElement(Box12, { flexDirection: "column", borderStyle: "round", borderColor: "red", paddingX: 2, paddingY: 1 }, (() => {
7240
7685
  const s = emojiSpace(2);
7241
- return /* @__PURE__ */ React11.createElement(Text11, { color: "red", bold: true }, "\u26D4", s, "DANGER: PURGE API KEY");
7242
- })(), /* @__PURE__ */ React11.createElement(Text11, { 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__ */ React11.createElement(Box11, { marginTop: 1 }, /* @__PURE__ */ React11.createElement(
7686
+ return /* @__PURE__ */ React12.createElement(Text12, { color: "red", bold: true }, "\u26D4", s, "DANGER: PURGE API KEY");
7687
+ })(), /* @__PURE__ */ React12.createElement(Text12, { 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__ */ React12.createElement(Box12, { marginTop: 1 }, /* @__PURE__ */ React12.createElement(
7243
7688
  CommandMenu,
7244
7689
  {
7245
7690
  title: "Are you absolutely sure?",
@@ -7263,7 +7708,7 @@ Selection: ${val}`,
7263
7708
  case "exit":
7264
7709
  return null;
7265
7710
  case "ask":
7266
- return /* @__PURE__ */ React11.createElement(Box11, { width: "100%" }, /* @__PURE__ */ React11.createElement(
7711
+ return /* @__PURE__ */ React12.createElement(Box12, { width: "100%" }, /* @__PURE__ */ React12.createElement(
7267
7712
  AskUserModal_default,
7268
7713
  {
7269
7714
  question: pendingAsk?.question,
@@ -7278,7 +7723,7 @@ Selection: ${val}`,
7278
7723
  }
7279
7724
  ));
7280
7725
  case "revert":
7281
- return /* @__PURE__ */ React11.createElement(Box11, { width: "100%", alignItems: "center", justifyContent: "center" }, /* @__PURE__ */ React11.createElement(
7726
+ return /* @__PURE__ */ React12.createElement(Box12, { width: "100%", alignItems: "center", justifyContent: "center" }, /* @__PURE__ */ React12.createElement(
7282
7727
  RevertModal,
7283
7728
  {
7284
7729
  prompts: recentPrompts,
@@ -7332,7 +7777,7 @@ Selection: ${val}`,
7332
7777
  }
7333
7778
  ));
7334
7779
  case "resume":
7335
- return /* @__PURE__ */ React11.createElement(Box11, { width: "100%", alignItems: "center", justifyContent: "center" }, /* @__PURE__ */ React11.createElement(
7780
+ return /* @__PURE__ */ React12.createElement(Box12, { width: "100%", alignItems: "center", justifyContent: "center" }, /* @__PURE__ */ React12.createElement(
7336
7781
  ResumeModal,
7337
7782
  {
7338
7783
  onSelect: async (id) => {
@@ -7362,9 +7807,9 @@ Selection: ${val}`,
7362
7807
  }
7363
7808
  ));
7364
7809
  case "memory":
7365
- return /* @__PURE__ */ React11.createElement(Box11, { width: "100%", alignItems: "center", justifyContent: "center" }, /* @__PURE__ */ React11.createElement(MemoryModal, { onClose: () => setActiveView("chat") }));
7810
+ return /* @__PURE__ */ React12.createElement(Box12, { width: "100%", alignItems: "center", justifyContent: "center" }, /* @__PURE__ */ React12.createElement(MemoryModal, { onClose: () => setActiveView("chat") }));
7366
7811
  case "profile":
7367
- return /* @__PURE__ */ React11.createElement(
7812
+ return /* @__PURE__ */ React12.createElement(
7368
7813
  ProfileForm,
7369
7814
  {
7370
7815
  initialData: profileData,
@@ -7377,7 +7822,7 @@ Selection: ${val}`,
7377
7822
  }
7378
7823
  );
7379
7824
  case "resolution":
7380
- return /* @__PURE__ */ React11.createElement(Box11, { width: "100%", alignItems: "center", justifyContent: "center" }, /* @__PURE__ */ React11.createElement(
7825
+ return /* @__PURE__ */ React12.createElement(Box12, { width: "100%", alignItems: "center", justifyContent: "center" }, /* @__PURE__ */ React12.createElement(
7381
7826
  ResolutionModal,
7382
7827
  {
7383
7828
  data: resolutionData,
@@ -7396,15 +7841,15 @@ Selection: ${val}`,
7396
7841
  }
7397
7842
  ));
7398
7843
  case "approval":
7399
- return /* @__PURE__ */ React11.createElement(Box11, { flexDirection: "column", borderStyle: "round", borderColor: "yellow", paddingX: 2, paddingY: 1, width: "100%" }, /* @__PURE__ */ React11.createElement(Text11, { color: "yellow", bold: true, underline: true }, "\u{1F510} SECURITY GATE: FILE WRITE PERMISSION"), /* @__PURE__ */ React11.createElement(Text11, { marginTop: 1 }, "The agent is attempting to modify: ", /* @__PURE__ */ React11.createElement(Text11, { color: "cyan" }, parseArgs(pendingApproval?.args || "{}").path || "Unknown File")), /* @__PURE__ */ React11.createElement(Box11, { marginTop: 1, borderStyle: "single", borderColor: "#333", paddingX: 1, flexDirection: "column" }, /* @__PURE__ */ React11.createElement(Text11, { color: "gray" }, "--- PROPOSED CONTENT / DIFF ---"), (() => {
7844
+ return /* @__PURE__ */ React12.createElement(Box12, { flexDirection: "column", borderStyle: "round", borderColor: "yellow", paddingX: 2, paddingY: 1, width: "100%" }, /* @__PURE__ */ React12.createElement(Text12, { color: "yellow", bold: true, underline: true }, "\u{1F510} SECURITY GATE: FILE WRITE PERMISSION"), /* @__PURE__ */ React12.createElement(Text12, { marginTop: 1 }, "The agent is attempting to modify: ", /* @__PURE__ */ React12.createElement(Text12, { color: "cyan" }, parseArgs(pendingApproval?.args || "{}").path || "Unknown File")), /* @__PURE__ */ React12.createElement(Box12, { marginTop: 1, borderStyle: "single", borderColor: "#333", paddingX: 1, flexDirection: "column" }, /* @__PURE__ */ React12.createElement(Text12, { color: "gray" }, "--- PROPOSED CONTENT / DIFF ---"), (() => {
7400
7845
  const args2 = parseArgs(pendingApproval?.args || "{}");
7401
7846
  const oldVal = args2.TargetContent || args2.content_to_replace || args2.replaceContent || null;
7402
7847
  const newVal = args2.content || args2.ReplacementContent || args2.content_to_add || args2.replacementContent || args2.newContent || null;
7403
7848
  if (oldVal && newVal) {
7404
- return /* @__PURE__ */ React11.createElement(Box11, { flexDirection: "column", marginTop: 1 }, /* @__PURE__ */ React11.createElement(Box11, null, /* @__PURE__ */ React11.createElement(Text11, { color: "red", wrap: "anywhere", bold: true }, "- ", oldVal)), /* @__PURE__ */ React11.createElement(Box11, { marginTop: 1 }, /* @__PURE__ */ React11.createElement(Text11, { color: "green", wrap: "anywhere", bold: true }, "+ ", newVal.replace(/\[\/n\]?/g, "\\n"))));
7849
+ return /* @__PURE__ */ React12.createElement(Box12, { flexDirection: "column", marginTop: 1 }, /* @__PURE__ */ React12.createElement(Box12, null, /* @__PURE__ */ React12.createElement(Text12, { color: "red", wrap: "anywhere", bold: true }, "- ", oldVal)), /* @__PURE__ */ React12.createElement(Box12, { marginTop: 1 }, /* @__PURE__ */ React12.createElement(Text12, { color: "green", wrap: "anywhere", bold: true }, "+ ", newVal.replace(/\[\/n\]?/g, "\\n"))));
7405
7850
  }
7406
- return /* @__PURE__ */ React11.createElement(Text11, { color: "white", wrap: "anywhere" }, (newVal ? newVal.replace(/\[\/n\]?/g, "\\n") : null) || "Updating file content...");
7407
- })()), /* @__PURE__ */ React11.createElement(Box11, { marginTop: 1 }, /* @__PURE__ */ React11.createElement(
7851
+ return /* @__PURE__ */ React12.createElement(Text12, { color: "white", wrap: "anywhere" }, (newVal ? newVal.replace(/\[\/n\]?/g, "\\n") : null) || "Updating file content...");
7852
+ })()), /* @__PURE__ */ React12.createElement(Box12, { marginTop: 1 }, /* @__PURE__ */ React12.createElement(
7408
7853
  CommandMenu,
7409
7854
  {
7410
7855
  title: "Action Required",
@@ -7423,7 +7868,7 @@ Selection: ${val}`,
7423
7868
  }
7424
7869
  )));
7425
7870
  case "updateManager":
7426
- return /* @__PURE__ */ React11.createElement(
7871
+ return /* @__PURE__ */ React12.createElement(
7427
7872
  CommandMenu,
7428
7873
  {
7429
7874
  title: "Select Preferred Update Manager",
@@ -7460,7 +7905,7 @@ Selection: ${val}`,
7460
7905
  }
7461
7906
  );
7462
7907
  case "update":
7463
- return /* @__PURE__ */ React11.createElement(
7908
+ return /* @__PURE__ */ React12.createElement(
7464
7909
  UpdateProcessor_default,
7465
7910
  {
7466
7911
  latest: latestVer,
@@ -7486,7 +7931,7 @@ Selection: ${val}`,
7486
7931
  }
7487
7932
  );
7488
7933
  case "terminalApproval":
7489
- return /* @__PURE__ */ React11.createElement(Box11, { flexDirection: "column", borderStyle: "round", borderColor: "red", paddingX: 2, paddingY: 1, width: "100%" }, /* @__PURE__ */ React11.createElement(Text11, { color: "red", bold: true, underline: true }, "\u{1F510} SECURITY GATE: TERMINAL COMMAND OVERSIGHT"), /* @__PURE__ */ React11.createElement(Box11, { marginTop: 1 }, /* @__PURE__ */ React11.createElement(Text11, null, "Agent requested to run: ", /* @__PURE__ */ React11.createElement(Text11, { color: "yellow", bold: true }, parseArgs(pendingApproval?.args || "{}").command || "Unknown Command"))), /* @__PURE__ */ React11.createElement(Box11, { marginTop: 1 }, /* @__PURE__ */ React11.createElement(
7934
+ return /* @__PURE__ */ React12.createElement(Box12, { flexDirection: "column", borderStyle: "round", borderColor: "red", paddingX: 2, paddingY: 1, width: "100%" }, /* @__PURE__ */ React12.createElement(Text12, { color: "red", bold: true, underline: true }, "\u{1F510} SECURITY GATE: TERMINAL COMMAND OVERSIGHT"), /* @__PURE__ */ React12.createElement(Box12, { marginTop: 1 }, /* @__PURE__ */ React12.createElement(Text12, null, "Agent requested to run: ", /* @__PURE__ */ React12.createElement(Text12, { color: "yellow", bold: true }, parseArgs(pendingApproval?.args || "{}").command || "Unknown Command"))), /* @__PURE__ */ React12.createElement(Box12, { marginTop: 1 }, /* @__PURE__ */ React12.createElement(
7490
7935
  CommandMenu,
7491
7936
  {
7492
7937
  title: "Risk Assessment Required",
@@ -7502,8 +7947,8 @@ Selection: ${val}`,
7502
7947
  }
7503
7948
  )));
7504
7949
  default:
7505
- return /* @__PURE__ */ React11.createElement(Box11, { flexDirection: "column", marginTop: 1, flexShrink: 0, width: "100%" }, /* @__PURE__ */ React11.createElement(Box11, { paddingX: 1, marginBottom: 0, justifyContent: "space-between", width: "100%" }, /* @__PURE__ */ React11.createElement(Box11, null, statusText ? /* @__PURE__ */ React11.createElement(Box11, null, isSpinnerActive && /* @__PURE__ */ React11.createElement(Text11, { color: "magenta" }, /* @__PURE__ */ React11.createElement(Spinner2, { type: "dots" })), /* @__PURE__ */ React11.createElement(Text11, { color: "magenta", bold: true, italic: true }, isSpinnerActive ? " " : "", statusText.toUpperCase())) : /* @__PURE__ */ React11.createElement(Text11, { color: "cyan", dimColor: true, italic: true }, "READY FOR COMMAND...")), /* @__PURE__ */ React11.createElement(Box11, null, /* @__PURE__ */ React11.createElement(Text11, { color: "gray", bold: true }, "[ "), /* @__PURE__ */ React11.createElement(Text11, { color: "white" }, tempModelOverride || activeModel), /* @__PURE__ */ React11.createElement(Text11, { color: "gray", bold: true }, " ]"))), /* @__PURE__ */ React11.createElement(
7506
- Box11,
7950
+ return /* @__PURE__ */ React12.createElement(Box12, { flexDirection: "column", marginTop: 1, flexShrink: 0, width: "100%" }, /* @__PURE__ */ React12.createElement(Box12, { paddingX: 1, marginBottom: 0, justifyContent: "space-between", width: "100%" }, /* @__PURE__ */ React12.createElement(Box12, null, statusText ? /* @__PURE__ */ React12.createElement(Box12, null, isSpinnerActive && /* @__PURE__ */ React12.createElement(Text12, { color: "magenta" }, /* @__PURE__ */ React12.createElement(Spinner2, { type: "dots" })), /* @__PURE__ */ React12.createElement(Text12, { color: "magenta", bold: true, italic: true }, isSpinnerActive ? " " : "", statusText.toUpperCase())) : /* @__PURE__ */ React12.createElement(Text12, { color: "cyan", dimColor: true, italic: true }, "READY FOR COMMAND...")), /* @__PURE__ */ React12.createElement(Box12, null, /* @__PURE__ */ React12.createElement(Text12, { color: "gray", bold: true }, "[ "), /* @__PURE__ */ React12.createElement(Text12, { color: "white" }, tempModelOverride || activeModel), /* @__PURE__ */ React12.createElement(Text12, { color: "gray", bold: true }, " ]"))), /* @__PURE__ */ React12.createElement(
7951
+ Box12,
7507
7952
  {
7508
7953
  borderStyle: "round",
7509
7954
  borderColor: isProcessing ? "magenta" : "cyan",
@@ -7511,7 +7956,7 @@ Selection: ${val}`,
7511
7956
  paddingY: 0,
7512
7957
  width: "100%"
7513
7958
  },
7514
- /* @__PURE__ */ React11.createElement(Box11, { flexDirection: "column", width: "100%" }, maxLines > 2 && !isExpanded ? /* @__PURE__ */ React11.createElement(Box11, { flexDirection: "row", width: "100%", paddingY: 0, height: 1, overflow: "hidden" }, /* @__PURE__ */ React11.createElement(Box11, { flexShrink: 0, width: 4 }, /* @__PURE__ */ React11.createElement(Text11, { color: "cyan", bold: true }, "\u{1F4A0} ")), /* @__PURE__ */ React11.createElement(Box11, { flexGrow: 1, flexDirection: "row" }, /* @__PURE__ */ React11.createElement(Box11, { flexShrink: 0 }, /* @__PURE__ */ React11.createElement(Text11, { color: "magenta", bold: true }, "[PASTED ", maxLines, " LINES]")), /* @__PURE__ */ React11.createElement(Box11, { flexGrow: 1, marginLeft: 1 }, /* @__PURE__ */ React11.createElement(
7959
+ /* @__PURE__ */ React12.createElement(Box12, { flexDirection: "column", width: "100%" }, maxLines > 2 && !isExpanded ? /* @__PURE__ */ React12.createElement(Box12, { flexDirection: "row", width: "100%", paddingY: 0, height: 1, overflow: "hidden" }, /* @__PURE__ */ React12.createElement(Box12, { flexShrink: 0, width: 4 }, /* @__PURE__ */ React12.createElement(Text12, { color: "cyan", bold: true }, "\u{1F4A0} ")), /* @__PURE__ */ React12.createElement(Box12, { flexGrow: 1, flexDirection: "row" }, /* @__PURE__ */ React12.createElement(Box12, { flexShrink: 0 }, /* @__PURE__ */ React12.createElement(Text12, { color: "magenta", bold: true }, "[PASTED ", maxLines, " LINES]")), /* @__PURE__ */ React12.createElement(Box12, { flexGrow: 1, marginLeft: 1 }, /* @__PURE__ */ React12.createElement(
7515
7960
  MultilineInput,
7516
7961
  {
7517
7962
  value: "",
@@ -7528,7 +7973,7 @@ Selection: ${val}`,
7528
7973
  newline: (key) => key.return && key.shift || key.return && key.ctrl || key.return && key.leftAlt || key.return && key.rightAlt
7529
7974
  }
7530
7975
  }
7531
- )))) : /* @__PURE__ */ React11.createElement(Box11, { flexDirection: "row", width: "100%", paddingY: 0 }, /* @__PURE__ */ React11.createElement(Box11, { flexShrink: 0, width: 4 }, /* @__PURE__ */ React11.createElement(Text11, { color: isProcessing ? "magenta" : "cyan", bold: true }, isProcessing ? "\u2726 " : "\u{1F4A0} ")), /* @__PURE__ */ React11.createElement(Box11, { flexGrow: 1 }, /* @__PURE__ */ React11.createElement(Box11, { flexGrow: 1, position: "relative" }, input === "" && /* @__PURE__ */ React11.createElement(Box11, { position: "absolute", paddingLeft: 0 }, activeCommand && !isTerminalFocused ? /* @__PURE__ */ React11.createElement(Text11, { color: "yellow" }, " Press TAB to interact with terminal...") : activeCommand && isTerminalFocused ? /* @__PURE__ */ React11.createElement(Text11, { color: "yellow", bold: true }, " [ TERMINAL FOCUSED ] Type to interact, press TAB to exit...") : escPressCount === 1 ? /* @__PURE__ */ React11.createElement(Text11, { color: "cyan", bold: true }, " Press ESC again to revert codebase to checkpoint...") : /* @__PURE__ */ React11.createElement(Text11, { color: "gray" }, escPressed ? " Press ESC again to cancel the request." : !isProcessing ? ` Send message or /cmd... (${terminalEnv.shortcut} for newline)` : " Enter a prompt to steer the agent.")), /* @__PURE__ */ React11.createElement(
7976
+ )))) : /* @__PURE__ */ React12.createElement(Box12, { flexDirection: "row", width: "100%", paddingY: 0 }, /* @__PURE__ */ React12.createElement(Box12, { flexShrink: 0, width: 4 }, /* @__PURE__ */ React12.createElement(Text12, { color: isProcessing ? "magenta" : "cyan", bold: true }, isProcessing ? "\u2726 " : "\u{1F4A0} ")), /* @__PURE__ */ React12.createElement(Box12, { flexGrow: 1 }, /* @__PURE__ */ React12.createElement(Box12, { flexGrow: 1, position: "relative" }, input === "" && /* @__PURE__ */ React12.createElement(Box12, { position: "absolute", paddingLeft: 0 }, activeCommand && !isTerminalFocused ? /* @__PURE__ */ React12.createElement(Text12, { color: "yellow" }, " Press TAB to interact with terminal...") : activeCommand && isTerminalFocused ? /* @__PURE__ */ React12.createElement(Text12, { color: "yellow", bold: true }, " [ TERMINAL FOCUSED ] Type to interact, press TAB to exit...") : escPressCount === 1 ? /* @__PURE__ */ React12.createElement(Text12, { color: "cyan", bold: true }, " Press ESC again to revert codebase to checkpoint...") : /* @__PURE__ */ React12.createElement(Text12, { color: "gray" }, escPressed ? " Press ESC again to cancel the request." : !isProcessing ? ` Send message or /cmd... (${terminalEnv.shortcut} for newline)` : " Enter a prompt to steer the agent.")), /* @__PURE__ */ React12.createElement(
7532
7977
  MultilineInput,
7533
7978
  {
7534
7979
  focus: !isTerminalFocused,
@@ -7548,22 +7993,22 @@ Selection: ${val}`,
7548
7993
  ));
7549
7994
  }
7550
7995
  };
7551
- return /* @__PURE__ */ React11.createElement(Box11, { flexDirection: "column", width: "100%" }, /* @__PURE__ */ React11.createElement(Box11, { flexDirection: "column", width: "100%", flexGrow: 1 }, windowedHistory.items.map((msg, idx) => /* @__PURE__ */ React11.createElement(MessageItem, { key: msg.id || idx, msg, showFullThinking, columns: stdout?.columns || 80 }))), /* @__PURE__ */ React11.createElement(Box11, { flexDirection: "column", padding: 1, width: "100%" }, (activeView === "chat" || ["ask", "approval", "terminalApproval"].includes(activeView)) && /* @__PURE__ */ React11.createElement(Box11, { flexDirection: "column", width: "100%" }, /* @__PURE__ */ React11.createElement(
7996
+ return /* @__PURE__ */ React12.createElement(Box12, { flexDirection: "column", width: "100%" }, /* @__PURE__ */ React12.createElement(Box12, { flexDirection: "column", width: "100%", flexGrow: 1 }, windowedHistory.items.map((msg, idx) => /* @__PURE__ */ React12.createElement(MessageItem, { key: msg.id || idx, msg, showFullThinking, columns: stdout?.columns || 80 }))), /* @__PURE__ */ React12.createElement(Box12, { flexDirection: "column", padding: 1, width: "100%" }, (activeView === "chat" || ["ask", "approval", "terminalApproval"].includes(activeView)) && /* @__PURE__ */ React12.createElement(Box12, { flexDirection: "column", width: "100%" }, /* @__PURE__ */ React12.createElement(
7552
7997
  ChatLayout_default,
7553
7998
  {
7554
7999
  messages: messages.slice(completedIndex),
7555
8000
  showFullThinking,
7556
8001
  columns: Math.max(20, (stdout?.columns || 80) - 1)
7557
8002
  }
7558
- ), activeCommand && /* @__PURE__ */ React11.createElement(Box11, { marginTop: 1 }, /* @__PURE__ */ React11.createElement(TerminalBox, { command: activeCommand, output: execOutput, isFocused: isTerminalFocused }))), isInitializing ? /* @__PURE__ */ React11.createElement(Box11, { borderStyle: "double", borderColor: "magenta", padding: 1, flexShrink: 0 }, /* @__PURE__ */ React11.createElement(Text11, { color: "magenta" }, "\u{1F30A} Starting Flux Flow...")) : !apiKey ? /* @__PURE__ */ React11.createElement(Box11, { borderStyle: "round", borderColor: "gray", padding: 0, flexDirection: "column", flexShrink: 0, width: "100%" }, /* @__PURE__ */ React11.createElement(Box11, { paddingX: 1, marginBottom: 1 }, /* @__PURE__ */ React11.createElement(Text11, { color: "yellow", bold: true }, "\u{1F511}", emojiSpace(2), "API KEY REQUIRED")), /* @__PURE__ */ React11.createElement(Box11, { paddingX: 1, flexDirection: "column" }, /* @__PURE__ */ React11.createElement(Text11, null, "Please enter your Gemini API Key to initialize the agent."), /* @__PURE__ */ React11.createElement(Box11, { marginTop: 1 }, /* @__PURE__ */ React11.createElement(Text11, { color: "cyan", bold: true }, "\u{1F4A0} "), /* @__PURE__ */ React11.createElement(
7559
- TextInput3,
8003
+ ), activeCommand && /* @__PURE__ */ React12.createElement(Box12, { marginTop: 1 }, /* @__PURE__ */ React12.createElement(TerminalBox, { command: activeCommand, output: execOutput, isFocused: isTerminalFocused }))), isInitializing ? /* @__PURE__ */ React12.createElement(Box12, { borderStyle: "double", borderColor: "magenta", padding: 1, flexShrink: 0 }, /* @__PURE__ */ React12.createElement(Text12, { color: "magenta" }, "\u{1F30A} Starting Flux Flow...")) : !apiKey ? /* @__PURE__ */ React12.createElement(Box12, { borderStyle: "round", borderColor: "gray", padding: 0, flexDirection: "column", flexShrink: 0, width: "100%" }, /* @__PURE__ */ React12.createElement(Box12, { paddingX: 1, marginBottom: 1 }, /* @__PURE__ */ React12.createElement(Text12, { color: "yellow", bold: true }, "\u{1F511}", emojiSpace(2), "API KEY REQUIRED")), /* @__PURE__ */ React12.createElement(Box12, { paddingX: 1, flexDirection: "column" }, /* @__PURE__ */ React12.createElement(Text12, null, "Please enter your Gemini API Key to initialize the agent."), /* @__PURE__ */ React12.createElement(Box12, { marginTop: 1 }, /* @__PURE__ */ React12.createElement(Text12, { color: "cyan", bold: true }, "\u{1F4A0} "), /* @__PURE__ */ React12.createElement(
8004
+ TextInput4,
7560
8005
  {
7561
8006
  value: tempKey,
7562
8007
  onChange: setTempKey,
7563
8008
  onSubmit: handleSetup,
7564
8009
  mask: "*"
7565
8010
  }
7566
- ))), /* @__PURE__ */ React11.createElement(Box11, { paddingX: 1, marginTop: 1 }, /* @__PURE__ */ React11.createElement(Text11, { color: "gray", dimColor: true, italic: true }, "(Press Enter to confirm and initialize)"))) : renderActiveView(), confirmExit && /* @__PURE__ */ React11.createElement(Box11, { borderStyle: "round", borderColor: "red", paddingX: 2, marginY: 0, width: "100%" }, /* @__PURE__ */ React11.createElement(Text11, { color: "red", bold: true }, "\u{1F534} EXIT CONFIRMATION: "), /* @__PURE__ */ React11.createElement(Text11, { color: "white" }, "Press "), /* @__PURE__ */ React11.createElement(Text11, { color: "red", bold: true }, "CTRL + C"), /* @__PURE__ */ React11.createElement(Text11, { color: "white" }, " again to exit (", exitCountdown, "s). Press "), /* @__PURE__ */ React11.createElement(Text11, { color: "cyan", bold: true }, "ESC"), /* @__PURE__ */ React11.createElement(Text11, { color: "white" }, " to cancel.")), /* @__PURE__ */ React11.createElement(Box11, { flexShrink: 0, width: "100%" }, /* @__PURE__ */ React11.createElement(
8011
+ ))), /* @__PURE__ */ React12.createElement(Box12, { paddingX: 1, marginTop: 1 }, /* @__PURE__ */ React12.createElement(Text12, { color: "gray", dimColor: true, italic: true }, "(Press Enter to confirm and initialize)"))) : renderActiveView(), confirmExit && /* @__PURE__ */ React12.createElement(Box12, { borderStyle: "round", borderColor: "red", paddingX: 2, marginY: 0, width: "100%" }, /* @__PURE__ */ React12.createElement(Text12, { color: "red", bold: true }, "\u{1F534} EXIT CONFIRMATION: "), /* @__PURE__ */ React12.createElement(Text12, { color: "white" }, "Press "), /* @__PURE__ */ React12.createElement(Text12, { color: "red", bold: true }, "CTRL + C"), /* @__PURE__ */ React12.createElement(Text12, { color: "white" }, " again to exit (", exitCountdown, "s). Press "), /* @__PURE__ */ React12.createElement(Text12, { color: "cyan", bold: true }, "ESC"), /* @__PURE__ */ React12.createElement(Text12, { color: "white" }, " to cancel.")), /* @__PURE__ */ React12.createElement(Box12, { flexShrink: 0, width: "100%" }, /* @__PURE__ */ React12.createElement(
7567
8012
  StatusBar_default,
7568
8013
  {
7569
8014
  mode,
@@ -7580,14 +8025,14 @@ Selection: ${val}`,
7580
8025
  const agentActiveMs = sessionApiTime + sessionToolTime;
7581
8026
  const apiPercent = agentActiveMs > 0 ? (sessionApiTime / agentActiveMs * 100).toFixed(1) : "0.0";
7582
8027
  const toolPercent = agentActiveMs > 0 ? (sessionToolTime / agentActiveMs * 100).toFixed(1) : "0.0";
7583
- return /* @__PURE__ */ React11.createElement(Box11, { flexDirection: "column", borderStyle: "round", paddingX: 3, paddingY: 1, borderColor: "red", width: Math.min(100, (stdout?.columns || 100) - 2), marginTop: 1 }, /* @__PURE__ */ React11.createElement(Box11, { marginBottom: 1 }, /* @__PURE__ */ React11.createElement(Text11, { color: "cyan", bold: true }, "Agent powering down. ", /* @__PURE__ */ React11.createElement(Text11, { color: "magenta" }, "Goodbye!"))), /* @__PURE__ */ React11.createElement(Box11, { flexDirection: "column" }, /* @__PURE__ */ React11.createElement(Text11, { color: "white", bold: true, underline: true }, "Interaction Summary"), /* @__PURE__ */ React11.createElement(Box11, { marginTop: 1 }, /* @__PURE__ */ React11.createElement(Box11, { width: 20 }, /* @__PURE__ */ React11.createElement(Text11, { color: "blue" }, "Session ID:")), /* @__PURE__ */ React11.createElement(Text11, { color: "white" }, chatId)), /* @__PURE__ */ React11.createElement(Box11, null, /* @__PURE__ */ React11.createElement(Box11, { width: 20 }, /* @__PURE__ */ React11.createElement(Text11, { color: "blue" }, "Tool Calls:")), /* @__PURE__ */ React11.createElement(Text11, { color: "white" }, sessionToolSuccess + sessionToolFailure + sessionToolDenied, " ( ", /* @__PURE__ */ React11.createElement(Text11, { color: "green" }, "\u2713 ", sessionToolSuccess), " ", /* @__PURE__ */ React11.createElement(Text11, { color: "yellow" }, "\u2298 ", sessionToolDenied), " ", /* @__PURE__ */ React11.createElement(Text11, { color: "red" }, "\u2715 ", sessionToolFailure), " )")), /* @__PURE__ */ React11.createElement(Box11, null, /* @__PURE__ */ React11.createElement(Box11, { width: 20 }, /* @__PURE__ */ React11.createElement(Text11, { color: "blue" }, "Success Rate:")), /* @__PURE__ */ React11.createElement(Text11, { color: "white" }, successRate, "%")), /* @__PURE__ */ React11.createElement(Box11, null, /* @__PURE__ */ React11.createElement(Box11, { width: 20 }, /* @__PURE__ */ React11.createElement(Text11, { color: "blue" }, "Tokens Consumed:")), /* @__PURE__ */ React11.createElement(Text11, { color: "white" }, formatTokens(sessionTotalTokens))), /* @__PURE__ */ React11.createElement(Box11, null, /* @__PURE__ */ React11.createElement(Box11, { width: 20 }, /* @__PURE__ */ React11.createElement(Text11, { color: "blue" }, "Images Made:")), /* @__PURE__ */ React11.createElement(Text11, { color: "white" }, sessionImageCount || 0)), /* @__PURE__ */ React11.createElement(Box11, null, /* @__PURE__ */ React11.createElement(Box11, { width: 20 }, /* @__PURE__ */ React11.createElement(Text11, { color: "blue" }, "Image Credits:")), /* @__PURE__ */ React11.createElement(Text11, { color: "white" }, Number(((sessionImageCredits || 0) * 1e3).toFixed(0)), " credits"))), /* @__PURE__ */ React11.createElement(Box11, { flexDirection: "column", marginTop: 1 }, /* @__PURE__ */ React11.createElement(Text11, { color: "white", bold: true, underline: true }, "Performance"), /* @__PURE__ */ React11.createElement(Box11, { marginTop: 1 }, /* @__PURE__ */ React11.createElement(Box11, { width: 20 }, /* @__PURE__ */ React11.createElement(Text11, { color: "blue" }, "Wall Time:")), /* @__PURE__ */ React11.createElement(Text11, { color: "white" }, formatMsDuration(wallTimeMs))), /* @__PURE__ */ React11.createElement(Box11, null, /* @__PURE__ */ React11.createElement(Box11, { width: 20 }, /* @__PURE__ */ React11.createElement(Text11, { color: "blue" }, "Agent Active:")), /* @__PURE__ */ React11.createElement(Text11, { color: "white" }, formatMsDuration(agentActiveMs))), /* @__PURE__ */ React11.createElement(Box11, { marginLeft: 2 }, /* @__PURE__ */ React11.createElement(Box11, { width: 18 }, /* @__PURE__ */ React11.createElement(Text11, { color: "blue", dimColor: true }, "\xBB API Time:")), /* @__PURE__ */ React11.createElement(Text11, { color: "white" }, formatMsDuration(sessionApiTime), " (", apiPercent, "%)")), /* @__PURE__ */ React11.createElement(Box11, { marginLeft: 2 }, /* @__PURE__ */ React11.createElement(Box11, { width: 18 }, /* @__PURE__ */ React11.createElement(Text11, { color: "blue", dimColor: true }, "\xBB Tool Time:")), /* @__PURE__ */ React11.createElement(Text11, { color: "white" }, formatMsDuration(sessionToolTime), " (", toolPercent, "%)"))));
8028
+ return /* @__PURE__ */ React12.createElement(Box12, { flexDirection: "column", borderStyle: "round", paddingX: 3, paddingY: 1, borderColor: "red", width: Math.min(100, (stdout?.columns || 100) - 2), marginTop: 1 }, /* @__PURE__ */ React12.createElement(Box12, { marginBottom: 1 }, /* @__PURE__ */ React12.createElement(Text12, { color: "cyan", bold: true }, "Agent powering down. ", /* @__PURE__ */ React12.createElement(Text12, { color: "magenta" }, "Goodbye!"))), /* @__PURE__ */ React12.createElement(Box12, { flexDirection: "column" }, /* @__PURE__ */ React12.createElement(Text12, { color: "white", bold: true, underline: true }, "Interaction Summary"), /* @__PURE__ */ React12.createElement(Box12, { marginTop: 1 }, /* @__PURE__ */ React12.createElement(Box12, { width: 20 }, /* @__PURE__ */ React12.createElement(Text12, { color: "blue" }, "Session ID:")), /* @__PURE__ */ React12.createElement(Text12, { color: "white" }, chatId)), /* @__PURE__ */ React12.createElement(Box12, null, /* @__PURE__ */ React12.createElement(Box12, { width: 20 }, /* @__PURE__ */ React12.createElement(Text12, { color: "blue" }, "Tool Calls:")), /* @__PURE__ */ React12.createElement(Text12, { color: "white" }, sessionToolSuccess + sessionToolFailure + sessionToolDenied, " ( ", /* @__PURE__ */ React12.createElement(Text12, { color: "green" }, "\u2713 ", sessionToolSuccess), " ", /* @__PURE__ */ React12.createElement(Text12, { color: "yellow" }, "\u2298 ", sessionToolDenied), " ", /* @__PURE__ */ React12.createElement(Text12, { color: "red" }, "\u2715 ", sessionToolFailure), " )")), /* @__PURE__ */ React12.createElement(Box12, null, /* @__PURE__ */ React12.createElement(Box12, { width: 20 }, /* @__PURE__ */ React12.createElement(Text12, { color: "blue" }, "Success Rate:")), /* @__PURE__ */ React12.createElement(Text12, { color: "white" }, successRate, "%")), /* @__PURE__ */ React12.createElement(Box12, null, /* @__PURE__ */ React12.createElement(Box12, { width: 20 }, /* @__PURE__ */ React12.createElement(Text12, { color: "blue" }, "Code Changes:")), /* @__PURE__ */ React12.createElement(Text12, { color: "white" }, /* @__PURE__ */ React12.createElement(Text12, { color: "green" }, "+", linesAdded), " ", /* @__PURE__ */ React12.createElement(Text12, { color: "red" }, "-", linesRemoved))), /* @__PURE__ */ React12.createElement(Box12, null, /* @__PURE__ */ React12.createElement(Box12, { width: 20 }, /* @__PURE__ */ React12.createElement(Text12, { color: "blue" }, "Tokens Consumed:")), /* @__PURE__ */ React12.createElement(Text12, { color: "white" }, formatTokens(sessionTotalTokens))), /* @__PURE__ */ React12.createElement(Box12, null, /* @__PURE__ */ React12.createElement(Box12, { width: 20 }, /* @__PURE__ */ React12.createElement(Text12, { color: "blue" }, "Images Made:")), /* @__PURE__ */ React12.createElement(Text12, { color: "white" }, sessionImageCount || 0)), /* @__PURE__ */ React12.createElement(Box12, null, /* @__PURE__ */ React12.createElement(Box12, { width: 20 }, /* @__PURE__ */ React12.createElement(Text12, { color: "blue" }, "Image Credits:")), /* @__PURE__ */ React12.createElement(Text12, { color: "white" }, Number(((sessionImageCredits || 0) * 1e3).toFixed(0)), " credits"))), /* @__PURE__ */ React12.createElement(Box12, { flexDirection: "column", marginTop: 1 }, /* @__PURE__ */ React12.createElement(Text12, { color: "white", bold: true, underline: true }, "Performance"), /* @__PURE__ */ React12.createElement(Box12, { marginTop: 1 }, /* @__PURE__ */ React12.createElement(Box12, { width: 20 }, /* @__PURE__ */ React12.createElement(Text12, { color: "blue" }, "Wall Time:")), /* @__PURE__ */ React12.createElement(Text12, { color: "white" }, formatMsDuration(wallTimeMs))), /* @__PURE__ */ React12.createElement(Box12, null, /* @__PURE__ */ React12.createElement(Box12, { width: 20 }, /* @__PURE__ */ React12.createElement(Text12, { color: "blue" }, "Agent Active:")), /* @__PURE__ */ React12.createElement(Text12, { color: "white" }, formatMsDuration(agentActiveMs))), /* @__PURE__ */ React12.createElement(Box12, { marginLeft: 2 }, /* @__PURE__ */ React12.createElement(Box12, { width: 18 }, /* @__PURE__ */ React12.createElement(Text12, { color: "blue", dimColor: true }, "\xBB API Time:")), /* @__PURE__ */ React12.createElement(Text12, { color: "white" }, formatMsDuration(sessionApiTime), " (", apiPercent, "%)")), /* @__PURE__ */ React12.createElement(Box12, { marginLeft: 2 }, /* @__PURE__ */ React12.createElement(Box12, { width: 18 }, /* @__PURE__ */ React12.createElement(Text12, { color: "blue", dimColor: true }, "\xBB Tool Time:")), /* @__PURE__ */ React12.createElement(Text12, { color: "white" }, formatMsDuration(sessionToolTime), " (", toolPercent, "%)"))));
7584
8029
  })(), suggestions.length > 0 && (() => {
7585
8030
  const windowSize = 5;
7586
8031
  const startIdx = Math.max(0, Math.min(selectedIndex - 2, suggestions.length - windowSize));
7587
8032
  const visible = suggestions.slice(startIdx, startIdx + windowSize);
7588
8033
  const remaining = suggestions.length - (startIdx + visible.length);
7589
- return /* @__PURE__ */ React11.createElement(
7590
- Box11,
8034
+ return /* @__PURE__ */ React12.createElement(
8035
+ Box12,
7591
8036
  {
7592
8037
  flexDirection: "column",
7593
8038
  borderStyle: "round",
@@ -7596,22 +8041,22 @@ Selection: ${val}`,
7596
8041
  paddingY: 0,
7597
8042
  width: "100%"
7598
8043
  },
7599
- /* @__PURE__ */ React11.createElement(Box11, { paddingX: 1, marginBottom: 0 }, /* @__PURE__ */ React11.createElement(Text11, { color: "gray", bold: true, dimColor: true }, "\u{1F50D} COMMAND SUGGESTIONS")),
8044
+ /* @__PURE__ */ React12.createElement(Box12, { paddingX: 1, marginBottom: 0 }, /* @__PURE__ */ React12.createElement(Text12, { color: "gray", bold: true, dimColor: true }, "\u{1F50D} COMMAND SUGGESTIONS")),
7600
8045
  visible.map((s, i) => {
7601
8046
  const actualIdx = startIdx + i;
7602
8047
  const isActive = actualIdx === selectedIndex;
7603
8048
  const isGemmaDisabled = s.cmd === "gemma-4-31b-it" && apiTier !== "Free";
7604
- return /* @__PURE__ */ React11.createElement(
7605
- Box11,
8049
+ return /* @__PURE__ */ React12.createElement(
8050
+ Box12,
7606
8051
  {
7607
8052
  key: s.cmd,
7608
8053
  flexDirection: "row",
7609
8054
  backgroundColor: isActive ? "#2a2a2a" : void 0,
7610
8055
  paddingX: 1
7611
8056
  },
7612
- /* @__PURE__ */ React11.createElement(Box11, { width: 3 }, /* @__PURE__ */ React11.createElement(Text11, { color: isActive ? "cyan" : "gray", bold: isActive }, isActive ? " \u276F" : " ")),
7613
- /* @__PURE__ */ React11.createElement(Box11, { width: 32 }, /* @__PURE__ */ React11.createElement(
7614
- Text11,
8057
+ /* @__PURE__ */ React12.createElement(Box12, { width: 3 }, /* @__PURE__ */ React12.createElement(Text12, { color: isActive ? "cyan" : "gray", bold: isActive }, isActive ? " \u276F" : " ")),
8058
+ /* @__PURE__ */ React12.createElement(Box12, { width: 32 }, /* @__PURE__ */ React12.createElement(
8059
+ Text12,
7615
8060
  {
7616
8061
  color: isGemmaDisabled ? "gray" : isActive ? "yellow" : "white",
7617
8062
  bold: isActive,
@@ -7619,19 +8064,20 @@ Selection: ${val}`,
7619
8064
  },
7620
8065
  s.cmd
7621
8066
  )),
7622
- /* @__PURE__ */ React11.createElement(Box11, { flexGrow: 1 }, /* @__PURE__ */ React11.createElement(Text11, { color: "gray", italic: true, dimColor: !isActive }, s.desc))
8067
+ /* @__PURE__ */ React12.createElement(Box12, { flexGrow: 1 }, /* @__PURE__ */ React12.createElement(Text12, { color: "gray", italic: true, dimColor: !isActive }, s.desc))
7623
8068
  );
7624
8069
  }),
7625
- suggestions.length > 5 && /* @__PURE__ */ React11.createElement(Box11, { paddingX: 1, height: 1 }, remaining > 0 ? /* @__PURE__ */ React11.createElement(Text11, { color: "gray", dimColor: true, italic: true }, " ... (", remaining, " more commands available)") : /* @__PURE__ */ React11.createElement(Text11, { color: "gray", dimColor: true, italic: true }, " (End of list)"))
8070
+ suggestions.length > 5 && /* @__PURE__ */ React12.createElement(Box12, { paddingX: 1, height: 1 }, remaining > 0 ? /* @__PURE__ */ React12.createElement(Text12, { color: "gray", dimColor: true, italic: true }, " ... (", remaining, " more commands available)") : /* @__PURE__ */ React12.createElement(Text12, { color: "gray", dimColor: true, italic: true }, " (End of list)"))
7626
8071
  );
7627
8072
  })()));
7628
8073
  }
7629
- var SESSION_START_TIME, CHANGELOG_URL, packageJsonPath, packageJson, versionFluxflow, updatedOn, ResolutionModal, FLUX_LOGO, parseAgentText;
8074
+ var SESSION_START_TIME, CHANGELOG_URL, linesAdded, linesRemoved, packageJsonPath, packageJson, versionFluxflow, updatedOn, ResolutionModal, FLUX_LOGO, parseAgentText;
7630
8075
  var init_app = __esm({
7631
8076
  "src/app.jsx"() {
7632
8077
  init_ChatLayout();
7633
8078
  init_StatusBar();
7634
8079
  init_CommandMenu();
8080
+ init_SettingsMenu();
7635
8081
  init_ProfileForm();
7636
8082
  init_AskUserModal();
7637
8083
  init_secrets();
@@ -7653,11 +8099,13 @@ var init_app = __esm({
7653
8099
  init_text();
7654
8100
  SESSION_START_TIME = Date.now();
7655
8101
  CHANGELOG_URL = "https://fluxflow-cli.onrender.com/changelog.html";
8102
+ linesAdded = 0;
8103
+ linesRemoved = 0;
7656
8104
  packageJsonPath = path16.join(path16.dirname(fileURLToPath(import.meta.url)), "../package.json");
7657
8105
  packageJson = JSON.parse(fs18.readFileSync(packageJsonPath, "utf8"));
7658
8106
  versionFluxflow = packageJson.version;
7659
8107
  updatedOn = packageJson.date || "2026-05-20";
7660
- ResolutionModal = ({ data, onResolve, onEdit }) => /* @__PURE__ */ React11.createElement(Box11, { flexDirection: "column", borderStyle: "round", borderColor: "gray", padding: 0, width: "100%" }, /* @__PURE__ */ React11.createElement(Box11, { paddingX: 1 }, /* @__PURE__ */ React11.createElement(Text11, { color: "magenta", bold: true, underline: true }, "\u{1F7E3} STEERING HINT RESOLUTION")), /* @__PURE__ */ React11.createElement(Box11, { paddingX: 1, marginTop: 1 }, /* @__PURE__ */ React11.createElement(Text11, null, "The agent already finished the task before your hint was consumed.")), /* @__PURE__ */ React11.createElement(Box11, { marginTop: 1, backgroundColor: "#222", paddingX: 2, width: "100%" }, /* @__PURE__ */ React11.createElement(Text11, { italic: true, color: "gray" }, '"', data, '"')), /* @__PURE__ */ React11.createElement(Box11, { paddingX: 1, marginTop: 1 }, /* @__PURE__ */ React11.createElement(Text11, { color: "cyan" }, "How would you like to proceed?")), /* @__PURE__ */ React11.createElement(Box11, { marginTop: 0 }, /* @__PURE__ */ React11.createElement(
8108
+ ResolutionModal = ({ data, onResolve, onEdit }) => /* @__PURE__ */ React12.createElement(Box12, { flexDirection: "column", borderStyle: "round", borderColor: "gray", padding: 0, width: "100%" }, /* @__PURE__ */ React12.createElement(Box12, { paddingX: 1 }, /* @__PURE__ */ React12.createElement(Text12, { color: "magenta", bold: true, underline: true }, "\u{1F7E3} STEERING HINT RESOLUTION")), /* @__PURE__ */ React12.createElement(Box12, { paddingX: 1, marginTop: 1 }, /* @__PURE__ */ React12.createElement(Text12, null, "The agent already finished the task before your hint was consumed.")), /* @__PURE__ */ React12.createElement(Box12, { marginTop: 1, backgroundColor: "#222", paddingX: 2, width: "100%" }, /* @__PURE__ */ React12.createElement(Text12, { italic: true, color: "gray" }, '"', data, '"')), /* @__PURE__ */ React12.createElement(Box12, { paddingX: 1, marginTop: 1 }, /* @__PURE__ */ React12.createElement(Text12, { color: "cyan" }, "How would you like to proceed?")), /* @__PURE__ */ React12.createElement(Box12, { marginTop: 0 }, /* @__PURE__ */ React12.createElement(
7661
8109
  CommandMenu,
7662
8110
  {
7663
8111
  title: "Select Action",
@@ -7760,7 +8208,7 @@ if (isBundled && !process.execArgv.some((arg) => arg.includes("max-old-space-siz
7760
8208
  ], { stdio: "inherit" });
7761
8209
  cp.on("exit", (code) => process.exit(code || 0));
7762
8210
  } else {
7763
- const { default: React12 } = await import("react");
8211
+ const { default: React13 } = await import("react");
7764
8212
  const { render } = await import("ink");
7765
8213
  const { default: App2 } = await Promise.resolve().then(() => (init_app(), app_exports));
7766
8214
  process.env.NODE_NO_WARNINGS = "1";
@@ -7783,5 +8231,5 @@ if (isBundled && !process.execArgv.some((arg) => arg.includes("max-old-space-siz
7783
8231
  console.warn = (...args) => !isNoise(args) && originalWarn(...args);
7784
8232
  console.error = (...args) => !isNoise(args) && originalError(...args);
7785
8233
  process.stdout.write("\x1Bc");
7786
- render(/* @__PURE__ */ React12.createElement(App2, { args: process.argv.slice(2) }), { exitOnCtrlC: false });
8234
+ render(/* @__PURE__ */ React13.createElement(App2, { args: process.argv.slice(2) }), { exitOnCtrlC: false });
7787
8235
  }