fluxflow-cli 1.0.12 → 1.0.13

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 +23 -49
  2. package/package.json +1 -1
package/dist/fluxflow.js CHANGED
@@ -192,7 +192,7 @@ function StatusBar({ mode, thinkingLevel, tokens = "0.0k", chatId = "NEW-SESSION
192
192
  },
193
193
  /* @__PURE__ */ React3.createElement(Box3, null, /* @__PURE__ */ React3.createElement(Text3, { color: modeColor, bold: true }, modeIcon, " ", mode.toUpperCase()), /* @__PURE__ */ React3.createElement(Text3, { color: "gray" }, " \u2502 "), /* @__PURE__ */ React3.createElement(Text3, { color: "magenta" }, "\u{1F9E0} ", thinkingLevel)),
194
194
  /* @__PURE__ */ React3.createElement(Box3, { flexGrow: 1, justifyContent: "center", paddingX: 2 }, /* @__PURE__ */ React3.createElement(Text3, { color: "gray", dimColor: true }, "\u{1F4C1} "), /* @__PURE__ */ React3.createElement(Text3, { color: "blue", dimColor: true, italic: true }, process.cwd())),
195
- /* @__PURE__ */ React3.createElement(Box3, null, /* @__PURE__ */ React3.createElement(Text3, { color: "gray" }, "MEM: "), /* @__PURE__ */ React3.createElement(Text3, { color: memStatus === "ON" ? "green" : "red" }, memStatus), /* @__PURE__ */ React3.createElement(Text3, { color: "gray" }, " \u2502 "), /* @__PURE__ */ React3.createElement(Text3, { color: "blue" }, " Tokens ", tokens > 1e3 ? `${(tokens / 1e3).toFixed(1)}k` : tokens, " (", Math.round(tokens / 196e3 * 100), "%)"), /* @__PURE__ */ React3.createElement(Text3, { color: "gray" }, " \u2502 "), /* @__PURE__ */ React3.createElement(Text3, { color: "dim" }, "ID: ", chatId, " "))
195
+ /* @__PURE__ */ React3.createElement(Box3, null, /* @__PURE__ */ React3.createElement(Text3, { color: "gray" }, "MEM: "), /* @__PURE__ */ React3.createElement(Text3, { color: memStatus === "ON" ? "green" : "red" }, memStatus), /* @__PURE__ */ React3.createElement(Text3, { color: "gray" }, " \u2502 "), /* @__PURE__ */ React3.createElement(Text3, { color: "blue" }, " Tokens ", tokens > 1e3 ? `${(tokens / 1e3).toFixed(1)}k` : tokens, " (", Math.round(tokens / 254e3 * 100), "%)"), /* @__PURE__ */ React3.createElement(Text3, { color: "gray" }, " \u2502 "), /* @__PURE__ */ React3.createElement(Text3, { color: "dim" }, "ID: ", chatId, " "))
196
196
  );
197
197
  }
198
198
 
@@ -345,11 +345,11 @@ tool:functions.tool_name(arguments)
345
345
  2. Web Scrape: tool:functions.web_scrape(url="<url>"). provides detail from a URL.
346
346
  ${mode === "Flux" ? `
347
347
  - DEV & FILE TOOLS (Available in FLUX MODE ONLY) -
348
- 1. View File: tool:functions.view_file(path="relative/path", start_line=number, end_line=number). Reads file content.
348
+ 1. View File: tool:functions.view_file(path="relative/path", start_line=number, end_line=number). Reads file content. Auto-truncates at 500 lines unless start_line and end_line are provided.
349
349
  2. List Files: tool:functions.list_files(path="relative/path"). Lists content of a directory.
350
350
  3. Read Folder: tool:functions.read_folder(path="relative/path"). Detailed stats of a directory.
351
- 4. Write File: tool:functions.write_file(path="relative/path", content="full content"). Creates/Overwrites a file. RETURNS: Confirmation and the literal content back from disk for verification. DONT WRAP WRITE FILE CALL CONTENT IN MARKDOWN CODE BLOCKS.
352
- 5. Update File: tool:functions.update_file(path="relative/path", content_to_replace="old", content_to_add="new"). Surgical patching. RETURNS: High-fidelity visual diff and old code block. You MUST verify that the change specifically matches your intent using the returned diff. PREFFER UPDATE FILE OVER WRITE FILE if file already exists. DONT WRAP UPDATE FILE CALL CONTENT IN MARKDOWN CODE BLOCKS.
351
+ 4. Write File: tool:functions.write_file(path="path", content="content"). Creates/Overwrites. NO CODE BLOCKS. RETURNS: Disk verification + original content (if overwritten) for 100% reversibility.
352
+ 5. Update File: tool:functions.update_file(path="relative/path", content_to_replace="old", content_to_add="new"). Surgical patching. RETURNS: High-fidelity visual diff and old code block. You MUST verify that the change specifically matches your intent using the returned diff. PREFFER UPDATE FILE OVER WRITE FILE if file already exists for better reversal tracking (if a file has 500+ lines, try to stick with update_file over full-rewrite). DONT WRAP UPDATE FILE CALL CONTENT IN MARKDOWN CODE BLOCKS.
353
353
  6. Execution: tool:functions.exec_command(command="terminal command"). Runs a shell command.`.trim() : `
354
354
  - DEV & FILE TOOLS are not available in FLOW MODE. If you need to access files, tell the user to switch to FLUX MODE (manually by user).`.trim()}
355
355
  -----------------
@@ -843,46 +843,6 @@ var chat = async (rawArgs, context = {}) => {
843
843
  }
844
844
  };
845
845
 
