fluxflow-cli 2.8.10 → 2.9.0
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 +133 -11
- package/package.json +1 -1
package/dist/fluxflow.js
CHANGED
|
@@ -1852,7 +1852,7 @@ 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: "yellow", dimColor: true, padding: 0, width: "100%" }, /* @__PURE__ */ React3.createElement(Box3, { paddingX: 1, backgroundColor: "#3a0000" }, /* @__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)));
|
|
@@ -2223,7 +2223,7 @@ ${mode === "Flux" ? "- **File Tools >> Code in chat**\n\n" : ""}- COMMUNICATION
|
|
|
2223
2223
|
2. [tool:functions.WebScrape(url="...")]. Proactive use for specific webpage/docs/api
|
|
2224
2224
|
|
|
2225
2225
|
${mode === "Flux" ? `- WORKSPACE TOOLS (path = relative to CWD & WILL BE FIRST ARGUMENT, path separator: '/') -
|
|
2226
|
-
1. [tool:functions.ReadFile(path="...", startLine=number, endLine=number)]. ${aiProvider !== "Google" ? `${isMultiModal ? `Supports images/docs. User gives image/doc: VIEW FIRST
|
|
2226
|
+
1. [tool:functions.ReadFile(path="...", startLine=number, endLine=number)]. ${aiProvider !== "Google" ? `${isMultiModal ? `Supports images/docs. **User gives image/doc: VIEW FIRST**` : `No Multimodal support`}` : `Supports images/docs. **User gives image/doc: VIEW FIRST**`}
|
|
2227
2227
|
2. [tool:functions.ReadFolder(path="...")]. Detailed DIR stats including File Sizes
|
|
2228
2228
|
3. [tool:functions.FileMap(path="path/file")]. Shows file structure, dependency, functions, variable maps
|
|
2229
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**
|
|
@@ -6370,6 +6370,7 @@ var init_ai = __esm({
|
|
|
6370
6370
|
await init_tools();
|
|
6371
6371
|
init_crypto();
|
|
6372
6372
|
init_arg_parser();
|
|
6373
|
+
init_view_file();
|
|
6373
6374
|
init_terminal();
|
|
6374
6375
|
init_text();
|
|
6375
6376
|
init_paths();
|
|
@@ -8028,12 +8029,133 @@ ${ideCtx.warnings}
|
|
|
8028
8029
|
}
|
|
8029
8030
|
}
|
|
8030
8031
|
const cleanAgentText = agentText.replace(/\s*\[Prompted on:.*?\]/g, "").trim();
|
|
8032
|
+
const tagRegex = /@\[([^\]]+)\]/g;
|
|
8033
|
+
let match;
|
|
8034
|
+
const tagsFound = [];
|
|
8035
|
+
tagRegex.lastIndex = 0;
|
|
8036
|
+
while ((match = tagRegex.exec(cleanAgentText)) !== null) {
|
|
8037
|
+
tagsFound.push(match[1]);
|
|
8038
|
+
}
|
|
8039
|
+
let taggedContextBlocks = [];
|
|
8040
|
+
let attachedBinaryPart = null;
|
|
8041
|
+
for (const tag of tagsFound) {
|
|
8042
|
+
try {
|
|
8043
|
+
let tagClean = tag.trim().replace(/^["']|["']$/g, "");
|
|
8044
|
+
const lineRangeRegex = /[:#]L?(\d+)(?:-L?(\d+))?$/i;
|
|
8045
|
+
const matchRange = tagClean.match(lineRangeRegex);
|
|
8046
|
+
let filePath = tagClean;
|
|
8047
|
+
let startLine = null;
|
|
8048
|
+
let endLine = null;
|
|
8049
|
+
if (matchRange) {
|
|
8050
|
+
startLine = parseInt(matchRange[1], 10);
|
|
8051
|
+
endLine = matchRange[2] ? parseInt(matchRange[2], 10) : startLine;
|
|
8052
|
+
filePath = tagClean.slice(0, matchRange.index);
|
|
8053
|
+
}
|
|
8054
|
+
const absPath = path19.resolve(process.cwd(), filePath);
|
|
8055
|
+
if (fs20.existsSync(absPath)) {
|
|
8056
|
+
const stats = fs20.statSync(absPath);
|
|
8057
|
+
if (stats.isFile()) {
|
|
8058
|
+
const pathLower = filePath.toLowerCase();
|
|
8059
|
+
const isPdf = pathLower.endsWith(".pdf");
|
|
8060
|
+
const isOfficeFile = pathLower.endsWith(".docx") || pathLower.endsWith(".doc") || pathLower.endsWith(".ppt") || pathLower.endsWith(".pptx") || pathLower.endsWith(".xls") || pathLower.endsWith(".xlsx");
|
|
8061
|
+
const isImage = /\.(png|jpg|jpeg|webp|gif|bmp)$/.test(pathLower);
|
|
8062
|
+
const isMultimodalFile = isImage || isPdf || isOfficeFile;
|
|
8063
|
+
const isSupported = aiProvider === "Google" || MULTIMODAL_MODELS.includes(modelName);
|
|
8064
|
+
if (isMultimodalFile && !isSupported) {
|
|
8065
|
+
let terminalWidth = 115;
|
|
8066
|
+
if (process.stdout.isTTY) {
|
|
8067
|
+
terminalWidth = process.stdout.columns - 10 || 120;
|
|
8068
|
+
}
|
|
8069
|
+
const boxLines = [`${isImage ? "\u{1F4F8}" : "\u{1F4C4}"} UNSUPPORTED MODALITY FOR THIS MODEL`];
|
|
8070
|
+
const maxLen = Math.max(...boxLines.map((l) => l.length));
|
|
8071
|
+
const boxWidth = Math.min(maxLen + 4, terminalWidth);
|
|
8072
|
+
const boxTop = `\u256D${"\u2500".repeat(boxWidth)}\u256E`;
|
|
8073
|
+
const boxMid = boxLines.map((line) => `\u2502 ${line.padEnd(boxWidth - 2).substring(0, boxWidth - 2)} \u2502`).join("\n");
|
|
8074
|
+
const boxBottom = `\u2570${"\u2500".repeat(boxWidth)}\u256F`;
|
|
8075
|
+
yield { type: "visual_feedback", content: `${boxTop}
|
|
8076
|
+
${boxMid}
|
|
8077
|
+
${boxBottom}` };
|
|
8078
|
+
continue;
|
|
8079
|
+
}
|
|
8080
|
+
const finalStart = startLine !== null ? startLine : 1;
|
|
8081
|
+
let finalEnd = endLine !== null ? endLine : startLine !== null ? startLine : finalStart + 499;
|
|
8082
|
+
if (finalEnd - finalStart > 500) {
|
|
8083
|
+
finalEnd = finalStart + 500;
|
|
8084
|
+
}
|
|
8085
|
+
const argsStr = `path=${JSON.stringify(filePath)}, startLine=${finalStart}, endLine=${finalEnd}`;
|
|
8086
|
+
const result = await view_file(argsStr, { isMultiModal: isSupported });
|
|
8087
|
+
let isError = false;
|
|
8088
|
+
let textResult = "";
|
|
8089
|
+
let binPart = null;
|
|
8090
|
+
if (typeof result === "string") {
|
|
8091
|
+
if (result.trim().startsWith("ERROR")) {
|
|
8092
|
+
isError = true;
|
|
8093
|
+
} else {
|
|
8094
|
+
textResult = result;
|
|
8095
|
+
}
|
|
8096
|
+
} else if (result && typeof result === "object") {
|
|
8097
|
+
if (result.binaryPart) {
|
|
8098
|
+
binPart = result.binaryPart;
|
|
8099
|
+
textResult = result.text || "";
|
|
8100
|
+
} else {
|
|
8101
|
+
isError = true;
|
|
8102
|
+
}
|
|
8103
|
+
} else {
|
|
8104
|
+
isError = true;
|
|
8105
|
+
}
|
|
8106
|
+
if (!isError) {
|
|
8107
|
+
let label = "";
|
|
8108
|
+
if (isImage) {
|
|
8109
|
+
label = `\u{1F4F8} Viewed: ${filePath}`;
|
|
8110
|
+
attachedBinaryPart = binPart;
|
|
8111
|
+
} else if (isPdf || isOfficeFile) {
|
|
8112
|
+
label = `\u{1F4C4} Viewed: ${filePath}`;
|
|
8113
|
+
attachedBinaryPart = binPart;
|
|
8114
|
+
} else {
|
|
8115
|
+
let totalLines = "...";
|
|
8116
|
+
try {
|
|
8117
|
+
const content = fs20.readFileSync(absPath, "utf8");
|
|
8118
|
+
totalLines = content.split("\n").length;
|
|
8119
|
+
} catch (e) {
|
|
8120
|
+
}
|
|
8121
|
+
label = `\u{1F4C4} Read: ${filePath} \u2192 Lines ${finalStart} - ${Math.min(finalEnd, totalLines)} of ${totalLines}`;
|
|
8122
|
+
taggedContextBlocks.push(textResult);
|
|
8123
|
+
}
|
|
8124
|
+
if (label) {
|
|
8125
|
+
let terminalWidth = 115;
|
|
8126
|
+
if (process.stdout.isTTY) {
|
|
8127
|
+
terminalWidth = process.stdout.columns - 10 || 120;
|
|
8128
|
+
}
|
|
8129
|
+
const boxLines = [label];
|
|
8130
|
+
const maxLen = Math.max(...boxLines.map((l) => l.length));
|
|
8131
|
+
const boxWidth = Math.min(maxLen + 4, terminalWidth);
|
|
8132
|
+
const boxTop = `\u256D${"\u2500".repeat(boxWidth)}\u256E`;
|
|
8133
|
+
const boxMid = boxLines.map((line) => `\u2502 ${line.padEnd(boxWidth - 2).substring(0, boxWidth - 2)} \u2502`).join("\n");
|
|
8134
|
+
const boxBottom = `\u2570${"\u2500".repeat(boxWidth)}\u256F`;
|
|
8135
|
+
yield { type: "visual_feedback", content: `${boxTop}
|
|
8136
|
+
${boxMid}
|
|
8137
|
+
${boxBottom}` };
|
|
8138
|
+
}
|
|
8139
|
+
}
|
|
8140
|
+
}
|
|
8141
|
+
}
|
|
8142
|
+
} catch (e) {
|
|
8143
|
+
}
|
|
8144
|
+
}
|
|
8145
|
+
let taggedContextStr = "";
|
|
8146
|
+
if (taggedContextBlocks.length > 0) {
|
|
8147
|
+
taggedContextStr = "[TAGGED CONTEXT]\n" + taggedContextBlocks.join("\n\n") + "\n[/TAGGED CONTEXT]\n";
|
|
8148
|
+
}
|
|
8031
8149
|
const firstUserMsg = `[SYSTEM METADATA (PRIORITY: DYNAMIC), Chat Context >> Metadata] Time: ${dateTimeStr}
|
|
8032
8150
|
CWD: ${process.cwd()}${cwdMismatch ? ` (WARNING: CWD Mismatch! Previous Path: ${lastCwd})` : ""}
|
|
8033
8151
|
**DIRECTORY STRUCTURE**
|
|
8034
8152
|
${dirStructure}${memoryPrompt}${ideBlock}
|
|
8035
|
-
${activeSummaryBlock}${thinkingLevel !== "Fast" && thinkingLevel !== "xHigh" && aiProvider === "Google" ? `${modelName.toLowerCase().startsWith("gemma") ? "[SYSTEM] **STRICTLY FOLLOW THINKING POLICY AS CRITICAL PRIORITY. DO NOT START A RESPONSE WITHOUT <think> ... </think>** [/SYSTEM]\n" : ""}` : ""}[USER] ${cleanAgentText.trim()} [/USER]`.trim();
|
|
8036
|
-
|
|
8153
|
+
${activeSummaryBlock}${thinkingLevel !== "Fast" && thinkingLevel !== "xHigh" && aiProvider === "Google" ? `${modelName.toLowerCase().startsWith("gemma") ? "[SYSTEM] **STRICTLY FOLLOW THINKING POLICY AS CRITICAL PRIORITY. DO NOT START A RESPONSE WITHOUT <think> ... </think>** [/SYSTEM]\n" : ""}` : ""}${taggedContextStr}[USER] ${cleanAgentText.trim()} [/USER]`.trim();
|
|
8154
|
+
const userMsgObj = { role: "user", text: firstUserMsg };
|
|
8155
|
+
if (attachedBinaryPart) {
|
|
8156
|
+
userMsgObj.binaryPart = attachedBinaryPart;
|
|
8157
|
+
}
|
|
8158
|
+
modifiedHistory.push(userMsgObj);
|
|
8037
8159
|
if (activeSummaryBlock && history[history.length - 1]?.id) {
|
|
8038
8160
|
yield { type: "summary_injected", content: { id: history[history.length - 1].id, text: firstUserMsg } };
|
|
8039
8161
|
}
|
|
@@ -8353,14 +8475,14 @@ ${ideErr} [/ERROR]`;
|
|
|
8353
8475
|
{ type: "end", idx: endIdx, start: "[[END]]", end: "[[END]]" }
|
|
8354
8476
|
].filter((i) => i.idx !== -1).sort((a, b) => a.idx - b.idx);
|
|
8355
8477
|
if (indices.length > 0) {
|
|
8356
|
-
const
|
|
8357
|
-
if (
|
|
8358
|
-
msgs.push({ type: "text", content: remaining.substring(0,
|
|
8478
|
+
const match2 = indices[0];
|
|
8479
|
+
if (match2.idx > 0) {
|
|
8480
|
+
msgs.push({ type: "text", content: remaining.substring(0, match2.idx) });
|
|
8359
8481
|
}
|
|
8360
8482
|
isBufferingToolCall = true;
|
|
8361
|
-
activeBufferType =
|
|
8483
|
+
activeBufferType = match2.type;
|
|
8362
8484
|
toolCallBuffer = "";
|
|
8363
|
-
remaining = remaining.substring(
|
|
8485
|
+
remaining = remaining.substring(match2.idx);
|
|
8364
8486
|
} else {
|
|
8365
8487
|
const potentialStarts = ["[tool", "[[END]]"];
|
|
8366
8488
|
let splitPoint = -1;
|
|
@@ -12594,7 +12716,7 @@ Selection: ${val}`,
|
|
|
12594
12716
|
}
|
|
12595
12717
|
if (packet.type === "visual_feedback") {
|
|
12596
12718
|
setMessages((prev) => [...prev, {
|
|
12597
|
-
id: "feedback-" + Date.now(),
|
|
12719
|
+
id: "feedback-" + Date.now() + "-" + Math.random().toString(36).substring(2, 9),
|
|
12598
12720
|
role: "system",
|
|
12599
12721
|
text: packet.content,
|
|
12600
12722
|
isVisualFeedback: true
|
|
@@ -13295,7 +13417,7 @@ Selection: ${val}`,
|
|
|
13295
13417
|
}
|
|
13296
13418
|
));
|
|
13297
13419
|
case "keybindingsPrompt":
|
|
13298
|
-
return /* @__PURE__ */ React14.createElement(Box14, { flexDirection: "column", borderStyle: "round", borderColor: "
|
|
13420
|
+
return /* @__PURE__ */ React14.createElement(Box14, { flexDirection: "column", borderStyle: "round", borderColor: "grey", paddingX: 2, paddingY: 1, width: "100%" }, /* @__PURE__ */ React14.createElement(Text14, { color: "white", bold: true, underline: true }, "\u2328 CONFIGURE SHIFT+ENTER NEWLINE"), /* @__PURE__ */ React14.createElement(Text14, { marginTop: 1 }, "To support multi-line inputs with ", /* @__PURE__ */ React14.createElement(Text14, { bold: true, color: "white" }, "Shift + Enter"), " for newline, a terminal sequence keybinding needs to be added to your IDE configuration."), /* @__PURE__ */ React14.createElement(Text14, { marginTop: 1 }, "Would you like FluxFlow to automatically add this to your ", getIDEName(), " keybindings?"), /* @__PURE__ */ React14.createElement(Box14, { marginTop: 1 }, /* @__PURE__ */ React14.createElement(
|
|
13299
13421
|
CommandMenu,
|
|
13300
13422
|
{
|
|
13301
13423
|
title: "Add Keybinding?",
|