fluxflow-cli 1.18.1 → 1.18.3

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 +42 -14
  2. package/package.json +1 -1
package/dist/fluxflow.js CHANGED
@@ -440,11 +440,15 @@ var init_TerminalBox = __esm({
440
440
  "src/components/TerminalBox.jsx"() {
441
441
  init_text();
442
442
  TerminalBox = React2.memo(({ command, output, completed = false, isFocused = false, columns = 80, isPty = false }) => {
443
- const processOutput = (text) => {
443
+ const processPTY = (text) => {
444
444
  if (!text) return "";
445
- return text.split(/\r\n|\r|\n/).map((line) => line.trimEnd()).join("\n").replace(/^\n+|\n+$/g, "");
445
+ const noTrailingCr = text.replace(/\r+\n/g, "\n");
446
+ return noTrailingCr.split("\n").map((line) => {
447
+ const parts = line.split("\r");
448
+ return parts[parts.length - 1];
449
+ }).join("\n");
446
450
  };
447
- const cleanOutput = processOutput(output);
451
+ const cleanOutput = isPty ? processPTY(output) : (output || "").replace(/\r\n/g, "\n");
448
452
  const displayOutput = isPty ? cleanOutput : cleanOutput ? wrapText(cleanOutput, columns - 6) : "";
449
453
  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 }, "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)")));
450
454
  });
@@ -3226,16 +3230,28 @@ var init_update_file = __esm({
3226
3230
  const targetPath = parsed.path;
3227
3231
  if (!targetPath) return 'ERROR: Missing "path" argument for update_file.';
3228
3232
  const patchPairs = [];
3229
- const legacyReplace = parsed.content_to_replace !== void 0 ? parsed.content_to_replace : parsed.replaceContent;
3230
- const legacyNew = parsed.content_to_add !== void 0 ? parsed.content_to_add : parsed.newContent;
3231
- if (legacyReplace !== void 0 && legacyNew !== void 0) {
3232
- patchPairs.push({ replace: legacyReplace, new: legacyNew });
3233
- }
3234
- for (let i = 1; i <= 10; i++) {
3235
- const r = parsed[`replaceContent${i}`];
3236
- const n = parsed[`newContent${i}`];
3237
- if (r !== void 0 && n !== void 0 && r !== legacyReplace) {
3233
+ const indices = /* @__PURE__ */ new Set();
3234
+ Object.keys(parsed).forEach((key) => {
3235
+ const m = key.match(/^(replaceContent|newContent|content_to_replace|content_to_add)(\d+)?$/);
3236
+ if (m) {
3237
+ const index = m[2] ? parseInt(m[2]) : 1;
3238
+ indices.add(index);
3239
+ }
3240
+ });
3241
+ const sortedIndices = Array.from(indices).sort((a, b) => a - b);
3242
+ for (const i of sortedIndices) {
3243
+ let r, n;
3244
+ if (i === 1) {
3245
+ r = parsed.replaceContent1 ?? (parsed.content_to_replace ?? parsed.replaceContent);
3246
+ n = parsed.newContent1 ?? (parsed.content_to_add ?? parsed.newContent);
3247
+ } else {
3248
+ r = parsed[`replaceContent${i}`] ?? parsed[`content_to_replace${i}`];
3249
+ n = parsed[`newContent${i}`] ?? parsed[`content_to_add${i}`];
3250
+ }
3251
+ if (r !== void 0 && n !== void 0) {
3238
3252
  patchPairs.push({ replace: r, new: n });
3253
+ } else if (r !== void 0 || n !== void 0) {
3254
+ return `ERROR: Mismatched replacement pair for index ${i}. Both replacement and new content must be provided.`;
3239
3255
  }
3240
3256
  }
3241
3257
  if (patchPairs.length === 0) {
@@ -3626,7 +3642,8 @@ var init_exec_command = __esm({
3626
3642
  });
3627
3643
  ptyProcess.onExit(({ exitCode }) => {
3628
3644
  activeChildProcess = null;
3629
- const finalOutput = output || "Command executed with no output.";
3645
+ const normalizedOutput = (output || "").replace(/\r\n/g, "\n").replace(/\r/g, "\n");
3646
+ const finalOutput = normalizedOutput || "Command executed with no output.";
3630
3647
  if (exitCode !== 0) {
3631
3648
  resolve(`ERROR: Command [${rawCommand}] failed with exit code [${exitCode}].
3632
3649
 
@@ -7785,10 +7802,21 @@ ${timestamp}` };
7785
7802
  onExecEnd: () => {
7786
7803
  setMessages((prev) => {
7787
7804
  if (!activeCommandRef.current) return prev;
7805
+ const rawOutput = execOutputRef.current || "";
7806
+ let normalizedOutput = "";
7807
+ if (isActiveCommandPty) {
7808
+ const noTrailingCr = rawOutput.replace(/\r+\n/g, "\n");
7809
+ normalizedOutput = noTrailingCr.split("\n").map((line) => {
7810
+ const parts = line.split("\r");
7811
+ return parts[parts.length - 1];
7812
+ }).join("\n");
7813
+ } else {
7814
+ normalizedOutput = rawOutput.replace(/\r\n/g, "\n");
7815
+ }
7788
7816
  const finalStatus = `[TERMINAL_RECORD]
7789
7817
  COMMAND: ${activeCommandRef.current}
7790
7818
  PTY: ${isActiveCommandPty}
7791
- OUTPUT: ${execOutputRef.current}`;
7819
+ OUTPUT: ${normalizedOutput}`;
7792
7820
  return [...prev, { id: "term-" + Date.now(), role: "system", text: finalStatus, isTerminalRecord: true }];
7793
7821
  });
7794
7822
  setActiveCommand(null);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "fluxflow-cli",
3
- "version": "1.18.1",
3
+ "version": "1.18.3",
4
4
  "date": "2026-05-30",
5
5
  "description": "A high-fidelity agentic terminal assistant for the Flux Era.",
6
6
  "keywords": [