fluxflow-cli 2.10.2 → 2.10.3
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 +137 -36
- package/package.json +4 -3
package/dist/fluxflow.js
CHANGED
|
@@ -1745,7 +1745,7 @@ var init_ChatLayout = __esm({
|
|
|
1745
1745
|
const level = headingMatch[1].length;
|
|
1746
1746
|
const hText = headingMatch[2];
|
|
1747
1747
|
result.push(
|
|
1748
|
-
/* @__PURE__ */ React3.createElement(Box3, { key: i, marginTop: 1, marginBottom:
|
|
1748
|
+
/* @__PURE__ */ React3.createElement(Box3, { key: i, marginTop: 1, marginBottom: 0, width: "100%" }, /* @__PURE__ */ React3.createElement(Text3, { bold: true, color: level === 1 ? "cyan" : level === 2 ? "purple" : level === 3 ? "yellow" : level === 4 ? "green" : level === 5 ? "blue" : "white", underline: true }, hText.toUpperCase()))
|
|
1749
1749
|
);
|
|
1750
1750
|
return;
|
|
1751
1751
|
}
|
|
@@ -1852,13 +1852,13 @@ var init_ChatLayout = __esm({
|
|
|
1852
1852
|
const isTerminalRecord = msg.isTerminalRecord;
|
|
1853
1853
|
const isHomeWarning = msg.isHomeWarning;
|
|
1854
1854
|
if (isHomeWarning) {
|
|
1855
|
-
return /* @__PURE__ */ React3.createElement(Box3, { marginBottom: 1, paddingX: 1, width: "100%" }, /* @__PURE__ */ React3.createElement(Box3, { flexDirection: "column", borderStyle: "round", borderColor: "
|
|
1855
|
+
return /* @__PURE__ */ React3.createElement(Box3, { marginBottom: 1, paddingX: 1, width: "100%" }, /* @__PURE__ */ React3.createElement(Box3, { flexDirection: "column", borderStyle: "round", borderColor: "white", dimColor: true, padding: 0, width: "100%" }, /* @__PURE__ */ React3.createElement(Box3, { paddingX: 1 }, /* @__PURE__ */ React3.createElement(Text3, { color: "white", bold: true }, msg.text)), /* @__PURE__ */ React3.createElement(Box3, { paddingX: 1, marginTop: 0, marginBottom: 0 }, /* @__PURE__ */ React3.createElement(Text3, { color: "white" }, msg.subText))));
|
|
1856
1856
|
}
|
|
1857
1857
|
if (msg.isLogo) {
|
|
1858
1858
|
return /* @__PURE__ */ React3.createElement(Box3, { flexDirection: "column", alignItems: "flex-start", width: "100%", marginY: 1 }, /* @__PURE__ */ React3.createElement(Text3, null, getFluxLogo(version, aiProvider)));
|
|
1859
1859
|
}
|
|
1860
1860
|
if (msg.id && String(msg.id).startsWith("welcome")) {
|
|
1861
|
-
return /* @__PURE__ */ React3.createElement(Box3, { flexDirection: "column", alignItems: "center", width: "100%", marginY: 1 }, /* @__PURE__ */ React3.createElement(Box3, { borderStyle: "round", borderColor: "
|
|
1861
|
+
return /* @__PURE__ */ React3.createElement(Box3, { flexDirection: "column", alignItems: "center", width: "100%", marginY: 1 }, /* @__PURE__ */ React3.createElement(Box3, { borderStyle: "round", borderColor: "grey", paddingX: 3, paddingY: 0 }, /* @__PURE__ */ React3.createElement(Text3, { color: "white", bold: true }, msg.text.trim())));
|
|
1862
1862
|
}
|
|
1863
1863
|
if (msg.isVisualFeedback) {
|
|
1864
1864
|
return (
|
|
@@ -1871,13 +1871,13 @@ var init_ChatLayout = __esm({
|
|
|
1871
1871
|
}
|
|
1872
1872
|
if (msg.role === "system" && msg.text?.includes("[TOOL RESULT]") && !isDiffResult && !isTerminalRecord && !isPatchError) return null;
|
|
1873
1873
|
if (msg.isImageStats) {
|
|
1874
|
-
return /* @__PURE__ */ React3.createElement(Box3, { marginBottom: 1, paddingX: 1, width: "100%" }, /* @__PURE__ */ React3.createElement(Box3, { flexDirection: "column", borderStyle: "round", borderColor: "
|
|
1874
|
+
return /* @__PURE__ */ React3.createElement(Box3, { marginBottom: 1, paddingX: 1, width: "100%" }, /* @__PURE__ */ React3.createElement(Box3, { flexDirection: "column", borderStyle: "round", borderColor: "grey", padding: 0, width: "100%" }, /* @__PURE__ */ React3.createElement(Box3, { paddingX: 1, backgroundColor: "#0e1b21" }, /* @__PURE__ */ React3.createElement(Text3, { color: "white", bold: true }, "IMAGE STATS")), /* @__PURE__ */ React3.createElement(Box3, { paddingX: 1, marginTop: 1, marginBottom: 1, flexDirection: "column" }, msg.text.split("\n").map((line, i) => /* @__PURE__ */ React3.createElement(Text3, { key: i, color: "grey" }, line)))));
|
|
1875
1875
|
}
|
|
1876
1876
|
if (msg.isAskRecord) {
|
|
1877
1877
|
const selectionMatch = msg.text.match(/Selection: (.*)/);
|
|
1878
1878
|
const selection = selectionMatch ? selectionMatch[1] : "No selection";
|
|
1879
1879
|
const s = emojiSpace(2);
|
|
1880
|
-
return /* @__PURE__ */ React3.createElement(Box3, { marginBottom: 0, paddingX: 1, width: "100%" }, /* @__PURE__ */ React3.createElement(Box3, { flexDirection: "column", borderStyle: "round", borderColor: "gray", padding: 0, width: "100%" }, /* @__PURE__ */ React3.createElement(Box3, { paddingX: 1 }, /* @__PURE__ */ React3.createElement(Text3, { color: "
|
|
1880
|
+
return /* @__PURE__ */ React3.createElement(Box3, { marginBottom: 0, paddingX: 1, width: "100%" }, /* @__PURE__ */ React3.createElement(Box3, { flexDirection: "column", borderStyle: "round", borderColor: "gray", padding: 0, width: "100%" }, /* @__PURE__ */ React3.createElement(Box3, { paddingX: 1 }, /* @__PURE__ */ React3.createElement(Text3, { color: "white", bold: true }, "AGENT REQUEST: RESOLVED")), /* @__PURE__ */ React3.createElement(Box3, { paddingX: 1, marginTop: 1, marginBottom: 1 }, /* @__PURE__ */ React3.createElement(Text3, { color: "white" }, "Selection: ", /* @__PURE__ */ React3.createElement(Text3, { color: "grey", bold: true }, selection)))));
|
|
1881
1881
|
}
|
|
1882
1882
|
if (msg.isAboutRecord) {
|
|
1883
1883
|
return /* @__PURE__ */ React3.createElement(Box3, { marginBottom: 0, paddingX: 1, width: "100%" }, /* @__PURE__ */ React3.createElement(Box3, { flexDirection: "column", borderStyle: "round", borderColor: "gray", padding: 0, width: "100%" }, /* @__PURE__ */ React3.createElement(Box3, { paddingX: 1 }, /* @__PURE__ */ React3.createElement(Text3, { color: "white", bold: true }, "ABOUT FLUX FLOW")), /* @__PURE__ */ React3.createElement(Box3, { paddingX: 1, marginTop: 1, marginBottom: 1 }, /* @__PURE__ */ React3.createElement(Text3, null, msg.text))));
|
|
@@ -1913,7 +1913,7 @@ var init_ChatLayout = __esm({
|
|
|
1913
1913
|
{ cmd: "/fluxflow", desc: "Project management" },
|
|
1914
1914
|
{ cmd: "/update", desc: "Check/Install updates" }
|
|
1915
1915
|
];
|
|
1916
|
-
return /* @__PURE__ */ React3.createElement(Box3, { marginBottom: 1, paddingX: 1, width: "100%" }, /* @__PURE__ */ React3.createElement(Box3, { flexDirection: "column", borderStyle: "round", borderColor: "
|
|
1916
|
+
return /* @__PURE__ */ React3.createElement(Box3, { marginBottom: 1, paddingX: 1, width: "100%" }, /* @__PURE__ */ React3.createElement(Box3, { flexDirection: "column", borderStyle: "round", borderColor: "grey", paddingX: 2, paddingY: 1, width: "100%" }, /* @__PURE__ */ React3.createElement(Text3, { color: "white", bold: true, underline: true }, "COMMAND REFERENCE"), /* @__PURE__ */ React3.createElement(Box3, { flexDirection: "column", marginTop: 1 }, commandList.map((c, i) => /* @__PURE__ */ React3.createElement(Box3, { key: i, flexDirection: "row" }, /* @__PURE__ */ React3.createElement(Box3, { width: 15 }, /* @__PURE__ */ React3.createElement(Text3, { color: "white", bold: true }, c.cmd)), /* @__PURE__ */ React3.createElement(Text3, { color: "gray" }, " - ", c.desc))))));
|
|
1917
1917
|
}
|
|
1918
1918
|
if (msg.isTerminalRecord) {
|
|
1919
1919
|
const cmdMatch = msg.text.match(/COMMAND: (.*)/);
|
|
@@ -2009,14 +2009,13 @@ function CommandMenu({ title, subtitle, items, onSelect }) {
|
|
|
2009
2009
|
Box5,
|
|
2010
2010
|
{
|
|
2011
2011
|
flexDirection: "column",
|
|
2012
|
-
borderStyle: "round",
|
|
2013
2012
|
borderColor: "white",
|
|
2014
2013
|
padding: 0,
|
|
2015
|
-
marginTop:
|
|
2014
|
+
marginTop: 0,
|
|
2016
2015
|
flexShrink: 0,
|
|
2017
2016
|
width: "100%"
|
|
2018
2017
|
},
|
|
2019
|
-
/* @__PURE__ */ React5.createElement(Box5, { paddingX: 1, paddingY: 0, marginBottom: subtitle ? 0 : 1 }, /* @__PURE__ */ React5.createElement(Text5, { color: "gray", bold: true },
|
|
2018
|
+
title && /* @__PURE__ */ React5.createElement(Box5, { paddingX: 1, paddingY: 0, marginBottom: subtitle ? 0 : 1 }, /* @__PURE__ */ React5.createElement(Text5, { color: "gray", bold: true }, typeof title === "string" ? title.toUpperCase() : title)),
|
|
2020
2019
|
subtitle && /* @__PURE__ */ React5.createElement(Box5, { paddingX: 1, marginBottom: 1 }, /* @__PURE__ */ React5.createElement(Text5, { color: "gray", italic: true }, " ", subtitle)),
|
|
2021
2020
|
/* @__PURE__ */ React5.createElement(Box5, { flexDirection: "column", width: "100%" }, /* @__PURE__ */ React5.createElement(
|
|
2022
2021
|
SelectInput,
|
|
@@ -2211,10 +2210,10 @@ var init_main_tools = __esm({
|
|
|
2211
2210
|
};
|
|
2212
2211
|
TOOL_PROTOCOL = (mode, osDetected, isMultiModal, aiProvider) => `
|
|
2213
2212
|
-- TOOL DEFINITIONS --
|
|
2214
|
-
Internal tools. MUST use the EXACT syntax '[tool:functions.ToolName(args)]'. **
|
|
2213
|
+
Internal tools. MUST use the EXACT syntax '[tool:functions.ToolName(args)]'. **NO OTHER SYNTAX/MARKERS ALLOWED, BRACKETS SHOULD BE PROPERLY USED AS PER SCHEMA**
|
|
2215
2214
|
|
|
2216
2215
|
**TOOL USAGE POLICY:**
|
|
2217
|
-
- **MAX 3 TOOL CALLS PER TURN${mode === "Flux" ? " (EXCEPTION FOR Todo TOOL: 3+ CALLS ALLOWED)" : ""}. Next Turn, verify tool results, plan next**
|
|
2216
|
+
- **MAX 3 TOOL CALLS PER TURN${mode === "Flux" ? " (EXCEPTION FOR Todo TOOL: 3+ CALLS ALLOWED, Run: Limit to 2 MAX)" : ""}. Next Turn, verify tool results, plan next**
|
|
2218
2217
|
${mode === "Flux" ? "- USE multiple search & replace on patch tool if editing same file/path with many changes \u2190 **HIGHLY RECOMMENDED**\n- Tool execution denied? MUST use 'Ask' tool immediately for user reason/changes. NEVER END RESPONSE OR PROCEED BLINDLY \u2190 **MANDATORY**\n- FileMap >> ReadFile to understand file efficiently\n- Want spefific STRING across project/file? SearchKeyword >> Guessing/ReadFile\n- HUGE FILES? SearchKeyword >> FileMap/Full File read\n- **MUST MARK DONE/APPEND Todos BASED ON REALTIME TASK PROGRESS ON *EACH TURN***" : ""}
|
|
2219
2218
|
${mode === "Flux" ? "- **File Tools >> Code in chat**\n\n" : ""}- COMMUNICATION TOOLS -
|
|
2220
2219
|
1. [tool:functions.Ask(question="...", optionA="option::description", ...MAX 4)]. Ambiguity Resolution. Mandatory Triggers: Path Divergence, Security, Risk Mitigation. ask >> finish. Suggest best options; don't ask for preferences
|
|
@@ -2230,7 +2229,7 @@ ${mode === "Flux" ? `- WORKSPACE TOOLS (path = relative to CWD & WILL BE FIRST A
|
|
|
2230
2229
|
4. [tool:functions.PatchFile(path="...", replaceContent1="full line/block", newContent1="...", ...MAX 6)]. Surgical Patch. **Multiple patch on same file/path? Use replaceContent2, newContent2 etc >>> multiple spams**. Unsure? ReadFile >> guessing. **MUST VERIFY DIFF**
|
|
2231
2230
|
5. [tool:functions.WriteFile(path="...", content="...")]. Creates/Overwrites. File Exist? PatchFile > WriteFile. Verify Imports
|
|
2232
2231
|
6. [tool:functions.SearchKeyword(keyword="...", file="optional")]. Global project search. If 'file' is provided, searches only that file. Finds definitions/logic without reading every file. Usage: Can search for relevent lines/logic area to read specifically for edit
|
|
2233
|
-
7. [tool:functions.Run(command="...")]. Runs ${osDetected === "Windows" ? isPsAvailable() ? `${isPtyAvailable ? "Interactive " : ""}WINDOWS POWERSHELL ONLY` : `${isPtyAvailable ? "Interactive " : ""}WINDOWS CMD ONLY` : `${isPtyAvailable ? "Interactive " : ""}BASH`} command. Destructive/Irreversible ops -> Ask user
|
|
2232
|
+
7. [tool:functions.Run(command="...")]. Runs ${osDetected === "Windows" ? isPsAvailable() ? `${isPtyAvailable ? "Interactive " : ""}WINDOWS POWERSHELL ONLY` : `${isPtyAvailable ? "Interactive " : ""}WINDOWS CMD ONLY` : `${isPtyAvailable ? "Interactive " : ""}BASH`} command. Destructive/Irreversible ops -> Ask user
|
|
2234
2233
|
8. [tool:functions.Todo(method="create/append/get", tasks=[ARRAY OF STRINGS], markDone=[ARRAY OF TASK STRINGS])]. Task List, Markdown IN ARRAY NOT ALLOWED. USAGE: ANALYZE USER REQUEST **IF** MULTIPLE TASK \u2192 BREAK DOWN TASK \u2192 CREATE TODO **BEFORE** DIVING IN. 'tasks' & 'markDone' OPTIONAL PARAMETERS WITH method 'get'. USE 'get' method WITH 'markDone' to mark task completed`.trim() : `- CREATIVE TOOLS (path = relative to CWD & WILL BE FIRST ARGUMENT, path separator: '/') -
|
|
2235
2234
|
1. [tool:functions.WritePDF(path="...", content="...", orientation="...")]. PROACTIVE A4 PAGE BREAKS MUST IN CSS. HTML/CSS for PREMIUM layout
|
|
2236
2235
|
2. [tool:functions.WriteDoc(path="...", content="...")]. A4 Word document
|
|
@@ -3256,7 +3255,7 @@ function ProfileForm({ initialData, onSave, onCancel }) {
|
|
|
3256
3255
|
flexDirection: "column",
|
|
3257
3256
|
width: "100%"
|
|
3258
3257
|
},
|
|
3259
|
-
/* @__PURE__ */ React7.createElement(Box7, { paddingX: 1, marginBottom: 1 }, /* @__PURE__ */ React7.createElement(Text7, { color: "white", bold: true }, "
|
|
3258
|
+
/* @__PURE__ */ React7.createElement(Box7, { paddingX: 1, marginBottom: 1 }, /* @__PURE__ */ React7.createElement(Text7, { color: "white", bold: true }, "DEVELOPER PROFILE CONFIGURATION")),
|
|
3260
3259
|
/* @__PURE__ */ React7.createElement(Box7, { paddingX: 1, flexDirection: "column" }, /* @__PURE__ */ React7.createElement(Box7, null, /* @__PURE__ */ React7.createElement(Text7, { color: "white", bold: true }, steps[step].label), /* @__PURE__ */ React7.createElement(
|
|
3261
3260
|
TextInput2,
|
|
3262
3261
|
{
|
|
@@ -3314,7 +3313,7 @@ var init_AskUserModal = __esm({
|
|
|
3314
3313
|
}
|
|
3315
3314
|
)), /* @__PURE__ */ React8.createElement(Box8, { marginTop: 1, paddingX: 1, marginBottom: 1 }, /* @__PURE__ */ React8.createElement(Text8, { color: "gray", italic: true }, "(Press Enter to send)")));
|
|
3316
3315
|
}
|
|
3317
|
-
return /* @__PURE__ */ React8.createElement(Box8, { flexDirection: "column", borderStyle: "round", borderColor: "gray", padding: 0, width: "100%" }, /* @__PURE__ */ React8.createElement(Box8, { paddingX: 1, marginBottom: 1 }, /* @__PURE__ */ React8.createElement(Text8, { color: "white", bold: true }, "
|
|
3316
|
+
return /* @__PURE__ */ React8.createElement(Box8, { flexDirection: "column", borderStyle: "round", borderColor: "gray", padding: 0, width: "100%" }, /* @__PURE__ */ React8.createElement(Box8, { paddingX: 1, marginBottom: 1 }, /* @__PURE__ */ React8.createElement(Text8, { color: "white", bold: true }, "AGENT REQUEST: ACTION REQUIRED")), /* @__PURE__ */ React8.createElement(Box8, { paddingX: 1, marginBottom: 1 }, /* @__PURE__ */ React8.createElement(Text8, { bold: true, color: "white" }, question)), /* @__PURE__ */ React8.createElement(Box8, { flexDirection: "column", width: "100%" }, allOptions.map((opt, idx) => {
|
|
3318
3317
|
const isSelected = idx === selectedIndex;
|
|
3319
3318
|
return /* @__PURE__ */ React8.createElement(
|
|
3320
3319
|
Box8,
|
|
@@ -3347,7 +3346,7 @@ Your tool syntax is: '[tool:functions.ToolName(args...)]'
|
|
|
3347
3346
|
[tool:functions.Memory(action="temp", content="<summary of the user prompt & model responses ONLY FROM LATEST PROMPT UNDER 40 WORDS>. [Talked on: <date> <hour>]")]. Time format: YYYY-MM-DD HH am/pm
|
|
3348
3347
|
|
|
3349
3348
|
${isMemoryEnabled ? `-- User-specific long-term/permanent memory (USE BASED ON CONVERSATION CONTEXT, DO NOT RE-SAVE MEMORY WHICH IS ALREADY SAVED) --
|
|
3350
|
-
- Add: [tool:functions.Memory(action="user", method="add", content="<string to add>. [Saved on: <date ONLY>]", score=2)] (Set score=2 ONLY if the user explicitly asked to "remember" or "save" this information, else omit this parameter entirely
|
|
3349
|
+
- Add: [tool:functions.Memory(action="user", method="add", content="<string to add>. [Saved on: <date ONLY>]", score=2)] (Set score=2 ONLY if the user explicitly asked to "remember" or "save" this information, else omit this parameter entirely)
|
|
3351
3350
|
- Delete: [tool:functions.Memory(action="user", method="delete", id="<memory id>")]
|
|
3352
3351
|
- Update: [tool:functions.Memory(action="user", method="update", content-new="string to update", id="<memory id>")]
|
|
3353
3352
|
|
|
@@ -9031,7 +9030,7 @@ ${ideErr} [/ERROR]`;
|
|
|
9031
9030
|
return tokens.some((token) => checkToken(token));
|
|
9032
9031
|
});
|
|
9033
9032
|
if (isViolating) {
|
|
9034
|
-
const denyMsg = `Access Denied.
|
|
9033
|
+
const denyMsg = `Access Denied. Prohibited from accessing external directories while "External Workspace Access" is disabled.`;
|
|
9035
9034
|
if (settings.onExecStart) settings.onExecStart(command || "Unknown");
|
|
9036
9035
|
yield { type: "exec_start" };
|
|
9037
9036
|
await new Promise((resolve) => setTimeout(resolve, 50));
|
|
@@ -9106,8 +9105,105 @@ ${boxBottom}` };
|
|
|
9106
9105
|
}
|
|
9107
9106
|
if (!forcePrompt && !decision) {
|
|
9108
9107
|
if (systemSettings2.networkAccess === false) {
|
|
9109
|
-
|
|
9110
|
-
|
|
9108
|
+
let normalized = cmdTrimmed.trim().replace(/\s+/g, " ").replace(/^['"]+|['"]+$/g, "").toLowerCase();
|
|
9109
|
+
const tokens = normalized.split(" ");
|
|
9110
|
+
const rawCmd = tokens[0];
|
|
9111
|
+
const cmd = rawCmd.split("/").pop().split("\\").pop().replace(/\.exe$/, "");
|
|
9112
|
+
const blockedCommands = /* @__PURE__ */ new Set([
|
|
9113
|
+
"curl",
|
|
9114
|
+
"wget",
|
|
9115
|
+
"httpie",
|
|
9116
|
+
"xh",
|
|
9117
|
+
"ssh",
|
|
9118
|
+
"scp",
|
|
9119
|
+
"sftp",
|
|
9120
|
+
"rsync",
|
|
9121
|
+
"ftp",
|
|
9122
|
+
"lftp",
|
|
9123
|
+
"tftp",
|
|
9124
|
+
"telnet",
|
|
9125
|
+
"nc",
|
|
9126
|
+
"netcat",
|
|
9127
|
+
"socat",
|
|
9128
|
+
"ping",
|
|
9129
|
+
"traceroute",
|
|
9130
|
+
"tracert",
|
|
9131
|
+
"dig",
|
|
9132
|
+
"nslookup",
|
|
9133
|
+
"host",
|
|
9134
|
+
"whois",
|
|
9135
|
+
"nmap",
|
|
9136
|
+
"docker",
|
|
9137
|
+
"podman",
|
|
9138
|
+
"kubectl",
|
|
9139
|
+
"helm",
|
|
9140
|
+
"gcloud",
|
|
9141
|
+
"aws",
|
|
9142
|
+
"az",
|
|
9143
|
+
"terraform",
|
|
9144
|
+
"ansible-playbook",
|
|
9145
|
+
"nix",
|
|
9146
|
+
"nix-env",
|
|
9147
|
+
"apt",
|
|
9148
|
+
"apt-get",
|
|
9149
|
+
"dpkg",
|
|
9150
|
+
"yum",
|
|
9151
|
+
"dnf",
|
|
9152
|
+
"pacman",
|
|
9153
|
+
"zypper",
|
|
9154
|
+
"brew",
|
|
9155
|
+
"apk",
|
|
9156
|
+
"choco",
|
|
9157
|
+
"scoop",
|
|
9158
|
+
"conda",
|
|
9159
|
+
"mamba",
|
|
9160
|
+
"aria2c",
|
|
9161
|
+
"axel",
|
|
9162
|
+
"smbclient",
|
|
9163
|
+
"lynx",
|
|
9164
|
+
"w3m",
|
|
9165
|
+
"links",
|
|
9166
|
+
"elinks",
|
|
9167
|
+
"heroku",
|
|
9168
|
+
"netlify",
|
|
9169
|
+
"vercel",
|
|
9170
|
+
"firebase",
|
|
9171
|
+
"supabase",
|
|
9172
|
+
"wrangler",
|
|
9173
|
+
"flyctl",
|
|
9174
|
+
"powershell",
|
|
9175
|
+
"pwsh",
|
|
9176
|
+
"certutil",
|
|
9177
|
+
"bitsadmin",
|
|
9178
|
+
"cloudflared",
|
|
9179
|
+
"ngrok",
|
|
9180
|
+
"tailscale",
|
|
9181
|
+
"zerotier",
|
|
9182
|
+
"rclone"
|
|
9183
|
+
]);
|
|
9184
|
+
let deny = false;
|
|
9185
|
+
if (blockedCommands.has(cmd)) {
|
|
9186
|
+
deny = true;
|
|
9187
|
+
}
|
|
9188
|
+
const hasSubcmd = (list) => tokens.slice(1).some((token) => list.includes(token));
|
|
9189
|
+
const shouldDenyPkgManager = (dangerCommands) => {
|
|
9190
|
+
const dangerIdx = tokens.findIndex((t) => dangerCommands.includes(t));
|
|
9191
|
+
const safeIdx = tokens.findIndex((t) => ["run", "exec", "test"].includes(t));
|
|
9192
|
+
return dangerIdx !== -1 && !(safeIdx !== -1 && safeIdx < dangerIdx);
|
|
9193
|
+
};
|
|
9194
|
+
if (cmd === "git" && hasSubcmd(["clone", "pull", "push", "fetch"])) deny = true;
|
|
9195
|
+
if (cmd === "go" && hasSubcmd(["get", "install"])) deny = true;
|
|
9196
|
+
if (cmd === "npm" && shouldDenyPkgManager(["install", "i", "update", "add"])) deny = true;
|
|
9197
|
+
if (cmd === "yarn" && shouldDenyPkgManager(["add", "install", "upgrade"])) deny = true;
|
|
9198
|
+
if (cmd === "pnpm" && shouldDenyPkgManager(["add", "install", "update"])) deny = true;
|
|
9199
|
+
if (cmd === "bun" && shouldDenyPkgManager(["add", "install", "update"])) deny = true;
|
|
9200
|
+
if (cmd === "deno" && hasSubcmd(["install", "add"])) deny = true;
|
|
9201
|
+
if (cmd === "pip" && hasSubcmd(["install", "download"])) deny = true;
|
|
9202
|
+
if (cmd === "pip3" && hasSubcmd(["install", "download"])) deny = true;
|
|
9203
|
+
if (cmd === "cargo" && hasSubcmd(["install", "add"])) deny = true;
|
|
9204
|
+
if (["bash", "sh", "zsh", "fish"].includes(cmd) && hasSubcmd(["-c"])) deny = true;
|
|
9205
|
+
if (cmd === "cmd" && hasSubcmd(["/c"])) deny = true;
|
|
9206
|
+
if (deny) {
|
|
9111
9207
|
decision = "deny";
|
|
9112
9208
|
isNetworkDeny = true;
|
|
9113
9209
|
}
|
|
@@ -9372,7 +9468,7 @@ ${boxBottom}` };
|
|
|
9372
9468
|
} else if (denyReason === "network") {
|
|
9373
9469
|
denyMsg = "Permission Denied: Sandbox Network Access Disabled by User Policy.";
|
|
9374
9470
|
} else if (denyReason === "prohibited" && normToolName === "exec_command") {
|
|
9375
|
-
denyMsg = "Permission Denied: Prohibited Command";
|
|
9471
|
+
denyMsg = "Permission Denied: Prohibited Command in User Policy";
|
|
9376
9472
|
}
|
|
9377
9473
|
if (normToolName === "write_file" || normToolName === "update_file") {
|
|
9378
9474
|
const action = normToolName === "write_file" ? "WRITE DENIED" : "UPDATE DENIED";
|
|
@@ -10020,7 +10116,7 @@ function MemoryModal({ onClose }) {
|
|
|
10020
10116
|
return "red";
|
|
10021
10117
|
};
|
|
10022
10118
|
const s = emojiSpace(2);
|
|
10023
|
-
return /* @__PURE__ */ React10.createElement(Box10, { flexDirection: "column", borderStyle: "round", borderColor: "gray", padding: 0, width: "100%" }, /* @__PURE__ */ React10.createElement(Box10, { paddingX: 1, marginBottom: 1, justifyContent: "space-between" }, /* @__PURE__ */ React10.createElement(Text10, { color: "white", bold: true }, "
|
|
10119
|
+
return /* @__PURE__ */ React10.createElement(Box10, { flexDirection: "column", borderStyle: "round", borderColor: "gray", padding: 0, width: "100%" }, /* @__PURE__ */ React10.createElement(Box10, { paddingX: 1, marginBottom: 1, justifyContent: "space-between" }, /* @__PURE__ */ React10.createElement(Text10, { color: "white", bold: true }, "SAVED MEMORIES"), /* @__PURE__ */ React10.createElement(Box10, null, /* @__PURE__ */ React10.createElement(Text10, { color: "gray" }, "Vault: "), /* @__PURE__ */ React10.createElement(Text10, { color: getBarColor() }, barStr), /* @__PURE__ */ React10.createElement(Text10, { color: "white", bold: true }, " ", usagePercent, "%"))), !isMemoryOn && memories.length > 0 ? /* @__PURE__ */ React10.createElement(Box10, { paddingX: 2, paddingY: 1 }, /* @__PURE__ */ React10.createElement(Text10, { italic: true, color: "gray" }, "Memory is currently Off...")) : memories.length === 0 ? /* @__PURE__ */ React10.createElement(Box10, { paddingX: 2, paddingY: 1 }, /* @__PURE__ */ React10.createElement(Text10, { italic: true, color: "gray" }, isMemoryOn ? "Learning..." : "Memory not available...")) : /* @__PURE__ */ React10.createElement(Box10, { flexDirection: "column" }, memories.map((mem, idx) => {
|
|
10024
10120
|
const isSelected = idx === selectedIndex;
|
|
10025
10121
|
return /* @__PURE__ */ React10.createElement(
|
|
10026
10122
|
Box10,
|
|
@@ -10031,7 +10127,7 @@ function MemoryModal({ onClose }) {
|
|
|
10031
10127
|
width: "100%"
|
|
10032
10128
|
},
|
|
10033
10129
|
/* @__PURE__ */ React10.createElement(Box10, { flexGrow: 1 }, /* @__PURE__ */ React10.createElement(Text10, { color: isSelected ? "white" : "grey", bold: isSelected }, isSelected ? "\u276F " : " ", idx + 1, ". ", cleanDisplay(mem.memory))),
|
|
10034
|
-
isSelected && /* @__PURE__ */ React10.createElement(Box10, { flexShrink: 0 }, /* @__PURE__ */ React10.createElement(Text10, { color: "grey", bold: true }, "[X] WIPE "))
|
|
10130
|
+
isSelected && /* @__PURE__ */ React10.createElement(Box10, { flexShrink: 0 }, /* @__PURE__ */ React10.createElement(Text10, { color: "grey", dimColor: true }, "[ "), " ", /* @__PURE__ */ React10.createElement(Text10, { color: "grey", dimColor: true, italic: true }, mem.score), /* @__PURE__ */ React10.createElement(Text10, { color: "grey", dimColor: true }, " ]"), /* @__PURE__ */ React10.createElement(Text10, { color: "grey", bold: true }, "[X] WIPE "))
|
|
10035
10131
|
);
|
|
10036
10132
|
})), /* @__PURE__ */ React10.createElement(
|
|
10037
10133
|
Box10,
|
|
@@ -11172,18 +11268,16 @@ function App({ args = [] }) {
|
|
|
11172
11268
|
id: "system-warning",
|
|
11173
11269
|
role: "system",
|
|
11174
11270
|
text: `[CRITICAL SECURITY ALERT] SYSTEM DIRECTORY DETECTED`,
|
|
11175
|
-
subText: `You are currently in a PROTECTED SYSTEM DIRECTORY (${process.cwd()}). Operating here is EXTREMELY dangerous as the agent could accidentally corrupt your OS or installed applications.
|
|
11176
|
-
isHomeWarning: true
|
|
11177
|
-
isMeta: true
|
|
11271
|
+
subText: `You are currently in a PROTECTED SYSTEM DIRECTORY (${process.cwd()}). Operating here is EXTREMELY dangerous as the agent could accidentally corrupt your OS or installed applications. Open FluxFlow in project folder to work safely.`,
|
|
11272
|
+
isHomeWarning: true
|
|
11178
11273
|
});
|
|
11179
11274
|
} else if (isHomeDir) {
|
|
11180
11275
|
msgs.push({
|
|
11181
11276
|
id: "home-warning",
|
|
11182
11277
|
role: "system",
|
|
11183
11278
|
text: `[SECURITY ALERT] HOME DIRECTORY DETECTED`,
|
|
11184
|
-
subText: `You are currently in ${os4.homedir()}. Working here is high-risk as the agent may modify system-sensitive configurations. Please
|
|
11185
|
-
isHomeWarning: true
|
|
11186
|
-
isMeta: true
|
|
11279
|
+
subText: `You are currently in ${os4.homedir()}. Working here is high-risk as the agent may modify system-sensitive configurations. Please open FluxFlow in project folder.`,
|
|
11280
|
+
isHomeWarning: true
|
|
11187
11281
|
});
|
|
11188
11282
|
}
|
|
11189
11283
|
return msgs;
|
|
@@ -12110,7 +12204,7 @@ ${cleanText}`, color: "magenta" }];
|
|
|
12110
12204
|
const s2 = emojiSpace(2);
|
|
12111
12205
|
setMessages((prev) => {
|
|
12112
12206
|
setCompletedIndex(prev.length + 1);
|
|
12113
|
-
return [...prev, { id: "revert-empty-" + Date.now(), role: "system", text: `
|
|
12207
|
+
return [...prev, { id: "revert-empty-" + Date.now(), role: "system", text: `Nothing to revert to.`, isMeta: true }];
|
|
12114
12208
|
});
|
|
12115
12209
|
}
|
|
12116
12210
|
});
|
|
@@ -12468,7 +12562,7 @@ ${list || "No saved chats found."}`, isMeta: true }];
|
|
|
12468
12562
|
} catch (err) {
|
|
12469
12563
|
setMessages((prev) => {
|
|
12470
12564
|
setCompletedIndex(prev.length + 1);
|
|
12471
|
-
return [...prev, { id: Date.now(), role: "system", text: `[RESET ERROR] Failed to
|
|
12565
|
+
return [...prev, { id: Date.now(), role: "system", text: `[RESET ERROR] Failed to clear data: ${err.message}` }];
|
|
12472
12566
|
});
|
|
12473
12567
|
}
|
|
12474
12568
|
};
|
|
@@ -12652,6 +12746,13 @@ ${list || "No saved chats found."}`, isMeta: true }];
|
|
|
12652
12746
|
});
|
|
12653
12747
|
break;
|
|
12654
12748
|
}
|
|
12749
|
+
case "/btw": {
|
|
12750
|
+
setMessages((prev) => {
|
|
12751
|
+
setCompletedIndex(prev.length + 1);
|
|
12752
|
+
return [...prev, { id: Date.now(), role: "system", text: `[SYSTEM] /btw only available when agent is working`, isMeta: true }];
|
|
12753
|
+
});
|
|
12754
|
+
break;
|
|
12755
|
+
}
|
|
12655
12756
|
default:
|
|
12656
12757
|
const s = emojiSpace(2);
|
|
12657
12758
|
setMessages((prev) => {
|
|
@@ -13487,7 +13588,7 @@ Selection: ${val}`,
|
|
|
13487
13588
|
title: "API KEY MANAGEMENT",
|
|
13488
13589
|
items: [
|
|
13489
13590
|
{ label: "Edit Current Key (Update)", value: "edit" },
|
|
13490
|
-
{ label: "Remove Current Key (
|
|
13591
|
+
{ label: "Remove Current Key (Delete)", value: "remove" },
|
|
13491
13592
|
{ label: "Cancel", value: "Cancel" }
|
|
13492
13593
|
],
|
|
13493
13594
|
onSelect: (item) => {
|
|
@@ -13507,13 +13608,13 @@ Selection: ${val}`,
|
|
|
13507
13608
|
case "deleteKey":
|
|
13508
13609
|
return /* @__PURE__ */ React14.createElement(Box14, { flexDirection: "column", borderStyle: "round", borderColor: "grey", paddingX: 2, paddingY: 1 }, (() => {
|
|
13509
13610
|
const s = emojiSpace(2);
|
|
13510
|
-
return /* @__PURE__ */ React14.createElement(Text14, { color: "white", bold: true }, "DANGER:
|
|
13511
|
-
})(), /* @__PURE__ */ React14.createElement(Text14, { marginTop: 1 }, "This will permanently delete
|
|
13611
|
+
return /* @__PURE__ */ React14.createElement(Text14, { color: "white", bold: true }, "DANGER: CLEAR CREDENTIALS");
|
|
13612
|
+
})(), /* @__PURE__ */ React14.createElement(Text14, { marginTop: 1 }, "This will permanently delete all saved API keys in credential cache. You will need to enter it again to use Flux."), /* @__PURE__ */ React14.createElement(Box14, { marginTop: 1 }, /* @__PURE__ */ React14.createElement(
|
|
13512
13613
|
CommandMenu,
|
|
13513
13614
|
{
|
|
13514
|
-
title: "Are you
|
|
13615
|
+
title: "Are you sure?",
|
|
13515
13616
|
items: [
|
|
13516
|
-
{ label: "YES,
|
|
13617
|
+
{ label: "YES, CLEAR CREDENTIALS", value: "yes" },
|
|
13517
13618
|
{ label: "NO, GO BACK", value: "no" }
|
|
13518
13619
|
],
|
|
13519
13620
|
onSelect: async (item) => {
|
|
@@ -13522,7 +13623,7 @@ Selection: ${val}`,
|
|
|
13522
13623
|
setApiKey(null);
|
|
13523
13624
|
setActiveView("chat");
|
|
13524
13625
|
const s = emojiSpace(2);
|
|
13525
|
-
setMessages((prev) => [...prev, { id: Date.now(), role: "system", text: `[
|
|
13626
|
+
setMessages((prev) => [...prev, { id: Date.now(), role: "system", text: `[CREDENTIAL CLEARED] API Key removed successfully.` }]);
|
|
13526
13627
|
} else {
|
|
13527
13628
|
setActiveView("key");
|
|
13528
13629
|
}
|
|
@@ -13878,7 +13979,7 @@ Selection: ${val}`,
|
|
|
13878
13979
|
aiProvider,
|
|
13879
13980
|
version: versionFluxflow
|
|
13880
13981
|
}
|
|
13881
|
-
), activeCommand && /* @__PURE__ */ React14.createElement(Box14, { marginTop: 1 }, /* @__PURE__ */ React14.createElement(TerminalBox, { command: activeCommand, output: execOutput, isFocused: isTerminalFocused, isPty: isActiveCommandPty }))), isInitializing ? /* @__PURE__ */ React14.createElement(Box14, { borderStyle: "double", borderColor: "grey", padding: 1, flexShrink: 0 }, /* @__PURE__ */ React14.createElement(Text14, { color: "white" }, "Starting Flux Flow...")) : !apiKey ? /* @__PURE__ */ React14.createElement(Box14, { borderStyle: "round", borderColor: "white", padding: 0, flexDirection: "column", flexShrink: 0, width: "100%" }, /* @__PURE__ */ React14.createElement(Box14, { paddingX: 1, marginBottom: 1 }, /* @__PURE__ */ React14.createElement(Text14, { color: "gray", bold: true }, "
|
|
13982
|
+
), activeCommand && /* @__PURE__ */ React14.createElement(Box14, { marginTop: 1 }, /* @__PURE__ */ React14.createElement(TerminalBox, { command: activeCommand, output: execOutput, isFocused: isTerminalFocused, isPty: isActiveCommandPty }))), isInitializing ? /* @__PURE__ */ React14.createElement(Box14, { borderStyle: "double", borderColor: "grey", padding: 1, flexShrink: 0 }, /* @__PURE__ */ React14.createElement(Text14, { color: "white" }, "Starting Flux Flow...")) : !apiKey ? /* @__PURE__ */ React14.createElement(Box14, { borderStyle: "round", borderColor: "white", padding: 0, flexDirection: "column", flexShrink: 0, width: "100%" }, /* @__PURE__ */ React14.createElement(Box14, { paddingX: 1, marginBottom: 1 }, /* @__PURE__ */ React14.createElement(Text14, { color: "gray", bold: true }, "API KEY REQUIRED")), /* @__PURE__ */ React14.createElement(Box14, { paddingX: 1, flexDirection: "column" }, setupStep === 0 ? /* @__PURE__ */ React14.createElement(React14.Fragment, null, /* @__PURE__ */ React14.createElement(Text14, { color: "white" }, "Select your Preferred Provider:"), /* @__PURE__ */ React14.createElement(Box14, { marginTop: 1 }, /* @__PURE__ */ React14.createElement(
|
|
13882
13983
|
CommandMenu,
|
|
13883
13984
|
{
|
|
13884
13985
|
items: [
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "fluxflow-cli",
|
|
3
|
-
"version": "2.10.
|
|
4
|
-
"date": "2026-06-
|
|
3
|
+
"version": "2.10.3",
|
|
4
|
+
"date": "2026-06-21",
|
|
5
5
|
"description": "A high-fidelity agentic terminal assistant for the Flux Era.",
|
|
6
6
|
"keywords": [
|
|
7
7
|
"ai",
|
|
@@ -10,7 +10,8 @@
|
|
|
10
10
|
"cli",
|
|
11
11
|
"gemini",
|
|
12
12
|
"ink",
|
|
13
|
-
"flux"
|
|
13
|
+
"flux",
|
|
14
|
+
"fluxflow"
|
|
14
15
|
],
|
|
15
16
|
"license": "MIT",
|
|
16
17
|
"repository": {
|