fluxflow-cli 1.12.6 → 1.12.8
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 +149 -20
- package/package.json +2 -2
package/dist/fluxflow.js
CHANGED
|
@@ -464,6 +464,7 @@ var init_ChatLayout = __esm({
|
|
|
464
464
|
{ cmd: "/clear", desc: "Clear terminal screen" },
|
|
465
465
|
{ cmd: "/resume", desc: "Load previous session" },
|
|
466
466
|
{ cmd: "/save", desc: "Force save current chat" },
|
|
467
|
+
{ cmd: "/export", desc: "Export current chat in a .txt file" },
|
|
467
468
|
{ cmd: "/chats", desc: "List all chat sessions" },
|
|
468
469
|
{ cmd: "/image", desc: "Generate images" },
|
|
469
470
|
{ cmd: "/mode", desc: "Toggle Flux/Flow modes" },
|
|
@@ -975,7 +976,7 @@ ${mode === "Flux" ? `- FILE TOOLS (path = relative to CWD) -
|
|
|
975
976
|
- File structure: Real newlines for code formatting`.trim() : `
|
|
976
977
|
- DEV TOOLS ARE NOT AVAILABLE IN FLOW MODE`.trim()}
|
|
977
978
|
|
|
978
|
-
- Results: Passed as [TOOL RESULT]
|
|
979
|
+
- Results: Passed as [TOOL RESULT] (system)
|
|
979
980
|
- Tool calls: End with [turn: continue]. Only use [turn: finish] after verifying goals
|
|
980
981
|
- Multi-call: Stack upto 5`.trim();
|
|
981
982
|
}
|
|
@@ -992,7 +993,7 @@ Your tool syntax is: '[tool:functions.ToolName(args...)]'
|
|
|
992
993
|
[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.
|
|
993
994
|
[tool:functions.Memory(action="temp", content="<summary of the user prompt & model responses ONLY FROM LATEST PROMPT UNDER 40 WORDS>. [Talked on: <date> <hour>]")]
|
|
994
995
|
|
|
995
|
-
${isMemoryEnabled ? `-- User-specific long-term/permanent memory (USE BASED ON CONVERSATION CONTEXT,
|
|
996
|
+
${isMemoryEnabled ? `-- User-specific long-term/permanent memory (USE BASED ON CONVERSATION CONTEXT, DO NOT RE-SAVE MEMORY WHICH IS ALREADY SAVED) --
|
|
996
997
|
- Add: [tool:functions.Memory(action="user", method="add", content="<string to add>. [Saved on: <date ONLY>]")]
|
|
997
998
|
- Delete: [tool:functions.Memory(action="user", method="delete", id="<memory id>")]
|
|
998
999
|
- Update: [tool:functions.Memory(action="user", method="update", content-new="string to update", id="<memory id>")]
|
|
@@ -1060,12 +1061,13 @@ ${parts.join("\n\n")}
|
|
|
1060
1061
|
if (thinkingLevel === "xHigh" || thinkingLevel === "Max") levelKey = "xHigh";
|
|
1061
1062
|
const thinkingConfig = thinking_prompts_default[levelKey] || thinking_prompts_default["Medium"];
|
|
1062
1063
|
const osDetected = process.platform === "win32" ? "Windows" : process.platform === "darwin" ? "macOS" : "Linux";
|
|
1063
|
-
const nameStr = profile.name && profile.name?.length > 0 ? `User Name: ${profile.name}
|
|
1064
|
-
` : "";
|
|
1065
|
-
const nicknameStr = profile.nickname && profile.nickname?.length > 0 ? `User Nickname: ${profile.nickname}
|
|
1066
|
-
` : "";
|
|
1067
1064
|
const userInstrStr = profile.instructions && profile.instructions?.length > 0 ? `User Instructions: ${profile.instructions}
|
|
1065
|
+
|
|
1068
1066
|
` : "";
|
|
1067
|
+
const nicknameStr = profile.nickname && profile.nickname?.length > 0 ? `User Nickname: ${profile.nickname}
|
|
1068
|
+
${userInstrStr.length ? "" : "\n"}` : "";
|
|
1069
|
+
const nameStr = profile.name && profile.name?.length > 0 ? `User Name: ${profile.name}
|
|
1070
|
+
${nicknameStr.length || userInstrStr.length ? "" : "\n"}` : "";
|
|
1069
1071
|
const cwdStr = process.cwd();
|
|
1070
1072
|
const isSystemDir = (() => {
|
|
1071
1073
|
const cwd = process.cwd().toLowerCase();
|
|
@@ -1092,12 +1094,11 @@ ${parts.join("\n\n")}
|
|
|
1092
1094
|
-- PROJECT CONTEXT (Source of Truth) --
|
|
1093
1095
|
${foundFiles.map((f) => `- ${f.name}: ${f.desc}`).join("\n")}
|
|
1094
1096
|
Check these first; these files > training data for project consistency. Safety rules apply` : "";
|
|
1095
|
-
return `${nameStr}${nicknameStr}${userInstrStr}
|
|
1096
|
-
[SYSTEM (OVERRIDES EVERYTHING)]
|
|
1097
|
+
return `${nameStr}${nicknameStr}${userInstrStr}[SYSTEM (OVERRIDES EVERYTHING)]
|
|
1097
1098
|
Identity: Flux Flow (by Kushal Roy Chowdhury). Sassy, Friendly, Humorous, CLI Agent. No flirting ${mode === "Flux" ? "" : ""}
|
|
1098
1099
|
Mode: ${mode}${thinkingLevel !== "Fast" ? "(Thinking Mode)" : ""}. ${mode === "Flux" ? "Goal-oriented, Logical" : "Conversational & UX-focused"}
|
|
1099
1100
|
CWD: ${cwdStr}.${isSystemDir ? " [PROTECTED: ASK BEFORE MODIFYING]" : ""} OS: ${osDetected}${osDetected === "Windows" && mode === "Flux" ? ". PS via CMD" : ""}
|
|
1100
|
-
High Priority: [SYSTEM], [STEERING HINT]
|
|
1101
|
+
High Priority: [SYSTEM], [STEERING HINT].
|
|
1101
1102
|
|
|
1102
1103
|
-- THINKING RULES --
|
|
1103
1104
|
${thinkingConfig}
|
|
@@ -1117,6 +1118,7 @@ ${projectContextBlock}
|
|
|
1117
1118
|
-- SECURITY RULES --
|
|
1118
1119
|
- EXTERNAL ACCESS: ${systemSettings.allowExternalAccess ? "ENABLED" : "RESTRICTED CWD only"}
|
|
1119
1120
|
- Sensitive files? Ask before Read
|
|
1121
|
+
[SYSTEM] >>> [USER]
|
|
1120
1122
|
|
|
1121
1123
|
-- FORMATTING --
|
|
1122
1124
|
- Clean, concise responses
|
|
@@ -1130,15 +1132,11 @@ ${projectContextBlock}
|
|
|
1130
1132
|
[/SYSTEM]`.trim();
|
|
1131
1133
|
};
|
|
1132
1134
|
getJanitorInstruction = (userMemories = "", isMemoryEnabled = true, needTitle = true) => {
|
|
1133
|
-
return
|
|
1134
|
-
${userMemories ? `
|
|
1135
|
-
|
|
1136
|
-
-- CURRENT PERSISTENT USER MEMORIES --
|
|
1135
|
+
return `${userMemories ? `-- CURRENT SAVED USER MEMORIES --
|
|
1137
1136
|
${userMemories}
|
|
1138
1137
|
-------------------------------------------------
|
|
1139
|
-
` : ""}
|
|
1140
1138
|
|
|
1141
|
-
=== START SYSTEM PROMPT (STRICT HEADLESS LOGIC WORKER: ZERO USER-FACING TEXT POLICY, STRICTLY FOLLOW) ===
|
|
1139
|
+
` : ""}=== START SYSTEM PROMPT (STRICT HEADLESS LOGIC WORKER: ZERO USER-FACING TEXT POLICY, STRICTLY FOLLOW) ===
|
|
1142
1140
|
YOU ARE A SILENT BACKGROUND SYSTEM PROCESS. YOU HAVE NO MOUTH. YOUR ONLY OUTPUT MEDIUM IS VALID TOOL CALLS.
|
|
1143
1141
|
[CRITICAL RULES]
|
|
1144
1142
|
1. OUTPUT ONLY '[tool:functions.xxx(args)]' CALLS (BRACKET WRAP IS MANDATORY).
|
|
@@ -3531,7 +3529,7 @@ var init_ai = __esm({
|
|
|
3531
3529
|
const isMemoryEnabled = systemSettings?.memory !== false;
|
|
3532
3530
|
const persistentStorage = readEncryptedJson(MEMORIES_FILE, []);
|
|
3533
3531
|
const janitorUserMemories = persistentStorage.map((m) => `- [${m.id}]: ${m.memory}`).join("\n");
|
|
3534
|
-
const janitorContents = history.slice(0, -1).filter((msg) => msg.text && !msg.text.includes("[TOOL RESULT]") && !msg.text.includes("OBSERVATION:") && !msg.isMeta && !msg.isLogo && !String(msg.id).startsWith("welcome") && !String(msg.id).startsWith("logo")).slice(-
|
|
3532
|
+
const janitorContents = history.slice(0, -1).filter((msg) => msg.text && !msg.text.includes("[TOOL RESULT]") && !msg.text.includes("OBSERVATION:") && !msg.isMeta && !msg.isLogo && !String(msg.id).startsWith("welcome") && !String(msg.id).startsWith("logo")).slice(-14).map((msg) => {
|
|
3535
3533
|
let processedText = msg.text.replace(/\[tool:functions\..*?\]/g, "").replace(/<think>[\s\S]*?<\/think>/g, "").replace(/\[Prompted on:.*?\]/g, "").replace(/\[METADATA \(PRIORITY: DYNAMIC\)\] Time: ([^|\n]+)/g, (match, p1) => {
|
|
3536
3534
|
return `[METADATA (PRIORITY: DYNAMIC)] Time: ${p1.replace(/:\d{2}/g, "")}`;
|
|
3537
3535
|
}).replace(/\[turn: continue\]/g, "").replace(/\[turn: finish\]/g, "").replace(/\[TOOL RESULTS\]/g, "").replace(/\[tool results\]/g, "").replace(/\r?\n\r?\n/g, "\n").replace(/\n\n/g, "\n").replace(/\\n\\n/g, "").trim();
|
|
@@ -3571,7 +3569,7 @@ ${originalTextProcessed.length > USER_CONTEXT_LENGTH ? "... (truncated) ...\n\n"
|
|
|
3571
3569
|
const MAX_JANITOR_RETRIES = 12;
|
|
3572
3570
|
while (attempts <= MAX_JANITOR_RETRIES) {
|
|
3573
3571
|
if (process.stdout.isTTY) {
|
|
3574
|
-
process.stdout.write(`\x1B]0;Retrying
|
|
3572
|
+
process.stdout.write(`\x1B]0;Retrying Finalizing... (${attempts + 1})...\x07`);
|
|
3575
3573
|
}
|
|
3576
3574
|
try {
|
|
3577
3575
|
if (!await checkQuota("background", settings)) {
|
|
@@ -3654,7 +3652,7 @@ ${originalTextProcessed.length > USER_CONTEXT_LENGTH ? "... (truncated) ...\n\n"
|
|
|
3654
3652
|
attempts++;
|
|
3655
3653
|
const date = (/* @__PURE__ */ new Date()).toLocaleString();
|
|
3656
3654
|
if (process.stdout.isTTY) {
|
|
3657
|
-
process.stdout.write(`\x1B]0;
|
|
3655
|
+
process.stdout.write(`\x1B]0;Finalizing Error\x07`);
|
|
3658
3656
|
}
|
|
3659
3657
|
await new Promise((resolve) => setTimeout(resolve, 1e3));
|
|
3660
3658
|
const janitorErrDir = path14.join(LOGS_DIR, "janitor");
|
|
@@ -3675,7 +3673,7 @@ ${originalTextProcessed.length > USER_CONTEXT_LENGTH ? "... (truncated) ...\n\n"
|
|
|
3675
3673
|
`);
|
|
3676
3674
|
if (attempts >= MAX_JANITOR_RETRIES) {
|
|
3677
3675
|
if (process.stdout.isTTY) {
|
|
3678
|
-
process.stdout.write(`\x1B]0;
|
|
3676
|
+
process.stdout.write(`\x1B]0;Finalizing Error\x07`);
|
|
3679
3677
|
}
|
|
3680
3678
|
await new Promise((resolve) => setTimeout(resolve, 3e3));
|
|
3681
3679
|
}
|
|
@@ -5458,6 +5456,7 @@ function App({ args = [] }) {
|
|
|
5458
5456
|
{ cmd: "/clear", desc: "Clear terminal screen" },
|
|
5459
5457
|
{ cmd: "/resume", desc: "Load previous session" },
|
|
5460
5458
|
{ cmd: "/save", desc: "Force save current chat" },
|
|
5459
|
+
{ cmd: "/export", desc: "Export current chat in a .txt file" },
|
|
5461
5460
|
{ cmd: "/chats", desc: "List all chat sessions" },
|
|
5462
5461
|
{
|
|
5463
5462
|
cmd: "/image",
|
|
@@ -5872,6 +5871,71 @@ ${hintText}`, color: "magenta" }];
|
|
|
5872
5871
|
});
|
|
5873
5872
|
break;
|
|
5874
5873
|
}
|
|
5874
|
+
case "/export": {
|
|
5875
|
+
const exportFile = `export-fluxflow-${chatId}.txt`;
|
|
5876
|
+
const exportPath = path15.join(process.cwd(), exportFile);
|
|
5877
|
+
const exportLines = [];
|
|
5878
|
+
let insideAgentBlock = false;
|
|
5879
|
+
for (let i = 0; i < messages.length; i++) {
|
|
5880
|
+
const msg = messages[i];
|
|
5881
|
+
if (!msg) continue;
|
|
5882
|
+
if (msg.role === "system" || msg.isMeta || msg.isLogo || String(msg.id).startsWith("welcome")) {
|
|
5883
|
+
continue;
|
|
5884
|
+
}
|
|
5885
|
+
if (msg.role === "user") {
|
|
5886
|
+
let cleanUserText = msg.text || "";
|
|
5887
|
+
cleanUserText = cleanUserText.replace(/\s*\[Prompted on:.*?\]/g, "").trim();
|
|
5888
|
+
if (exportLines.length > 0) {
|
|
5889
|
+
exportLines.push("");
|
|
5890
|
+
}
|
|
5891
|
+
exportLines.push("[USER]");
|
|
5892
|
+
exportLines.push(cleanUserText);
|
|
5893
|
+
insideAgentBlock = false;
|
|
5894
|
+
} else if (msg.role === "think") {
|
|
5895
|
+
if (!insideAgentBlock) {
|
|
5896
|
+
exportLines.push("");
|
|
5897
|
+
exportLines.push("[AGENT]");
|
|
5898
|
+
insideAgentBlock = true;
|
|
5899
|
+
}
|
|
5900
|
+
const cleanThinkText = (msg.text || "").replace(/\[turn:\s*continue\]/gi, "").replace(/\[turn:\s*finish\]/gi, "").replace(/\[TOOL RESULTS\]/gi, "").trim();
|
|
5901
|
+
if (cleanThinkText) {
|
|
5902
|
+
exportLines.push("[thoughts]");
|
|
5903
|
+
exportLines.push(cleanThinkText);
|
|
5904
|
+
}
|
|
5905
|
+
} else if (msg.role === "agent") {
|
|
5906
|
+
if (!insideAgentBlock) {
|
|
5907
|
+
exportLines.push("");
|
|
5908
|
+
exportLines.push("[AGENT]");
|
|
5909
|
+
insideAgentBlock = true;
|
|
5910
|
+
}
|
|
5911
|
+
const blocks = parseAgentText(msg.text || "");
|
|
5912
|
+
for (const block of blocks) {
|
|
5913
|
+
if (block.type === "output") {
|
|
5914
|
+
const cleanContent = block.content.replace(/\[turn:\s*continue\]/gi, "").replace(/\[turn:\s*finish\]/gi, "").replace(/\[TOOL RESULTS\]/gi, "").trim();
|
|
5915
|
+
if (cleanContent) {
|
|
5916
|
+
exportLines.push("[output]");
|
|
5917
|
+
exportLines.push(cleanContent);
|
|
5918
|
+
}
|
|
5919
|
+
} else if (block.type === "tool") {
|
|
5920
|
+
exportLines.push("[tool]");
|
|
5921
|
+
exportLines.push(`${block.toolName} ${block.args}`);
|
|
5922
|
+
}
|
|
5923
|
+
}
|
|
5924
|
+
}
|
|
5925
|
+
}
|
|
5926
|
+
const fileContent = exportLines.join("\n");
|
|
5927
|
+
fs17.writeFileSync(exportPath, fileContent, "utf8");
|
|
5928
|
+
setMessages((prev) => {
|
|
5929
|
+
setCompletedIndex(prev.length + 1);
|
|
5930
|
+
return [...prev, {
|
|
5931
|
+
id: Date.now(),
|
|
5932
|
+
role: "system",
|
|
5933
|
+
text: `\u{1F4E4} [EXPORT] Chat exported successfully to "${exportFile}"`,
|
|
5934
|
+
isMeta: true
|
|
5935
|
+
}];
|
|
5936
|
+
});
|
|
5937
|
+
break;
|
|
5938
|
+
}
|
|
5875
5939
|
case "/chats": {
|
|
5876
5940
|
const run = async () => {
|
|
5877
5941
|
const history = await loadHistory();
|
|
@@ -6963,7 +7027,7 @@ Selection: ${val}`,
|
|
|
6963
7027
|
);
|
|
6964
7028
|
})()));
|
|
6965
7029
|
}
|
|
6966
|
-
var SESSION_START_TIME, CHANGELOG_URL, packageJsonPath, packageJson, versionFluxflow, updatedOn, ResolutionModal, FLUX_LOGO;
|
|
7030
|
+
var SESSION_START_TIME, CHANGELOG_URL, packageJsonPath, packageJson, versionFluxflow, updatedOn, ResolutionModal, FLUX_LOGO, parseAgentText;
|
|
6967
7031
|
var init_app = __esm({
|
|
6968
7032
|
"src/app.jsx"() {
|
|
6969
7033
|
init_ChatLayout();
|
|
@@ -7014,6 +7078,71 @@ var init_app = __esm({
|
|
|
7014
7078
|
\u2588\u2588\u2551 \u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2557\u255A\u2588\u2588\u2588\u2588\u2588\u2588\u2554\u255D\u2588\u2588\u2554\u255D \u2588\u2588\u2557 \u2588\u2588\u2551 \u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2557\u255A\u2588\u2588\u2588\u2588\u2588\u2588\u2554\u255D\u255A\u2588\u2588\u2588\u2554\u2588\u2588\u2588\u2554\u255D
|
|
7015
7079
|
\u255A\u2550\u255D \u255A\u2550\u2550\u2550\u2550\u2550\u2550\u255D \u255A\u2550\u2550\u2550\u2550\u2550\u255D \u255A\u2550\u255D \u255A\u2550\u255D \u255A\u2550\u255D \u255A\u2550\u2550\u2550\u2550\u2550\u2550\u255D \u255A\u2550\u2550\u2550\u2550\u2550\u255D \u255A\u2550\u2550\u255D\u255A\u2550\u2550\u255D`
|
|
7016
7080
|
);
|
|
7081
|
+
parseAgentText = (text) => {
|
|
7082
|
+
const blocks = [];
|
|
7083
|
+
const toolRegex = /\[\s*tool:functions\.([a-z0-9_]+)\s*\(/gi;
|
|
7084
|
+
let lastIdx = 0;
|
|
7085
|
+
let match;
|
|
7086
|
+
while ((match = toolRegex.exec(text)) !== null) {
|
|
7087
|
+
const toolName = match[1];
|
|
7088
|
+
const startIdx = match.index + match[0].length - 1;
|
|
7089
|
+
let balance = 0;
|
|
7090
|
+
let inString = null;
|
|
7091
|
+
let isEscaped = false;
|
|
7092
|
+
let endIdx = -1;
|
|
7093
|
+
let closingParenIdx = -1;
|
|
7094
|
+
for (let i = startIdx; i < text.length; i++) {
|
|
7095
|
+
const char = text[i];
|
|
7096
|
+
if (!inString && (char === '"' || char === "'" || char === "`")) {
|
|
7097
|
+
inString = char;
|
|
7098
|
+
isEscaped = false;
|
|
7099
|
+
} else if (inString && char === inString && !isEscaped) {
|
|
7100
|
+
inString = null;
|
|
7101
|
+
}
|
|
7102
|
+
if (!inString) {
|
|
7103
|
+
if (char === "(") balance++;
|
|
7104
|
+
else if (char === ")") balance--;
|
|
7105
|
+
if (balance === 0) {
|
|
7106
|
+
closingParenIdx = i;
|
|
7107
|
+
let j = i + 1;
|
|
7108
|
+
while (j < text.length && /\s/.test(text[j])) j++;
|
|
7109
|
+
if (j < text.length && text[j] === "]") {
|
|
7110
|
+
endIdx = j;
|
|
7111
|
+
break;
|
|
7112
|
+
}
|
|
7113
|
+
}
|
|
7114
|
+
}
|
|
7115
|
+
if (char === "\\") {
|
|
7116
|
+
isEscaped = !isEscaped;
|
|
7117
|
+
} else {
|
|
7118
|
+
isEscaped = false;
|
|
7119
|
+
}
|
|
7120
|
+
}
|
|
7121
|
+
if (endIdx !== -1) {
|
|
7122
|
+
const beforeText = text.substring(lastIdx, match.index);
|
|
7123
|
+
if (beforeText.trim()) {
|
|
7124
|
+
blocks.push({ type: "output", content: beforeText });
|
|
7125
|
+
}
|
|
7126
|
+
const finalArgsText = text.substring(startIdx + 1, closingParenIdx);
|
|
7127
|
+
blocks.push({
|
|
7128
|
+
type: "tool",
|
|
7129
|
+
toolName: toolName.trim(),
|
|
7130
|
+
args: finalArgsText.trim()
|
|
7131
|
+
});
|
|
7132
|
+
lastIdx = endIdx + 1;
|
|
7133
|
+
toolRegex.lastIndex = lastIdx;
|
|
7134
|
+
} else {
|
|
7135
|
+
break;
|
|
7136
|
+
}
|
|
7137
|
+
}
|
|
7138
|
+
if (lastIdx < text.length) {
|
|
7139
|
+
const remainingText = text.substring(lastIdx);
|
|
7140
|
+
if (remainingText.trim()) {
|
|
7141
|
+
blocks.push({ type: "output", content: remainingText });
|
|
7142
|
+
}
|
|
7143
|
+
}
|
|
7144
|
+
return blocks;
|
|
7145
|
+
};
|
|
7017
7146
|
}
|
|
7018
7147
|
});
|
|
7019
7148
|
|