fluxflow-cli 2.8.7 → 2.8.9

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 +158 -6
  2. package/package.json +2 -2
package/dist/fluxflow.js CHANGED
@@ -1586,12 +1586,33 @@ var init_ChatLayout = __esm({
1586
1586
  }
1587
1587
  }
1588
1588
  }
1589
- return result.replace(/\[TOOL RESULT\]:?\s*/gi, "").split("\n").filter((line) => !line.trim().startsWith("SUCCESS:") && !line.trim().startsWith("ERROR:")).join("\n").replace(/\[\s*turn\s*:\s*(continue|finish)\s*\]/gi, "").replace(/\[\[END\]\]/gi, "").replace(/\[\s*turn\s*:?.*?$/gi, "").replace(/\n\s*turn\s*:?.*?$/gi, "").replace(/\[\s*$/gi, "").replace(/\n\nResponded on .*/g, "").replace(/\n\n\[Prompted on: .*\]/g, "").replace(/(\$?\\?\/?\\rightarrow\$?|\$\\rightarrow\$)/gi, "\u2192").replace(/(\$?\\?\/?\\leftarrow\$?|\$\\leftarrow\$)/gi, "\u2190").replace(/(\$?\\?\/?\\uparrow\$?|\$\\uparrow\$)/gi, "\u2191").replace(/(\$?\\?\/?\\downarrow\$?|\$\\downarrow\$)/gi, "\u2193").replace(/(\$?\\?\/?\\leftrightarrow\$?|\$\\leftrightarrow\$)/gi, "\u2194").replace(/@\[TerminalName:.*?, ProcessId:.*?\]/gi, "").replace(/\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();
1589
+ return result.replace(/\[SYSTEM\][\s\S]*?\[\/SYSTEM\]/gi, "").replace(/\[TOOL RESULT\]:?\s*/gi, "").split("\n").filter((line) => !line.trim().startsWith("SUCCESS:") && !line.trim().startsWith("ERROR:")).join("\n").replace(/\[\s*turn\s*:\s*(continue|finish)\s*\]/gi, "").replace(/\[\[END\]\]/gi, "").replace(/\[\s*turn\s*:?.*?$/gi, "").replace(/\n\s*turn\s*:?.*?$/gi, "").replace(/\[\s*$/gi, "").replace(/\n\nResponded on .*/g, "").replace(/\n\n\[Prompted on: .*\]/g, "").replace(/(\$?\\?\/?\\rightarrow\$?|\$\\rightarrow\$)/gi, "\u2192").replace(/(\$?\\?\/?\\leftarrow\$?|\$\\leftarrow\$)/gi, "\u2190").replace(/(\$?\\?\/?\\uparrow\$?|\$\\uparrow\$)/gi, "\u2191").replace(/(\$?\\?\/?\\downarrow\$?|\$\\downarrow\$)/gi, "\u2193").replace(/(\$?\\?\/?\\leftrightarrow\$?|\$\\leftrightarrow\$)/gi, "\u2194").replace(/@\[TerminalName:.*?, ProcessId:.*?\]/gi, "").replace(/\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;
1593
1593
  const availableWidth = columns - 10;
1594
- return /* @__PURE__ */ React3.createElement(Box3, { width: "100%", flexDirection: "column" }, /* @__PURE__ */ React3.createElement(MarkdownText, { text: cleaned.trim(), color: "gray", columns: availableWidth, italic: true }));
1594
+ const trimmed = cleaned.trim();
1595
+ if (!trimmed.includes("```")) {
1596
+ return /* @__PURE__ */ React3.createElement(Box3, { width: "100%", flexDirection: "column" }, /* @__PURE__ */ React3.createElement(MarkdownText, { text: trimmed, color: "gray", columns: availableWidth, italic: true }));
1597
+ }
1598
+ const parts = trimmed.split(/(```\w*\n?[\s\S]*?(?:```|$))/g);
1599
+ return /* @__PURE__ */ React3.createElement(Box3, { width: "100%", flexDirection: "column" }, parts.map((part, i) => {
1600
+ if (part.startsWith("```")) {
1601
+ const match = part.match(/```(\w*)\n?([\s\S]*?)(?:```|$)/);
1602
+ const code = match ? match[2] : part.replace(/^```\w*\n?/, "").replace(/```$/, "");
1603
+ const wrappedCode = wrapText(code.trimEnd(), availableWidth);
1604
+ return /* @__PURE__ */ React3.createElement(Box3, { key: i, flexDirection: "column", width: "100%" }, wrappedCode.split("\n").map((line, idx) => /* @__PURE__ */ React3.createElement(Text3, { key: idx, color: "cyan" }, line)));
1605
+ }
1606
+ let cleanPart = part;
1607
+ if (i > 0) {
1608
+ cleanPart = cleanPart.replace(/^[\r\n]+/, "");
1609
+ }
1610
+ if (i < parts.length - 1) {
1611
+ cleanPart = cleanPart.replace(/[\r\n]+$/, "");
1612
+ }
1613
+ if (!cleanPart) return null;
1614
+ return /* @__PURE__ */ React3.createElement(MarkdownText, { key: i, text: cleanPart, color: "gray", columns: availableWidth, italic: true });
1615
+ }));
1595
1616
  };
1596
1617
  parseMathSymbols = (content) => {
1597
1618
  return content.replace(/\\multiply|\\mul|\\times/g, "\xD7").replace(/\\div/g, "\xF7").replace(/\\cdot/g, "\u22C5").replace(/\\infty/g, "\u221E").replace(/\\pm/g, "\xB1").replace(/\\leq/g, "\u2264").replace(/\\geq/g, "\u2265").replace(/\\neq/g, "\u2260").replace(/\\sqrt\s*\{([^}]+)\}/g, "\u221A($1)").replace(/\\sqrt\s*(\w+|\d+)/g, "\u221A($1)").replace(/\\alpha/g, "\u03B1").replace(/\\beta/g, "\u03B2").replace(/\\theta/g, "\u03B8").replace(/\\pi/g, "\u03C0").replace(/\\approx/g, "\u2248").replace(/\\Delta/g, "\u0394").replace(/\\sigma/g, "\u03C3").replace(/\\sum/g, "\u03A3").replace(/\\prod/g, "\u03A0").replace(/\\rightarrow|\\to/g, "\u2192").replace(/\\left\b|\\right\b/g, "").replace(/\\left\(|\\right\)/g, (match) => match.includes("left") ? "(" : ")").replace(/\\left\[|\\right\]/g, (match) => match.includes("left") ? "[" : "]").replace(/\\\{|\\\}/g, (match) => match.includes("{") ? "{" : "}").replace(/\\text\s*\{([^}]+)\}/g, "$1").replace(/\\text\s+(\w+)/g, "$1").replace(/\\%/g, "%");
@@ -3427,7 +3448,8 @@ ${projectContextBlock}
3427
3448
 
3428
3449
  -- FORMATTING --
3429
3450
  - GFM Supported
3430
- - NO CHAT OUTPUT AFTER TOOL CALL IN SAME TURN
3451
+ - NO CHAT RESPONSE **AFTER** CALLING TOOLS IN SAME TURN
3452
+ - ONE THINKING BLOCK PER TURN
3431
3453
  - Basic LaTeX${mode === "Flux" ? "" : ". Kaomojis"}
3432
3454
  === END SYSTEM PROMPT ===`.trim();
3433
3455
  };
@@ -9283,7 +9305,7 @@ ${boxBottom}` };
9283
9305
  await incrementUsage("toolFailure");
9284
9306
  if (settings.onToolResult) settings.onToolResult("failure", normToolName);
9285
9307
  }
