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.
- package/README.md +4 -2
- package/dist/fluxflow.js +718 -270
- 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(
|
|
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/
|
|
620
|
-
import React5, { useState as useState2
|
|
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] =
|
|
625
|
-
const [currentInput, setCurrentInput] =
|
|
626
|
-
const [profile, setProfile] =
|
|
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__ */
|
|
656
|
-
|
|
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__ */
|
|
667
|
-
/* @__PURE__ */
|
|
668
|
-
|
|
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__ */
|
|
675
|
-
/* @__PURE__ */
|
|
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
|
|
685
|
-
import { Box as
|
|
686
|
-
import
|
|
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] =
|
|
693
|
-
const [customInput, setCustomInput] =
|
|
694
|
-
const [selectedIndex, setSelectedIndex] =
|
|
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
|
-
|
|
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__ */
|
|
716
|
-
|
|
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__ */
|
|
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__ */
|
|
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__ */
|
|
727
|
-
|
|
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__ */
|
|
737
|
-
opt.description && /* @__PURE__ */
|
|
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__ */
|
|
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" : "
|
|
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
|
|
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
|
|
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
|
-
|
|
4777
|
-
|
|
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
|
|
5040
|
-
import { Box as
|
|
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] =
|
|
5043
|
-
const [keys, setKeys] =
|
|
5044
|
-
const [selectedIndex, setSelectedIndex] =
|
|
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
|
-
|
|
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__ */
|
|
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__ */
|
|
5088
|
-
|
|
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__ */
|
|
5096
|
-
isSelected && /* @__PURE__ */
|
|
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__ */
|
|
5099
|
-
|
|
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__ */
|
|
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
|
|
5132
|
-
import { Box as
|
|
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] =
|
|
5135
|
-
const [selectedIndex, setSelectedIndex] =
|
|
5136
|
-
const [isMemoryOn, setIsMemoryOn] =
|
|
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
|
-
|
|
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__ */
|
|
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__ */
|
|
5184
|
-
|
|
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__ */
|
|
5192
|
-
isSelected && /* @__PURE__ */
|
|
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__ */
|
|
5195
|
-
|
|
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__ */
|
|
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
|
|
5218
|
-
import { Box as
|
|
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] =
|
|
5226
|
-
const [log, setLog] =
|
|
5227
|
-
const [error, setError] =
|
|
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__ */
|
|
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__ */
|
|
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__ */
|
|
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
|
|
5284
|
-
import { Box as
|
|
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] =
|
|
5287
|
-
|
|
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__ */
|
|
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__ */
|
|
5312
|
-
|
|
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__ */
|
|
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__ */
|
|
5322
|
-
|
|
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__ */
|
|
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
|
|
5407
|
-
import { Box as
|
|
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
|
|
5847
|
+
import TextInput4 from "ink-text-input";
|
|
5415
5848
|
import gradient from "gradient-string";
|
|
5416
5849
|
function App({ args = [] }) {
|
|
5417
|
-
const [confirmExit, setConfirmExit] =
|
|
5418
|
-
const [exitCountdown, setExitCountdown] =
|
|
5850
|
+
const [confirmExit, setConfirmExit] = useState9(false);
|
|
5851
|
+
const [exitCountdown, setExitCountdown] = useState9(10);
|
|
5419
5852
|
const { stdout } = useStdout();
|
|
5420
|
-
const [input, setInput] =
|
|
5421
|
-
const [isExpanded, setIsExpanded] =
|
|
5422
|
-
const [mode, setMode] =
|
|
5423
|
-
const [terminalSize, setTerminalSize] =
|
|
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] =
|
|
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] =
|
|
5532
|
-
const [latestVer, setLatestVer] =
|
|
5533
|
-
const [showFullThinking, setShowFullThinking] =
|
|
5534
|
-
const [activeModel, setActiveModel] =
|
|
5535
|
-
const [janitorModel, setJanitorModel] =
|
|
5536
|
-
const [isInitializing, setIsInitializing] =
|
|
5537
|
-
const [apiKey, setApiKey] =
|
|
5538
|
-
const [tempKey, setTempKey] =
|
|
5539
|
-
const [activeView, setActiveView] =
|
|
5540
|
-
const [apiTier, setApiTier] =
|
|
5541
|
-
const [quotas, setQuotas] =
|
|
5542
|
-
const [inputConfig, setInputConfig] =
|
|
5543
|
-
const [systemSettings, setSystemSettings] =
|
|
5544
|
-
const [profileData, setProfileData] =
|
|
5545
|
-
const [imageSettings, setImageSettings] =
|
|
5546
|
-
const [sessionStats, setSessionStats] =
|
|
5547
|
-
const [sessionAgentCalls, setSessionAgentCalls] =
|
|
5548
|
-
const [sessionBackgroundCalls, setSessionBackgroundCalls] =
|
|
5549
|
-
const [sessionTotalTokens, setSessionTotalTokens] =
|
|
5550
|
-
const [sessionToolSuccess, setSessionToolSuccess] =
|
|
5551
|
-
const [sessionToolFailure, setSessionToolFailure] =
|
|
5552
|
-
const [sessionToolDenied, setSessionToolDenied] =
|
|
5553
|
-
const [sessionApiTime, setSessionApiTime] =
|
|
5554
|
-
const [sessionToolTime, setSessionToolTime] =
|
|
5555
|
-
const [sessionImageCount, setSessionImageCount] =
|
|
5556
|
-
const [sessionImageCredits, setSessionImageCredits] =
|
|
5557
|
-
const [dailyUsage, setDailyUsage] =
|
|
5558
|
-
const [chatId, setChatId] =
|
|
5559
|
-
const [activeCommand, setActiveCommand] =
|
|
5560
|
-
const [execOutput, setExecOutput] =
|
|
5561
|
-
const [isTerminalFocused, setIsTerminalFocused] =
|
|
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] =
|
|
5592
|
-
const [pendingApproval, setPendingApproval] =
|
|
5593
|
-
const [pendingAsk, setPendingAsk] =
|
|
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] =
|
|
5609
|
-
const [isSpinnerActive, setIsSpinnerActive] =
|
|
5610
|
-
const [isProcessing, setIsProcessing] =
|
|
5611
|
-
const [escPressed, setEscPressed] =
|
|
5612
|
-
const [escTimer, setEscTimer] =
|
|
5613
|
-
const [escPressCount, setEscPressCount] =
|
|
5614
|
-
const [recentPrompts, setRecentPrompts] =
|
|
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] =
|
|
5617
|
-
const [resolutionData, setResolutionData] =
|
|
5618
|
-
const [tempModelOverride, setTempModelOverride] =
|
|
5619
|
-
const [messages, setMessages] =
|
|
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] =
|
|
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
|
-
|
|
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
|
|
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
|
-
|
|
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__ */
|
|
7007
|
-
|
|
7501
|
+
return /* @__PURE__ */ React12.createElement(
|
|
7502
|
+
SettingsMenu,
|
|
7008
7503
|
{
|
|
7009
|
-
|
|
7010
|
-
|
|
7011
|
-
|
|
7012
|
-
|
|
7013
|
-
|
|
7014
|
-
|
|
7015
|
-
|
|
7016
|
-
|
|
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__ */
|
|
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__ */
|
|
7108
|
-
|
|
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__ */
|
|
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__ */
|
|
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__ */
|
|
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__ */
|
|
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__ */
|
|
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__ */
|
|
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__ */
|
|
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__ */
|
|
7242
|
-
})(), /* @__PURE__ */
|
|
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__ */
|
|
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__ */
|
|
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__ */
|
|
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__ */
|
|
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__ */
|
|
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__ */
|
|
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__ */
|
|
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__ */
|
|
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__ */
|
|
7407
|
-
})()), /* @__PURE__ */
|
|
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__ */
|
|
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__ */
|
|
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__ */
|
|
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__ */
|
|
7506
|
-
|
|
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__ */
|
|
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__ */
|
|
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__ */
|
|
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__ */
|
|
7559
|
-
|
|
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__ */
|
|
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__ */
|
|
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__ */
|
|
7590
|
-
|
|
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__ */
|
|
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__ */
|
|
7605
|
-
|
|
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__ */
|
|
7613
|
-
/* @__PURE__ */
|
|
7614
|
-
|
|
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__ */
|
|
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__ */
|
|
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__ */
|
|
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:
|
|
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__ */
|
|
8234
|
+
render(/* @__PURE__ */ React13.createElement(App2, { args: process.argv.slice(2) }), { exitOnCtrlC: false });
|
|
7787
8235
|
}
|