fluxflow-cli 2.8.9 → 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.
Files changed (2) hide show
  1. package/dist/fluxflow.js +143 -23
  2. 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: "red", padding: 0, width: "100%" }, /* @__PURE__ */ React3.createElement(Box3, { paddingX: 1, backgroundColor: "#3a0000" }, /* @__PURE__ */ React3.createElement(Text3, { color: "red", bold: true }, msg.text)), /* @__PURE__ */ React3.createElement(Box3, { paddingX: 1, marginTop: 0, marginBottom: 0 }, /* @__PURE__ */ React3.createElement(Text3, { color: "white" }, msg.subText))));
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` : `No Multimodal support`}` : `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**
@@ -4922,9 +4922,7 @@ ${tail}`;
4922
4922
 
4923
4923
  - Stats: [${verifiedLineCount} lines, ${(verifiedSize / 1024).toFixed(1)} KB]
4924
4924
  ${ancestry}- Content Preview:
4925
- ${snippet}
4926
-
4927
- [SYSTEM] Check the content preview for verification [/SYSTEM]`;
4925
+ ${snippet}`;
4928
4926
  } catch (err) {
4929
4927
  const errorMsg = err instanceof Error ? err.message : String(err);
4930
4928
  return `ERROR: Failed to write file [${targetPath}]: ${errorMsg}`;
@@ -6372,6 +6370,7 @@ var init_ai = __esm({
6372
6370
  await init_tools();
6373
6371
  init_crypto();
6374
6372
  init_arg_parser();
6373
+ init_view_file();
6375
6374
  init_terminal();
6376
6375
  init_text();
6377
6376
  init_paths();
@@ -8030,12 +8029,133 @@ ${ideCtx.warnings}
8030
8029
  }
8031
8030
  }
8032
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
+ }
8033
8149
  const firstUserMsg = `[SYSTEM METADATA (PRIORITY: DYNAMIC), Chat Context >> Metadata] Time: ${dateTimeStr}
8034
8150
  CWD: ${process.cwd()}${cwdMismatch ? ` (WARNING: CWD Mismatch! Previous Path: ${lastCwd})` : ""}
8035
8151
  **DIRECTORY STRUCTURE**
8036
8152
  ${dirStructure}${memoryPrompt}${ideBlock}
8037
- ${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>**\n[/SYSTEM]\n" : ""}` : ""}[USER] ${cleanAgentText.trim()} [/USER]`.trim();
8038
- modifiedHistory.push({ role: "user", text: firstUserMsg });
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);
8039
8159
  if (activeSummaryBlock && history[history.length - 1]?.id) {
8040
8160
  yield { type: "summary_injected", content: { id: history[history.length - 1].id, text: firstUserMsg } };
8041
8161
  }
@@ -8057,7 +8177,7 @@ ${activeSummaryBlock}${thinkingLevel !== "Fast" && thinkingLevel !== "xHigh" &&
8057
8177
  modifiedHistory = getTruncatedHistory(modifiedHistory, 6);
8058
8178
  }
8059
8179
  if (loop > 0) {
8060
- yield { type: "status", content: "Working...." };
8180
+ yield { type: "status", content: "Working..." };
8061
8181
  }
8062
8182
  if (TERMINATION_SIGNAL) {
8063
8183
  yield { type: "status", content: "Request Cancelled" };
@@ -8072,7 +8192,7 @@ ${activeSummaryBlock}${thinkingLevel !== "Fast" && thinkingLevel !== "xHigh" &&
8072
8192
 
8073
8193
  [STEERING HINT]: ${hint}`;
8074
8194
  } else {
8075
- 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>**\n[/SYSTEM]\n" : ""}` : ""}[STEERING HINT]: ${hint}` });
8195
+ 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}` });
8076
8196
  }
8077
8197
  yield { type: "status", content: "Steering Hint Injected." };
8078
8198
  }
@@ -8205,13 +8325,13 @@ ${activeSummaryBlock}${thinkingLevel !== "Fast" && thinkingLevel !== "xHigh" &&
8205
8325
  const ideErr = ideCtxJIT ? ideCtxJIT.diagnostics : null;
8206
8326
  if (ideErr && lastUserMsg && lastUserMsg.role === "user" && lastUserMsg.parts?.[0]?.text) {
8207
8327
  lastUserMsg.parts[0].text += `
8208
- [COMPILE ERROR] ${ideErr} [/ERROR]`;
8328
+ ${ideErr} [/ERROR]`;
8209
8329
  }
8210
8330
  }
8211
8331
  const isGemma = modelName && modelName.toLowerCase().startsWith("gemma") && aiProvider === "Google";