9286
- const aiContent = `[TOOL RESULT]: ${(result || "").toString().split(/\r?\n/).filter((line) => !line.includes("[[UI_CONTEXT]]")).join("\n")}`;
9308
+ const aiContent = `[TOOL RESULT]: ${(result || "").toString().replaceAll("[UI_CONTEXT]", "[CONTEXT]")}`;
9287
9309
  toolResults.push({ role: "user", text: aiContent, binaryPart });
9288
9310
  anyToolExecutedInThisTurn = true;
9289
9311
  let uiContent = `[TOOL RESULT]: ${result || ""}`;
@@ -10627,6 +10649,56 @@ function App({ args = [] }) {
10627
10649
  const lastFocusEventTime = useRef3(0);
10628
10650
  const [apiKey, setApiKey] = useState11(null);
10629
10651
  const [tempKey, setTempKey] = useState11("");
10652
+ const addShiftEnterBinding = async (ideName) => {
10653
+ const kbPath = getKeybindingsPath(ideName);
10654
+ if (!kbPath) return;
10655
+ try {
10656
+ await fs22.ensureDir(path20.dirname(kbPath));
10657
+ let bindings = [];
10658
+ if (fs22.existsSync(kbPath)) {
10659
+ const content = fs22.readFileSync(kbPath, "utf8").trim();
10660
+ if (content) {
10661
+ try {
10662
+ bindings = parseJsonc(content);
10663
+ } catch (e) {
10664
+ bindings = [];
10665
+ }
10666
+ }
10667
+ }
10668
+ if (!Array.isArray(bindings)) {
10669
+ bindings = [];
10670
+ }
10671
+ bindings.push({
10672
+ "key": "shift+enter",
10673
+ "command": "workbench.action.terminal.sendSequence",
10674
+ "args": {
10675
+ "text": "\x1B[13;2u"
10676
+ },
10677
+ "when": "terminalFocus"
10678
+ });
10679
+ fs22.writeFileSync(kbPath, JSON.stringify(bindings, null, 4), "utf8");
10680
+ cachedShortcut = "Shift + Enter";
10681
+ setMessages((prev) => {
10682
+ setCompletedIndex(prev.length + 1);
10683
+ return [...prev, {
10684
+ id: "kb-success-" + Date.now(),
10685
+ role: "system",
10686
+ text: `\u2705 Successfully configured Shift+Enter in your ${ideName} keybindings!`,
10687
+ isMeta: true
10688
+ }];
10689
+ });
10690
+ } catch (err) {
10691
+ setMessages((prev) => {
10692
+ setCompletedIndex(prev.length + 1);
10693
+ return [...prev, {
10694
+ id: "kb-error-" + Date.now(),
10695
+ role: "system",
10696
+ text: `\u274C Failed to update keybindings: ${err.message}`,
10697
+ isMeta: true
10698
+ }];
10699
+ });
10700
+ }
10701
+ };
10630
10702
  const [activeView, setActiveView] = useState11("chat");
10631
10703
  const [apiTier, setApiTier] = useState11("Free");
10632
10704
  const [quotas, setQuotas] = useState11({ agentLimit: 999999, backgroundLimit: 999999, searchLimit: 100, customModelId: "", customLimit: 0 });
@@ -10749,7 +10821,9 @@ function App({ args = [] }) {
10749
10821
  const isIDE = !["Terminal", "Windows Terminal"].includes(ideName) || !!process.env.VSC_TERMINAL_URL || !!process.env.INTELLIJ_TERMINAL_COMMAND_BLOCKS;
10750
10822
  return {
10751
10823
  isIDE,
10752
- shortcut: isIDE ? "Shift + Enter" : "Ctrl + Enter"
10824
+ get shortcut() {
10825
+ return cachedShortcut;
10826
+ }
10753
10827
  };
10754
10828
  }, []);
