fluxflow-cli 2.8.10 → 2.10.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 +345 -37
- package/package.json +2 -2
package/dist/fluxflow.js
CHANGED
|
@@ -1586,7 +1586,7 @@ var init_ChatLayout = __esm({
|
|
|
1586
1586
|
}
|
|
1587
1587
|
}
|
|
1588
1588
|
}
|
|
1589
|
-
return result.
|
|
1589
|
+
return result.replaceAll(/\[SYSTEM\][\s\S]*?\[\/SYSTEM\]/gi, "").replaceAll(/<(think|thought)>[\s\S]*?(?:<\/(think|thought)>|$)/gi, "").replace(/\[ANSWER\][\s\S]*?(?:\[\/ANSWER\]|$)/gi, "").replaceAll(/\[TOOL RESULT\]:?\s*/gi, "").split("\n").filter((line) => !line.trim().startsWith("SUCCESS:") && !line.trim().startsWith("ERROR:")).join("\n").replaceAll(/\[\s*turn\s*:\s*(continue|finish)\s*\]/gi, "").replaceAll(/\[\[END\]\]/gi, "").replaceAll(/\[\s*turn\s*:?.*?$/gi, "").replaceAll(/\n\s*turn\s*:?.*?$/gi, "").replaceAll(/\[\s*$/gi, "").replaceAll(/\n\nResponded on .*/g, "").replaceAll(/\n\n\[Prompted on: .*\]/g, "").replaceAll(/(\$?\\?\/?\\rightarrow\$?|\$\\rightarrow\$)/gi, "\u2192").replaceAll(/(\$?\\?\/?\\leftarrow\$?|\$\\leftarrow\$)/gi, "\u2190").replaceAll(/(\$?\\?\/?\\uparrow\$?|\$\\uparrow\$)/gi, "\u2191").replaceAll(/(\$?\\?\/?\\downarrow\$?|\$\\downarrow\$)/gi, "\u2193").replaceAll(/(\$?\\?\/?\\leftrightarrow\$?|\$\\leftrightarrow\$)/gi, "\u2194").replaceAll(/@\[TerminalName:.*?, ProcessId:.*?\]/gi, "").replaceAll(/\b(write_file|update_file|read_folder|view_file|exec_command|web_search|web_scrape|search_keyword|write_pdf|write_docx|generate_image)\b/gi, (match) => TOOL_LABELS[match.toLowerCase()] || match).trim();
|
|
1590
1590
|
};
|
|
1591
1591
|
formatThinkText = (cleaned, columns = 80) => {
|
|
1592
1592
|
if (!cleaned) return null;
|
|
@@ -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)));
|
|
@@ -1896,6 +1896,7 @@ var init_ChatLayout = __esm({
|
|
|
1896
1896
|
{ cmd: "/save", desc: "Force save current chat" },
|
|
1897
1897
|
{ cmd: "/export", desc: "Export current chat in a .txt file" },
|
|
1898
1898
|
{ cmd: "/chats", desc: "List all chat sessions" },
|
|
1899
|
+
{ cmd: "/btw", desc: "Send raw inquiry mid-turn" },
|
|
1899
1900
|
{ cmd: "/image", desc: "Generate images" },
|
|
1900
1901
|
{ cmd: "/mode", desc: "Toggle Flux/Flow modes" },
|
|
1901
1902
|
{ cmd: "/thinking", desc: "Set AI reasoning depth" },
|
|
@@ -2223,7 +2224,7 @@ ${mode === "Flux" ? "- **File Tools >> Code in chat**\n\n" : ""}- COMMUNICATION
|
|
|
2223
2224
|
2. [tool:functions.WebScrape(url="...")]. Proactive use for specific webpage/docs/api
|
|
2224
2225
|
|
|
2225
2226
|
${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
|
|
2227
|
+
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
2228
|
2. [tool:functions.ReadFolder(path="...")]. Detailed DIR stats including File Sizes
|
|
2228
2229
|
3. [tool:functions.FileMap(path="path/file")]. Shows file structure, dependency, functions, variable maps
|
|
2229
2230
|
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**
|
|
@@ -2462,6 +2463,7 @@ var init_exec_command = __esm({
|
|
|
2462
2463
|
const looksLikePath = (str) => {
|
|
2463
2464
|
if (!str.includes("/")) return false;
|
|
2464
2465
|
if (/^(https?|file|ftp):\/\//i.test(str)) return false;
|
|
2466
|
+
if (str.startsWith("@")) return false;
|
|
2465
2467
|
if (str.startsWith("/") && (str.match(/\//g) || []).length === 1) {
|
|
2466
2468
|
return false;
|
|
2467
2469
|
}
|
|
@@ -3448,8 +3450,7 @@ ${projectContextBlock}
|
|
|
3448
3450
|
|
|
3449
3451
|
-- FORMATTING --
|
|
3450
3452
|
- GFM Supported
|
|
3451
|
-
- NO CHAT
|
|
3452
|
-
- ONE THINKING BLOCK PER TURN
|
|
3453
|
+
- NO CHAT **AFTER** FIRING TOOLS IN THIS TURN
|
|
3453
3454
|
- Basic LaTeX${mode === "Flux" ? "" : ". Kaomojis"}
|
|
3454
3455
|
=== END SYSTEM PROMPT ===`.trim();
|
|
3455
3456
|
};
|
|
@@ -6370,6 +6371,7 @@ var init_ai = __esm({
|
|
|
6370
6371
|
await init_tools();
|
|
6371
6372
|
init_crypto();
|
|
6372
6373
|
init_arg_parser();
|
|
6374
|
+
init_view_file();
|
|
6373
6375
|
init_terminal();
|
|
6374
6376
|
init_text();
|
|
6375
6377
|
init_paths();
|
|
@@ -8028,12 +8030,133 @@ ${ideCtx.warnings}
|
|
|
8028
8030
|
}
|
|
8029
8031
|
}
|
|
8030
8032
|
const cleanAgentText = agentText.replace(/\s*\[Prompted on:.*?\]/g, "").trim();
|
|
8033
|
+
const tagRegex = /@\[([^\]]+)\]/g;
|
|
8034
|
+
let match;
|
|
8035
|
+
const tagsFound = [];
|
|
8036
|
+
tagRegex.lastIndex = 0;
|
|
8037
|
+
while ((match = tagRegex.exec(cleanAgentText)) !== null) {
|
|
8038
|
+
tagsFound.push(match[1]);
|
|
8039
|
+
}
|
|
8040
|
+
let taggedContextBlocks = [];
|
|
8041
|
+
let attachedBinaryPart = null;
|
|
8042
|
+
for (const tag of tagsFound) {
|
|
8043
|
+
try {
|
|
8044
|
+
let tagClean = tag.trim().replace(/^["']|["']$/g, "");
|
|
8045
|
+
const lineRangeRegex = /[:#]L?(\d+)(?:-L?(\d+))?$/i;
|
|
8046
|
+
const matchRange = tagClean.match(lineRangeRegex);
|
|
8047
|
+
let filePath = tagClean;
|
|
8048
|
+
let startLine = null;
|
|
8049
|
+
let endLine = null;
|
|
8050
|
+
if (matchRange) {
|
|
8051
|
+
startLine = parseInt(matchRange[1], 10);
|
|
8052
|
+
endLine = matchRange[2] ? parseInt(matchRange[2], 10) : startLine;
|
|
8053
|
+
filePath = tagClean.slice(0, matchRange.index);
|
|
8054
|
+
}
|
|
8055
|
+
const absPath = path19.resolve(process.cwd(), filePath);
|
|
8056
|
+
if (fs20.existsSync(absPath)) {
|
|
8057
|
+
const stats = fs20.statSync(absPath);
|
|
8058
|
+
if (stats.isFile()) {
|
|
8059
|
+
const pathLower = filePath.toLowerCase();
|
|
8060
|
+
const isPdf = pathLower.endsWith(".pdf");
|
|
8061
|
+
const isOfficeFile = pathLower.endsWith(".docx") || pathLower.endsWith(".doc") || pathLower.endsWith(".ppt") || pathLower.endsWith(".pptx") || pathLower.endsWith(".xls") || pathLower.endsWith(".xlsx");
|
|
8062
|
+
const isImage = /\.(png|jpg|jpeg|webp|gif|bmp)$/.test(pathLower);
|
|
8063
|
+
const isMultimodalFile = isImage || isPdf || isOfficeFile;
|
|
8064
|
+
const isSupported = aiProvider === "Google" || MULTIMODAL_MODELS.includes(modelName);
|
|
8065
|
+
if (isMultimodalFile && !isSupported) {
|
|
8066
|
+
let terminalWidth = 115;
|
|
8067
|
+
if (process.stdout.isTTY) {
|
|
8068
|
+
terminalWidth = process.stdout.columns - 10 || 120;
|
|
8069
|
+
}
|
|
8070
|
+
const boxLines = [`${isImage ? "\u{1F4F8}" : "\u{1F4C4}"} UNSUPPORTED MODALITY FOR THIS MODEL`];
|
|
8071
|
+
const maxLen = Math.max(...boxLines.map((l) => l.length));
|
|
8072
|
+
const boxWidth = Math.min(maxLen + 4, terminalWidth);
|
|
8073
|
+
const boxTop = `\u256D${"\u2500".repeat(boxWidth)}\u256E`;
|
|
8074
|
+
const boxMid = boxLines.map((line) => `\u2502 ${line.padEnd(boxWidth - 2).substring(0, boxWidth - 2)} \u2502`).join("\n");
|
|
8075
|
+
const boxBottom = `\u2570${"\u2500".repeat(boxWidth)}\u256F`;
|
|
8076
|
+
yield { type: "visual_feedback", content: `${boxTop}
|
|
8077
|
+
${boxMid}
|
|
8078
|
+
${boxBottom}` };
|
|
8079
|
+
continue;
|
|
8080
|
+
}
|
|
8081
|
+
const finalStart = startLine !== null ? startLine : 1;
|
|
8082
|
+
let finalEnd = endLine !== null ? endLine : startLine !== null ? startLine : finalStart + 499;
|
|
8083
|
+
if (finalEnd - finalStart > 500) {
|
|
8084
|
+
finalEnd = finalStart + 500;
|
|
8085
|
+
}
|
|
8086
|
+
const argsStr = `path=${JSON.stringify(filePath)}, startLine=${finalStart}, endLine=${finalEnd}`;
|
|
8087
|
+
const result = await view_file(argsStr, { isMultiModal: isSupported });
|
|
8088
|
+
let isError = false;
|
|
8089
|
+
let textResult = "";
|
|
8090
|
+
let binPart = null;
|
|
8091
|
+
if (typeof result === "string") {
|
|
8092
|
+
if (result.trim().startsWith("ERROR")) {
|
|
8093
|
+
isError = true;
|
|
8094
|
+
} else {
|
|
8095
|
+
textResult = result;
|
|
8096
|
+
}
|
|
8097
|
+
} else if (result && typeof result === "object") {
|
|
8098
|
+
if (result.binaryPart) {
|
|
8099
|
+
binPart = result.binaryPart;
|
|
8100
|
+
textResult = result.text || "";
|
|
8101
|
+
} else {
|
|
8102
|
+
isError = true;
|
|
8103
|
+
}
|
|
8104
|
+
} else {
|
|
8105
|
+
isError = true;
|
|
8106
|
+
}
|
|
8107
|
+
if (!isError) {
|
|
8108
|
+
let label = "";
|
|
8109
|
+
if (isImage) {
|
|
8110
|
+
label = `\u{1F4F8} Viewed: ${filePath}`;
|
|
8111
|
+
attachedBinaryPart = binPart;
|
|
8112
|
+
} else if (isPdf || isOfficeFile) {
|
|
8113
|
+
label = `\u{1F4C4} Viewed: ${filePath}`;
|
|
8114
|
+
attachedBinaryPart = binPart;
|
|
8115
|
+
} else {
|
|
8116
|
+
let totalLines = "...";
|
|
8117
|
+
try {
|
|
8118
|
+
const content = fs20.readFileSync(absPath, "utf8");
|
|
8119
|
+
totalLines = content.split("\n").length;
|
|
8120
|
+
} catch (e) {
|
|
8121
|
+
}
|
|
8122
|
+
label = `\u{1F4C4} Read: ${filePath} \u2192 Lines ${finalStart} - ${Math.min(finalEnd, totalLines)} of ${totalLines}`;
|
|
8123
|
+
taggedContextBlocks.push(textResult);
|
|
8124
|
+
}
|
|
8125
|
+
if (label) {
|
|
8126
|
+
let terminalWidth = 115;
|
|
8127
|
+
if (process.stdout.isTTY) {
|
|
8128
|
+
terminalWidth = process.stdout.columns - 10 || 120;
|
|
8129
|
+
}
|
|
8130
|
+
const boxLines = [label];
|
|
8131
|
+
const maxLen = Math.max(...boxLines.map((l) => l.length));
|
|
8132
|
+
const boxWidth = Math.min(maxLen + 4, terminalWidth);
|
|
8133
|
+
const boxTop = `\u256D${"\u2500".repeat(boxWidth)}\u256E`;
|
|
8134
|
+
const boxMid = boxLines.map((line) => `\u2502 ${line.padEnd(boxWidth - 2).substring(0, boxWidth - 2)} \u2502`).join("\n");
|
|
8135
|
+
const boxBottom = `\u2570${"\u2500".repeat(boxWidth)}\u256F`;
|
|
8136
|
+
yield { type: "visual_feedback", content: `${boxTop}
|
|
8137
|
+
${boxMid}
|
|
8138
|
+
${boxBottom}` };
|
|
8139
|
+
}
|
|
8140
|
+
}
|
|
8141
|
+
}
|
|
8142
|
+
}
|
|
8143
|
+
} catch (e) {
|
|
8144
|
+
}
|
|
8145
|
+
}
|
|
8146
|
+
let taggedContextStr = "";
|
|
8147
|
+
if (taggedContextBlocks.length > 0) {
|
|
8148
|
+
taggedContextStr = "[TAGGED CONTEXT]\n" + taggedContextBlocks.join("\n\n") + "\n[/TAGGED CONTEXT]\n";
|
|
8149
|
+
}
|
|
8031
8150
|
const firstUserMsg = `[SYSTEM METADATA (PRIORITY: DYNAMIC), Chat Context >> Metadata] Time: ${dateTimeStr}
|
|
8032
8151
|
CWD: ${process.cwd()}${cwdMismatch ? ` (WARNING: CWD Mismatch! Previous Path: ${lastCwd})` : ""}
|
|
8033
8152
|
**DIRECTORY STRUCTURE**
|
|
8034
8153
|
${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
|
-
|
|
8154
|
+
${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();
|
|
8155
|
+
const userMsgObj = { role: "user", text: firstUserMsg };
|
|
8156
|
+
if (attachedBinaryPart) {
|
|
8157
|
+
userMsgObj.binaryPart = attachedBinaryPart;
|
|
8158
|
+
}
|
|
8159
|
+
modifiedHistory.push(userMsgObj);
|
|
8037
8160
|
if (activeSummaryBlock && history[history.length - 1]?.id) {
|
|
8038
8161
|
yield { type: "summary_injected", content: { id: history[history.length - 1].id, text: firstUserMsg } };
|
|
8039
8162
|
}
|
|
@@ -8065,14 +8188,25 @@ ${activeSummaryBlock}${thinkingLevel !== "Fast" && thinkingLevel !== "xHigh" &&
|
|
|
8065
8188
|
if (steeringCallback) {
|
|
8066
8189
|
const hint = await steeringCallback();
|
|
8067
8190
|
if (hint) {
|
|
8068
|
-
if (
|
|
8069
|
-
modifiedHistory[modifiedHistory.length - 1].
|
|
8191
|
+
if (hint.startsWith("/btw")) {
|
|
8192
|
+
if (modifiedHistory.length > 0 && modifiedHistory[modifiedHistory.length - 1].role === "user") {
|
|
8193
|
+
modifiedHistory[modifiedHistory.length - 1].text += `
|
|
8070
8194
|
|
|
8071
|
-
[
|
|
8195
|
+
[SYSTEM] USER QUESTION. RESOLVE THIS SPECIFIC QUERY WITHIN '[ANSWER] ... [/ANSWER]' CONCISELY, NATURALLY [/SYSTEM]
|
|
8196
|
+
[QUESTION] ${hint.replace("/btw", "").trim()} [/QUESTION]`;
|
|
8197
|
+
} else {
|
|
8198
|
+
modifiedHistory.push({ role: "user", text: `${thinkingLevel !== "Fast" && thinkingLevel !== "xHigh" && aiProvider === "Google" ? `${modelName.toLowerCase().startsWith("gemma") ? "[SYSTEM] USER QUESTION. RESOLVE THIS SPECIFIC QUERY WITHIN '[ANSWER] ... [/ANSWER]' CONCISELY, NATURALLY\n**STRICTLY FOLLOW THINKING POLICY AS CRITICAL PRIORITY. DO NOT START A RESPONSE WITHOUT <think> ... </think>** [/SYSTEM]\n" : ""}` : ""}[QUESTION] ${hint.replace("/btw", "").trim()} [/QUESTION]` });
|
|
8199
|
+
}
|
|
8072
8200
|
} else {
|
|
8073
|
-
modifiedHistory.
|
|
8201
|
+
if (modifiedHistory.length > 0 && modifiedHistory[modifiedHistory.length - 1].role === "user") {
|
|
8202
|
+
modifiedHistory[modifiedHistory.length - 1].text += `
|
|
8203
|
+
|
|
8204
|
+
[STEERING HINT] ${hint.trim()} [/STEERING HINT]`;
|
|
8205
|
+
} else {
|
|
8206
|
+
modifiedHistory.push({ role: "user", text: `${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" : ""}` : ""}[STEERING HINT] ${hint.trim()} [/STEERING HINT]` });
|
|
8207
|
+
}
|
|
8074
8208
|
}
|
|
8075
|
-
yield { type: "status", content: "Steering Hint Injected
|
|
8209
|
+
yield { type: "status", content: `${hint.startsWith("/btw") ? "Question Forwarded..." : "Steering Hint Injected..."}` };
|
|
8076
8210
|
}
|
|
8077
8211
|
}
|
|
8078
8212
|
let stream;
|
|
@@ -8198,13 +8332,15 @@ ${activeSummaryBlock}${thinkingLevel !== "Fast" && thinkingLevel !== "xHigh" &&
|
|
|
8198
8332
|
currentSystemInstruction = getSystemInstruction(profile, !(targetModel || "gemma").toLowerCase().startsWith("gemma") ? "GEM" : thinkingLevel, mode, systemSettings, isMemoryEnabled, isFirstPrompt, aiProvider, isMultiModal);
|
|
8199
8333
|
const lastUserMsg = contents[contents.length - 1];
|
|
8200
8334
|
if (isBridgeConnected()) {
|
|
8201
|
-
|
|
8335
|
+
yield { type: "status", content: "Checking Code..." };
|
|
8336
|
+
await new Promise((resolve) => setTimeout(resolve, 2500));
|
|
8202
8337
|
const ideCtxJIT = await getIDEContext();
|
|
8203
8338
|
const ideErr = ideCtxJIT ? ideCtxJIT.diagnostics : null;
|
|
8204
8339
|
if (ideErr && lastUserMsg && lastUserMsg.role === "user" && lastUserMsg.parts?.[0]?.text) {
|
|
8205
8340
|
lastUserMsg.parts[0].text += `
|
|
8206
8341
|
${ideErr} [/ERROR]`;
|
|
8207
8342
|
}
|
|
8343
|
+
yield { type: "status", content: "Working..." };
|
|
8208
8344
|
}
|
|
8209
8345
|
const isGemma = modelName && modelName.toLowerCase().startsWith("gemma") && aiProvider === "Google";
|
|
8210
8346
|
if (isGemma) {
|
|
@@ -8353,14 +8489,14 @@ ${ideErr} [/ERROR]`;
|
|
|
8353
8489
|
{ type: "end", idx: endIdx, start: "[[END]]", end: "[[END]]" }
|
|
8354
8490
|
].filter((i) => i.idx !== -1).sort((a, b) => a.idx - b.idx);
|
|
8355
8491
|
if (indices.length > 0) {
|
|
8356
|
-
const
|
|
8357
|
-
if (
|
|
8358
|
-
msgs.push({ type: "text", content: remaining.substring(0,
|
|
8492
|
+
const match2 = indices[0];
|
|
8493
|
+
if (match2.idx > 0) {
|
|
8494
|
+
msgs.push({ type: "text", content: remaining.substring(0, match2.idx) });
|
|
8359
8495
|
}
|
|
8360
8496
|
isBufferingToolCall = true;
|
|
8361
|
-
activeBufferType =
|
|
8497
|
+
activeBufferType = match2.type;
|
|
8362
8498
|
toolCallBuffer = "";
|
|
8363
|
-
remaining = remaining.substring(
|
|
8499
|
+
remaining = remaining.substring(match2.idx);
|
|
8364
8500
|
} else {
|
|
8365
8501
|
const potentialStarts = ["[tool", "[[END]]"];
|
|
8366
8502
|
let splitPoint = -1;
|
|
@@ -8763,12 +8899,112 @@ ${ideErr} [/ERROR]`;
|
|
|
8763
8899
|
if (command && settings.systemSettings && settings.systemSettings.allowExternalAccess === false) {
|
|
8764
8900
|
const riskyPatterns = [/[a-zA-Z]:[\\\/]/i, /^\//, /\.\.[\\\/]/, /\/etc\//, /\/var\//, /\/root\//, /\/bin\//, /\/usr\//];
|
|
8765
8901
|
const currentDrive = path19.resolve(process.cwd()).substring(0, 3).toLowerCase();
|
|
8766
|
-
const
|
|
8767
|
-
|
|
8768
|
-
|
|
8769
|
-
|
|
8902
|
+
const splitCommands = (cmdString) => {
|
|
8903
|
+
const commands = [];
|
|
8904
|
+
let current = "";
|
|
8905
|
+
let inQuote = null;
|
|
8906
|
+
for (let i = 0; i < cmdString.length; i++) {
|
|
8907
|
+
const char = cmdString[i];
|
|
8908
|
+
if (inQuote) {
|
|
8909
|
+
if (char === inQuote) inQuote = null;
|
|
8910
|
+
current += char;
|
|
8911
|
+
} else {
|
|
8912
|
+
if (char === '"' || char === "'") {
|
|
8913
|
+
inQuote = char;
|
|
8914
|
+
current += char;
|
|
8915
|
+
} else if (char === "&" && cmdString[i + 1] === "&" || char === "|" && cmdString[i + 1] === "|") {
|
|
8916
|
+
if (current.trim()) {
|
|
8917
|
+
commands.push(current.trim());
|
|
8918
|
+
current = "";
|
|
8919
|
+
}
|
|
8920
|
+
i++;
|
|
8921
|
+
} else if (char === ";" || char === "|" || char === "&") {
|
|
8922
|
+
if (current.trim()) {
|
|
8923
|
+
commands.push(current.trim());
|
|
8924
|
+
current = "";
|
|
8925
|
+
}
|
|
8926
|
+
} else {
|
|
8927
|
+
current += char;
|
|
8928
|
+
}
|
|
8929
|
+
}
|
|
8770
8930
|
}
|
|
8771
|
-
|
|
8931
|
+
if (current.trim()) {
|
|
8932
|
+
commands.push(current.trim());
|
|
8933
|
+
}
|
|
8934
|
+
return commands;
|
|
8935
|
+
};
|
|
8936
|
+
const tokenizeCommand = (cmd) => {
|
|
8937
|
+
const tokens = [];
|
|
8938
|
+
let current = "";
|
|
8939
|
+
let inQuote = null;
|
|
8940
|
+
for (let i = 0; i < cmd.length; i++) {
|
|
8941
|
+
const char = cmd[i];
|
|
8942
|
+
if (inQuote) {
|
|
8943
|
+
if (char === inQuote) {
|
|
8944
|
+
inQuote = null;
|
|
8945
|
+
current += char;
|
|
8946
|
+
} else {
|
|
8947
|
+
current += char;
|
|
8948
|
+
}
|
|
8949
|
+
} else {
|
|
8950
|
+
if (char === '"' || char === "'") {
|
|
8951
|
+
inQuote = char;
|
|
8952
|
+
current += char;
|
|
8953
|
+
} else if (/\s/.test(char)) {
|
|
8954
|
+
if (current) {
|
|
8955
|
+
tokens.push(current);
|
|
8956
|
+
current = "";
|
|
8957
|
+
}
|
|
8958
|
+
} else {
|
|
8959
|
+
current += char;
|
|
8960
|
+
}
|
|
8961
|
+
}
|
|
8962
|
+
}
|
|
8963
|
+
if (current) {
|
|
8964
|
+
tokens.push(current);
|
|
8965
|
+
}
|
|
8966
|
+
return tokens;
|
|
8967
|
+
};
|
|
8968
|
+
const checkToken = (token) => {
|
|
8969
|
+
const cleanToken = token.replace(/^['"]|['"]$/g, "").trim();
|
|
8970
|
+
if (!cleanToken) return false;
|
|
8971
|
+
if (process.platform === "win32" && /^\/[a-zA-Z0-9?]+$/.test(cleanToken)) {
|
|
8972
|
+
return false;
|
|
8973
|
+
}
|
|
8974
|
+
return riskyPatterns.some((pattern) => {
|
|
8975
|
+
if (pattern.source === "[a-zA-Z]:[\\\\\\/]") {
|
|
8976
|
+
const driveMatch = cleanToken.match(/[a-zA-Z]:[\\\/]/i);
|
|
8977
|
+
return driveMatch && driveMatch[0].toLowerCase() !== currentDrive;
|
|
8978
|
+
}
|
|
8979
|
+
return pattern.test(cleanToken);
|
|
8980
|
+
});
|
|
8981
|
+
};
|
|
8982
|
+
const commandParts = splitCommands(command);
|
|
8983
|
+
const isViolating = commandParts.some((cmdPart) => {
|
|
8984
|
+
const tokens = tokenizeCommand(cmdPart);
|
|
8985
|
+
if (tokens.length === 0) return false;
|
|
8986
|
+
const exe = tokens[0].replace(/^['"]|['"]$/g, "").toLowerCase();
|
|
8987
|
+
const isSafePrint = ["echo", "printf", "write-output"].includes(exe);
|
|
8988
|
+
if (isSafePrint) {
|
|
8989
|
+
let checkNext = false;
|
|
8990
|
+
return tokens.some((token) => {
|
|
8991
|
+
const clean = token.replace(/^['"]|['"]$/g, "");
|
|
8992
|
+
if (clean === ">" || clean === ">>" || clean === "<") {
|
|
8993
|
+
checkNext = true;
|
|
8994
|
+
return false;
|
|
8995
|
+
}
|
|
8996
|
+
if (clean.startsWith(">") || clean.startsWith("<")) {
|
|
8997
|
+
const pathPart = clean.replace(/^[><]+/, "");
|
|
8998
|
+
return checkToken(pathPart);
|
|
8999
|
+
}
|
|
9000
|
+
if (checkNext) {
|
|
9001
|
+
checkNext = false;
|
|
9002
|
+
return checkToken(token);
|
|
9003
|
+
}
|
|
9004
|
+
return false;
|
|
9005
|
+
});
|
|
9006
|
+
}
|
|
9007
|
+
return tokens.some((token) => checkToken(token));
|
|
8772
9008
|
});
|
|
8773
9009
|
if (isViolating) {
|
|
8774
9010
|
const denyMsg = `Access Denied. Terminal is prohibited from accessing system drives (C://) or external directories while "External Workspace Access" is disabled.`;
|
|
@@ -10919,6 +11155,28 @@ function App({ args = [] }) {
|
|
|
10919
11155
|
return msgs;
|
|
10920
11156
|
});
|
|
10921
11157
|
const queuedPromptRef = useRef3(null);
|
|
11158
|
+
const [btwResponse, setBtwResponse] = useState11("");
|
|
11159
|
+
const [showBtwBox, setShowBtwBox] = useState11(false);
|
|
11160
|
+
const btwResponseRef = useRef3("");
|
|
11161
|
+
const btwClosedRef = useRef3(null);
|
|
11162
|
+
useEffect8(() => {
|
|
11163
|
+
if (messages.length === 0) return;
|
|
11164
|
+
const lastMsg = messages[messages.length - 1];
|
|
11165
|
+
if (lastMsg && (lastMsg.role === "agent" || lastMsg.role === "assistant")) {
|
|
11166
|
+
const text = lastMsg.text || "";
|
|
11167
|
+
const match = text.match(/\[ANSWER\]([\s\S]*?)(?:\[\/ANSWER\]|$)/i);
|
|
11168
|
+
if (match) {
|
|
11169
|
+
const content = match[1].trim();
|
|
11170
|
+
if (content && content !== btwResponseRef.current) {
|
|
11171
|
+
setBtwResponse(content);
|
|
11172
|
+
btwResponseRef.current = content;
|
|
11173
|
+
if (btwClosedRef.current !== lastMsg.id) {
|
|
11174
|
+
setShowBtwBox(true);
|
|
11175
|
+
}
|
|
11176
|
+
}
|
|
11177
|
+
}
|
|
11178
|
+
}
|
|
11179
|
+
}, [messages]);
|
|
10922
11180
|
const [completedIndex, setCompletedIndex] = useState11(messages.length);
|
|
10923
11181
|
const windowedHistory = useMemo2(() => {
|
|
10924
11182
|
const MAX_HISTORY_LINES = 2e3;
|
|
@@ -11029,6 +11287,16 @@ function App({ args = [] }) {
|
|
|
11029
11287
|
return;
|
|
11030
11288
|
}
|
|
11031
11289
|
if (key.escape) {
|
|
11290
|
+
if (showBtwBox) {
|
|
11291
|
+
setShowBtwBox(false);
|
|
11292
|
+
if (messages.length > 0) {
|
|
11293
|
+
const lastMsg = messages[messages.length - 1];
|
|
11294
|
+
if (lastMsg) {
|
|
11295
|
+
btwClosedRef.current = lastMsg.id;
|
|
11296
|
+
}
|
|
11297
|
+
}
|
|
11298
|
+
return;
|
|
11299
|
+
}
|
|
11032
11300
|
if (suggestions.length > 0 && activeView === "chat") {
|
|
11033
11301
|
setIsFilePickerDismissed(true);
|
|
11034
11302
|
return;
|
|
@@ -11415,6 +11683,7 @@ function App({ args = [] }) {
|
|
|
11415
11683
|
{ cmd: "/save", desc: "Force save current chat" },
|
|
11416
11684
|
{ cmd: "/export", desc: "Export current chat in a .txt file" },
|
|
11417
11685
|
{ cmd: "/chats", desc: "List all chat sessions" },
|
|
11686
|
+
{ cmd: "/btw", desc: "Ask a question without intefering with ongoing tasks" },
|
|
11418
11687
|
// {
|
|
11419
11688
|
// cmd: '/image', desc: 'Generate images using Pollinations', subs: [
|
|
11420
11689
|
// {
|
|
@@ -11711,7 +11980,17 @@ function App({ args = [] }) {
|
|
|
11711
11980
|
if (!absoluteClean.trim()) return;
|
|
11712
11981
|
if (isProcessing) {
|
|
11713
11982
|
const hintText = absoluteClean.trim();
|
|
11714
|
-
if (hintText.startsWith("/")) {
|
|
11983
|
+
if (hintText.startsWith("/btw")) {
|
|
11984
|
+
const question = hintText.replace(/^\/btw\s*/, "").trim();
|
|
11985
|
+
if (question.length <= 3) {
|
|
11986
|
+
setMessages((prev) => {
|
|
11987
|
+
setCompletedIndex(prev.length + 1);
|
|
11988
|
+
return [...prev, { id: "hint-err-" + Date.now(), role: "system", text: "[RESTRICTED] Inquiry question must be more than 3 characters.", isMeta: true }];
|
|
11989
|
+
});
|
|
11990
|
+
setInput("");
|
|
11991
|
+
return;
|
|
11992
|
+
}
|
|
11993
|
+
} else if (hintText.startsWith("/")) {
|
|
11715
11994
|
setMessages((prev) => {
|
|
11716
11995
|
setCompletedIndex(prev.length + 1);
|
|
11717
11996
|
return [...prev, { id: "hint-err-" + Date.now(), role: "system", text: "[RESTRICTED] Steering Hints cannot start with /", isMeta: true }];
|
|
@@ -11723,8 +12002,11 @@ function App({ args = [] }) {
|
|
|
11723
12002
|
queuedPromptRef.current = hintText;
|
|
11724
12003
|
setMessages((prev) => {
|
|
11725
12004
|
setCompletedIndex(prev.length + 1);
|
|
11726
|
-
|
|
11727
|
-
|
|
12005
|
+
const isBtw = hintText.startsWith("/btw");
|
|
12006
|
+
const cleanText = isBtw ? hintText.replace(/^\/btw\s*/, "") : hintText;
|
|
12007
|
+
const prefix = isBtw ? "[QUESTION: QUEUED]" : "[STEERING HINT: QUEUED]";
|
|
12008
|
+
return [...prev, { id: "hint-" + Date.now(), role: "user", text: `${prefix}
|
|
12009
|
+
${cleanText}`, color: "magenta" }];
|
|
11728
12010
|
});
|
|
11729
12011
|
setInput("");
|
|
11730
12012
|
return;
|
|
@@ -12497,13 +12779,19 @@ Selection: ${val}`,
|
|
|
12497
12779
|
setQueuedPrompt(null);
|
|
12498
12780
|
queuedPromptRef.current = null;
|
|
12499
12781
|
setMessages((prev) => {
|
|
12500
|
-
const index = [...prev].reverse().findIndex((m) => m.text?.includes("[STEERING HINT: QUEUED]"));
|
|
12782
|
+
const index = [...prev].reverse().findIndex((m) => m.text?.includes("[STEERING HINT: QUEUED]") || m.text?.includes("[QUESTION: QUEUED]"));
|
|
12501
12783
|
if (index !== -1) {
|
|
12502
12784
|
const actualIndex = prev.length - 1 - index;
|
|
12503
12785
|
const newMsgs = [...prev];
|
|
12786
|
+
let text = newMsgs[actualIndex].text;
|
|
12787
|
+
if (text.includes("[STEERING HINT: QUEUED]")) {
|
|
12788
|
+
text = text.replace("[STEERING HINT: QUEUED]", "[STEERING HINT: INJECTED]");
|
|
12789
|
+
} else if (text.includes("[QUESTION: QUEUED]")) {
|
|
12790
|
+
text = text.replace("[QUESTION: QUEUED]", "[QUESTION: ASKED]");
|
|
12791
|
+
}
|
|
12504
12792
|
newMsgs[actualIndex] = {
|
|
12505
12793
|
...newMsgs[actualIndex],
|
|
12506
|
-
text
|
|
12794
|
+
text,
|
|
12507
12795
|
color: "cyan"
|
|
12508
12796
|
};
|
|
12509
12797
|
return newMsgs;
|
|
@@ -12594,7 +12882,7 @@ Selection: ${val}`,
|
|
|
12594
12882
|
}
|
|
12595
12883
|
if (packet.type === "visual_feedback") {
|
|
12596
12884
|
setMessages((prev) => [...prev, {
|
|
12597
|
-
id: "feedback-" + Date.now(),
|
|
12885
|
+
id: "feedback-" + Date.now() + "-" + Math.random().toString(36).substring(2, 9),
|
|
12598
12886
|
role: "system",
|
|
12599
12887
|
text: packet.content,
|
|
12600
12888
|
isVisualFeedback: true
|
|
@@ -12721,11 +13009,26 @@ Selection: ${val}`,
|
|
|
12721
13009
|
const hasThinkTag = chunkLower.includes("<think") || chunkLower.includes("<thought");
|
|
12722
13010
|
const canThink = !inThinkMode && !inCodeBlock && !inToolCall && !thinkConsumedInTurn;
|
|
12723
13011
|
if (hasThinkTag && canThink) {
|
|
13012
|
+
const match = chunkText.match(/<(think|thought)/i);
|
|
13013
|
+
const tagIndex = match.index;
|
|
13014
|
+
const beforeText = chunkText.substring(0, tagIndex);
|
|
13015
|
+
const afterText = chunkText.substring(tagIndex);
|
|
13016
|
+
if (beforeText) {
|
|
13017
|
+
if (!currentAgentId) {
|
|
13018
|
+
currentAgentId = "agent-" + Date.now();
|
|
13019
|
+
setMessages((prev) => [...prev, { id: currentAgentId, role: "agent", text: beforeText, isStreaming: true }]);
|
|
13020
|
+
} else {
|
|
13021
|
+
setMessages((prev) => prev.map(
|
|
13022
|
+
(m) => m.id === currentAgentId ? { ...m, text: m.text + beforeText, isStreaming: true } : m
|
|
13023
|
+
));
|
|
13024
|
+
}
|
|
13025
|
+
}
|
|
12724
13026
|
inThinkMode = true;
|
|
12725
13027
|
thinkConsumedInTurn = true;
|
|
12726
|
-
|
|
13028
|
+
let thinkStartText = afterText.replace(/<(think|thought)>/gi, "");
|
|
12727
13029
|
currentThinkId = "think-" + Date.now();
|
|
12728
|
-
setMessages((prev) => [...prev, { id: currentThinkId, role: "think", text:
|
|
13030
|
+
setMessages((prev) => [...prev, { id: currentThinkId, role: "think", text: thinkStartText, isStreaming: true, startTime: Date.now() }]);
|
|
13031
|
+
continue;
|
|
12729
13032
|
}
|
|
12730
13033
|
if ((chunkLower.includes("</think>") || chunkLower.includes("</thought>")) && currentThinkId) {
|
|
12731
13034
|
const parts = chunkText.split(/<\/(think|thought)>/gi);
|
|
@@ -12810,9 +13113,13 @@ Selection: ${val}`,
|
|
|
12810
13113
|
queuedPromptRef.current = null;
|
|
12811
13114
|
setMessages((prev) => {
|
|
12812
13115
|
const newMsgs = [...prev];
|
|
12813
|
-
const hintMsg = newMsgs.reverse().find((m) => m.text?.includes("[STEERING HINT: QUEUED]"));
|
|
13116
|
+
const hintMsg = newMsgs.reverse().find((m) => m.text?.includes("[STEERING HINT: QUEUED]") || m.text?.includes("[QUESTION: QUEUED]"));
|
|
12814
13117
|
if (hintMsg) {
|
|
12815
|
-
|
|
13118
|
+
if (hintMsg.text.includes("[STEERING HINT: QUEUED]")) {
|
|
13119
|
+
hintMsg.text = hintMsg.text.replace("[STEERING HINT: QUEUED]", "[STEERING HINT: FINISHED_TURN]");
|
|
13120
|
+
} else if (hintMsg.text.includes("[QUESTION: QUEUED]")) {
|
|
13121
|
+
hintMsg.text = hintMsg.text.replace("[QUESTION: QUEUED]", "[QUESTION: FINISHED_TURN]");
|
|
13122
|
+
}
|
|
12816
13123
|
}
|
|
12817
13124
|
return newMsgs.reverse();
|
|
12818
13125
|
});
|
|
@@ -13295,7 +13602,7 @@ Selection: ${val}`,
|
|
|
13295
13602
|
}
|
|
13296
13603
|
));
|
|
13297
13604
|
case "keybindingsPrompt":
|
|
13298
|
-
return /* @__PURE__ */ React14.createElement(Box14, { flexDirection: "column", borderStyle: "round", borderColor: "
|
|
13605
|
+
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
13606
|
CommandMenu,
|
|
13300
13607
|
{
|
|
13301
13608
|
title: "Add Keybinding?",
|
|
@@ -13482,7 +13789,7 @@ Selection: ${val}`,
|
|
|
13482
13789
|
}
|
|
13483
13790
|
)));
|
|
13484
13791
|
default:
|
|
13485
|
-
return /* @__PURE__ */ React14.createElement(Box14, { flexDirection: "column", marginTop: 1, flexShrink: 0, width: "100%" }, /* @__PURE__ */ React14.createElement(Box14, { paddingX: 1, marginBottom: 0, justifyContent: "space-between", width: "100%" }, /* @__PURE__ */ React14.createElement(Box14, null, statusText ? /* @__PURE__ */ React14.createElement(Box14, null, /* @__PURE__ */ React14.createElement(Text14, { color: "gray", bold: true, italic: true }, statusText)) : /* @__PURE__ */ React14.createElement(Text14, { color: "gray", italic: true }, input.length > 0 && escPressCount ? "Press ESC again to clear input" : "Waiting for input...")), /* @__PURE__ */ React14.createElement(Box14, null, wittyPhrase && /* @__PURE__ */ React14.createElement(Text14, { color: "gray", italic: true }, wittyPhrase, " "), /* @__PURE__ */ React14.createElement(Text14, { color: "gray", bold: true }, "[ "), /* @__PURE__ */ React14.createElement(Text14, { color: "white" }, tempModelOverride || activeModel), /* @__PURE__ */ React14.createElement(Text14, { color: "gray", bold: true }, " ]"))), /* @__PURE__ */ React14.createElement(Box14, { flexDirection: "column", width: "100%" }, /* @__PURE__ */ React14.createElement(Box14, { width: "100%", height: 1, overflow: "hidden" }, /* @__PURE__ */ React14.createElement(Text14, { color: "#555555" }, "\u2584".repeat(Math.max(1, terminalSize.columns)))), /* @__PURE__ */ React14.createElement(
|
|
13792
|
+
return /* @__PURE__ */ React14.createElement(Box14, { flexDirection: "column", marginTop: 1, flexShrink: 0, width: "100%" }, showBtwBox && btwResponse && /* @__PURE__ */ React14.createElement(Box14, { flexDirection: "column", borderStyle: "round", borderColor: "grey", paddingX: 2, paddingY: 1, width: "100%", marginBottom: 1 }, /* @__PURE__ */ React14.createElement(Box14, { justifyContent: "space-between", width: "100%" }, /* @__PURE__ */ React14.createElement(Text14, { color: "white", bold: true, underline: true }, "INQUIRY RESPONSE"), /* @__PURE__ */ React14.createElement(Text14, { color: "gray" }, "[ ESC to Close ]")), /* @__PURE__ */ React14.createElement(Box14, { marginTop: 1, width: "100%" }, /* @__PURE__ */ React14.createElement(CodeRenderer, { text: btwResponse, columns: terminalSize.columns - 6 }))), /* @__PURE__ */ React14.createElement(Box14, { paddingX: 1, marginBottom: 0, justifyContent: "space-between", width: "100%" }, /* @__PURE__ */ React14.createElement(Box14, null, statusText ? /* @__PURE__ */ React14.createElement(Box14, null, /* @__PURE__ */ React14.createElement(Text14, { color: "gray", bold: true, italic: true }, statusText)) : /* @__PURE__ */ React14.createElement(Text14, { color: "gray", italic: true }, input.length > 0 && escPressCount ? "Press ESC again to clear input" : "Waiting for input...")), /* @__PURE__ */ React14.createElement(Box14, null, wittyPhrase && /* @__PURE__ */ React14.createElement(Text14, { color: "gray", italic: true }, wittyPhrase, " "), /* @__PURE__ */ React14.createElement(Text14, { color: "gray", bold: true }, "[ "), /* @__PURE__ */ React14.createElement(Text14, { color: "white" }, tempModelOverride || activeModel), /* @__PURE__ */ React14.createElement(Text14, { color: "gray", bold: true }, " ]"))), /* @__PURE__ */ React14.createElement(Box14, { flexDirection: "column", width: "100%" }, /* @__PURE__ */ React14.createElement(Box14, { width: "100%", height: 1, overflow: "hidden" }, /* @__PURE__ */ React14.createElement(Text14, { color: "#555555" }, "\u2584".repeat(Math.max(1, terminalSize.columns)))), /* @__PURE__ */ React14.createElement(
|
|
13486
13793
|
Box14,
|
|
13487
13794
|
{
|
|
13488
13795
|
backgroundColor: "#555555",
|
|
@@ -13758,7 +14065,7 @@ var init_app = __esm({
|
|
|
13758
14065
|
height
|
|
13759
14066
|
},
|
|
13760
14067
|
/* @__PURE__ */ React14.createElement(Box14, { marginBottom: 1, width: Math.min(80, width - 4), justifyContent: "flex-start" }, /* @__PURE__ */ React14.createElement(Text14, null, getFluxLogo(versionFluxflow))),
|
|
13761
|
-
/* @__PURE__ */ React14.createElement(Box14, { flexDirection: "column", borderStyle: "double", borderColor: "grey", paddingX: 3, paddingY: 1, width: Math.min(80, width - 4) }, /* @__PURE__ */ React14.createElement(Text14, { bold: true, color: "white", textAlign: "center" }, "\u{1F680} UPGRADE YOUR WORKFLOW"), /* @__PURE__ */ React14.createElement(Box14, { marginY: 1, flexDirection: "column", alignItems: "left" }, /* @__PURE__ */ React14.createElement(Text14, null, "You're in ", /* @__PURE__ */ React14.createElement(Text14, { bold: true, color: "cyan" }, ideName), ", but the ", /* @__PURE__ */ React14.createElement(Text14, { bold: true, color: "white" }, "FluxFlow-CLI Companion"), " is not installed."), /* @__PURE__ */ React14.createElement(Box14, { flexDirection: "column", marginY: 1 }, /* @__PURE__ */ React14.createElement(Text14, { color: "gray" }, " \u2705 Real-time
|
|
14068
|
+
/* @__PURE__ */ React14.createElement(Box14, { flexDirection: "column", borderStyle: "double", borderColor: "grey", paddingX: 3, paddingY: 1, width: Math.min(80, width - 4) }, /* @__PURE__ */ React14.createElement(Text14, { bold: true, color: "white", textAlign: "center" }, "\u{1F680} UPGRADE YOUR WORKFLOW"), /* @__PURE__ */ React14.createElement(Box14, { marginY: 1, flexDirection: "column", alignItems: "left" }, /* @__PURE__ */ React14.createElement(Text14, null, "You're in ", /* @__PURE__ */ React14.createElement(Text14, { bold: true, color: "cyan" }, ideName), ", but the ", /* @__PURE__ */ React14.createElement(Text14, { bold: true, color: "white" }, "FluxFlow-CLI Companion"), " is not installed."), /* @__PURE__ */ React14.createElement(Box14, { flexDirection: "column", marginY: 1 }, /* @__PURE__ */ React14.createElement(Text14, { color: "gray" }, " \u2705 Real-time IDE context & Error Resolution"), /* @__PURE__ */ React14.createElement(Text14, { color: "gray" }, " \u2705 Auto-open files created by agent"), /* @__PURE__ */ React14.createElement(Text14, { color: "gray" }, " \u2705 Native DIFFing for AI edits"), /* @__PURE__ */ React14.createElement(Text14, { color: "gray" }, " \u2705 Direct IDE context sharing"), /* @__PURE__ */ React14.createElement(Text14, { color: "gray" }, " \u2705 Surgical Diagnostic Sync"), /* @__PURE__ */ React14.createElement(Text14, { color: "gray" }, " \u2705 Native Right-Click \u276F Chat integration"), /* @__PURE__ */ React14.createElement(Text14, { color: "gray" }, " \u2705 Live Status in IDE"), /* @__PURE__ */ React14.createElement(Text14, { color: "gray" }, " \u2705 Clickable terminal-to-code links"))), /* @__PURE__ */ React14.createElement(Box14, { flexDirection: "column", marginTop: 1 }, options.map((opt, i) => /* @__PURE__ */ React14.createElement(Box14, { key: i }, /* @__PURE__ */ React14.createElement(Text14, { color: selectedIndex === i ? "yellow" : "white", bold: selectedIndex === i }, selectedIndex === i ? " \u276F " : " ", opt.label)))), /* @__PURE__ */ React14.createElement(Box14, { marginTop: 1, alignItems: "center", justifyContent: "center" }, /* @__PURE__ */ React14.createElement(Text14, { dimColor: true, italic: true }, "(Use arrows to navigate, Enter to select)")))
|
|
13762
14069
|
);
|
|
13763
14070
|
};
|
|
13764
14071
|
SESSION_START_TIME = Date.now();
|
|
@@ -13770,7 +14077,7 @@ var init_app = __esm({
|
|
|
13770
14077
|
packageJson = JSON.parse(fs22.readFileSync(packageJsonPath, "utf8"));
|
|
13771
14078
|
versionFluxflow = packageJson.version;
|
|
13772
14079
|
updatedOn = packageJson.date || "2026-05-20";
|
|
13773
|
-
ResolutionModal = ({ data, onResolve, onEdit }) => /* @__PURE__ */ React14.createElement(Box14, { flexDirection: "column", borderStyle: "round", borderColor: "
|
|
14080
|
+
ResolutionModal = ({ data, onResolve, onEdit }) => /* @__PURE__ */ React14.createElement(Box14, { flexDirection: "column", borderStyle: "round", borderColor: "grey", padding: 0, width: "100%" }, /* @__PURE__ */ React14.createElement(Box14, { paddingX: 1 }, /* @__PURE__ */ React14.createElement(Text14, { color: "white", bold: true, underline: true }, data.startsWith("/btw") ? "QUESTION" : "STEERING HINT", " RESOLUTION")), /* @__PURE__ */ React14.createElement(Box14, { paddingX: 1, marginTop: 1 }, /* @__PURE__ */ React14.createElement(Text14, null, "The agent already finished the task before your ", data.startsWith("/btw") ? "question" : "hint", " was consumed.")), /* @__PURE__ */ React14.createElement(Box14, { marginTop: 1, backgroundColor: "#222", paddingX: 2, width: "100%" }, /* @__PURE__ */ React14.createElement(Text14, { italic: true, color: "gray" }, '"', data.replace("/btw", "").trim(), '"')), /* @__PURE__ */ React14.createElement(Box14, { paddingX: 1, marginTop: 1 }, /* @__PURE__ */ React14.createElement(Text14, { color: "grey" }, "How would you like to proceed?")), /* @__PURE__ */ React14.createElement(Box14, { marginTop: 0 }, /* @__PURE__ */ React14.createElement(
|
|
13774
14081
|
CommandMenu,
|
|
13775
14082
|
{
|
|
13776
14083
|
title: "Select Action",
|
|
@@ -13954,6 +14261,7 @@ if (isBundled && !process.execArgv.some((arg) => arg.includes("max-old-space-siz
|
|
|
13954
14261
|
/save Force save current chat
|
|
13955
14262
|
/export Export current chat in a .txt file
|
|
13956
14263
|
/chats List all chat sessions
|
|
14264
|
+
/btw <question> Send raw inquiry to the agent mid-turn
|
|
13957
14265
|
/image setup key <default|custom> Configure image API key strategy
|
|
13958
14266
|
/image setup quality <low...premium> Configure default image generation quality
|
|
13959
14267
|
/image stats Show image quota stats
|