fluxflow-cli 1.9.9 → 1.9.12
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/fluxflow.js +171 -162
- package/package.json +1 -1
package/dist/fluxflow.js
CHANGED
|
@@ -10,6 +10,7 @@ var __export = (target, all) => {
|
|
|
10
10
|
};
|
|
11
11
|
|
|
12
12
|
// src/utils/text.js
|
|
13
|
+
import os from "os";
|
|
13
14
|
var wrapText, formatTokens, truncatePath;
|
|
14
15
|
var init_text = __esm({
|
|
15
16
|
"src/utils/text.js"() {
|
|
@@ -82,13 +83,14 @@ var init_text = __esm({
|
|
|
82
83
|
if (!tokens && tokens !== 0) return "0.0k";
|
|
83
84
|
const num = typeof tokens === "string" ? parseFloat(tokens) : tokens;
|
|
84
85
|
if (num >= 1e6) {
|
|
85
|
-
return `${(num / 1e6).toFixed(
|
|
86
|
+
return `${(num / 1e6).toFixed(1)}m`;
|
|
86
87
|
} else if (num >= 1e3) {
|
|
87
|
-
return `${(num / 1e3).toFixed(
|
|
88
|
+
return `${(num / 1e3).toFixed(1)}k`;
|
|
88
89
|
}
|
|
89
90
|
return num.toString();
|
|
90
91
|
};
|
|
91
92
|
truncatePath = (p, maxLength = 40) => {
|
|
93
|
+
p = p.replace(os.homedir(), "~");
|
|
92
94
|
if (!p || p.length <= maxLength) return p;
|
|
93
95
|
const half = Math.floor((maxLength - 3) / 2);
|
|
94
96
|
return p.substring(0, half) + "..." + p.substring(p.length - half);
|
|
@@ -798,13 +800,13 @@ __export(paths_exports, {
|
|
|
798
800
|
TEMP_MEM_FILE: () => TEMP_MEM_FILE,
|
|
799
801
|
USAGE_FILE: () => USAGE_FILE
|
|
800
802
|
});
|
|
801
|
-
import
|
|
803
|
+
import os2 from "os";
|
|
802
804
|
import path2 from "path";
|
|
803
805
|
import fs2 from "fs";
|
|
804
806
|
var FLUXFLOW_DIR, SETTINGS_FILE, externalDir, DATA_DIR, LOGS_DIR, SECRET_DIR, HISTORY_FILE, USAGE_FILE, MEMORIES_FILE, TEMP_MEM_FILE;
|
|
805
807
|
var init_paths = __esm({
|
|
806
808
|
"src/utils/paths.js"() {
|
|
807
|
-
FLUXFLOW_DIR = path2.join(
|
|
809
|
+
FLUXFLOW_DIR = path2.join(os2.homedir(), ".fluxflow");
|
|
808
810
|
SETTINGS_FILE = path2.join(FLUXFLOW_DIR, "settings.json");
|
|
809
811
|
externalDir = null;
|
|
810
812
|
try {
|
|
@@ -868,7 +870,7 @@ var TOOL_PROTOCOL;
|
|
|
868
870
|
var init_main_tools = __esm({
|
|
869
871
|
"src/data/main_tools.js"() {
|
|
870
872
|
TOOL_PROTOCOL = (mode) => `
|
|
871
|
-
--
|
|
873
|
+
-- TOOL DEFINITIONS --
|
|
872
874
|
You have access to internal tools. To call a tool, you MUST use the following exact syntax on a new line:
|
|
873
875
|
[tool:functions.tool_name(arguments)]
|
|
874
876
|
|
|
@@ -881,7 +883,7 @@ NOTE: Suggest best options; don't ask for preferences. System handles the rest.
|
|
|
881
883
|
2. Web Scrape: [tool:functions.web_scrape(url="<url>")]. provides detail from a URL.
|
|
882
884
|
|
|
883
885
|
${mode === "Flux" ? `
|
|
884
|
-
- DEV
|
|
886
|
+
- DEV TOOLS (path will always be relative to CWD) -
|
|
885
887
|
1. View File: [tool:functions.view_file(path="...", start_line=N, end_line=N)]. Reads content (800 lines max). Supports images/docs. If user provides an image/doc, view it first.
|
|
886
888
|
2. Read Folder: [tool:functions.read_folder(path="...")]. Detailed stats of a directory.
|
|
887
889
|
3. Write File: [tool:functions.write_file(path="...", content="content to write")]. Creates/Overwrites. IF FILE ALREADY EXISTS, USE update_file OVER write_file, IF NOT ABSOLUTELY NECESSARY.
|
|
@@ -894,18 +896,17 @@ CSS: background-color,color,font-family,font-size(pt),font-style,font-weight,mar
|
|
|
894
896
|
8. Execution: [tool:functions.exec_command(command="command")]. Runs a shell command. Use ask tool to confirm before executing any destructive or irreversible operations.
|
|
895
897
|
9. Search: [tool:functions.search_keyword(keyword="...")]. Global search. Use to locate definitions/logic without reading every file.
|
|
896
898
|
|
|
897
|
-
- VERIFY SUCCESS CONTENTS. Fix errors. No
|
|
898
|
-
- No guessing; read files before editing.
|
|
899
|
+
- VERIFY SUCCESS CONTENTS. Fix errors. No hallucinations.
|
|
899
900
|
- File tools > Chat code blocks.
|
|
900
901
|
|
|
901
902
|
- Escape quotes: Use \\" inside code strings.
|
|
902
903
|
- Literal escapes: Double-escape sequences (e.g., \\\\n, \\\\t).
|
|
903
904
|
- File structure: Use real newlines for code formatting.`.trim() : `
|
|
904
|
-
- DEV
|
|
905
|
+
- DEV TOOLS ARE NOT AVAILABLE IN FLOW MODE. If you need to access files, tell the user to switch to FLUX.`.trim()}
|
|
905
906
|
|
|
906
907
|
- Results: Passed as [TOOL_RESULT] (SYSTEM), USER_PROMPT (USER).
|
|
907
908
|
- Tool calls: End with [turn: continue]. Only use [turn: finish] after verifying goals.
|
|
908
|
-
- Multi-call: Stack 1-by-1.
|
|
909
|
+
- Multi-call: Stack 1-by-1. Upto 4.
|
|
909
910
|
-- END TOOL DEFINITIONS --`.trim();
|
|
910
911
|
}
|
|
911
912
|
});
|
|
@@ -915,12 +916,12 @@ var JANITOR_TOOLS_PROTOCOL;
|
|
|
915
916
|
var init_janitor_tools = __esm({
|
|
916
917
|
"src/data/janitor_tools.js"() {
|
|
917
918
|
JANITOR_TOOLS_PROTOCOL = (isMemoryEnabled = true, needTitle = true) => `
|
|
918
|
-
${needTitle ? `--
|
|
919
|
+
${needTitle ? `-- CHAT MANAGEMENT TOOLS --
|
|
919
920
|
1. YOU MUST UPDATE CHAT TITLE (URGENT PRIORITY):
|
|
920
921
|
[tool:functions.chat(title='<short creative title of FULL conversation in 3-5 words>')]. Consider full chat context to generate title NOT just latest message.
|
|
921
922
|
-- END CHAT MANAGEMENT TOOLS --
|
|
922
923
|
`.trimEnd() : ""}
|
|
923
|
-
--
|
|
924
|
+
-- MEMORY TOOLS (YOU SHOULD NOT OUTPUT ANYTHING OTHER THAN THESE SPECIFIC TOOLS) --
|
|
924
925
|
Your tool syntax is: '[tool:functions.function_name(args...)]'
|
|
925
926
|
You have access to the following memory functions to persist important information:
|
|
926
927
|
|
|
@@ -945,7 +946,6 @@ var init_thinking_prompts = __esm({
|
|
|
945
946
|
"src/data/thinking_prompts.json"() {
|
|
946
947
|
thinking_prompts_default = {
|
|
947
948
|
Max: `EFFORT_LEVEL: MAX
|
|
948
|
-
**THINKING <think> ... </think> IS MANDATORY**
|
|
949
949
|
Think in a continuous, fluid analytical monologue within the <think>...</think> block. Do NOT use headings, bullet points, or artificial sections. Engage in a deep "Stream of Consciousness" that follows this cognitive path:
|
|
950
950
|
Deep Analysis: Deconstruct the request into its core technical and logic requirements.
|
|
951
951
|
Hypothesis & Test: Propose multiple solutions mentally and critique them for edge cases or security risks.
|
|
@@ -956,21 +956,34 @@ RULES:
|
|
|
956
956
|
- Be thorough and exhaustive. Explore the 'why' behind every decision, depth and nuances.
|
|
957
957
|
- Use internal critique: Question your own logic as you go.
|
|
958
958
|
- MANDATORY THINKING: You MUST engage in full reasoning regardless of perceived simplicity.`,
|
|
959
|
-
High: "EFFORT_LEVEL: HIGH\
|
|
960
|
-
Medium: "EFFORT_LEVEL: MEDIUM\
|
|
961
|
-
Minimal: "EFFORT_LEVEL: LOW\
|
|
959
|
+
High: "EFFORT_LEVEL: HIGH\nThink in a stable, analytical monologue within the <think>...</think> block. Avoid headings or structured formatting. Your thinking should be a continuous stream of logical deduction:\nAnalyze the immediate task and its dependencies.\nMentally simulate the execution to identify potential failure points.\nStructure a precise plan that addresses both primary goals and secondary constraints.\nRULES:\n- NO HEADINGS. Maintain a fluid monologue style.\n- Be detailed and rigorous in your self-questioning.\n- Focus on accuracy, technical correctness, depth and nuances.\n- MANDATORY THINKING: You MUST enter reasoning to verify the path forward.",
|
|
960
|
+
Medium: "EFFORT_LEVEL: MEDIUM\nThink in a concise, stable monologue within the <think>...</think> block. No headings needed. Focus on the core logic required to solve the task efficiently:\nIdentify the most direct path to the solution.\nBriefly consider and discard obvious alternatives.\nConfirm the plan meets the user's immediate requirements.\nRULES:\n- NO HEADINGS. Keep it as a simple, logical stream.\n- Be efficient. Spend energy only on what matters for the task.\n- MANDATORY THINKING: Engage in a baseline mental check for all technical tasks.",
|
|
961
|
+
Minimal: "EFFORT_LEVEL: LOW\nThink in a brief, focused monologue within the <think>...</think> block. No headings. Just a quick mental check before acting:\nVerify the objective.\nNote the target files/tools.\nRULES:\n- NO HEADINGS. Just a few lines of clear, linear thought.\n- Use minimal thinking for simple or conversational requests."
|
|
962
962
|
};
|
|
963
963
|
}
|
|
964
964
|
});
|
|
965
965
|
|
|
966
966
|
// src/utils/prompts.js
|
|
967
|
-
|
|
967
|
+
import fs4 from "fs";
|
|
968
|
+
var getMemoryPrompt, getSystemInstruction, getJanitorInstruction;
|
|
968
969
|
var init_prompts = __esm({
|
|
969
970
|
"src/utils/prompts.js"() {
|
|
970
971
|
init_main_tools();
|
|
971
972
|
init_janitor_tools();
|
|
972
973
|
init_thinking_prompts();
|
|
973
|
-
|
|
974
|
+
getMemoryPrompt = (tempMemories = "", userMemories = "", isMemoryEnabled = true, isContext32k = false) => {
|
|
975
|
+
if (!isMemoryEnabled) return "";
|
|
976
|
+
const tempMemoriesStr = tempMemories?.length > 0 && !isContext32k ? `-- RECENT CONTEXT FROM OTHER CHATS (PRIORITY: LOW) --
|
|
977
|
+
${tempMemories}
|
|
978
|
+
-- END RECENT CONTEXT --` : "";
|
|
979
|
+
const userMemoriesStr = userMemories?.length > 0 ? `--- SAVED MEMORIES (PRIORITY: MEDIUM, TUNES USER PREFERENCES) ---
|
|
980
|
+
${userMemories}
|
|
981
|
+
-- END SAVED MEMORIES --` : "";
|
|
982
|
+
const parts = [userMemoriesStr, tempMemoriesStr].filter((p) => p.length > 0);
|
|
983
|
+
return parts.length > 0 ? `${parts.join("\n\n")}
|
|
984
|
+
` : "";
|
|
985
|
+
};
|
|
986
|
+
getSystemInstruction = (profile, thinkingLevel, mode, systemSettings, isMemoryEnabled = true, maxLoops, currentLoop) => {
|
|
974
987
|
let levelKey = thinkingLevel;
|
|
975
988
|
if (thinkingLevel === "Low") levelKey = "Minimal";
|
|
976
989
|
if (thinkingLevel === "xHigh" || thinkingLevel === "Max") levelKey = "Max";
|
|
@@ -982,7 +995,7 @@ var init_prompts = __esm({
|
|
|
982
995
|
` : "";
|
|
983
996
|
const userInstrStr = profile.instructions && profile.instructions?.length > 0 ? `User Instructions: ${profile.instructions}.
|
|
984
997
|
` : "";
|
|
985
|
-
const dateTimeStr = (/* @__PURE__ */ new Date()).toLocaleString();
|
|
998
|
+
const dateTimeStr = (/* @__PURE__ */ new Date()).toLocaleString([], { year: "numeric", month: "numeric", day: "numeric", hour: "2-digit", minute: "2-digit", hour12: true });
|
|
986
999
|
const cwdStr = process.cwd();
|
|
987
1000
|
const isSystemDir = (() => {
|
|
988
1001
|
const cwd = process.cwd().toLowerCase();
|
|
@@ -996,26 +1009,28 @@ var init_prompts = __esm({
|
|
|
996
1009
|
return cwd === "/" || sysPaths.some((p) => cwd.startsWith(p));
|
|
997
1010
|
}
|
|
998
1011
|
})();
|
|
999
|
-
const
|
|
1000
|
-
|
|
1001
|
-
|
|
1002
|
-
|
|
1003
|
-
|
|
1004
|
-
|
|
1005
|
-
|
|
1006
|
-
|
|
1007
|
-
|
|
1008
|
-
|
|
1009
|
-
|
|
1010
|
-
|
|
1011
|
-
|
|
1012
|
-
|
|
1012
|
+
const projectContextFiles = [
|
|
1013
|
+
{ name: "Fluxflow.md", desc: "HIGHEST PRIORITY. Overrides all other files." },
|
|
1014
|
+
{ name: "README.md", desc: "Goals" },
|
|
1015
|
+
{ name: "Agent.md", desc: "Standards" },
|
|
1016
|
+
{ name: "Skills.md", desc: "Workflows" },
|
|
1017
|
+
{ name: "design.md", desc: "UI/UX" },
|
|
1018
|
+
{ name: "architecture.md", desc: "System Structure" }
|
|
1019
|
+
];
|
|
1020
|
+
const foundFiles = projectContextFiles.filter((f) => fs4.existsSync(f.name));
|
|
1021
|
+
const projectContextBlock = mode === "Flux" && foundFiles.length > 0 ? `
|
|
1022
|
+
-- PROJECT CONTEXT (Source of Truth) --
|
|
1023
|
+
${foundFiles.map((f) => `- ${f.name}: ${f.desc}`).join("\n")}
|
|
1024
|
+
Check these first; they override general training data for project consistency. Safety rules still apply.
|
|
1025
|
+
-- END PROJECT CONTEXT --` : "";
|
|
1026
|
+
return `${nameStr}${nicknameStr}${userInstrStr}
|
|
1027
|
+
=== SYSTEM INSTRUCTION (STRICT PRIORITY, OVERRIDES EVERYTHING) ===
|
|
1013
1028
|
Identity: Flux Flow (by Kushal Roy Chowdhury). Sassy, Friendly CLI Agent. No flirting.
|
|
1014
|
-
Mode: ${mode} (THINKING
|
|
1029
|
+
Mode: ${mode} (THINKING MODE). ${mode === "Flux" ? "Goal-oriented. Plan & use tools." : "Conversation & UX focus. Web/Comm tools only."}
|
|
1015
1030
|
Context: CWD: ${cwdStr}.${isSystemDir ? " [PROTECTED: ASK BEFORE MODIFYING]." : ""} OS: ${osDetected}.${osDetected === "Windows" ? " (Backslashes only. Prefer PS via CMD)." : ""}
|
|
1016
1031
|
Protocol: [SYSTEM] and [STEERING HINT] are high-priority.
|
|
1017
1032
|
|
|
1018
|
-
--
|
|
1033
|
+
-- THINKING INSTRUCTIONS --
|
|
1019
1034
|
${thinkingConfig}
|
|
1020
1035
|
***CRITICAL THINKING POLICY***
|
|
1021
1036
|
- Always use <think> ... </think> before answering or using any tool.
|
|
@@ -1024,25 +1039,19 @@ ${thinkingConfig}
|
|
|
1024
1039
|
-- END THINKING INSTRUCTIONS --
|
|
1025
1040
|
|
|
1026
1041
|
${TOOL_PROTOCOL(mode)}
|
|
1027
|
-
${
|
|
1028
|
-
-- PROJECT CONTEXT (Source of Truth) --
|
|
1029
|
-
- Fluxflow.md: HIGHEST PRIORITY. Overrides all other files.
|
|
1030
|
-
- README.md (Goals), Agent.md (Standards), Skills.md (Workflows).
|
|
1031
|
-
- design.md (UI/UX), architecture.md (System Structure).
|
|
1032
|
-
Check these first; they override general training data for project consistency. Safety rules still apply.
|
|
1033
|
-
-- END PROJECT CONTEXT --` : ""}
|
|
1042
|
+
${projectContextBlock}
|
|
1034
1043
|
|
|
1035
1044
|
-- MEMORY INSTRUCTIONS --
|
|
1036
1045
|
- Memory: ${isMemoryEnabled ? "Use recent context/logs to personalize. Keep it subtle." : "OFF (tell user to enable in /settings if needed)."}
|
|
1037
1046
|
- Time: All logs are timestamped. Always use **relative time** (e.g., 'few mins ago', 'few hours ago'...), never absolute.
|
|
1038
1047
|
-- END MEMORY INSTRUCTIONS --
|
|
1039
1048
|
|
|
1040
|
-
--
|
|
1049
|
+
-- SECURITY BOUNDARY --
|
|
1041
1050
|
- EXTERNAL_WORKSPACE_ACCESS: ${systemSettings.allowExternalAccess ? "ENABLED (Global)." : "RESTRICTED (CWD only). Suggest /settings to enable external access if needed."}
|
|
1042
|
-
- Safety: Ask permission before reading
|
|
1051
|
+
- Safety: Ask permission before reading sensitive files.
|
|
1043
1052
|
-- END SECURITY BOUNDARY --
|
|
1044
1053
|
|
|
1045
|
-
--
|
|
1054
|
+
-- TEMPORAL AWARENESS --
|
|
1046
1055
|
Every ${isMemoryEnabled ? "Prompt, Responses & Memories" : "Prompt & Responses"} are time stamped. You can use those times if temporal context is required. If recalled from ${isMemoryEnabled ? "Memories, Prompts, or Responses" : "Prompts, or Responses"}. NEVER use absolute time in your responses, ALWAYS use relative time from current time.
|
|
1047
1056
|
-- END TEMPORAL AWARENESS --
|
|
1048
1057
|
|
|
@@ -1051,13 +1060,13 @@ Every ${isMemoryEnabled ? "Prompt, Responses & Memories" : "Prompt & Responses"}
|
|
|
1051
1060
|
- Tables: GFM (Max 4 cols, short rows). Use sparingly.
|
|
1052
1061
|
- NO LaTeX. Code blocks for literature/poems only. Kaomojis > emojis.
|
|
1053
1062
|
|
|
1054
|
-
--
|
|
1055
|
-
-
|
|
1063
|
+
-- RESPONSE PROTOCOL --
|
|
1064
|
+
- End with [turn: continue] for more steps or [turn: finish] when done.
|
|
1056
1065
|
- Multi-tool: Stack tools if needed, but always end with [turn: continue] if called any tools.
|
|
1057
|
-
TO END THE LOOP YOU **MUST** WRITE [turn: finish] AT VERY END OF YOUR RESPONSE.
|
|
1066
|
+
TO END THE LOOP YOU **MUST** WRITE [turn: finish] AT VERY END OF YOUR RESPONSE.
|
|
1058
1067
|
-- END RESPONSE PROTOCOL --
|
|
1059
1068
|
|
|
1060
|
-
[
|
|
1069
|
+
[METADATA (PRIORITY: DYNAMIC)] Time: ${dateTimeStr} | v1.9.12 | Turn Progress: ${currentLoop}/${maxLoops} steps (Summarize & prompt user if limit is reached).
|
|
1061
1070
|
=== END SYSTEM INSTRUCTION ===`.trim();
|
|
1062
1071
|
};
|
|
1063
1072
|
getJanitorInstruction = (originalText, agentRaws, userMemories = "", isMemoryEnabled = true, needTitle = true) => {
|
|
@@ -1092,14 +1101,14 @@ ${isMemoryEnabled ? `If user tell something that is important (like, hobbies, pr
|
|
|
1092
1101
|
|
|
1093
1102
|
${JANITOR_TOOLS_PROTOCOL(isMemoryEnabled, needTitle)}
|
|
1094
1103
|
|
|
1095
|
-
Current date and Time: ${(/* @__PURE__ */ new Date()).toLocaleString()}
|
|
1104
|
+
Current date and Time: ${(/* @__PURE__ */ new Date()).toLocaleString([], { year: "numeric", month: "numeric", day: "numeric", hour: "2-digit", hour12: true })}
|
|
1096
1105
|
=== END SYSTEM INSTRUCTION ===`.trim();
|
|
1097
1106
|
};
|
|
1098
1107
|
}
|
|
1099
1108
|
});
|
|
1100
1109
|
|
|
1101
1110
|
// src/utils/history.js
|
|
1102
|
-
import
|
|
1111
|
+
import fs5 from "fs-extra";
|
|
1103
1112
|
import path4 from "path";
|
|
1104
1113
|
import { nanoid } from "nanoid";
|
|
1105
1114
|
var WRITE_LOCK, withLock, loadHistory, saveChat, saveChatTitle, deleteChat, generateChatId, cleanupOldHistory, getTruncatedHistory;
|
|
@@ -1122,9 +1131,9 @@ var init_history = __esm({
|
|
|
1122
1131
|
return nextLock;
|
|
1123
1132
|
};
|
|
1124
1133
|
loadHistory = async () => {
|
|
1125
|
-
if (await
|
|
1134
|
+
if (await fs5.pathExists(HISTORY_FILE)) {
|
|
1126
1135
|
try {
|
|
1127
|
-
return await
|
|
1136
|
+
return await fs5.readJson(HISTORY_FILE);
|
|
1128
1137
|
} catch (e) {
|
|
1129
1138
|
return {};
|
|
1130
1139
|
}
|
|
@@ -1142,8 +1151,8 @@ var init_history = __esm({
|
|
|
1142
1151
|
messages: persistentMessages,
|
|
1143
1152
|
updatedAt: Date.now()
|
|
1144
1153
|
};
|
|
1145
|
-
await
|
|
1146
|
-
await
|
|
1154
|
+
await fs5.ensureDir(path4.dirname(HISTORY_FILE));
|
|
1155
|
+
await fs5.writeJson(HISTORY_FILE, history, { spaces: 2 });
|
|
1147
1156
|
});
|
|
1148
1157
|
};
|
|
1149
1158
|
saveChatTitle = async (id, title) => {
|
|
@@ -1155,15 +1164,15 @@ var init_history = __esm({
|
|
|
1155
1164
|
} else {
|
|
1156
1165
|
history[id] = { name: title, messages: [], updatedAt: Date.now() };
|
|
1157
1166
|
}
|
|
1158
|
-
await
|
|
1159
|
-
await
|
|
1167
|
+
await fs5.ensureDir(path4.dirname(HISTORY_FILE));
|
|
1168
|
+
await fs5.writeJson(HISTORY_FILE, history, { spaces: 2 });
|
|
1160
1169
|
});
|
|
1161
1170
|
};
|
|
1162
1171
|
deleteChat = async (id) => {
|
|
1163
1172
|
return withLock(async () => {
|
|
1164
1173
|
const history = await loadHistory();
|
|
1165
1174
|
delete history[id];
|
|
1166
|
-
await
|
|
1175
|
+
await fs5.writeJson(HISTORY_FILE, history, { spaces: 2 });
|
|
1167
1176
|
const temp = readEncryptedJson(TEMP_MEM_FILE, {});
|
|
1168
1177
|
if (temp[id]) {
|
|
1169
1178
|
delete temp[id];
|
|
@@ -1202,7 +1211,7 @@ var init_history = __esm({
|
|
|
1202
1211
|
});
|
|
1203
1212
|
|
|
1204
1213
|
// src/utils/usage.js
|
|
1205
|
-
import
|
|
1214
|
+
import fs6 from "fs-extra";
|
|
1206
1215
|
import path5 from "path";
|
|
1207
1216
|
var cachedUsage, writeTimeout, lastWriteTime, isDirty, loadUsageFromFile, flushUsage, queueFlush, initUsage, forceFlushUsage, getDailyUsage, incrementUsage, addToUsage, checkQuota;
|
|
1208
1217
|
var init_usage = __esm({
|
|
@@ -1215,8 +1224,8 @@ var init_usage = __esm({
|
|
|
1215
1224
|
loadUsageFromFile = async () => {
|
|
1216
1225
|
const today = (/* @__PURE__ */ new Date()).toISOString().split("T")[0];
|
|
1217
1226
|
try {
|
|
1218
|
-
if (await
|
|
1219
|
-
const data = await
|
|
1227
|
+
if (await fs6.exists(USAGE_FILE)) {
|
|
1228
|
+
const data = await fs6.readJson(USAGE_FILE);
|
|
1220
1229
|
if (data && data.date === today && data.stats) {
|
|
1221
1230
|
return {
|
|
1222
1231
|
...data,
|
|
@@ -1241,11 +1250,11 @@ var init_usage = __esm({
|
|
|
1241
1250
|
flushUsage = async () => {
|
|
1242
1251
|
if (!isDirty || !cachedUsage) return;
|
|
1243
1252
|
try {
|
|
1244
|
-
await
|
|
1253
|
+
await fs6.ensureDir(path5.dirname(USAGE_FILE));
|
|
1245
1254
|
let diskData = null;
|
|
1246
1255
|
try {
|
|
1247
|
-
if (await
|
|
1248
|
-
diskData = await
|
|
1256
|
+
if (await fs6.exists(USAGE_FILE)) {
|
|
1257
|
+
diskData = await fs6.readJson(USAGE_FILE);
|
|
1249
1258
|
}
|
|
1250
1259
|
} catch (e) {
|
|
1251
1260
|
}
|
|
@@ -1257,11 +1266,11 @@ var init_usage = __esm({
|
|
|
1257
1266
|
}
|
|
1258
1267
|
}
|
|
1259
1268
|
const tempFile = USAGE_FILE + ".tmp";
|
|
1260
|
-
await
|
|
1261
|
-
const fd = await
|
|
1262
|
-
await
|
|
1263
|
-
await
|
|
1264
|
-
await
|
|
1269
|
+
await fs6.writeJson(tempFile, cachedUsage, { spaces: 2 });
|
|
1270
|
+
const fd = await fs6.open(tempFile, "r+");
|
|
1271
|
+
await fs6.fsync(fd);
|
|
1272
|
+
await fs6.close(fd);
|
|
1273
|
+
await fs6.rename(tempFile, USAGE_FILE);
|
|
1265
1274
|
isDirty = false;
|
|
1266
1275
|
lastWriteTime = Date.now();
|
|
1267
1276
|
} catch (e) {
|
|
@@ -1459,7 +1468,7 @@ var init_arg_parser = __esm({
|
|
|
1459
1468
|
|
|
1460
1469
|
// src/tools/web_search.js
|
|
1461
1470
|
import puppeteer from "puppeteer";
|
|
1462
|
-
import
|
|
1471
|
+
import fs7 from "fs";
|
|
1463
1472
|
import path6 from "path";
|
|
1464
1473
|
var web_search;
|
|
1465
1474
|
var init_web_search = __esm({
|
|
@@ -1484,7 +1493,7 @@ var init_web_search = __esm({
|
|
|
1484
1493
|
]
|
|
1485
1494
|
});
|
|
1486
1495
|
const page = await browser.newPage();
|
|
1487
|
-
await page.setUserAgent("Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/
|
|
1496
|
+
await page.setUserAgent("Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/148.0.0.0 Safari/537.36");
|
|
1488
1497
|
await page.setViewport({ width: 1366, height: 768 });
|
|
1489
1498
|
const jitter = attempt === 1 ? Math.random() * 1e3 + 500 : Math.random() * 2e3 + 1e3;
|
|
1490
1499
|
await new Promise((r) => setTimeout(r, jitter));
|
|
@@ -1515,8 +1524,8 @@ Snippet: ${snippet}`;
|
|
|
1515
1524
|
}
|
|
1516
1525
|
const finalResults = results.join("\n\n");
|
|
1517
1526
|
const toolLogDir = path6.join(LOGS_DIR, "tools");
|
|
1518
|
-
if (!
|
|
1519
|
-
|
|
1527
|
+
if (!fs7.existsSync(toolLogDir)) fs7.mkdirSync(toolLogDir, { recursive: true });
|
|
1528
|
+
fs7.appendFileSync(path6.join(toolLogDir, "search-results.log"), `SEARCH ${(/* @__PURE__ */ new Date()).toLocaleString()} - Query: [${query}]. Count: ${results.length}.
|
|
1520
1529
|
Content:
|
|
1521
1530
|
${finalResults}
|
|
1522
1531
|
|
|
@@ -1544,7 +1553,7 @@ ${finalResults}`;
|
|
|
1544
1553
|
|
|
1545
1554
|
// src/tools/web_scrape.js
|
|
1546
1555
|
import puppeteer2 from "puppeteer";
|
|
1547
|
-
import
|
|
1556
|
+
import fs8 from "fs";
|
|
1548
1557
|
import path7 from "path";
|
|
1549
1558
|
var web_scrape;
|
|
1550
1559
|
var init_web_scrape = __esm({
|
|
@@ -1568,7 +1577,7 @@ var init_web_scrape = __esm({
|
|
|
1568
1577
|
]
|
|
1569
1578
|
});
|
|
1570
1579
|
const page = await browser.newPage();
|
|
1571
|
-
await page.setUserAgent("Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/
|
|
1580
|
+
await page.setUserAgent("Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/148.0.0.0 Safari/537.36");
|
|
1572
1581
|
await page.setViewport({ width: 1366, height: 768 });
|
|
1573
1582
|
const jitter = attempt === 1 ? Math.random() * 1e3 + 500 : Math.random() * 2e3 + 1e3;
|
|
1574
1583
|
await new Promise((r) => setTimeout(r, jitter));
|
|
@@ -1613,8 +1622,8 @@ var init_web_scrape = __esm({
|
|
|
1613
1622
|
if (!htmlContent) throw new Error("EMPTY_RENDER_RESULT");
|
|
1614
1623
|
const cleanedHtml = htmlContent.replace(/\s+/g, " ").replace(/>\s+</g, "><").trim().substring(0, 3e4);
|
|
1615
1624
|
const toolLogDir = path7.join(LOGS_DIR, "tools");
|
|
1616
|
-
if (!
|
|
1617
|
-
|
|
1625
|
+
if (!fs8.existsSync(toolLogDir)) fs8.mkdirSync(toolLogDir, { recursive: true });
|
|
1626
|
+
fs8.appendFileSync(path7.join(toolLogDir, "search-scraped.log"), `PUPPETEER ${(/* @__PURE__ */ new Date()).toLocaleString()} - URL: [${url}]. Length: ${cleanedHtml.length}.
|
|
1618
1627
|
Content:
|
|
1619
1628
|
${cleanedHtml}${htmlContent.length > 3e4 ? "\n\n[TRUNCATED AT 30K CHARS]" : ""}
|
|
1620
1629
|
|
|
@@ -1662,7 +1671,7 @@ var init_memory = __esm({
|
|
|
1662
1671
|
if (!content) return "ERROR: Missing 'content' for temp memory.";
|
|
1663
1672
|
const tempStorage = readEncryptedJson(TEMP_MEM_FILE, {});
|
|
1664
1673
|
if (!tempStorage[chatId]) tempStorage[chatId] = [];
|
|
1665
|
-
const MAX_CHARS =
|
|
1674
|
+
const MAX_CHARS = 1024 * 4;
|
|
1666
1675
|
let currentTotalLength = tempStorage[chatId].reduce((acc, m) => acc + m.length, 0);
|
|
1667
1676
|
while (tempStorage[chatId].length > 0 && currentTotalLength + content.length > MAX_CHARS) {
|
|
1668
1677
|
const removed = tempStorage[chatId].shift();
|
|
@@ -1676,7 +1685,7 @@ var init_memory = __esm({
|
|
|
1676
1685
|
const memories = readEncryptedJson(MEMORIES_FILE, []);
|
|
1677
1686
|
if (method === "add") {
|
|
1678
1687
|
if (!content) return "ERROR: Missing 'content' for memory addition.";
|
|
1679
|
-
const MAX_CHARS =
|
|
1688
|
+
const MAX_CHARS = 1024 * 4;
|
|
1680
1689
|
let currentTotalLength = memories.reduce((acc, m) => acc + (m.memory?.length || 0), 0);
|
|
1681
1690
|
while (memories.length > 0 && currentTotalLength + content.length > MAX_CHARS) {
|
|
1682
1691
|
const removed = memories.shift();
|
|
@@ -1735,7 +1744,7 @@ var init_chat = __esm({
|
|
|
1735
1744
|
});
|
|
1736
1745
|
|
|
1737
1746
|
// src/tools/list_files.js
|
|
1738
|
-
import
|
|
1747
|
+
import fs9 from "fs";
|
|
1739
1748
|
import path8 from "path";
|
|
1740
1749
|
var list_files;
|
|
1741
1750
|
var init_list_files = __esm({
|
|
@@ -1745,14 +1754,14 @@ var init_list_files = __esm({
|
|
|
1745
1754
|
const { path: targetPath = "." } = parseArgs(args);
|
|
1746
1755
|
const absolutePath = path8.resolve(process.cwd(), targetPath);
|
|
1747
1756
|
try {
|
|
1748
|
-
if (!
|
|
1757
|
+
if (!fs9.existsSync(absolutePath)) {
|
|
1749
1758
|
return `ERROR: Path [${targetPath}] does not exist.`;
|
|
1750
1759
|
}
|
|
1751
|
-
const stats =
|
|
1760
|
+
const stats = fs9.statSync(absolutePath);
|
|
1752
1761
|
if (!stats.isDirectory()) {
|
|
1753
1762
|
return `ERROR: Path [${targetPath}] is a file, not a directory. Use view_file instead.`;
|
|
1754
1763
|
}
|
|
1755
|
-
const files =
|
|
1764
|
+
const files = fs9.readdirSync(absolutePath);
|
|
1756
1765
|
if (files.length === 0) {
|
|
1757
1766
|
return `Directory [${targetPath}] is empty.`;
|
|
1758
1767
|
}
|
|
@@ -1764,7 +1773,7 @@ var init_list_files = __esm({
|
|
|
1764
1773
|
let indicator = "\u{1F4C4}";
|
|
1765
1774
|
let metaPart = "";
|
|
1766
1775
|
try {
|
|
1767
|
-
const fStats =
|
|
1776
|
+
const fStats = fs9.statSync(fPath);
|
|
1768
1777
|
indicator = fStats.isDirectory() ? "\u{1F4C1}" : "\u{1F4C4}";
|
|
1769
1778
|
const sizeKB = (fStats.size / 1024).toFixed(1);
|
|
1770
1779
|
metaPart = fStats.isFile() ? ` - [${sizeKB} KB]` : "";
|
|
@@ -1796,7 +1805,7 @@ ${list}${footer}`;
|
|
|
1796
1805
|
});
|
|
1797
1806
|
|
|
1798
1807
|
// src/tools/view_file.js
|
|
1799
|
-
import
|
|
1808
|
+
import fs10 from "fs";
|
|
1800
1809
|
import path9 from "path";
|
|
1801
1810
|
var view_file;
|
|
1802
1811
|
var init_view_file = __esm({
|
|
@@ -1811,10 +1820,10 @@ var init_view_file = __esm({
|
|
|
1811
1820
|
if (!targetPath) return 'ERROR: Missing "path" argument for view_file.';
|
|
1812
1821
|
const absolutePath = path9.resolve(process.cwd(), targetPath);
|
|
1813
1822
|
try {
|
|
1814
|
-
if (!
|
|
1823
|
+
if (!fs10.existsSync(absolutePath)) {
|
|
1815
1824
|
return `ERROR: File [${targetPath}] does not exist.`;
|
|
1816
1825
|
}
|
|
1817
|
-
const stats =
|
|
1826
|
+
const stats = fs10.statSync(absolutePath);
|
|
1818
1827
|
if (stats.isDirectory()) {
|
|
1819
1828
|
return `ERROR: Path [${targetPath}] is a directory. Use list_files instead.`;
|
|
1820
1829
|
}
|
|
@@ -1829,7 +1838,7 @@ var init_view_file = __esm({
|
|
|
1829
1838
|
".doc": "application/msword"
|
|
1830
1839
|
};
|
|
1831
1840
|
if (mimeMap[ext]) {
|
|
1832
|
-
const buffer =
|
|
1841
|
+
const buffer = fs10.readFileSync(absolutePath);
|
|
1833
1842
|
const base64 = buffer.toString("base64");
|
|
1834
1843
|
const mimeType = mimeMap[ext];
|
|
1835
1844
|
return {
|
|
@@ -1842,7 +1851,7 @@ var init_view_file = __esm({
|
|
|
1842
1851
|
}
|
|
1843
1852
|
};
|
|
1844
1853
|
}
|
|
1845
|
-
let content =
|
|
1854
|
+
let content = fs10.readFileSync(absolutePath, "utf8");
|
|
1846
1855
|
if (content.startsWith("\uFEFF")) {
|
|
1847
1856
|
content = content.slice(1);
|
|
1848
1857
|
}
|
|
@@ -1865,7 +1874,7 @@ ${code}`;
|
|
|
1865
1874
|
});
|
|
1866
1875
|
|
|
1867
1876
|
// src/tools/write_file.js
|
|
1868
|
-
import
|
|
1877
|
+
import fs11 from "fs";
|
|
1869
1878
|
import path10 from "path";
|
|
1870
1879
|
var write_file;
|
|
1871
1880
|
var init_write_file = __esm({
|
|
@@ -1880,9 +1889,9 @@ var init_write_file = __esm({
|
|
|
1880
1889
|
const parentDir = path10.dirname(absolutePath);
|
|
1881
1890
|
try {
|
|
1882
1891
|
let ancestry = "";
|
|
1883
|
-
if (
|
|
1892
|
+
if (fs11.existsSync(absolutePath)) {
|
|
1884
1893
|
try {
|
|
1885
|
-
const oldData =
|
|
1894
|
+
const oldData = fs11.readFileSync(absolutePath, "utf8");
|
|
1886
1895
|
const lines = oldData.split(/\r?\n/);
|
|
1887
1896
|
ancestry = `Old File contents:
|
|
1888
1897
|
${lines.map((l, i) => `${i + 1} | ${l}`).join("\n")}
|
|
@@ -1894,15 +1903,15 @@ ${lines.map((l, i) => `${i + 1} | ${l}`).join("\n")}
|
|
|
1894
1903
|
`;
|
|
1895
1904
|
}
|
|
1896
1905
|
}
|
|
1897
|
-
if (!
|
|
1898
|
-
|
|
1906
|
+
if (!fs11.existsSync(parentDir)) {
|
|
1907
|
+
fs11.mkdirSync(parentDir, { recursive: true });
|
|
1899
1908
|
}
|
|
1900
1909
|
const strip = (t) => t.replace(/^```[\w]*\n?/, "").replace(/```\s*$/, "").replace(/\r\n/g, "\n").replace(/\r/g, "\n");
|
|
1901
1910
|
const processedContent = strip(content);
|
|
1902
1911
|
const lineCount = processedContent.split(/\r?\n/).length;
|
|
1903
1912
|
const originalSize = Buffer.byteLength(processedContent, "utf8");
|
|
1904
|
-
|
|
1905
|
-
let verifiedContent =
|
|
1913
|
+
fs11.writeFileSync(absolutePath, processedContent, "utf8");
|
|
1914
|
+
let verifiedContent = fs11.readFileSync(absolutePath, "utf8");
|
|
1906
1915
|
const verifiedSize = Buffer.byteLength(verifiedContent, "utf8");
|
|
1907
1916
|
const verifiedLines = verifiedContent.split(/\r?\n/);
|
|
1908
1917
|
const verifiedLineCount = verifiedLines.length;
|
|
@@ -1938,7 +1947,7 @@ Check if Starting and Ending matches your write.`;
|
|
|
1938
1947
|
});
|
|
1939
1948
|
|
|
1940
1949
|
// src/tools/update_file.js
|
|
1941
|
-
import
|
|
1950
|
+
import fs12 from "fs";
|
|
1942
1951
|
import path11 from "path";
|
|
1943
1952
|
var update_file;
|
|
1944
1953
|
var init_update_file = __esm({
|
|
@@ -1954,16 +1963,16 @@ var init_update_file = __esm({
|
|
|
1954
1963
|
content_to_add = strip(content_to_add);
|
|
1955
1964
|
const absolutePath = path11.resolve(process.cwd(), targetPath);
|
|
1956
1965
|
try {
|
|
1957
|
-
if (!
|
|
1966
|
+
if (!fs12.existsSync(absolutePath)) {
|
|
1958
1967
|
return `ERROR: File [${targetPath}] does not exist. Use write_file instead.`;
|
|
1959
1968
|
}
|
|
1960
|
-
let diskContent =
|
|
1969
|
+
let diskContent = fs12.readFileSync(absolutePath, "utf8");
|
|
1961
1970
|
if (diskContent.startsWith("\uFEFF")) {
|
|
1962
1971
|
diskContent = diskContent.slice(1);
|
|
1963
1972
|
}
|
|
1964
1973
|
const normalizedDisk = diskContent.replace(/\r\n/g, "\n").replace(/\r/g, "\n");
|
|
1965
1974
|
if (diskContent !== normalizedDisk) {
|
|
1966
|
-
|
|
1975
|
+
fs12.writeFileSync(absolutePath, normalizedDisk, "utf8");
|
|
1967
1976
|
diskContent = normalizedDisk;
|
|
1968
1977
|
}
|
|
1969
1978
|
const currentContent = diskContent;
|
|
@@ -2032,7 +2041,7 @@ var init_update_file = __esm({
|
|
|
2032
2041
|
const firstLeadingContext = currentContent.substring(firstLineStart, startPos);
|
|
2033
2042
|
const finalContentToAdd = adjustIndentation(content_to_add, firstMatchContent, firstLeadingContext);
|
|
2034
2043
|
const finalContentToReplace = firstMatchContent;
|
|
2035
|
-
|
|
2044
|
+
fs12.writeFileSync(absolutePath, newFileContent, "utf8");
|
|
2036
2045
|
const allOriginalLines = currentContent.split(/\r?\n/);
|
|
2037
2046
|
const startLine = currentContent.substring(0, startPos).split(/\r?\n/).length;
|
|
2038
2047
|
const oldLines = content_to_replace.split(/\r?\n/);
|
|
@@ -2168,7 +2177,7 @@ ${finalOutput}`);
|
|
|
2168
2177
|
});
|
|
2169
2178
|
|
|
2170
2179
|
// src/tools/read_folder.js
|
|
2171
|
-
import
|
|
2180
|
+
import fs13 from "fs";
|
|
2172
2181
|
import path12 from "path";
|
|
2173
2182
|
var read_folder;
|
|
2174
2183
|
var init_read_folder = __esm({
|
|
@@ -2178,14 +2187,14 @@ var init_read_folder = __esm({
|
|
|
2178
2187
|
const { path: targetPath = "." } = parseArgs(args);
|
|
2179
2188
|
const absolutePath = path12.resolve(process.cwd(), targetPath);
|
|
2180
2189
|
try {
|
|
2181
|
-
if (!
|
|
2190
|
+
if (!fs13.existsSync(absolutePath)) {
|
|
2182
2191
|
return `ERROR: Path [${targetPath}] does not exist.`;
|
|
2183
2192
|
}
|
|
2184
|
-
const stats =
|
|
2193
|
+
const stats = fs13.statSync(absolutePath);
|
|
2185
2194
|
if (!stats.isDirectory()) {
|
|
2186
2195
|
return `ERROR: Path [${targetPath}] is a file, not a directory. Use view_file instead.`;
|
|
2187
2196
|
}
|
|
2188
|
-
const files =
|
|
2197
|
+
const files = fs13.readdirSync(absolutePath);
|
|
2189
2198
|
const totalItems = files.length;
|
|
2190
2199
|
const maxDisplay = 100;
|
|
2191
2200
|
const displayItems = files.slice(0, maxDisplay);
|
|
@@ -2195,7 +2204,7 @@ var init_read_folder = __esm({
|
|
|
2195
2204
|
let indicator = "\u{1F4C4}";
|
|
2196
2205
|
let info = { name: file, type: "unknown", size: "N/A", mtime: "N/A" };
|
|
2197
2206
|
try {
|
|
2198
|
-
const fStats =
|
|
2207
|
+
const fStats = fs13.statSync(fPath);
|
|
2199
2208
|
info = {
|
|
2200
2209
|
name: file,
|
|
2201
2210
|
type: fStats.isDirectory() ? "directory" : "file",
|
|
@@ -2279,7 +2288,7 @@ var init_ask_user = __esm({
|
|
|
2279
2288
|
// src/tools/write_pdf.js
|
|
2280
2289
|
import puppeteer3 from "puppeteer";
|
|
2281
2290
|
import path13 from "path";
|
|
2282
|
-
import
|
|
2291
|
+
import fs14 from "fs-extra";
|
|
2283
2292
|
import { PDFDocument } from "pdf-lib";
|
|
2284
2293
|
var write_pdf;
|
|
2285
2294
|
var init_write_pdf = __esm({
|
|
@@ -2297,7 +2306,7 @@ var init_write_pdf = __esm({
|
|
|
2297
2306
|
const absolutePath = path13.resolve(process.cwd(), targetPath);
|
|
2298
2307
|
let browser = null;
|
|
2299
2308
|
try {
|
|
2300
|
-
await
|
|
2309
|
+
await fs14.ensureDir(path13.dirname(absolutePath));
|
|
2301
2310
|
browser = await puppeteer3.launch({
|
|
2302
2311
|
headless: true,
|
|
2303
2312
|
args: [
|
|
@@ -2360,8 +2369,8 @@ var init_write_pdf = __esm({
|
|
|
2360
2369
|
pdfDoc.setCreator("FluxFlow PDF Engine");
|
|
2361
2370
|
pdfDoc.setProducer("FluxFlow (Generative AI)");
|
|
2362
2371
|
const finalPdfBytes = await pdfDoc.save();
|
|
2363
|
-
await
|
|
2364
|
-
const stats = await
|
|
2372
|
+
await fs14.writeFile(absolutePath, finalPdfBytes);
|
|
2373
|
+
const stats = await fs14.stat(absolutePath);
|
|
2365
2374
|
return `SUCCESS: PDF generated successfully at [${targetPath}] (${(stats.size / 1024).toFixed(2)} KB).`;
|
|
2366
2375
|
} catch (err) {
|
|
2367
2376
|
return `ERROR: Failed to generate PDF [${targetPath}]: ${err.message}`;
|
|
@@ -2373,7 +2382,7 @@ var init_write_pdf = __esm({
|
|
|
2373
2382
|
});
|
|
2374
2383
|
|
|
2375
2384
|
// src/tools/write_docx.js
|
|
2376
|
-
import
|
|
2385
|
+
import fs15 from "fs-extra";
|
|
2377
2386
|
import path14 from "path";
|
|
2378
2387
|
import HTMLtoDOCX from "html-to-docx";
|
|
2379
2388
|
var write_docx;
|
|
@@ -2389,7 +2398,7 @@ var init_write_docx = __esm({
|
|
|
2389
2398
|
if (!content) return 'ERROR: Missing "content" (HTML) for write_docx.';
|
|
2390
2399
|
const absolutePath = path14.resolve(process.cwd(), targetPath);
|
|
2391
2400
|
try {
|
|
2392
|
-
await
|
|
2401
|
+
await fs15.ensureDir(path14.dirname(absolutePath));
|
|
2393
2402
|
const fileName = path14.basename(targetPath);
|
|
2394
2403
|
const fullHtml = content.includes("<html") ? content : `
|
|
2395
2404
|
<!DOCTYPE html>
|
|
@@ -2411,7 +2420,7 @@ var init_write_docx = __esm({
|
|
|
2411
2420
|
footer: true,
|
|
2412
2421
|
pageNumber: true
|
|
2413
2422
|
});
|
|
2414
|
-
await
|
|
2423
|
+
await fs15.writeFile(absolutePath, docxBuffer);
|
|
2415
2424
|
return `SUCCESS: Word document [${targetPath}] generated successfully.
|
|
2416
2425
|
- Size: ${(docxBuffer.length / 1024).toFixed(1)} KB`;
|
|
2417
2426
|
} catch (err) {
|
|
@@ -2422,7 +2431,7 @@ var init_write_docx = __esm({
|
|
|
2422
2431
|
});
|
|
2423
2432
|
|
|
2424
2433
|
// src/tools/write_pptx.js
|
|
2425
|
-
import
|
|
2434
|
+
import fs16 from "fs-extra";
|
|
2426
2435
|
import path15 from "path";
|
|
2427
2436
|
import pptxgen from "pptxgenjs";
|
|
2428
2437
|
import html2pptxgenjs from "html2pptxgenjs";
|
|
@@ -2440,7 +2449,7 @@ var init_write_pptx = __esm({
|
|
|
2440
2449
|
if (!content) return 'ERROR: No "content" (HTML) provided for write_pptx.';
|
|
2441
2450
|
const absolutePath = path15.resolve(process.cwd(), targetPath);
|
|
2442
2451
|
try {
|
|
2443
|
-
await
|
|
2452
|
+
await fs16.ensureDir(path15.dirname(absolutePath));
|
|
2444
2453
|
const PptxConstructor = typeof pptxgen === "function" ? pptxgen : pptxgen.default;
|
|
2445
2454
|
if (!PptxConstructor) throw new Error("Could not find PptxGenJS constructor in module");
|
|
2446
2455
|
const pres = new PptxConstructor();
|
|
@@ -2477,7 +2486,7 @@ var init_write_pptx = __esm({
|
|
|
2477
2486
|
}
|
|
2478
2487
|
}
|
|
2479
2488
|
const buffer = await pres.write({ outputType: "nodebuffer" });
|
|
2480
|
-
await
|
|
2489
|
+
await fs16.writeFile(absolutePath, buffer);
|
|
2481
2490
|
return `SUCCESS: Native HTML-to-PPTX [${targetPath}] generated with ${slideBlocks.length} slides.
|
|
2482
2491
|
- Size: ${(buffer.length / 1024).toFixed(1)} KB`;
|
|
2483
2492
|
} catch (err) {
|
|
@@ -2596,7 +2605,7 @@ var init_tools = __esm({
|
|
|
2596
2605
|
// src/utils/ai.js
|
|
2597
2606
|
import { GoogleGenAI, ThinkingLevel, HarmBlockThreshold, HarmCategory } from "@google/genai";
|
|
2598
2607
|
import path16 from "path";
|
|
2599
|
-
import
|
|
2608
|
+
import fs17 from "fs";
|
|
2600
2609
|
var client, TERMINATION_SIGNAL, signalTermination, TOOL_LABELS2, getToolDetail, runJanitorTask, getActiveToolContext, getContextSafeText, contextSafeReplace, getSanitizedText, detectToolCalls, initAI, getAIStream;
|
|
2601
2610
|
var init_ai = __esm({
|
|
2602
2611
|
"src/utils/ai.js"() {
|
|
@@ -2714,8 +2723,8 @@ var init_ai = __esm({
|
|
|
2714
2723
|
if (lastUsage) await addToUsage("tokens", lastUsage.totalTokenCount || 0);
|
|
2715
2724
|
const date = (/* @__PURE__ */ new Date()).toLocaleString();
|
|
2716
2725
|
const janitorLogDir = path16.join(LOGS_DIR, "janitor");
|
|
2717
|
-
if (!
|
|
2718
|
-
|
|
2726
|
+
if (!fs17.existsSync(janitorLogDir)) fs17.mkdirSync(janitorLogDir, { recursive: true });
|
|
2727
|
+
fs17.appendFileSync(path16.join(janitorLogDir, "debug.log"), `
|
|
2719
2728
|
|
|
2720
2729
|
---------------------------------------------------
|
|
2721
2730
|
|
|
@@ -2736,7 +2745,7 @@ DEBUG [${date}]: ${finalSynthesis}
|
|
|
2736
2745
|
const result = await dispatchTool(janitorToolCall.toolName, janitorToolCall.args, toolContext);
|
|
2737
2746
|
const date = (/* @__PURE__ */ new Date()).toLocaleString();
|
|
2738
2747
|
const janitorLogDir = path16.join(LOGS_DIR, "janitor");
|
|
2739
|
-
|
|
2748
|
+
fs17.appendFileSync(path16.join(janitorLogDir, "debug.log"), `DEBUG [${date}]: RESULT [${janitorToolCall.toolName}]: ${result}
|
|
2740
2749
|
`);
|
|
2741
2750
|
if (janitorToolCall.toolName === "memory" && !janitorToolCall.args.includes("action='temp'")) {
|
|
2742
2751
|
if (onMemoryUpdated) onMemoryUpdated();
|
|
@@ -2747,8 +2756,8 @@ DEBUG [${date}]: ${finalSynthesis}
|
|
|
2747
2756
|
attempts++;
|
|
2748
2757
|
const date = (/* @__PURE__ */ new Date()).toLocaleString();
|
|
2749
2758
|
const janitorErrDir = path16.join(LOGS_DIR, "janitor");
|
|
2750
|
-
if (!
|
|
2751
|
-
|
|
2759
|
+
if (!fs17.existsSync(janitorErrDir)) fs17.mkdirSync(janitorErrDir, { recursive: true });
|
|
2760
|
+
fs17.appendFileSync(path16.join(janitorErrDir, "error.log"), `ERROR [Attempt ${attempts}/${MAX_JANITOR_RETRIES + 1}] [${date}]: ${String(janitorErr)}
|
|
2752
2761
|
|
|
2753
2762
|
`);
|
|
2754
2763
|
if (attempts > MAX_JANITOR_RETRIES) break;
|
|
@@ -2758,7 +2767,7 @@ DEBUG [${date}]: ${finalSynthesis}
|
|
|
2758
2767
|
}
|
|
2759
2768
|
if (attempts) {
|
|
2760
2769
|
const janitorErrDir = path16.join(LOGS_DIR, "janitor");
|
|
2761
|
-
|
|
2770
|
+
fs17.appendFileSync(path16.join(janitorErrDir, "error.log"), `-----------------------------------------------------------------------------
|
|
2762
2771
|
|
|
2763
2772
|
|
|
2764
2773
|
`);
|
|
@@ -2982,9 +2991,10 @@ DEBUG [${date}]: ${finalSynthesis}
|
|
|
2982
2991
|
const otherMemories = Object.entries(tempStorage).filter(([id]) => id !== chatId).flatMap(([_, mems]) => mems).map((mem) => `- ${mem}`).join("\n");
|
|
2983
2992
|
const persistentStorage = readEncryptedJson(MEMORIES_FILE, []);
|
|
2984
2993
|
const mainUserMemories = persistentStorage.map((m) => `- ${m.memory}`).join("\n");
|
|
2985
|
-
const
|
|
2986
|
-
|
|
2987
|
-
|
|
2994
|
+
const isContext32k = (sessionStats?.tokens || 0) >= 32e3;
|
|
2995
|
+
const memoryPrompt = getMemoryPrompt(otherMemories, mainUserMemories, isMemoryEnabled, isContext32k);
|
|
2996
|
+
const firstUserMsg = `${memoryPrompt}[SYSTEM] **STRICTLY FOLLOW THINKING POLICY AS HIGHEST PRIORITY. NEVER START A RESPONSE WITHOUT THINKING**.
|
|
2997
|
+
USER_PROMPT: "${agentText.replace(/\s*\[Prompted on:.*?\]/g, "").trim()}"`.trim();
|
|
2988
2998
|
modifiedHistory.push({ role: "user", text: firstUserMsg });
|
|
2989
2999
|
let lastUsage = null;
|
|
2990
3000
|
const MAX_LOOPS = mode === "Flux" ? 70 : 7;
|
|
@@ -3014,7 +3024,7 @@ USER_PROMPT: "${agentText}"`.trim();
|
|
|
3014
3024
|
|
|
3015
3025
|
[STEERING HINT]: ${hint}`;
|
|
3016
3026
|
} else {
|
|
3017
|
-
modifiedHistory.push({ role: "user", text: `[SYSTEM] **STRICTLY FOLLOW THINKING POLICY AS HIGHEST PRIORITY. NEVER START A RESPONSE WITHOUT THINKING
|
|
3027
|
+
modifiedHistory.push({ role: "user", text: `[SYSTEM] **STRICTLY FOLLOW THINKING POLICY AS HIGHEST PRIORITY. NEVER START A RESPONSE WITHOUT THINKING**.
|
|
3018
3028
|
|
|
3019
3029
|
[STEERING HINT]: ${hint}` });
|
|
3020
3030
|
}
|
|
@@ -3066,8 +3076,7 @@ USER_PROMPT: "${agentText}"`.trim();
|
|
|
3066
3076
|
} else if (retryCount > 0) {
|
|
3067
3077
|
yield { type: "model_update", content: null };
|
|
3068
3078
|
}
|
|
3069
|
-
const
|
|
3070
|
-
const currentSystemInstruction = getSystemInstruction(profile, thinkingLevel, mode, systemSettings, otherMemories, mainUserMemories, isMemoryEnabled, isContext32k, MAX_LOOPS, loop + 1);
|
|
3079
|
+
const currentSystemInstruction = getSystemInstruction(profile, thinkingLevel, mode, systemSettings, isMemoryEnabled, MAX_LOOPS, loop + 1);
|
|
3071
3080
|
const jitInstruction = `
|
|
3072
3081
|
|
|
3073
3082
|
[SYSTEM] Tool result received. Analyze output and proceed with your turn. **STRICTLY MAINTAIN THINKING PROTOCOL. NEVER START A RESPONSE WITHOUT THINKING**.`;
|
|
@@ -3247,8 +3256,8 @@ USER_PROMPT: "${agentText}"`.trim();
|
|
|
3247
3256
|
let actualEndLine = eLine;
|
|
3248
3257
|
try {
|
|
3249
3258
|
const absPath = path16.resolve(process.cwd(), targetPath2);
|
|
3250
|
-
if (
|
|
3251
|
-
const content =
|
|
3259
|
+
if (fs17.existsSync(absPath)) {
|
|
3260
|
+
const content = fs17.readFileSync(absPath, "utf8");
|
|
3252
3261
|
const lines = content.split("\n").length;
|
|
3253
3262
|
totalLines = lines;
|
|
3254
3263
|
actualEndLine = Math.min(eLine, lines);
|
|
@@ -3327,7 +3336,7 @@ ${boxBottom}` };
|
|
|
3327
3336
|
const denyMsg = `Access Denied. You are not allowed to access files outside the current workspace. To enable this, ask the user to turn on "External Workspace Access" in /settings.`;
|
|
3328
3337
|
toolResults.push({ role: "user", text: `[TOOL_RESULT]: ERROR: ${denyMsg}
|
|
3329
3338
|
|
|
3330
|
-
[SYSTEM] **
|
|
3339
|
+
[SYSTEM] **STRICTLY FOLLOW THINKING POLICY AS HIGHEST PRIORITY. NEVER START A RESPONSE WITHOUT THINKING**.` });
|
|
3331
3340
|
yield { type: "tool_result", content: `[TOOL_RESULT]: ERROR: ${denyMsg}` };
|
|
3332
3341
|
toolCallPointer++;
|
|
3333
3342
|
continue;
|
|
@@ -3342,7 +3351,7 @@ ${boxBottom}` };
|
|
|
3342
3351
|
const denyMsg = `Permission Denied: User rejected the ${toolCall.toolName === "exec_command" ? "terminal execution" : "file edit"}.`;
|
|
3343
3352
|
toolResults.push({ role: "user", text: `[TOOL_RESULT]: DENIED: ${denyMsg}
|
|
3344
3353
|
|
|
3345
|
-
[SYSTEM] **
|
|
3354
|
+
[SYSTEM] **STRICTLY FOLLOW THINKING POLICY AS HIGHEST PRIORITY. NEVER START A RESPONSE WITHOUT THINKING**.` });
|
|
3346
3355
|
yield { type: "tool_result", content: `[TOOL_RESULT]: DENIED: ${denyMsg}` };
|
|
3347
3356
|
await incrementUsage("toolDenied");
|
|
3348
3357
|
if (settings.onToolResult) settings.onToolResult("denied");
|
|
@@ -3426,8 +3435,8 @@ ${boxBottom}` };
|
|
|
3426
3435
|
const errLog = String(err);
|
|
3427
3436
|
const date = (/* @__PURE__ */ new Date()).toLocaleString();
|
|
3428
3437
|
const agentErrDir = path16.join(LOGS_DIR, "agent");
|
|
3429
|
-
if (!
|
|
3430
|
-
|
|
3438
|
+
if (!fs17.existsSync(agentErrDir)) fs17.mkdirSync(agentErrDir, { recursive: true });
|
|
3439
|
+
fs17.appendFileSync(path16.join(agentErrDir, "error.log"), `ERROR [${date}]: ${errLog}
|
|
3431
3440
|
|
|
3432
3441
|
----------------------------------------------------------------------
|
|
3433
3442
|
|
|
@@ -3440,7 +3449,7 @@ ${boxBottom}` };
|
|
|
3440
3449
|
if (toolResults.length > 0) {
|
|
3441
3450
|
toolResults.forEach((tr) => modifiedHistory.push(tr));
|
|
3442
3451
|
}
|
|
3443
|
-
modifiedHistory.push({ role: "user", text: "[SYSTEM] Response got cut for internal error, continue from checkpoint seamlessly
|
|
3452
|
+
modifiedHistory.push({ role: "user", text: "[SYSTEM] Response got cut for internal error, continue from checkpoint seamlessly, DON'T repeat what you already said! PICK UP FROM THE WORD IN A WAY THAT USER SHOULD NOT NOTICE ANY CUTOFF. Rules:\n- Do not reuse <think> if the thinking already started just continue from the word and end it properly.\n- If the cutoff was in middle of a tool call, start the tool call from start.\n- Visually the new pickup and continuation should look natual sentence flow.\n- DON'T try to think shorter, keep length standard." });
|
|
3444
3453
|
accumulatedContext += turnText;
|
|
3445
3454
|
for (let i = waitTime / 1e3; i > 0; i--) {
|
|
3446
3455
|
yield { type: "status", content: `Error Occured. Recovering Stream (${inStreamRetryCount}/${MAX_RETRIES}) [${i}s]...` };
|
|
@@ -3524,7 +3533,7 @@ ${timestamp}`;
|
|
|
3524
3533
|
});
|
|
3525
3534
|
|
|
3526
3535
|
// src/utils/settings.js
|
|
3527
|
-
import
|
|
3536
|
+
import fs18 from "fs-extra";
|
|
3528
3537
|
import path17 from "path";
|
|
3529
3538
|
var DEFAULT_SETTINGS, loadSettings, migrateToExternal, saveSettings;
|
|
3530
3539
|
var init_settings = __esm({
|
|
@@ -3560,8 +3569,8 @@ var init_settings = __esm({
|
|
|
3560
3569
|
};
|
|
3561
3570
|
loadSettings = async () => {
|
|
3562
3571
|
try {
|
|
3563
|
-
if (await
|
|
3564
|
-
const saved = await
|
|
3572
|
+
if (await fs18.exists(SETTINGS_FILE)) {
|
|
3573
|
+
const saved = await fs18.readJson(SETTINGS_FILE);
|
|
3565
3574
|
const merged = {
|
|
3566
3575
|
...DEFAULT_SETTINGS,
|
|
3567
3576
|
...saved,
|
|
@@ -3571,7 +3580,7 @@ var init_settings = __esm({
|
|
|
3571
3580
|
};
|
|
3572
3581
|
if (merged.showFullThinking === false) {
|
|
3573
3582
|
merged.showFullThinking = true;
|
|
3574
|
-
await
|
|
3583
|
+
await fs18.writeJson(SETTINGS_FILE, merged, { spaces: 2 });
|
|
3575
3584
|
}
|
|
3576
3585
|
return merged;
|
|
3577
3586
|
}
|
|
@@ -3587,9 +3596,9 @@ var init_settings = __esm({
|
|
|
3587
3596
|
const src = path17.join(FLUXFLOW_DIR2, folder);
|
|
3588
3597
|
const dest = path17.join(newPath, folder);
|
|
3589
3598
|
try {
|
|
3590
|
-
if (await
|
|
3591
|
-
await
|
|
3592
|
-
await
|
|
3599
|
+
if (await fs18.exists(src)) {
|
|
3600
|
+
await fs18.ensureDir(dest);
|
|
3601
|
+
await fs18.copy(src, dest, { overwrite: true });
|
|
3593
3602
|
}
|
|
3594
3603
|
} catch (err) {
|
|
3595
3604
|
console.error(`Migration failed for ${folder}:`, err);
|
|
@@ -3603,8 +3612,8 @@ var init_settings = __esm({
|
|
|
3603
3612
|
await migrateToExternal(settings.systemSettings.externalDataPath);
|
|
3604
3613
|
}
|
|
3605
3614
|
const updated = { ...current, ...settings };
|
|
3606
|
-
await
|
|
3607
|
-
await
|
|
3615
|
+
await fs18.ensureDir(path17.dirname(SETTINGS_FILE));
|
|
3616
|
+
await fs18.writeJson(SETTINGS_FILE, updated, { spaces: 2 });
|
|
3608
3617
|
return true;
|
|
3609
3618
|
} catch (err) {
|
|
3610
3619
|
console.error("Failed to save settings:", err);
|
|
@@ -3817,7 +3826,7 @@ var init_UpdateProcessor = __esm({
|
|
|
3817
3826
|
import puppeteer4 from "puppeteer";
|
|
3818
3827
|
import { exec as exec3 } from "child_process";
|
|
3819
3828
|
import { promisify } from "util";
|
|
3820
|
-
import
|
|
3829
|
+
import fs19 from "fs";
|
|
3821
3830
|
var execAsync, checkPuppeteerReady, installPuppeteerBrowser;
|
|
3822
3831
|
var init_setup = __esm({
|
|
3823
3832
|
"src/utils/setup.js"() {
|
|
@@ -3825,7 +3834,7 @@ var init_setup = __esm({
|
|
|
3825
3834
|
checkPuppeteerReady = () => {
|
|
3826
3835
|
try {
|
|
3827
3836
|
const exePath = puppeteer4.executablePath();
|
|
3828
|
-
const exists = exePath &&
|
|
3837
|
+
const exists = exePath && fs19.existsSync(exePath);
|
|
3829
3838
|
if (exists) return true;
|
|
3830
3839
|
} catch (e) {
|
|
3831
3840
|
return false;
|
|
@@ -3855,11 +3864,11 @@ var app_exports = {};
|
|
|
3855
3864
|
__export(app_exports, {
|
|
3856
3865
|
default: () => App
|
|
3857
3866
|
});
|
|
3858
|
-
import
|
|
3867
|
+
import os3 from "os";
|
|
3859
3868
|
import React10, { useState as useState7, useEffect as useEffect5, useRef as useRef2, useMemo } from "react";
|
|
3860
3869
|
import { Box as Box10, Text as Text10, useInput as useInput4, useStdout } from "ink";
|
|
3861
3870
|
import Spinner2 from "ink-spinner";
|
|
3862
|
-
import
|
|
3871
|
+
import fs20 from "fs-extra";
|
|
3863
3872
|
import path18 from "path";
|
|
3864
3873
|
import { exec as exec4 } from "child_process";
|
|
3865
3874
|
import { MultilineInput } from "ink-multiline-input";
|
|
@@ -4026,7 +4035,7 @@ function App() {
|
|
|
4026
4035
|
const [messages, setMessages] = useState7(() => {
|
|
4027
4036
|
const logoMsg = { id: "logo-" + Date.now(), role: "system", text: FLUX_LOGO, isLogo: true, isMeta: true };
|
|
4028
4037
|
const welcomeMsg = { id: "welcome", role: "system", text: "\u{1F30A}\u26A1 Welcome to Flux Flow! Type /help for commands.", isMeta: true };
|
|
4029
|
-
const isHomeDir = process.cwd() ===
|
|
4038
|
+
const isHomeDir = process.cwd() === os3.homedir();
|
|
4030
4039
|
const isSystemDir = (() => {
|
|
4031
4040
|
const cwd = process.cwd().toLowerCase();
|
|
4032
4041
|
if (process.platform === "win32") {
|
|
@@ -4054,7 +4063,7 @@ function App() {
|
|
|
4054
4063
|
id: "home-warning",
|
|
4055
4064
|
role: "system",
|
|
4056
4065
|
text: `[SECURITY ALERT] HOME DIRECTORY DETECTED`,
|
|
4057
|
-
subText: `You are currently in ${
|
|
4066
|
+
subText: `You are currently in ${os3.homedir()}. Working here is high-risk as the agent may modify system-sensitive configurations. Please move to a project folder for safety.`,
|
|
4058
4067
|
isHomeWarning: true,
|
|
4059
4068
|
isMeta: true
|
|
4060
4069
|
});
|
|
@@ -4064,7 +4073,7 @@ function App() {
|
|
|
4064
4073
|
const queuedPromptRef = useRef2(null);
|
|
4065
4074
|
const [completedIndex, setCompletedIndex] = useState7(messages.length);
|
|
4066
4075
|
const windowedHistory = useMemo(() => {
|
|
4067
|
-
const MAX_HISTORY_LINES =
|
|
4076
|
+
const MAX_HISTORY_LINES = 1536;
|
|
4068
4077
|
const width = terminalSize.columns || 80;
|
|
4069
4078
|
let totalLines = 0;
|
|
4070
4079
|
let startIdx = 0;
|
|
@@ -4582,12 +4591,12 @@ ${list || "No saved chats found."}`, isMeta: true }];
|
|
|
4582
4591
|
setCompletedIndex(prev.length + 1);
|
|
4583
4592
|
return [...prev, { id: Date.now(), role: "system", text: "\u2622\uFE0F [NUCLEAR] Initiating reset...", isMeta: true }];
|
|
4584
4593
|
});
|
|
4585
|
-
if (
|
|
4586
|
-
if (
|
|
4587
|
-
if (
|
|
4594
|
+
if (fs20.existsSync(LOGS_DIR)) fs20.removeSync(LOGS_DIR);
|
|
4595
|
+
if (fs20.existsSync(SECRET_DIR)) fs20.removeSync(SECRET_DIR);
|
|
4596
|
+
if (fs20.existsSync(SETTINGS_FILE)) fs20.removeSync(SETTINGS_FILE);
|
|
4588
4597
|
try {
|
|
4589
|
-
const items =
|
|
4590
|
-
if (items.length === 0)
|
|
4598
|
+
const items = fs20.readdirSync(FLUXFLOW_DIR);
|
|
4599
|
+
if (items.length === 0) fs20.removeSync(FLUXFLOW_DIR);
|
|
4591
4600
|
} catch (e) {
|
|
4592
4601
|
}
|
|
4593
4602
|
setTimeout(() => {
|
|
@@ -4645,13 +4654,13 @@ ${list || "No saved chats found."}`, isMeta: true }];
|
|
|
4645
4654
|
- [Define custom step-by-step recipes for this project here]
|
|
4646
4655
|
`;
|
|
4647
4656
|
const filePath = path18.join(process.cwd(), "FluxFlow.md");
|
|
4648
|
-
if (
|
|
4657
|
+
if (fs20.pathExistsSync(filePath)) {
|
|
4649
4658
|
setMessages((prev) => {
|
|
4650
4659
|
setCompletedIndex(prev.length + 1);
|
|
4651
4660
|
return [...prev, { id: "init-err-" + Date.now(), role: "system", text: "\u274C ERROR: FluxFlow.md already exists in this directory.", isMeta: true }];
|
|
4652
4661
|
});
|
|
4653
4662
|
} else {
|
|
4654
|
-
|
|
4663
|
+
fs20.writeFileSync(filePath, template);
|
|
4655
4664
|
setMessages((prev) => {
|
|
4656
4665
|
setCompletedIndex(prev.length + 1);
|
|
4657
4666
|
return [...prev, { id: "init-ok-" + Date.now(), role: "system", text: "\u2705 [SUCCESS] FluxFlow.md has been initialized. You can now customize it for this project.", isMeta: true }];
|
|
@@ -5502,7 +5511,7 @@ Selection: ${val}`,
|
|
|
5502
5511
|
newline: (key) => key.return && key.shift || key.return && key.ctrl || key.return && key.leftAlt || key.return && key.rightAlt
|
|
5503
5512
|
}
|
|
5504
5513
|
}
|
|
5505
|
-
)))) : /* @__PURE__ */ React10.createElement(Box10, { flexDirection: "row", width: "100%", paddingY: 0 }, /* @__PURE__ */ React10.createElement(Box10, { flexShrink: 0, width: 4 }, /* @__PURE__ */ React10.createElement(Text10, { color: isProcessing ? "magenta" : "cyan", bold: true }, isProcessing ? "\
|
|
5514
|
+
)))) : /* @__PURE__ */ React10.createElement(Box10, { flexDirection: "row", width: "100%", paddingY: 0 }, /* @__PURE__ */ React10.createElement(Box10, { flexShrink: 0, width: 4 }, /* @__PURE__ */ React10.createElement(Text10, { color: isProcessing ? "magenta" : "cyan", bold: true }, isProcessing ? "\u2726 " : "\u{1F4A0} ")), /* @__PURE__ */ React10.createElement(Box10, { flexGrow: 1 }, /* @__PURE__ */ React10.createElement(Box10, { flexGrow: 1, position: "relative" }, input === "" && /* @__PURE__ */ React10.createElement(Box10, { position: "absolute", paddingLeft: 0 }, activeCommand && !isTerminalFocused ? /* @__PURE__ */ React10.createElement(Text10, { color: "yellow" }, " Press TAB to interact with terminal...") : activeCommand && isTerminalFocused ? /* @__PURE__ */ React10.createElement(Text10, { color: "yellow", bold: true }, " [ TERMINAL FOCUSED ] Type to interact, press TAB to exit...") : /* @__PURE__ */ React10.createElement(Text10, { 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__ */ React10.createElement(
|
|
5506
5515
|
MultilineInput,
|
|
5507
5516
|
{
|
|
5508
5517
|
focus: !isTerminalFocused,
|
|
@@ -5625,8 +5634,8 @@ var init_app = __esm({
|
|
|
5625
5634
|
init_text();
|
|
5626
5635
|
SESSION_START_TIME = Date.now();
|
|
5627
5636
|
CHANGELOG_URL = "https://fluxflow-cli.onrender.com/changelog.html";
|
|
5628
|
-
versionFluxflow = "1.9.
|
|
5629
|
-
updatedOn = "2026-05-
|
|
5637
|
+
versionFluxflow = "1.9.12";
|
|
5638
|
+
updatedOn = "2026-05-15";
|
|
5630
5639
|
ResolutionModal = ({ data, onResolve, onEdit }) => /* @__PURE__ */ React10.createElement(Box10, { flexDirection: "column", borderStyle: "round", borderColor: "gray", padding: 0, width: "100%" }, /* @__PURE__ */ React10.createElement(Box10, { paddingX: 1 }, /* @__PURE__ */ React10.createElement(Text10, { color: "magenta", bold: true, underline: true }, "\u{1F7E3} STEERING HINT RESOLUTION")), /* @__PURE__ */ React10.createElement(Box10, { paddingX: 1, marginTop: 1 }, /* @__PURE__ */ React10.createElement(Text10, null, "The agent already finished the task before your hint was consumed.")), /* @__PURE__ */ React10.createElement(Box10, { marginTop: 1, backgroundColor: "#222", paddingX: 2, width: "100%" }, /* @__PURE__ */ React10.createElement(Text10, { italic: true, color: "gray" }, '"', data, '"')), /* @__PURE__ */ React10.createElement(Box10, { paddingX: 1, marginTop: 1 }, /* @__PURE__ */ React10.createElement(Text10, { color: "cyan" }, "How would you like to proceed?")), /* @__PURE__ */ React10.createElement(Box10, { marginTop: 0 }, /* @__PURE__ */ React10.createElement(
|
|
5631
5640
|
CommandMenu,
|
|
5632
5641
|
{
|