10755
10829
  const activeCommandRef = useRef3(null);
@@ -11215,6 +11289,28 @@ function App({ args = [] }) {
11215
11289
  setMessages((prev) => [...prev, { id: "sys-err-" + Date.now(), role: "system", text: `ERROR: Chat session [${id}] not found. Started new session.`, isMeta: true }]);
11216
11290
  }
11217
11291
  }
11292
+ const detectedIde = getIDEName();
11293
+ const isIDE = !["Terminal", "Windows Terminal"].includes(detectedIde);
11294
+ if (isIDE) {
11295
+ const kbPath = getKeybindingsPath(detectedIde);
11296
+ if (kbPath) {
11297
+ try {
11298
+ let bindings = [];
11299
+ if (fs22.existsSync(kbPath)) {
11300
+ const content = fs22.readFileSync(kbPath, "utf8").trim();
11301
+ if (content) {
11302
+ bindings = parseJsonc(content);
11303
+ }
11304
+ }
11305
+ if (!hasShiftEnterBinding(bindings)) {
11306
+ setActiveView("keybindingsPrompt");
11307
+ } else {
11308
+ cachedShortcut = "Shift + Enter";
11309
+ }
11310
+ } catch (e) {
11311
+ }
11312
+ }
11313
+ }
11218
11314
  setIsInitializing(false);
