fluxflow-cli 1.18.13 → 1.18.14

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 +37 -45
  2. package/package.json +1 -1
package/dist/fluxflow.js CHANGED
@@ -442,13 +442,20 @@ var init_TerminalBox = __esm({
442
442
  TerminalBox = React2.memo(({ command, output, completed = false, isFocused = false, columns = 80, isPty = false }) => {
443
443
  const processPTY = (text) => {
444
444
  if (!text) return "";
445
- const noTrailingCr = text.replace(/\r+\n/g, "\n");
445
+ const screenResetRegex = /\x1b\[H|\x1b\[2J|\x1b\[3J|\x1bc/g;
446
+ const resetMatches = [...text.matchAll(screenResetRegex)];
447
+ let workingText = text;
448
+ if (resetMatches.length > 0) {
449
+ const lastMatch = resetMatches[resetMatches.length - 1];
450
+ workingText = text.substring(lastMatch.index + lastMatch[0].length);
451
+ }
452
+ const noTrailingCr = workingText.replace(/\r+\n/g, "\n");
446
453
  return noTrailingCr.split("\n").map((line) => {
447
454
  const parts = line.split("\r");
448
455
  return parts[parts.length - 1];
449
456
  }).join("\n");
450
457
  };
451
- const cleanOutput = isPty ? processPTY(output) : (output || "").replace(/\r\n/g, "\n");
458
+ const cleanOutput = isPty ? output || "" : (output || "").replace(/\r\n/g, "\n").replace(/\n{3,}/g, "\n\n");
452
459
  const displayOutput = isPty ? cleanOutput : cleanOutput ? wrapText(cleanOutput, columns - 6) : "";
453
460
  return /* @__PURE__ */ React2.createElement(Box2, { flexDirection: "column", borderStyle: isFocused ? "double" : "round", borderColor: completed ? "#334155" : isFocused ? "yellow" : "cyan", paddingX: 2, paddingY: completed ? 0 : 1, width: "100%" }, /* @__PURE__ */ React2.createElement(Box2, { marginBottom: 1, justifyContent: "space-between", width: "100%" }, /* @__PURE__ */ React2.createElement(Box2, { flexShrink: 1, paddingRight: 2 }, /* @__PURE__ */ React2.createElement(Text2, null, /* @__PURE__ */ React2.createElement(Text2, { color: completed ? "gray" : isFocused ? "yellow" : "cyan", bold: true }, completed ? "\u{1F3C1} FINISHED:" : "\u26A1 EXECUTING:", " "), /* @__PURE__ */ React2.createElement(Text2, { color: completed ? "gray" : "white" }, command))), isPty && /* @__PURE__ */ React2.createElement(Box2, { flexShrink: 0, paddingX: 1 }, /* @__PURE__ */ React2.createElement(Text2, { color: completed ? "gray" : "magenta", bold: true }, "ADVANCE"))), displayOutput ? /* @__PURE__ */ React2.createElement(Box2, { marginTop: completed ? 0 : 1, backgroundColor: isPty ? void 0 : "#0a0a0a", paddingX: 1 }, /* @__PURE__ */ React2.createElement(Text2, { color: completed ? "gray" : void 0 }, displayOutput)) : !completed && /* @__PURE__ */ React2.createElement(Box2, { marginTop: 1, backgroundColor: isPty ? void 0 : "#0a0a0a", paddingX: 1 }, /* @__PURE__ */ React2.createElement(Text2, { color: "gray", italic: true }, "Waiting for output...")), /* @__PURE__ */ React2.createElement(Box2, { justifyContent: "space-between", marginTop: 1 }, !completed ? /* @__PURE__ */ React2.createElement(Text2, { color: "gray", dimColor: true, italic: true }, isFocused ? "Press TAB to unfocus, then double-press ESC to terminate." : "Double-press ESC to terminate if hanging.") : /* @__PURE__ */ React2.createElement(Box2, null), /* @__PURE__ */ React2.createElement(Text2, { color: completed ? "#475569" : isFocused ? "yellow" : "cyan", bold: true }, completed ? "\u25CF ARCHIVED" : isFocused ? "\u25B6 TERMINAL FOCUSED" : "\u25CF LIVE (Press TAB to focus)")));
454
461
  });
@@ -1138,6 +1145,7 @@ var init_main_tools = __esm({
1138
1145
  Access to internal tools. To call a tool, MUST use the exact syntax on a new line: [tool:functions.ToolName(args)]
1139
1146
  STRICT POLICY
1140
1147
  - **MAX 3 TOOL CALLS PER TURN. Next Turn, verify results, plan next**${mode === "Flux" ? "\n- **File Tools >> Code in chat**" : ""}
1148
+ - Use contexual BEST tools, no brute forcing
1141
1149
 
1142
1150
  - COMMUNICATION TOOLS -
1143
1151
  1. [tool:functions.Ask(question="...", optionA="option::description", ...MAX 4)]. Ambiguity Resolution. Mandatory Triggers: Path Divergence, Security, Risk Mitigation. ask >> finish
@@ -1544,7 +1552,7 @@ ${cleanOut}`), 500);
1544
1552
  if (isResolved) return;
1545
1553
  activeChildProcess = null;
1546
1554
  const normalizedOutput = (output || "").replace(/\r\n/g, "\n").replace(/\r/g, "\n");
1547
- const finalOutput = stripAnsi(normalizedOutput) || "Command executed with no output.";
1555
+ const finalOutput = stripAnsi(normalizedOutput).replace(/\n{3,}/g, "\n\n") || "Command executed with no output.";
1548
1556
  if (exitCode !== 0) {
1549
1557
  resolve(`ERROR: Command [${rawCommand}] failed with exit code [${exitCode}].
1550
1558
 
@@ -1633,7 +1641,7 @@ ${stdout}`);
1633
1641
  ${stderr}`);
1634
1642
  if (code !== 0) result.push(`EXIT CODE: ${code}`);
1635
1643
  const rawOutput = result.join("\n\n") || "Command executed with no output.";
1636
- const finalOutput = stripAnsi(rawOutput);
1644
+ const finalOutput = stripAnsi(rawOutput).replace(/\n{3,}/g, "\n\n");
1637
1645
  if (code !== 0) {
1638
1646
  resolve(`ERROR: Command [${rawCommand}] failed with exit code [${code}].
1639
1647
 
@@ -2414,8 +2422,8 @@ ${foundFiles.map((f) => `- ${f.name}: ${f.desc}`).join("\n")}
2414
2422
  Check these first; These Files > Training Data. Safety rules apply
2415
2423
  ` : "";
2416
2424
  return `${nameStr}${nicknameStr}${userInstrStr}[SYSTEM]
2417
- Identity: Flux Flow (by Kushal Roy Chowdhury). Sassy${mode === "Flux" ? ", No Flirting, Respectful" : ", Friendly, Humorous, Sarcastic"}, CLI Agent
2418
- Mode: ${mode}${thinkingLevel !== "Fast" ? " (Thinking Mode)" : ""}. ${mode === "Flux" ? "Logical, Highly Detailed, Task-Driven. Prioritizes scalable file/folder structures, modular architecture, clean code abstractions, step-by-step execution. Industry standard latest coding practices/libraries, clean code, Double Check Imports, Client-Server Sync" : "Conversational, Concise"}
2425
+ Identity: Flux Flow (by Kushal Roy Chowdhury). Conversational, Sassy${mode === "Flux" ? ", Respectful" : ", Friendly, Humorous, Sarcastic"}, CLI Agent
2426
+ Mode: ${mode}${thinkingLevel !== "Fast" ? " (Thinking Mode)" : ""}. ${mode === "Flux" ? "Logical, Highly Detailed, Task-Driven. Prioritizes scalable file/folder structures, modular architecture, clean code abstractions, step-by-step execution. Industry standard latest coding practices/libraries, clean code, Double Check Imports, Client-Server Sync" : "Concise"}
2419
2427
 
2420
2428
  -- AGENT LOOP RULES (PRIORITY: HIGH) --
2421
2429
  - **MUST END WITH [turn: continue] to CONTINUE loop OR [turn: finish] to END loop**
@@ -7219,14 +7227,8 @@ function App({ args = [] }) {
7219
7227
  const isTerminalWaitingForInput = useMemo2(() => {
7220
7228
  if (!activeCommand || !execOutput) return false;
7221
7229
  const lastChunk = execOutput.trim();
7222
- return lastChunk.endsWith("?") || lastChunk.endsWith(":") || /\[[yYnN/]+\]\s*$/.test(lastChunk);
7230
+ return lastChunk.endsWith("?") || lastChunk.endsWith(":") || /\[[yYnN/]+\]\s*$/.test(lastChunk) || /\([yYnN]\)\s*$/.test(lastChunk);
7223
7231
  }, [activeCommand, execOutput]);
7224
- const terminalWidth = stdout?.columns || 80;
7225
- const wrapWidth = Math.max(20, terminalWidth - 10);
7226
- const wrappedLinesCount = input.split(/\r?\n/).reduce((acc, line) => {
7227
- return acc + Math.max(1, Math.ceil(line.length / wrapWidth));
7228
- }, 0);
7229
- const maxLines = Math.max(1, wrappedLinesCount);
7230
7232
  useInput7((inputText, key) => {
7231
7233
  if (key.tab && activeCommand) {
7232
7234
  setIsTerminalFocused((prev) => !prev);
@@ -7267,16 +7269,6 @@ function App({ args = [] }) {
7267
7269
  }
7268
7270
  return;
7269
7271
  }
7270
- if (maxLines > 2 && !isExpanded && activeView === "chat") {
7271
- if (key.backspace || key.delete) {
7272
- setInput("");
7273
- return;
7274
- }
7275
- if (key.return) {
7276
- setIsExpanded(true);
7277
- return;
7278
- }
7279
- }
7280
7272
  if (key.escape) {
7281
7273
  if (suggestions.length > 0 && activeView === "chat") {
7282
7274
  setIsFilePickerDismissed(true);
@@ -8254,7 +8246,14 @@ ${timestamp}` };
8254
8246
  const rawOutput = execOutputRef.current || "";
8255
8247
  let normalizedOutput = "";
8256
8248
  if (isActiveCommandPty) {
8257
- const noTrailingCr = rawOutput.replace(/\r+\n/g, "\n");
8249
+ const screenResetRegex = /\x1b\[H|\x1b\[2J|\x1b\[3J|\x1bc/g;
8250
+ const resetMatches = [...rawOutput.matchAll(screenResetRegex)];
8251
+ let workingText = rawOutput;
8252
+ if (resetMatches.length > 0) {
8253
+ const lastMatch = resetMatches[resetMatches.length - 1];
8254
+ workingText = rawOutput.substring(lastMatch.index + lastMatch[0].length);
8255
+ }
8256
+ const noTrailingCr = workingText.replace(/\r+\n/g, "\n");
8258
8257
  normalizedOutput = noTrailingCr.split("\n").map((line) => {
8259
8258
  const parts = line.split("\r");
8260
8259
  return parts[parts.length - 1];
@@ -8262,11 +8261,21 @@ ${timestamp}` };
8262
8261
  } else {
8263
8262
  normalizedOutput = rawOutput.replace(/\r\n/g, "\n");
8264
8263
  }
8265
- const finalStatus = `[TERMINAL_RECORD]
8264
+ const finalStatusRaw = `[TERMINAL_RECORD]
8266
8265
  COMMAND: ${activeCommandRef.current}
8267
8266
  PTY: ${isActiveCommandPty}
8268
- OUTPUT: ${normalizedOutput}`;
8269
- return [...prev, { id: "term-" + Date.now(), role: "system", text: finalStatus, isTerminalRecord: true }];
8267
+ OUTPUT: ${rawOutput}`;
8268
+ const finalStatusNormalized = `[TERMINAL_RECORD]
8269
+ COMMAND: ${activeCommandRef.current}
8270
+ PTY: ${isActiveCommandPty}
8271
+ OUTPUT: ${normalizedOutput.replace(/\n{3,}/g, "\n\n")}`;
8272
+ return [...prev, {
8273
+ id: "term-" + Date.now(),
8274
+ role: "system",
8275
+ text: finalStatusRaw,
8276
+ fullText: finalStatusNormalized,
8277
+ isTerminalRecord: true
8278
+ }];
8270
8279
  });
8271
8280
  setActiveCommand(null);
8272
8281
  setIsTerminalFocused(false);
@@ -9163,24 +9172,7 @@ Selection: ${val}`,
9163
9172
  paddingY: 0,
9164
9173
  width: "100%"
9165
9174
  },
9166
- /* @__PURE__ */ React13.createElement(Box13, { flexDirection: "column", width: "100%" }, maxLines > 2 && !isExpanded ? /* @__PURE__ */ React13.createElement(Box13, { flexDirection: "row", width: "100%", paddingY: 0, height: 1, overflow: "hidden" }, /* @__PURE__ */ React13.createElement(Box13, { flexShrink: 0, width: 4 }, /* @__PURE__ */ React13.createElement(Text13, { color: "cyan", bold: true }, "\u{1F4A0} ")), /* @__PURE__ */ React13.createElement(Box13, { flexGrow: 1, flexDirection: "row" }, /* @__PURE__ */ React13.createElement(Box13, { flexShrink: 0 }, /* @__PURE__ */ React13.createElement(Text13, { color: "magenta", bold: true }, "[PASTED ", maxLines, " LINES]")), /* @__PURE__ */ React13.createElement(Box13, { flexGrow: 1, marginLeft: 1 }, /* @__PURE__ */ React13.createElement(
9167
- MultilineInput,
9168
- {
9169
- value: "",
9170
- placeholder: " (Backspace to delete / Enter to expand)",
9171
- onChange: (val) => {
9172
- if (val.length > 0) {
9173
- setIsExpanded(true);
9174
- setInput(input + val);
9175
- }
9176
- },
9177
- onSubmit: () => setIsExpanded(true),
9178
- keyBindings: {
9179
- submit: (key) => key.return && !key.shift && !key.ctrl && !key.leftAlt && !key.rightAlt,
9180
- newline: (key) => key.return && key.shift || key.return && key.ctrl || key.return && key.leftAlt || key.return && key.rightAlt
9181
- }
9182
- }
9183
- )))) : /* @__PURE__ */ React13.createElement(Box13, { flexDirection: "row", width: "100%", paddingY: 0 }, /* @__PURE__ */ React13.createElement(Box13, { flexShrink: 0, width: 4 }, /* @__PURE__ */ React13.createElement(Text13, { color: isProcessing ? "magenta" : "cyan", bold: true }, isProcessing ? "\u2726 " : "\u{1F4A0} ")), /* @__PURE__ */ React13.createElement(Box13, { flexGrow: 1 }, /* @__PURE__ */ React13.createElement(Box13, { flexGrow: 1, position: "relative" }, input === "" && /* @__PURE__ */ React13.createElement(Box13, { position: "absolute", paddingLeft: 0 }, activeCommand && !isTerminalFocused ? /* @__PURE__ */ React13.createElement(Text13, { color: "yellow" }, isTerminalWaitingForInput ? " Terminal is waiting for user input. Press TAB to interact" : " Press TAB to interact with terminal...") : activeCommand && isTerminalFocused ? /* @__PURE__ */ React13.createElement(Text13, { color: "yellow", bold: true }, " [ TERMINAL FOCUSED ] Type to interact, press TAB to exit...") : escPressCount === 1 ? /* @__PURE__ */ React13.createElement(Text13, { color: "cyan", bold: true }, " Press ESC again to ", input.length > 0 ? "clear input" : "revert codebase to checkpoint", "...") : /* @__PURE__ */ React13.createElement(Text13, { color: "gray" }, escPressed ? " Press ESC again to cancel the request." : !isProcessing ? ` Send message or /cmd... (${terminalEnv.shortcut} for newline)` : " Enter a prompt to steer the agent.")), /* @__PURE__ */ React13.createElement(
9175
+ /* @__PURE__ */ React13.createElement(Box13, { flexDirection: "column", width: "100%" }, /* @__PURE__ */ React13.createElement(Box13, { flexDirection: "row", width: "100%", paddingY: 0 }, /* @__PURE__ */ React13.createElement(Box13, { flexShrink: 0, width: 4 }, /* @__PURE__ */ React13.createElement(Text13, { color: isProcessing ? "magenta" : "cyan", bold: true }, isProcessing ? "\u2726 " : "\u{1F4A0} ")), /* @__PURE__ */ React13.createElement(Box13, { flexGrow: 1 }, /* @__PURE__ */ React13.createElement(Box13, { flexGrow: 1, position: "relative" }, input === "" && /* @__PURE__ */ React13.createElement(Box13, { position: "absolute", paddingLeft: 0 }, activeCommand && !isTerminalFocused ? /* @__PURE__ */ React13.createElement(Text13, { color: "yellow" }, isTerminalWaitingForInput ? " Terminal is waiting for user input. Press TAB to interact" : " Press TAB to interact with terminal...") : activeCommand && isTerminalFocused ? /* @__PURE__ */ React13.createElement(Text13, { color: "yellow", bold: true }, " [ TERMINAL FOCUSED ] Type to interact, press TAB to exit...") : escPressCount === 1 ? /* @__PURE__ */ React13.createElement(Text13, { color: "cyan", bold: true }, " Press ESC again to ", input.length > 0 ? "clear input" : "revert codebase to checkpoint", "...") : /* @__PURE__ */ React13.createElement(Text13, { color: "gray" }, escPressed ? " Press ESC again to cancel the request." : !isProcessing ? ` Send message or /cmd... (${terminalEnv.shortcut} for newline)` : " Enter a prompt to steer the agent.")), /* @__PURE__ */ React13.createElement(
9184
9176
  MultilineInput,
9185
9177
  {
9186
9178
  key: `input-${inputKey}`,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "fluxflow-cli",
3
- "version": "1.18.13",
3
+ "version": "1.18.14",
4
4
  "date": "2026-06-01",
5
5
  "description": "A high-fidelity agentic terminal assistant for the Flux Era.",
6
6
  "keywords": [