fluxflow-cli 1.1.0 โ 1.1.2
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 +71 -80
- package/dist/fluxflow.js +68 -47
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,80 +1,71 @@
|
|
|
1
|
-
#
|
|
2
|
-
 & [Ink](https://github.com/vadimdemedes/ink)**: For the interactive CLI rendering.
|
|
75
|
-
- **[@google/genai](https://www.npmjs.com/package/@google/genai)**: The core AI SDK powering the agent's intelligence.
|
|
76
|
-
- **[chalk](https://www.npmjs.com/package/chalk) & [gradient-string](https://www.npmjs.com/package/gradient-string)**: For terminal styling and aesthetics.
|
|
77
|
-
- **[fs-extra](https://www.npmjs.com/package/fs-extra)**: For robust file system operations.
|
|
78
|
-
|
|
79
|
-
---
|
|
80
|
-
*Created as a demonstration of highly capable AI tooling.*
|
|
1
|
+
# ๐ Flux Flow (`fluxflow-cli`)
|
|
2
|
+

|
|
3
|
+
|
|
4
|
+
### *The High-Fidelity Agentic Terminal for the Flux Era.*
|
|
5
|
+
|
|
6
|
+
**Flux Flow** is not just another CLIโit's a high-speed, sassy, and goal-oriented CLI AI Agent powered by the latest Gemini/Gemma frontier models. Designed for developers who demand a premium UI/UX while managing complex file-system tasks, web research, and autonomous workflows.
|
|
7
|
+
|
|
8
|
+
---
|
|
9
|
+
|
|
10
|
+
## ๐ Instant Ignition (No Setup Required)
|
|
11
|
+
You don't even need to install it. Just fire up your terminal and run:
|
|
12
|
+
|
|
13
|
+
```bash
|
|
14
|
+
# Run instantly (Zero Setup)
|
|
15
|
+
npx fluxflow-cli
|
|
16
|
+
|
|
17
|
+
# OR Install Globally
|
|
18
|
+
npm install -g fluxflow-cli
|
|
19
|
+
fluxflow-cli
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
*The agent will prompt you for your Gemini API Key on the first run and store it securely in an XOR-encrypted vault.*
|
|
23
|
+
|
|
24
|
+
---
|
|
25
|
+
|
|
26
|
+
## โจ Why Flux Flow?
|
|
27
|
+
|
|
28
|
+
### ๐จ **Premium Visual Sovereignty**
|
|
29
|
+
Experience a terminal UI that feels alive. Built with **Ink** and **React**, Flux Flow features:
|
|
30
|
+
- **Dynamic Status Bar**: Real-time telemetry showing your "Neural Headroom" (token usage), Thinking Level, and Session ID.
|
|
31
|
+
- **Archived Terminal Flow**: See execution outputs transform from live elements into permanent conversation records.
|
|
32
|
+
- **Rich Aesthetics**: High-contrast, sleek design with smooth transitions and micro-animations.
|
|
33
|
+
|
|
34
|
+
### ๐ง **The Dual-Intelligence System**
|
|
35
|
+
- **Flux Mode (Dev)**: High-speed, agentic problem solving with a 50-turn persistent loop for massive coding tasks.
|
|
36
|
+
- **Flow Mode (Chat)**: Optimized for deep research, high-quality conversation, and web-assisted reasoning.
|
|
37
|
+
|
|
38
|
+
### ๐ก๏ธ **Digital Fortress Governance**
|
|
39
|
+
Security isn't an afterthought; it's a boundary.
|
|
40
|
+
- **External Path Hardlock**: Restricts the agent to your Current Working Directory (CWD) unless you explicitly unlock it.
|
|
41
|
+
- **Human-in-the-Loop (HITL)**: Every file write and terminal command requires your high-fidelity approval.
|
|
42
|
+
- **XOR Vaulting**: All local session histories, memories, and API keys are obfuscated and encrypted at rest.
|
|
43
|
+
- **Adaptive Failover**: Automatic multi-stage retry logic with high-concurrency fallback model switching (Gemini 3.1 Flash Lite) during peak API congestion.
|
|
44
|
+
|
|
45
|
+
### ๐งน **The Background Janitor**
|
|
46
|
+
While you move at high speed, the Janitor follows behindโrefining session titles, compressing data, and ensuring your context window remains at absolute peak performance.
|
|
47
|
+
|
|
48
|
+
---
|
|
49
|
+
|
|
50
|
+
## ๐ ๏ธ Key Capabilities
|
|
51
|
+
- **Deep File-System Interaction**: Edit, move, and refactor code across multiple files with atomic precision.
|
|
52
|
+
- **Real-Time Web Intelligence**: Autonomous web-searching via DuckDuckGo for live news and technical research.
|
|
53
|
+
- **Autonomous Project Alignment**: Automatically detects and adheres to project-specific instructions in `Agent.md`, `Skills.md`, and `Fluxflow.md` for high-fidelity alignment with your coding standards and custom workflows.
|
|
54
|
+
- **High-Reliability Fallback**: Automatic failover to a lighter, high-concurrency model during peak traffic to ensure zero session loss.
|
|
55
|
+
- **Persistent Memory**: The agent learns from your preferences and project requirements across sessions.
|
|
56
|
+
|
|
57
|
+
---
|
|
58
|
+
|
|
59
|
+
## โ๏ธ Configuration
|
|
60
|
+
Type `/settings` in-app to live-configure:
|
|
61
|
+
- **Thinking Level**: Low, Medium, or High (Deep-Reasoning).
|
|
62
|
+
- **Auto-Execution**: For ultimate high-speed flow (Advanced users only).
|
|
63
|
+
- **Security Perimeter**: Toggle External Workspace access.
|
|
64
|
+
|
|
65
|
+
---
|
|
66
|
+
|
|
67
|
+
## ๐ License
|
|
68
|
+
MIT ยฉ 2026 Flux Flow Team.
|
|
69
|
+
|
|
70
|
+
---
|
|
71
|
+
*Forged with โก and ๐งฌ. Welcome to the FluxFlow.*
|
package/dist/fluxflow.js
CHANGED
|
@@ -410,7 +410,7 @@ tool:functions.tool_name(arguments)
|
|
|
410
410
|
- WEB TOOLS (Available in Flux & Flow) -
|
|
411
411
|
1. Web Search: tool:functions.web_search(query="<query>", limit=number). Find info. limit is optional (3-10, default 10). If user asks about something that is not in your training data, proactively use this tool to find the information.Winder search recomemded (limit = 10) when exploring a topic.
|
|
412
412
|
2. Web Scrape: tool:functions.web_scrape(url="<url>"). provides detail from a URL.
|
|
413
|
-
3. Ask User: tool:functions.ask(question="...", optionA="Option::Desc", optionB="Option::Desc").
|
|
413
|
+
3. Ask User: tool:functions.ask(question="...", optionA="Option::Desc", optionB="Option::Desc"). You can use this tool if you hit a roadblock and need user direction on which path to continue. This allows you to pause for guidance without ending your task loop. Format options as 'Short Label::Detailed Description'. You can provide 2 - 4 options (optionA, optionB, optionC, optionD). Tool can also return result as none of the 4 if user write custom one. Example cases to use this tool: ask or user permission (Yes/No). Ask user to choose between two or more options. Ask user for any clarification needed to proceed with the task.
|
|
414
414
|
${mode === "Flux" ? `
|
|
415
415
|
- DEV & FILE TOOLS (Available in FLUX MODE ONLY) -
|
|
416
416
|
1. View File: tool:functions.view_file(path="relative/path", start_line=number, end_line=number). Reads file content. Auto-truncates at 500 lines unless start_line and end_line are provided.
|
|
@@ -524,6 +524,7 @@ Every ${isMemoryEnabled ? "Prompt, Responses & Memories" : "Prompt & Responses"}
|
|
|
524
524
|
|
|
525
525
|
-- START REPONSE FINISH PROTOCOL --
|
|
526
526
|
WHEN YOU ARE DONE AND NEED NO LONGER AGENT LOOP FOR THE TASK, WRITE [turn: finish] AT VERY END OF YOUR RESPONSE TO AVOID AGENT LOOPS. IF YOU ARE NOT COMPLETED YET AND WANT NEXT LOOP WRITE [turn: continue] AT VERY END OF YOUR RESPONSE TO CONTINUE AGENT LOOPS. YOU CAN STACK MULTIPLE TOOLS AT ONCE BUT **HAVE TO** WRITE [turn: continue] AFTER WRITING ALL TOOL CALLS.
|
|
527
|
+
When you 'finish' an agentic loop, you will lose your previous turn 'thinking' data. So only write [turn: finish] when you are absolutely sure that you are done with the task. Or user has to prompt again and re-thinking again from scratch will use tokens that were already planned.
|
|
527
528
|
-- END REPONSE FINISH PROTOCOL --
|
|
528
529
|
Current date and Time is: ${dateTimeStr}
|
|
529
530
|
--- END SYSTEM INSTRUCTION ---`.trim();
|
|
@@ -1229,7 +1230,7 @@ ${formatted}${footer}`;
|
|
|
1229
1230
|
var ask_user = async (args, context) => {
|
|
1230
1231
|
const parsed = parseArgs(args);
|
|
1231
1232
|
const { question } = parsed;
|
|
1232
|
-
if (!question) return 'ERROR: Missing "question" argument for
|
|
1233
|
+
if (!question) return 'ERROR: Missing "question" argument for ask.';
|
|
1233
1234
|
if (!context.onAskUser) return "ERROR: onAskUser callback not provided in tool context.";
|
|
1234
1235
|
const options = [];
|
|
1235
1236
|
Object.keys(parsed).forEach((key) => {
|
|
@@ -1295,35 +1296,39 @@ var signalTermination = () => {
|
|
|
1295
1296
|
};
|
|
1296
1297
|
var detectToolCalls = (text) => {
|
|
1297
1298
|
const results = [];
|
|
1298
|
-
const
|
|
1299
|
-
let
|
|
1300
|
-
while (
|
|
1301
|
-
const
|
|
1302
|
-
|
|
1303
|
-
const
|
|
1304
|
-
|
|
1305
|
-
|
|
1306
|
-
|
|
1307
|
-
|
|
1308
|
-
|
|
1309
|
-
|
|
1310
|
-
|
|
1311
|
-
|
|
1312
|
-
|
|
1313
|
-
|
|
1314
|
-
|
|
1315
|
-
|
|
1316
|
-
|
|
1299
|
+
const toolRegex = /(?:\[?\s*tool:functions\.)([a-z0-9_]+)\s*\(([\s\S]*?)\)(?:\s*\]?)/gi;
|
|
1300
|
+
let match;
|
|
1301
|
+
while ((match = toolRegex.exec(text)) !== null) {
|
|
1302
|
+
const fullMatch = match[0];
|
|
1303
|
+
const toolName = match[1];
|
|
1304
|
+
const args = match[2];
|
|
1305
|
+
let openCount = (args.match(/\(/g) || []).length;
|
|
1306
|
+
let closeCount = (args.match(/\)/g) || []).length;
|
|
1307
|
+
let finalArgs = args;
|
|
1308
|
+
let finalFullMatch = fullMatch;
|
|
1309
|
+
if (openCount > closeCount) {
|
|
1310
|
+
const startIdx = match.index + fullMatch.indexOf("(");
|
|
1311
|
+
let balance = 0;
|
|
1312
|
+
let endIdx = -1;
|
|
1313
|
+
for (let i = startIdx; i < text.length; i++) {
|
|
1314
|
+
if (text[i] === "(") balance++;
|
|
1315
|
+
if (text[i] === ")") balance--;
|
|
1316
|
+
if (balance === 0) {
|
|
1317
|
+
endIdx = i;
|
|
1318
|
+
break;
|
|
1319
|
+
}
|
|
1320
|
+
}
|
|
1321
|
+
if (endIdx !== -1) {
|
|
1322
|
+
finalArgs = text.substring(startIdx + 1, endIdx);
|
|
1323
|
+
finalFullMatch = text.substring(match.index, endIdx + 1);
|
|
1324
|
+
toolRegex.lastIndex = endIdx + 1;
|
|
1317
1325
|
}
|
|
1318
1326
|
}
|
|
1319
|
-
|
|
1320
|
-
|
|
1321
|
-
|
|
1322
|
-
|
|
1323
|
-
|
|
1324
|
-
const args = text.substring(openParenIdx + 1, endIdx);
|
|
1325
|
-
results.push({ fullMatch, toolName, args });
|
|
1326
|
-
searchIdx = endIdx + 1;
|
|
1327
|
+
results.push({
|
|
1328
|
+
fullMatch: finalFullMatch,
|
|
1329
|
+
toolName: toolName.trim(),
|
|
1330
|
+
args: finalArgs.trim()
|
|
1331
|
+
});
|
|
1327
1332
|
}
|
|
1328
1333
|
return results;
|
|
1329
1334
|
};
|
|
@@ -1375,7 +1380,7 @@ USER_PROMPT: ${agentText}`.trim();
|
|
|
1375
1380
|
}
|
|
1376
1381
|
}
|
|
1377
1382
|
yield { type: "turn_reset", content: true };
|
|
1378
|
-
const contents = modifiedHistory.filter((msg) => (msg.role === "user" || msg.role === "agent" || msg.role === "system") && !String(msg.id).startsWith("welcome")).map((msg) => ({
|
|
1383
|
+
const contents = modifiedHistory.filter((msg) => (msg.role === "user" || msg.role === "agent" || msg.role === "system") && !String(msg.id).startsWith("welcome") && !msg.isMeta).map((msg) => ({
|
|
1379
1384
|
role: msg.role === "user" || msg.role === "system" ? "user" : "model",
|
|
1380
1385
|
parts: [{ text: msg.text }]
|
|
1381
1386
|
}));
|
|
@@ -1609,7 +1614,8 @@ ${boxBottom}
|
|
|
1609
1614
|
yield { type: "status", content: "Working..." };
|
|
1610
1615
|
}
|
|
1611
1616
|
const cleanedTurnText = turnText.replace(/<think>[\s\S]*?<\/think>/g, "").replace(/\[?\s*(turn\s*:)?\s*(continue|finish)\s*\]?/gi, "").trim();
|
|
1612
|
-
|
|
1617
|
+
const isActuallyFinished = hasFinish || !shouldContinue && toolResults.length === 0 && turnText.length < 5;
|
|
1618
|
+
if (isActuallyFinished) {
|
|
1613
1619
|
const lateHint = await steeringCallback();
|
|
1614
1620
|
if (lateHint) {
|
|
1615
1621
|
toolResults.push(`[USER STEERING HINT]: ${lateHint}`);
|
|
@@ -1694,7 +1700,7 @@ ${timestamp}`;
|
|
|
1694
1700
|
}
|
|
1695
1701
|
break;
|
|
1696
1702
|
}
|
|
1697
|
-
if (
|
|
1703
|
+
if (isActuallyFinished) break;
|
|
1698
1704
|
const nextAgentMsg = cleanedTurnText.trim() || "*Working...*";
|
|
1699
1705
|
modifiedHistory.push({ role: "agent", text: nextAgentMsg });
|
|
1700
1706
|
const nextUserMsg = toolResults.length > 0 ? `${toolResults.join("\n")}` : "";
|
|
@@ -1838,7 +1844,8 @@ function MemoryModal({ onClose }) {
|
|
|
1838
1844
|
// src/app.jsx
|
|
1839
1845
|
var SESSION_START_TIME = Date.now();
|
|
1840
1846
|
var CHANGELOG_URL = "https://fluxflow-cli.onrender.com/changelog.html";
|
|
1841
|
-
var versionFluxflow = "1.1.
|
|
1847
|
+
var versionFluxflow = "1.1.2";
|
|
1848
|
+
var updatedOn = "2026-04-26";
|
|
1842
1849
|
var ResolutionModal = ({ data, onResolve, onEdit }) => /* @__PURE__ */ React9.createElement(Box9, { flexDirection: "column", borderStyle: "round", borderColor: "magenta", paddingX: 2, paddingY: 1, width: "100%" }, /* @__PURE__ */ React9.createElement(Text9, { color: "magenta", bold: true, underline: true }, "\u{1F7E3} STEERING HINT RESOLUTION"), /* @__PURE__ */ React9.createElement(Text9, { marginTop: 1 }, "The agent already finished the task (turn: finish) before your hint was consumed."), /* @__PURE__ */ React9.createElement(Box9, { marginTop: 1, backgroundColor: "#222", paddingX: 1, width: "100%" }, /* @__PURE__ */ React9.createElement(Text9, { italic: true, color: "gray" }, '"', data, '"')), /* @__PURE__ */ React9.createElement(Box9, { marginTop: 1 }, /* @__PURE__ */ React9.createElement(Text9, { color: "cyan" }, "How would you like to proceed?")), /* @__PURE__ */ React9.createElement(Box9, { marginTop: 1 }, /* @__PURE__ */ React9.createElement(
|
|
1843
1850
|
CommandMenu,
|
|
1844
1851
|
{
|
|
@@ -1888,16 +1895,18 @@ function App() {
|
|
|
1888
1895
|
const response = await fetch("https://registry.npmjs.org/fluxflow-cli/latest");
|
|
1889
1896
|
const data = await response.json();
|
|
1890
1897
|
const latestVersion = data?.version;
|
|
1898
|
+
if (latestVersion) setLatestVer(latestVersion);
|
|
1891
1899
|
if (latestVersion && latestVersion !== versionFluxflow) {
|
|
1892
1900
|
setMessages((prev) => {
|
|
1893
1901
|
const newMsgs = [...prev];
|
|
1894
1902
|
newMsgs.splice(1, 0, {
|
|
1895
1903
|
id: "update-" + Date.now(),
|
|
1896
1904
|
role: "system",
|
|
1897
|
-
text: `\u{1F680} **New version '${latestVersion}' is available!**
|
|
1905
|
+
text: `\u{1F680} **New version 'v${latestVersion}' is available!**
|
|
1898
1906
|
Type \`npm i -g fluxflow-cli\` to update.
|
|
1899
1907
|
Check what's new using \`/changelog\` command.`,
|
|
1900
|
-
isUpdateNotification: true
|
|
1908
|
+
isUpdateNotification: true,
|
|
1909
|
+
isMeta: true
|
|
1901
1910
|
});
|
|
1902
1911
|
return newMsgs;
|
|
1903
1912
|
});
|
|
@@ -1908,6 +1917,7 @@ Check what's new using \`/changelog\` command.`,
|
|
|
1908
1917
|
checkVersion();
|
|
1909
1918
|
}, []);
|
|
1910
1919
|
const [thinkingLevel, setThinkingLevel] = useState5("Medium");
|
|
1920
|
+
const [latestVer, setLatestVer] = useState5(null);
|
|
1911
1921
|
const [showFullThinking, setShowFullThinking] = useState5(false);
|
|
1912
1922
|
const [activeModel, setActiveModel] = useState5("gemma-4-31b-it");
|
|
1913
1923
|
const [janitorModel, setJanitorModel] = useState5("gemma-4-26b-a4b-it");
|
|
@@ -2058,7 +2068,7 @@ Check what's new using \`/changelog\` command.`,
|
|
|
2058
2068
|
setTempKey("");
|
|
2059
2069
|
}
|
|
2060
2070
|
};
|
|
2061
|
-
const COMMANDS = ["/mode", "/thinking", "/model", "/resume", "/memory", "/profile", "/settings", "/key", "/stats", "/reset", "/help", "/clear", "/quit", "/changelog"];
|
|
2071
|
+
const COMMANDS = ["/mode", "/thinking", "/model", "/resume", "/memory", "/profile", "/settings", "/key", "/stats", "/reset", "/help", "/clear", "/quit", "/changelog", "/about"];
|
|
2062
2072
|
const handleSubmit = (value) => {
|
|
2063
2073
|
const normalizedValue = value.replace(/\r\n/g, "\n").replace(/\r/g, "\n").trimEnd();
|
|
2064
2074
|
if (normalizedValue.endsWith("\\")) {
|
|
@@ -2133,7 +2143,7 @@ ${hintText}`, color: "magenta" }];
|
|
|
2133
2143
|
setMode(newMode);
|
|
2134
2144
|
setMessages((prev) => {
|
|
2135
2145
|
setCompletedIndex(prev.length + 1);
|
|
2136
|
-
return [...prev, { id: Date.now(), role: "system", text: `\u2699\uFE0F [SYSTEM] Mode switched to ${newMode}
|
|
2146
|
+
return [...prev, { id: Date.now(), role: "system", text: `\u2699\uFE0F [SYSTEM] Mode switched to ${newMode}`, isMeta: true }];
|
|
2137
2147
|
});
|
|
2138
2148
|
} else {
|
|
2139
2149
|
setActiveView("mode");
|
|
@@ -2146,13 +2156,13 @@ ${hintText}`, color: "magenta" }];
|
|
|
2146
2156
|
setShowFullThinking(true);
|
|
2147
2157
|
setMessages((prev) => {
|
|
2148
2158
|
setCompletedIndex(prev.length + 1);
|
|
2149
|
-
return [...prev, { id: Date.now(), role: "system", text: "\u2699\uFE0F [SYSTEM] Full Thinking Process: VISIBLE" }];
|
|
2159
|
+
return [...prev, { id: Date.now(), role: "system", text: "\u2699\uFE0F [SYSTEM] Full Thinking Process: VISIBLE", isMeta: true }];
|
|
2150
2160
|
});
|
|
2151
2161
|
} else if (arg === "hide") {
|
|
2152
2162
|
setShowFullThinking(false);
|
|
2153
2163
|
setMessages((prev) => {
|
|
2154
2164
|
setCompletedIndex(prev.length + 1);
|
|
2155
|
-
return [...prev, { id: Date.now(), role: "system", text: "\u2699\uFE0F [SYSTEM] Full Thinking Process: HIDDEN (Headings only)" }];
|
|
2165
|
+
return [...prev, { id: Date.now(), role: "system", text: "\u2699\uFE0F [SYSTEM] Full Thinking Process: HIDDEN (Headings only)", isMeta: true }];
|
|
2156
2166
|
});
|
|
2157
2167
|
} else if (parts[1]) {
|
|
2158
2168
|
let val = parts[1].toLowerCase();
|
|
@@ -2167,7 +2177,7 @@ ${hintText}`, color: "magenta" }];
|
|
|
2167
2177
|
setThinkingLevel(formattedLevel);
|
|
2168
2178
|
setMessages((prev) => {
|
|
2169
2179
|
setCompletedIndex(prev.length + 1);
|
|
2170
|
-
return [...prev, { id: Date.now(), role: "system", text: `\u2699\uFE0F [SYSTEM] Thinking level set to ${formattedLevel}
|
|
2180
|
+
return [...prev, { id: Date.now(), role: "system", text: `\u2699\uFE0F [SYSTEM] Thinking level set to ${formattedLevel}`, isMeta: true }];
|
|
2171
2181
|
});
|
|
2172
2182
|
}
|
|
2173
2183
|
} else {
|
|
@@ -2181,7 +2191,7 @@ ${hintText}`, color: "magenta" }];
|
|
|
2181
2191
|
setActiveModel(mod);
|
|
2182
2192
|
setMessages((prev) => {
|
|
2183
2193
|
setCompletedIndex(prev.length + 1);
|
|
2184
|
-
return [...prev, { id: Date.now(), role: "system", text: `\u2699\uFE0F [SYSTEM] Model switched to ${mod}
|
|
2194
|
+
return [...prev, { id: Date.now(), role: "system", text: `\u2699\uFE0F [SYSTEM] Model switched to ${mod}`, isMeta: true }];
|
|
2185
2195
|
});
|
|
2186
2196
|
} else {
|
|
2187
2197
|
setActiveView("model");
|
|
@@ -2214,7 +2224,7 @@ ${hintText}`, color: "magenta" }];
|
|
|
2214
2224
|
saveChat(chatId, name, messages);
|
|
2215
2225
|
setMessages((prev) => {
|
|
2216
2226
|
setCompletedIndex(prev.length + 1);
|
|
2217
|
-
return [...prev, { id: Date.now(), role: "system", text: `\u{1F4BE} [MEMORY] Chat saved as "${name}" (ID: ${chatId})
|
|
2227
|
+
return [...prev, { id: Date.now(), role: "system", text: `\u{1F4BE} [MEMORY] Chat saved as "${name}" (ID: ${chatId})`, isMeta: true }];
|
|
2218
2228
|
});
|
|
2219
2229
|
break;
|
|
2220
2230
|
}
|
|
@@ -2225,7 +2235,7 @@ ${hintText}`, color: "magenta" }];
|
|
|
2225
2235
|
setMessages((prev) => {
|
|
2226
2236
|
setCompletedIndex(prev.length + 1);
|
|
2227
2237
|
return [...prev, { id: Date.now(), role: "system", text: `\u{1F5C3}\uFE0F [HISTORY] Saved Chats:
|
|
2228
|
-
${list || "No saved chats found."}
|
|
2238
|
+
${list || "No saved chats found."}`, isMeta: true }];
|
|
2229
2239
|
});
|
|
2230
2240
|
};
|
|
2231
2241
|
run();
|
|
@@ -2240,7 +2250,7 @@ ${list || "No saved chats found."}` }];
|
|
|
2240
2250
|
try {
|
|
2241
2251
|
setMessages((prev) => {
|
|
2242
2252
|
setCompletedIndex(prev.length + 1);
|
|
2243
|
-
return [...prev, { id: Date.now(), role: "system", text: "\u2622\uFE0F [NUCLEAR] Initiating reset..." }];
|
|
2253
|
+
return [...prev, { id: Date.now(), role: "system", text: "\u2622\uFE0F [NUCLEAR] Initiating reset...", isMeta: true }];
|
|
2244
2254
|
});
|
|
2245
2255
|
if (fs14.existsSync(LOGS_DIR)) fs14.removeSync(LOGS_DIR);
|
|
2246
2256
|
if (fs14.existsSync(SECRET_DIR)) fs14.removeSync(SECRET_DIR);
|
|
@@ -2264,27 +2274,38 @@ ${list || "No saved chats found."}` }];
|
|
|
2264
2274
|
runReset();
|
|
2265
2275
|
break;
|
|
2266
2276
|
}
|
|
2277
|
+
case "/about": {
|
|
2278
|
+
const updateStatus = latestVer ? latestVer !== versionFluxflow ? `Update Available [v${latestVer}]` : "No Update Available" : "Checking for updates...";
|
|
2279
|
+
const aboutText = `\u2139\uFE0F **FluxFlow Version:** v${versionFluxflow}
|
|
2280
|
+
\u{1F504} **Status:** ${updateStatus}
|
|
2281
|
+
\u{1F4C5} **Updated on:** ${updatedOn}`;
|
|
2282
|
+
setMessages((prev) => {
|
|
2283
|
+
setCompletedIndex(prev.length + 1);
|
|
2284
|
+
return [...prev, { id: Date.now(), role: "system", text: aboutText, isMeta: true }];
|
|
2285
|
+
});
|
|
2286
|
+
break;
|
|
2287
|
+
}
|
|
2267
2288
|
case "/changelog": {
|
|
2268
2289
|
const platform = process.platform;
|
|
2269
2290
|
const command = platform === "win32" ? "start" : platform === "darwin" ? "open" : "xdg-open";
|
|
2270
2291
|
exec(`${command} ${CHANGELOG_URL}`);
|
|
2271
2292
|
setMessages((prev) => {
|
|
2272
2293
|
setCompletedIndex(prev.length + 1);
|
|
2273
|
-
return [...prev, { id: Date.now(), role: "system", text: `\u{1F310} [BROWSER] Opening changelog: ${CHANGELOG_URL}
|
|
2294
|
+
return [...prev, { id: Date.now(), role: "system", text: `\u{1F310} [BROWSER] Opening changelog: ${CHANGELOG_URL}`, isMeta: true }];
|
|
2274
2295
|
});
|
|
2275
2296
|
break;
|
|
2276
2297
|
}
|
|
2277
2298
|
case "/help": {
|
|
2278
2299
|
setMessages((prev) => {
|
|
2279
2300
|
setCompletedIndex(prev.length + 1);
|
|
2280
|
-
return [...prev, { id: Date.now(), role: "system", text: "\u2699\uFE0F [SYSTEM] Available commands: " + COMMANDS.join(", ") }];
|
|
2301
|
+
return [...prev, { id: Date.now(), role: "system", text: "\u2699\uFE0F [SYSTEM] Available commands: " + COMMANDS.join(", "), isMeta: true }];
|
|
2281
2302
|
});
|
|
2282
2303
|
break;
|
|
2283
2304
|
}
|
|
2284
2305
|
default:
|
|
2285
2306
|
setMessages((prev) => {
|
|
2286
2307
|
setCompletedIndex(prev.length + 1);
|
|
2287
|
-
return [...prev, { id: Date.now(), role: "system", text: `\u2699\uFE0F [SYSTEM] Unknown command: ${cmd}
|
|
2308
|
+
return [...prev, { id: Date.now(), role: "system", text: `\u2699\uFE0F [SYSTEM] Unknown command: ${cmd}`, isMeta: true }];
|
|
2288
2309
|
});
|
|
2289
2310
|
}
|
|
2290
2311
|
} else {
|