11219
11315
  }
11220
11316
  init();
@@ -13200,6 +13296,25 @@ Selection: ${val}`,
13200
13296
  onClose: () => setActiveView("chat")
13201
13297
  }
13202
13298
  ));
13299
+ 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(
13301
+ CommandMenu,
13302
+ {
13303
+ title: "Add Keybinding?",
13304
+ items: [
13305
+ { label: "Yes, configure automatically", value: "yes" },
13306
+ { label: "No, skip", value: "no" }
13307
+ ],
13308
+ onSelect: async (item) => {
13309
+ if (item.value === "yes") {
13310
+ await addShiftEnterBinding(getIDEName());
13311
+ } else {
13312
+ cachedShortcut = "\\ + Enter";
13313
+ }
13314
+ setActiveView("chat");
13315
+ }
13316
+ }
13317
+ )));
13203
13318
  case "memory":
13204
13319
  return /* @__PURE__ */ React14.createElement(Box14, { width: "100%", alignItems: "center", justifyContent: "center" }, /* @__PURE__ */ React14.createElement(MemoryModal, { onClose: () => setActiveView("chat") }));
13205
13320
  case "parserDownload":
@@ -13532,7 +13647,7 @@ Selection: ${val}`,
13532
13647
  return /* @__PURE__ */ React14.createElement(Box14, { flexDirection: "column", borderStyle: "round", paddingX: 3, paddingY: 1, borderColor: "grey", width: Math.min(100, (stdout?.columns || 100) - 2), marginTop: 0, marginBottom: 0 }, /* @__PURE__ */ React14.createElement(Box14, { marginBottom: 1 }, /* @__PURE__ */ React14.createElement(Text14, { bold: true }, gradient2(["blue", "purple"])("Agent powering down. Goodbye!"))), /* @__PURE__ */ React14.createElement(Box14, { flexDirection: "column" }, /* @__PURE__ */ React14.createElement(Text14, { color: "white", bold: true, underline: true }, "Interaction Summary"), /* @__PURE__ */ React14.createElement(Box14, { marginTop: 1 }, /* @__PURE__ */ React14.createElement(Box14, { width: 20 }, /* @__PURE__ */ React14.createElement(Text14, { color: "blue" }, "Session ID:")), /* @__PURE__ */ React14.createElement(Text14, { color: "white" }, chatId)), /* @__PURE__ */ React14.createElement(Box14, null, /* @__PURE__ */ React14.createElement(Box14, { width: 20 }, /* @__PURE__ */ React14.createElement(Text14, { color: "blue" }, "Tool Calls:")), /* @__PURE__ */ React14.createElement(Text14, { color: "white" }, sessionToolSuccess + sessionToolFailure + sessionToolDenied, " ( ", /* @__PURE__ */ React14.createElement(Text14, { color: "green" }, "\u2713 ", sessionToolSuccess), " ", /* @__PURE__ */ React14.createElement(Text14, { color: "yellow" }, "\u2298 ", sessionToolDenied), " ", /* @__PURE__ */ React14.createElement(Text14, { color: "red" }, "\u2715 ", sessionToolFailure), " )")), /* @__PURE__ */ React14.createElement(Box14, null, /* @__PURE__ */ React14.createElement(Box14, { width: 20 }, /* @__PURE__ */ React14.createElement(Text14, { color: "blue" }, "Success Rate:")), /* @__PURE__ */ React14.createElement(Text14, { color: "white" }, successRate, "%")), /* @__PURE__ */ React14.createElement(Box14, null, /* @__PURE__ */ React14.createElement(Box14, { width: 20 }, /* @__PURE__ */ React14.createElement(Text14, { color: "blue" }, "Code Changes:")), /* @__PURE__ */ React14.createElement(Text14, { color: "white" }, /* @__PURE__ */ React14.createElement(Text14, { color: "green" }, "+", linesAdded), " ", /* @__PURE__ */ React14.createElement(Text14, { color: "red" }, "-", linesRemoved))), /* @__PURE__ */ React14.createElement(Box14, null, /* @__PURE__ */ React14.createElement(Box14, { width: 20 }, /* @__PURE__ */ React14.createElement(Text14, { color: "blue" }, "Tokens Consumed:")), /* @__PURE__ */ React14.createElement(Text14, { color: "white" }, formatTokens(sessionTotalTokens))), sessionTotalTokens > 0 && /* @__PURE__ */ React14.createElement(React14.Fragment, null, /* @__PURE__ */ React14.createElement(Box14, { marginLeft: 2 }, /* @__PURE__ */ React14.createElement(Box14, { width: 18 }, /* @__PURE__ */ React14.createElement(Text14, { color: "grey" }, "\xBB Input Tokens:")), /* @__PURE__ */ React14.createElement(Text14, { color: "white" }, formatTokens(sessionTotalTokens - sessionTotalCandidateTokens))), sessionTotalCachedTokens > 0 && /* @__PURE__ */ React14.createElement(Box14, { marginLeft: 4 }, /* @__PURE__ */ React14.createElement(Box14, { width: 16 }, /* @__PURE__ */ React14.createElement(Text14, { color: "grey" }, "\xBB Cached:")), /* @__PURE__ */ React14.createElement(Text14, { color: "white" }, formatTokens(sessionTotalCachedTokens))), sessionTotalCandidateTokens > 0 && /* @__PURE__ */ React14.createElement(Box14, { marginLeft: 2 }, /* @__PURE__ */ React14.createElement(Box14, { width: 18 }, /* @__PURE__ */ React14.createElement(Text14, { color: "grey" }, "\xBB Output Tokens:")), /* @__PURE__ */ React14.createElement(Text14, { color: "white" }, formatTokens(sessionTotalCandidateTokens)))), sessionImageCount > 0 && /* @__PURE__ */ React14.createElement(React14.Fragment, null, /* @__PURE__ */ React14.createElement(Box14, null, /* @__PURE__ */ React14.createElement(Box14, { width: 20 }, /* @__PURE__ */ React14.createElement(Text14, { color: "blue" }, "Images Made:")), /* @__PURE__ */ React14.createElement(Text14, { color: "white" }, sessionImageCount)), /* @__PURE__ */ React14.createElement(Box14, null, /* @__PURE__ */ React14.createElement(Box14, { width: 20 }, /* @__PURE__ */ React14.createElement(Text14, { color: "blue" }, "Image Credits:")), /* @__PURE__ */ React14.createElement(Text14, { color: "white" }, Number(((sessionImageCredits || 0) * 1e3).toFixed(0)), " credits")))), /* @__PURE__ */ React14.createElement(Box14, { flexDirection: "column", marginTop: 1 }, /* @__PURE__ */ React14.createElement(Text14, { color: "white", bold: true, underline: true }, "Performance"), /* @__PURE__ */ React14.createElement(Box14, { marginTop: 1 }, /* @__PURE__ */ React14.createElement(Box14, { width: 20 }, /* @__PURE__ */ React14.createElement(Text14, { color: "blue" }, "Wall Time:")), /* @__PURE__ */ React14.createElement(Text14, { color: "white" }, formatMsDuration(wallTimeMs))), /* @__PURE__ */ React14.createElement(Box14, null, /* @__PURE__ */ React14.createElement(Box14, { width: 20 }, /* @__PURE__ */ React14.createElement(Text14, { color: "blue" }, "Agent Active:")), /* @__PURE__ */ React14.createElement(Text14, { color: "white" }, formatMsDuration(agentActiveMs))), /* @__PURE__ */ React14.createElement(Box14, { marginLeft: 2 }, /* @__PURE__ */ React14.createElement(Box14, { width: 18 }, /* @__PURE__ */ React14.createElement(Text14, { color: "grey" }, "\xBB API Time:")), /* @__PURE__ */ React14.createElement(Text14, { color: "white" }, formatMsDuration(sessionApiTime), " (", apiPercent, "%)")), /* @__PURE__ */ React14.createElement(Box14, { marginLeft: 2 }, /* @__PURE__ */ React14.createElement(Box14, { width: 18 }, /* @__PURE__ */ React14.createElement(Text14, { color: "grey" }, "\xBB Tool Time:")), /* @__PURE__ */ React14.createElement(Text14, { color: "white" }, formatMsDuration(sessionToolTime), " (", toolPercent, "%)"))));