8212
8332
  if (isGemma) {
8213
8333
  const jitInstruction = `
8214
- [SYSTEM] Tool result received. Analyze output and proceed with your turn${thinkingLevel !== "Fast" && thinkingLevel !== "xHigh" && aiProvider === "Google" ? `. **STRICTLY MAINTAIN THINKING POLICY. DO NOT START A RESPONSE WITHOUT <think> ... </think>**` : ""}[/SYSTEM]`;
8334
+ [SYSTEM] Tool result received. Analyze output and proceed with your turn${thinkingLevel !== "Fast" && thinkingLevel !== "xHigh" && aiProvider === "Google" ? `. **STRICTLY MAINTAIN THINKING POLICY. DO NOT START A RESPONSE WITHOUT <think> ... </think>**` : ""} [/SYSTEM]`;
8215
8335
  if (lastUserMsg && lastUserMsg.role === "user" && lastUserMsg.parts?.[0]?.text?.startsWith("[TOOL RESULT]")) {
8216
8336
  lastUserMsg.parts[0].text += jitInstruction;
8217
8337
  }
@@ -8221,7 +8341,7 @@ ${activeSummaryBlock}${thinkingLevel !== "Fast" && thinkingLevel !== "xHigh" &&
8221
8341
  const currentStep = loop + 1;
8222
8342
  if (currentStep >= stepThreshold && lastUserMsg && lastUserMsg.parts?.[0]) {
8223
8343
  lastUserMsg.parts[0].text += `
8224
- [SYSTEM] WARNING, Turn Limit Impending: Step ${currentStep}/${MAX_LOOPS}. Wrap up quickly/prompt user to continue & use [[END]] quickly.[/SYSTEM]`;
8344
+ [SYSTEM] WARNING, Turn Limit Impending: Step ${currentStep}/${MAX_LOOPS}. Wrap up quickly/prompt user to continue & use [[END]] quickly. [/SYSTEM]`;
8225
8345
  }
8226
8346
  }