846
- // src/tools/summary.js
847
- var summary = async (rawArgs, context = {}) => {
848
- const parseArg = (key) => {
849
- const regex = new RegExp(`${key}\\s*=\\s*(["'])(.*?)\\1(?=\\s*[,)]|\\s+\\w+\\s*=|$)`, "s");
850
- const match = rawArgs.match(regex);
851
- return match ? match[2].trim() : null;
852
- };
853
- const content = parseArg("content");
854
- const chatId = context.chatId;
855
- const { startIndex, endIndex } = context.summarizedIndices || {};
856
- if (!chatId) return "ERROR: No active chatId found in tool context.";
857
- if (!content) return "ERROR: Missing 'content' argument.";
858
- if (startIndex === void 0 || endIndex === void 0) {
859
- return "ERROR: Summary tool called without target range indices in context.";
860
- }
861
- try {
862
- const history = await loadHistory();
863
- if (history[chatId]) {
864
- const messages = history[chatId].messages;
865
- const summaryMsg = {
866
- id: `summary-${Date.now()}`,
867
- role: "system",
868
- text: content
869
- };
870
- const actualStart = Math.min(startIndex, messages.length - 1);
871
- const actualEnd = Math.min(endIndex, messages.length - 1);
872
- const count = actualEnd - actualStart + 1;
873
- if (count > 0) {
874
- messages.splice(actualStart, count, summaryMsg);
875
- await saveChat(chatId, history[chatId].name, messages);
876
- return `SUCCESS: Compressed ${count} turns into a summary block.`;
877
- }
878
- return "ERROR: Targeted range for summarization is invalid or empty.";
879
- }
880
- return "ERROR: Chat session not found.";
881
- } catch (err) {
882
- return `ERROR: Failed to save summary: ${err.message}`;
883
- }
884
- };
885
-
886
846
  // src/tools/list_files.js
887
847
  import fs7 from "fs";
888
848
  import path8 from "path";
@@ -980,6 +940,21 @@ var write_file = async (args) => {
980
940
  const absolutePath = path10.resolve(process.cwd(), targetPath);
981
941
  const parentDir = path10.dirname(absolutePath);
982
942
  try {
943
+ let ancestry = "";
944
+ if (fs9.existsSync(absolutePath)) {
945
+ try {
946
+ const oldData = fs9.readFileSync(absolutePath, "utf8");
947
+ const lines = oldData.split(/\r?\n/);
948
+ ancestry = `Old File contents:
949
+ ${lines.map((l, i) => `${i + 1} | ${l}`).join("\n")}
950
+
951
+ `;
952
+ } catch (e) {
953
+ ancestry = `[Note: Could not read existing file for reversal reference]
954
+
955
+ `;
956
+ }
957
+ }
983
958
  if (!fs9.existsSync(parentDir)) {
984
959
  fs9.mkdirSync(parentDir, { recursive: true });
985
960
  }
@@ -1010,7 +985,7 @@ ${tail}`;
1010
985
  return `SUCCESS: File [${targetPath}] verified and persisted.
1011
986
 
1012
987
  - Stats: [${verifiedLineCount} lines, ${(verifiedSize / 1024).toFixed(1)} KB]
1013
- - Content Preview:
988
+ ${ancestry}- Content Preview:
1014
989
  ${snippet}`;
1015
990
  } catch (err) {
1016
991
  return `ERROR: Failed to write file [${targetPath}]: ${err.message}`;
@@ -1187,7 +1162,6 @@ var TOOL_MAP = {
1187
1162
  web_scrape,
1188
1163
  memory,
1189
1164
  chat,
1190
- summary,
1191
1165
  list_files,
1192
1166
  view_file,
1193
1167
  write_file,
@@ -1264,7 +1238,7 @@ var getAIStream = async function* (modelName, history, settings, steeringCallbac
1264
1238
  const needTitle = isFirstPrompt || hasTitleSignal;
1265
1239
  const agentText = originalText.replace(/\[TITLE-UPDATE\]/g, "").trim();
1266
1240
  let modifiedHistory = [...history.slice(0, -1)];
1267
- if (systemSettings?.compression === 0 && (sessionStats?.tokens || 0) > 196e3) {
1241
+ if (systemSettings?.compression === 0 && (sessionStats?.tokens || 0) > 254e3) {
1268
1242
  modifiedHistory = getTruncatedHistory(modifiedHistory, 4);
1269
1243
  }
1270
1244
  const tempStorage = readEncryptedJson(TEMP_MEM_FILE, {});
@@ -1342,10 +1316,10 @@ USER_PROMPT: ${agentText}`.trim();
1342
1316
  if (retryCount < MAX_RETRIES) {
1343
1317
  retryCount++;
1344
1318
  const waitTime = Math.floor(Math.random() * (2e3 - 800 + 1)) + 800;
1345
- yield { type: "status", content: `Retrying (${retryCount}/${MAX_RETRIES})...` };
1319
+ yield { type: "status", content: `Retrying (${retryCount}/${MAX_RETRIES + 1})...` };
1346
1320
  await new Promise((resolve) => setTimeout(resolve, waitTime));
1347
1321
  } else {
1348
- throw new Error(`Model cannot be reached: ${errMsg}. (Failed ${MAX_RETRIES} times)`);
1322
+ throw new Error(`Model cannot be reached: ${errMsg}. (Failed ${MAX_RETRIES + 1} times)`);
1349
1323
  }
1350
1324
  }
1351
1325
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "fluxflow-cli",
3
- "version": "1.0.12",
3
+ "version": "1.0.13",
4
4
  "description": "A high-fidelity agentic terminal assistant for the Flux Era.",
5
5
  "keywords": [
6
6
  "ai",