13533
13648
  })())));
13534
13649
  }
13535
- var getIDEName, getPromoOptions, BridgePromo, SESSION_START_TIME, CHANGELOG_URL, DOCS_URL, linesAdded, linesRemoved, packageJsonPath, packageJson, versionFluxflow, updatedOn, ResolutionModal, parseAgentText, getProjectFiles;
13650
+ var getIDEName, getIDEDirName, getKeybindingsPath, parseJsonc, hasShiftEnterBinding, getPromoOptions, BridgePromo, SESSION_START_TIME, CHANGELOG_URL, DOCS_URL, linesAdded, linesRemoved, packageJsonPath, packageJson, versionFluxflow, updatedOn, ResolutionModal, parseAgentText, getProjectFiles, cachedShortcut;
13536
13651
  var init_app = __esm({
13537
13652
  async "src/app.jsx"() {
13538
13653
  init_MultilineInput();
@@ -13580,10 +13695,46 @@ var init_app = __esm({
13580
13695
  if (termProgram === "trae" || inEnvVars("trae")) return "Trae";
13581
13696
  if (termProgram === "codium" || inEnvVars("codium") || inEnvVars("vscode-oss")) return "VSCodium";
13582
13697
  if (inEnvVars("positron")) return "Positron";
13698
+ if (termProgram === "vscode-insiders" || inEnvVars("insiders")) return "VS Code Insiders";
13583
13699
  if (termProgram === "vscode" || process.env.VSCODE_GIT_IPC_HANDLE || inEnvVars("vscode")) return "VS Code";
13584
13700
  if (process.env.INTELLIJ_TERMINAL_COMMAND_BLOCKS || inEnvVars("intellij")) return "JetBrains";
13585
13701
  return "Terminal";
13586
13702
  };
13703
+ getIDEDirName = (ideName) => {
13704
+ switch (ideName) {
13705
+ case "VS Code":
13706
+ return "Code";
13707
+ case "VS Code Insiders":
13708
+ return "Code - Insiders";
13709
+ case "Antigravity":
13710
+ return "Antigravity IDE";
13711
+ default:
13712
+ return ideName;
13713
+ }
13714
+ };
13715
+ getKeybindingsPath = (ideName) => {
13716
+ const dirName = getIDEDirName(ideName);
13717
+ const home = os4.homedir();
13718
+ if (process.platform === "win32") {
13719
+ const appData = process.env.APPDATA;
13720
+ if (!appData) return null;
13721
+ return path20.join(appData, dirName, "User", "keybindings.json");
13722
+ } else if (process.platform === "darwin") {
13723
+ return path20.join(home, "Library", "Application Support", dirName, "User", "keybindings.json");
13724
+ } else {
13725
+ return path20.join(home, ".config", dirName, "User", "keybindings.json");
13726
+ }
13727
+ };
13728
+ parseJsonc = (content) => {
13729
+ const clean = content.replace(/\/\*[\s\S]*?\*\/|([^\\:]|^)\/\/.*$/gm, "$1");
13730
+ return JSON.parse(clean);
13731
+ };
13732
+ hasShiftEnterBinding = (bindings) => {
13733
+ if (!Array.isArray(bindings)) return false;
13734
+ return bindings.some(
13735
+ (b) => b && typeof b.key === "string" && b.key.toLowerCase().replace(/\s+/g, "") === "shift+enter" && b.command === "workbench.action.terminal.sendSequence" && b.args && b.args.text === "\x1B[13;2u" && typeof b.when === "string" && b.when.includes("terminalFocus")
13736
+ );
13737
+ };
13587
13738
  getPromoOptions = (ideName) => {
13588
13739
  const isStandardVSCode = ideName === "VS Code";
13589
13740
  const options = [];
@@ -13739,6 +13890,7 @@ var init_app = __esm({
13739
13890
  return fileList;
13740
13891
  };
13741
13892
  })();
13893
+ cachedShortcut = "\\ + Enter";
13742
13894
  }
13743
13895
  });
13744
13896
 
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "fluxflow-cli",
3
- "version": "2.8.7",
4
- "date": "2026-06-18",
3
+ "version": "2.8.9",
4
+ "date": "2026-06-19",
5
5
  "description": "A high-fidelity agentic terminal assistant for the Flux Era.",
6
6
  "keywords": [
7
7
  "ai",