8227
8347
  const abortPromise = new Promise((_, reject) => {
@@ -8355,14 +8475,14 @@ ${activeSummaryBlock}${thinkingLevel !== "Fast" && thinkingLevel !== "xHigh" &&
8355
8475
  { type: "end", idx: endIdx, start: "[[END]]", end: "[[END]]" }
8356
8476
  ].filter((i) => i.idx !== -1).sort((a, b) => a.idx - b.idx);
8357
8477
  if (indices.length > 0) {
8358
- const match = indices[0];
8359
- if (match.idx > 0) {
8360
- msgs.push({ type: "text", content: remaining.substring(0, match.idx) });
8478
+ const match2 = indices[0];
8479
+ if (match2.idx > 0) {
8480
+ msgs.push({ type: "text", content: remaining.substring(0, match2.idx) });
8361
8481
  }
8362
8482
  isBufferingToolCall = true;
8363
- activeBufferType = match.type;
8483
+ activeBufferType = match2.type;
8364
8484
  toolCallBuffer = "";
8365
- remaining = remaining.substring(match.idx);
8485
+ remaining = remaining.substring(match2.idx);
8366
8486
  } else {
8367
8487
  const potentialStarts = ["[tool", "[[END]]"];
8368
8488
  let splitPoint = -1;
@@ -8432,7 +8552,7 @@ ${activeSummaryBlock}${thinkingLevel !== "Fast" && thinkingLevel !== "xHigh" &&
8432
8552
  ]);
8433
8553
  if (done) break;
8434
8554
  if (isFirstChunk) {
8435
- yield { type: "status", content: "Working..." };
8555
+ yield { type: "status", content: "Thinking..." };
8436
8556
  isFirstChunk = false;
8437
8557
  }
8438
8558
  if (TERMINATION_SIGNAL) {
@@ -9455,7 +9575,7 @@ ${boxBottom}` };
9455
9575
  const waitTime = Math.min(1e3 * Math.pow(2, inStreamRetryCount - 1), 24e3);
9456
9576
  if (turnText.trim().length > 0) {
9457
9577
  modifiedHistory.push({ role: "agent", text: turnText });
9458
- const recoveryText = "[SYSTEM]\n- SEAMLESS CONTINUATION: Resume immediately. Pick up from last words with zero gap/disruption\n- NO REPETITION: Do not repeat any text already written\n- NO RE-THINK: Do not restart or open <think> if reasoning already started. Continue the thinking and close thinking block </think> if opened before outputting user response\n- MID-TOOL SAFETY: If cutoff was mid-tool call, restart that tool call from start\n- STEALTH: Do not mention/apologize for cutoff[/SYSTEM]";
9578
+ const recoveryText = "[SYSTEM]\n- SEAMLESS CONTINUATION: Resume immediately. Pick up from last words with zero gap/disruption\n- NO REPETITION: Do not repeat any text already written\n- NO RE-THINK: Do not restart or open <think> if reasoning already started. Continue the thinking and close thinking block </think> if opened before outputting user response\n- MID-TOOL SAFETY: If cutoff was mid-tool call, restart that tool call from start\n- STEALTH: Do not mention/apologize for cutoff [/SYSTEM]";
9459
9579
  if (toolResults.length > 0) {
9460
9580
  toolResults.forEach((tr, idx) => {
9461
9581
  if (idx === toolResults.length - 1) {
@@ -9528,7 +9648,7 @@ Error Log can be found in ${path19.join(LOGS_DIR, "agent", "error.log")}`);
9528
9648
  const hasFinish = /\[\s*(turn\s*:)?\s*finish\s*\]/i.test(signalSafeText.toLowerCase()) || /\[\[END\]\]/i.test(signalSafeText.toLowerCase()) || true;
9529
9649
  const hasContinue = /\[\s*(turn\s*:)?\s*continue\s*\]/i.test(signalSafeText.toLowerCase());
9530
9650
  const shouldContinue = toolCallPointer > 0;
9531
- yield { type: "status", content: "Working..." };
9651
+ yield { type: "status", content: "Thinking..." };
9532
9652
  const cleanedTurnText = contextSafeReplace(turnText, /(\[\s*(turn\s*:)?\s*(continue|finish)\s*\]|\[\[END\]\])/gi, "").trim();
9533
9653
  let isActuallyFinished = (hasFinish || toolResults.length === 0) && !isThinkingLoop && !isStutteringLoop && !isGeneralLoop;
9534
9654
  isActuallyFinished = toolResults.length === 0 ? isActuallyFinished : false;
@@ -9561,7 +9681,7 @@ Error Log can be found in ${path19.join(LOGS_DIR, "agent", "error.log")}`);
9561
9681
  }
9562
9682
  } else {
9563
9683
  if (wasToolCalledInLastLoop) {
9564
- modifiedHistory.push({ role: "user", text: `[SYSTEM] Failed to verify tool execution, Verify tool syntax, proper escaping or ask user if tool worked when unsure[/SYSTEM]` });
9684
+ modifiedHistory.push({ role: "user", text: `[SYSTEM] Failed to verify tool execution, Verify tool syntax, proper escaping or ask user if tool worked when unsure [/SYSTEM]` });
9565
9685
  } else {
9566
9686
  modifiedHistory.push({ role: "user", text: `[SYSTEM] ${isStutteringLoop && !isThinkingLoop ? `STUTTERING DETECTED by Internal System. Re-calibrate your response & proceed.` : `${isThinkingLoop ? " OVER THINKING" : " LOOP"} DETECTED by Internal System${isThinkingLoop ? " for current EFFORT_LEVEL" : ""}. ${isThinkingLoop ? "If you have planned the task, prioritize execution/output" : "If you have finished your task use [[END]]"}`} [/SYSTEM]` });
9567
9687
  }
@@ -12596,7 +12716,7 @@ Selection: ${val}`,
12596
12716
  }
12597
12717
  if (packet.type === "visual_feedback") {
12598
12718
  setMessages((prev) => [...prev, {
12599
- id: "feedback-" + Date.now(),
12719
+ id: "feedback-" + Date.now() + "-" + Math.random().toString(36).substring(2, 9),
12600
12720
  role: "system",
12601
12721
  text: packet.content,
12602
12722
  isVisualFeedback: true
@@ -13297,7 +13417,7 @@ Selection: ${val}`,
13297
13417
  }
13298
13418
  ));
13299
13419
  case "keybindingsPrompt":
13300
- return /* @__PURE__ */ React14.createElement(Box14, { flexDirection: "column", borderStyle: "round", borderColor: "cyan", paddingX: 2, paddingY: 1, width: "100%" }, /* @__PURE__ */ React14.createElement(Text14, { color: "cyan", bold: true, underline: true }, "\u2328\uFE0F 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(
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(
13301
13421
  CommandMenu,
13302
13422
  {
13303
13423
  title: "Add Keybinding?",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "fluxflow-cli",
3
- "version": "2.8.9",
3
+ "version": "2.9.0",
4
4
  "date": "2026-06-19",
5
5
  "description": "A high-fidelity agentic terminal assistant for the Flux Era.",
6
6
  "keywords": [