fluxflow-cli 1.18.15 → 1.18.17

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 +187 -107
  2. package/package.json +1 -1
package/dist/fluxflow.js CHANGED
@@ -1033,15 +1033,27 @@ var init_arg_parser = __esm({
1033
1033
  while (searchIndex < argsString.length) {
1034
1034
  let qIdx = argsString.indexOf(quote, searchIndex);
1035
1035
  if (qIdx === -1) break;
1036
- if (argsString[qIdx - 1] === "\\" && argsString[qIdx - 2] !== "\\") {
1036
+ let backslashCount = 0;
1037
+ for (let k = qIdx - 1; k >= 0 && argsString[k] === "\\"; k--) {
1038
+ backslashCount++;
1039
+ }
1040
+ if (backslashCount % 2 !== 0) {
1037
1041
  searchIndex = qIdx + 1;
1038
1042
  continue;
1039
1043
  }
1040
- const after = argsString.substring(qIdx + 1).trim();
1044
+ const afterRaw = argsString.substring(qIdx + 1);
1045
+ const after = afterRaw.trim();
1041
1046
  const isLogicalEnd = after === "" || // End of entire string
1042
1047
  after.startsWith(",") || // Next argument separator
1043
1048
  /^(\w+)\s*=/.test(after) || // Next argument key=
1044
1049
  after.startsWith(")") && (after.length === 1 || /^\)\s*([,\]\s]|tool:)/i.test(after));
1050
+ if (isLogicalEnd && afterRaw.startsWith("\n")) {
1051
+ const nextLine = after.split("\n")[0];
1052
+ if (!nextLine.includes("=") && !nextLine.includes(")")) {
1053
+ searchIndex = qIdx + 1;
1054
+ continue;
1055
+ }
1056
+ }
1045
1057
  if (isLogicalEnd) {
1046
1058
  end = qIdx;
1047
1059
  break;
@@ -1056,18 +1068,21 @@ var init_arg_parser = __esm({
1056
1068
  i = argsString.length;
1057
1069
  }
1058
1070
  const isPathKey = key.toLowerCase().includes("path") || ["dest", "source", "to", "from"].includes(key.toLowerCase());
1059
- if (isPathKey) {
1060
- value = value.replace(/\\"/g, '"').replace(/\\'/g, "'").replace(/\\`/g, "`").replace(/\\\\/g, "\\");
1061
- } else {
1062
- try {
1063
- if (value.includes("\\")) {
1064
- const surgicalValue = value.replace(/(^|[^\\])"/g, '$1\\"');
1065
- value = JSON.parse(`"${surgicalValue.replace(/\n/g, "\\n").replace(/\r/g, "\\r")}"`);
1066
- }
1067
- } catch (e) {
1068
- value = value.replace(/\\"/g, '"').replace(/\\'/g, "'").replace(/\\`/g, "`").replace(/\\\\/g, "\\").replace(/\\n/g, "\n");
1071
+ value = value.replace(/\\(.)/g, (match, char) => {
1072
+ switch (char) {
1073
+ case "n":
1074
+ return "\n";
1075
+ case "r":
1076
+ return "\r";
1077
+ case "t":
1078
+ return " ";
1079
+ case "\\":
1080
+ return "\\";
1081
+ default:
1082
+ if (char === quote) return quote;
1083
+ return match;
1069
1084
  }
1070
- }
1085
+ });
1071
1086
  } else if (i < argsString.length && argsString[i] === "[") {
1072
1087
  let balance = 0;
1073
1088
  let inString = null;
@@ -1075,10 +1090,16 @@ var init_arg_parser = __esm({
1075
1090
  let end = -1;
1076
1091
  for (let j = i; j < argsString.length; j++) {
1077
1092
  const char = argsString[j];
1078
- if (!inString && (char === '"' || char === "'" || char === "`")) {
1093
+ if (inString && char === inString) {
1094
+ let backslashCount = 0;
1095
+ for (let k = j - 1; k >= 0 && argsString[k] === "\\"; k--) {
1096
+ backslashCount++;
1097
+ }
1098
+ if (backslashCount % 2 === 0) {
1099
+ inString = null;
1100
+ }
1101
+ } else if (!inString && (char === '"' || char === "'" || char === "`")) {
1079
1102
  inString = char;
1080
- } else if (inString && char === inString && argsString[j - 1] !== "\\") {
1081
- inString = null;
1082
1103
  }
1083
1104
  if (!inString) {
1084
1105
  if (char === "[") balance++;
@@ -4653,7 +4674,23 @@ var init_generate_image = __esm({
4653
4674
  await RevertManager.recordFileChange(absolutePath);
4654
4675
  await fs15.writeFile(absolutePath, finalBuffer);
4655
4676
  await recordImageGeneration(settings);
4656
- return `SUCCESS: Image successfully generated from prompt [${prompt}] and saved to [${outputPath}].`;
4677
+ const ext = path14.extname(outputPath).toLowerCase();
4678
+ const mimeMap = {
4679
+ ".jpg": "image/jpeg",
4680
+ ".jpeg": "image/jpeg",
4681
+ ".png": "image/png",
4682
+ ".webp": "image/webp"
4683
+ };
4684
+ const mimeType = mimeMap[ext] || "image/png";
4685
+ return {
4686
+ text: `SUCCESS: Image successfully generated from prompt [${prompt}] and saved to [${outputPath}]. Output attached to multimodal part`,
4687
+ binaryPart: {
4688
+ inlineData: {
4689
+ data: finalBuffer.toString("base64"),
4690
+ mimeType
4691
+ }
4692
+ }
4693
+ };
4657
4694
  } catch (err) {
4658
4695
  return `ERROR: Failed during image generation: ${err.message}`;
4659
4696
  }
@@ -5106,30 +5143,36 @@ ${originalTextProcessed.length > USER_CONTEXT_LENGTH ? "... (truncated) ...\n\n"
5106
5143
  const startIdx = match.index + match[0].length - 1;
5107
5144
  let balance = 0;
5108
5145
  let inString = null;
5109
- let isEscaped = false;
5110
5146
  let endIdx = -1;
5111
5147
  for (let i = startIdx; i < text.length; i++) {
5112
5148
  const char = text[i];
5113
- if (!inString && (char === '"' || char === "'" || char === "`")) {
5114
- inString = char;
5115
- isEscaped = false;
5116
- } else if (inString && char === inString && !isEscaped) {
5117
- inString = null;
5118
- }
5119
- if (!inString) {
5120
- if (char === "(") balance++;
5121
- else if (char === ")") balance--;
5122
- if (balance === 0) {
5123
- let j = i + 1;
5124
- while (j < text.length && /\s/.test(text[j])) j++;
5125
- if (j < text.length && text[j] === "]") {
5126
- endIdx = j;
5127
- break;
5149
+ if (inString) {
5150
+ if (char === inString) {
5151
+ let backslashCount = 0;
5152
+ for (let j = i - 1; j >= 0 && text[j] === "\\"; j--) {
5153
+ backslashCount++;
5154
+ }
5155
+ if (backslashCount % 2 === 0) {
5156
+ inString = null;
5157
+ }
5158
+ }
5159
+ } else {
5160
+ if (char === '"' || char === "'" || char === "`") {
5161
+ inString = char;
5162
+ } else if (char === "(") {
5163
+ balance++;
5164
+ } else if (char === ")") {
5165
+ balance--;
5166
+ if (balance === 0) {
5167
+ let j = i + 1;
5168
+ while (j < text.length && /\s/.test(text[j])) j++;
5169
+ if (j < text.length && text[j] === "]") {
5170
+ endIdx = j;
5171
+ break;
5172
+ }
5128
5173
  }
5129
5174
  }
5130
5175
  }
5131
- if (char === "\\") isEscaped = !isEscaped;
5132
- else isEscaped = false;
5133
5176
  }
5134
5177
  if (endIdx !== -1) {
5135
5178
  result += "[tool:functions." + match[1] + "()]";
@@ -5157,30 +5200,36 @@ ${originalTextProcessed.length > USER_CONTEXT_LENGTH ? "... (truncated) ...\n\n"
5157
5200
  const startIdx = match.index + match[0].length - 1;
5158
5201
  let balance = 0;
5159
5202
  let inString = null;
5160
- let isEscaped = false;
5161
5203
  let endIdx = -1;
5162
5204
  for (let i = startIdx; i < text.length; i++) {
5163
5205
  const char = text[i];
5164
- if (!inString && (char === '"' || char === "'" || char === "`")) {
5165
- inString = char;
5166
- isEscaped = false;
5167
- } else if (inString && char === inString && !isEscaped) {
5168
- inString = null;
5169
- }
5170
- if (!inString) {
5171
- if (char === "(") balance++;
5172
- else if (char === ")") balance--;
5173
- if (balance === 0) {
5174
- let j = i + 1;
5175
- while (j < text.length && /\s/.test(text[j])) j++;
5176
- if (j < text.length && text[j] === "]") {
5177
- endIdx = j;
5178
- break;
5206
+ if (inString) {
5207
+ if (char === inString) {
5208
+ let backslashCount = 0;
5209
+ for (let j = i - 1; j >= 0 && text[j] === "\\"; j--) {
5210
+ backslashCount++;
5211
+ }
5212
+ if (backslashCount % 2 === 0) {
5213
+ inString = null;
5214
+ }
5215
+ }
5216
+ } else {
5217
+ if (char === '"' || char === "'" || char === "`") {
5218
+ inString = char;
5219
+ } else if (char === "(") {
5220
+ balance++;
5221
+ } else if (char === ")") {
5222
+ balance--;
5223
+ if (balance === 0) {
5224
+ let j = i + 1;
5225
+ while (j < text.length && /\s/.test(text[j])) j++;
5226
+ if (j < text.length && text[j] === "]") {
5227
+ endIdx = j;
5228
+ break;
5229
+ }
5179
5230
  }
5180
5231
  }
5181
5232
  }
5182
- if (char === "\\") isEscaped = !isEscaped;
5183
- else isEscaped = false;
5184
5233
  }
5185
5234
  if (endIdx !== -1) {
5186
5235
  result += text.substring(match.index, endIdx + 1);
@@ -5209,34 +5258,37 @@ ${originalTextProcessed.length > USER_CONTEXT_LENGTH ? "... (truncated) ...\n\n"
5209
5258
  const startIdx = match.index + match[0].length - 1;
5210
5259
  let balance = 0;
5211
5260
  let inString = null;
5212
- let isEscaped = false;
5213
5261
  let endIdx = -1;
5214
5262
  let closingParenIdx = -1;
5215
5263
  for (let i = startIdx; i < text.length; i++) {
5216
5264
  const char = text[i];
5217
- if (!inString && (char === '"' || char === "'" || char === "`")) {
5218
- inString = char;
5219
- isEscaped = false;
5220
- } else if (inString && char === inString && !isEscaped) {
5221
- inString = null;
5222
- }
5223
- if (!inString) {
5224
- if (char === "(") balance++;
5225
- else if (char === ")") balance--;
5226
- if (balance === 0) {
5227
- closingParenIdx = i;
5228
- let j = i + 1;
5229
- while (j < text.length && /\s/.test(text[j])) j++;
5230
- if (j < text.length && text[j] === "]") {
5231
- endIdx = j;
5232
- break;
5265
+ if (inString) {
5266
+ if (char === inString) {
5267
+ let backslashCount = 0;
5268
+ for (let j = i - 1; j >= 0 && text[j] === "\\"; j--) {
5269
+ backslashCount++;
5270
+ }
5271
+ if (backslashCount % 2 === 0) {
5272
+ inString = null;
5233
5273
  }
5234
5274
  }
5235
- }
5236
- if (char === "\\") {
5237
- isEscaped = !isEscaped;
5238
5275
  } else {
5239
- isEscaped = false;
5276
+ if (char === '"' || char === "'" || char === "`") {
5277
+ inString = char;
5278
+ } else if (char === "(") {
5279
+ balance++;
5280
+ } else if (char === ")") {
5281
+ balance--;
5282
+ if (balance === 0) {
5283
+ closingParenIdx = i;
5284
+ let j = i + 1;
5285
+ while (j < text.length && /\s/.test(text[j])) j++;
5286
+ if (j < text.length && text[j] === "]") {
5287
+ endIdx = j;
5288
+ break;
5289
+ }
5290
+ }
5291
+ }
5240
5292
  }
5241
5293
  }
5242
5294
  if (endIdx !== -1) {
@@ -5694,10 +5746,13 @@ ${thinkingLevel != "Fast" ? "[SYSTEM] **STRICTLY FOLLOW THINKING POLICY AS CRITI
5694
5746
  accumulatedContext = "";
5695
5747
  }
5696
5748
  }
5697
- const contents = modifiedHistory.filter((msg) => (msg.role === "user" || msg.role === "agent" || msg.role === "system") && !String(msg.id).startsWith("welcome") && !msg.isMeta && !msg.isTerminalRecord && !(msg.text && msg.text.startsWith("[TERMINAL_RECORD]"))).map((msg) => {
5749
+ const contents = modifiedHistory.filter((msg) => (msg.role === "user" || msg.role === "agent" || msg.role === "system") && !String(msg.id).startsWith("welcome") && !msg.isMeta && !msg.isTerminalRecord && !(msg.text && msg.text.startsWith("[TERMINAL_RECORD]"))).map((msg, idx, arr) => {
5698
5750
  const parts = [{ text: msg.text }];
5699
5751
  if (msg.binaryPart) {
5700
- parts.push(msg.binaryPart);
5752
+ const physicalUserTurnsAfter = arr.slice(idx + 1).filter((m) => m.role === "user" && !m.text?.startsWith("[TOOL RESULT]")).length;
5753
+ if (physicalUserTurnsAfter <= 4) {
5754
+ parts.push(msg.binaryPart);
5755
+ }
5701
5756
  }
5702
5757
  return {
5703
5758
  role: msg.role === "user" || msg.role === "system" ? "user" : "model",
@@ -5705,7 +5760,7 @@ ${thinkingLevel != "Fast" ? "[SYSTEM] **STRICTLY FOLLOW THINKING POLICY AS CRITI
5705
5760
  };
5706
5761
  });
5707
5762
  if (!await checkQuota("agent", settings)) {
5708
- throw new Error("Error: Daily Quota Exausted for Agent");
5763
+ throw new Error("Error: Quota Exausted for Agent");
5709
5764
  }
5710
5765
  let targetModel = modelName;
5711
5766
  if (retryCount === MAX_RETRIES - 1) {
@@ -5749,7 +5804,8 @@ ${thinkingLevel != "Fast" ? "[SYSTEM] **STRICTLY FOLLOW THINKING POLICY AS CRITI
5749
5804
  { category: HarmCategory.HARM_CATEGORY_SEXUALLY_EXPLICIT, threshold: HarmBlockThreshold.BLOCK_NONE },
5750
5805
  { category: HarmCategory.HARM_CATEGORY_DANGEROUS_CONTENT, threshold: HarmBlockThreshold.BLOCK_NONE }
5751
5806
  ],
5752
- thinkingConfig: { includeThoughts: false, thinkingLevel: targetModel.includes("pro") ? ThinkingLevel.HIGH : ThinkingLevel.MINIMAL }
5807
+ thinkingConfig: { includeThoughts: false, thinkingLevel: ThinkingLevel.MINIMAL }
5808
+ // Optimized for Gemma 4.
5753
5809
  }
5754
5810
  });
5755
5811
  if (addedMarker && contents[contents.length - 1]?.parts?.[0]) {
@@ -7099,19 +7155,31 @@ function App({ args = [] }) {
7099
7155
  const [isTerminalFocused, setIsTerminalFocused] = useState10(false);
7100
7156
  const [tick, setTick] = useState10(0);
7101
7157
  useEffect7(() => {
7102
- if (apiTier !== "Free" && activeModel === "gemma-4-31b-it") {
7158
+ const s = emojiSpace(2);
7159
+ if (apiTier === "Free") {
7160
+ setActiveModel("gemma-4-31b-it");
7161
+ setMessages((prev) => {
7162
+ setCompletedIndex(prev.length + 1);
7163
+ return [...prev, {
7164
+ id: "tier-switch-" + Date.now(),
7165
+ role: "system",
7166
+ text: `\u26A0\uFE0F${s}**[TIER LIMIT]** Auto-switched to Gemma (Free default).`,
7167
+ isMeta: true
7168
+ }];
7169
+ });
7170
+ } else {
7103
7171
  setActiveModel("gemini-3-flash-preview");
7104
7172
  setMessages((prev) => {
7105
7173
  setCompletedIndex(prev.length + 1);
7106
7174
  return [...prev, {
7107
7175
  id: "tier-switch-" + Date.now(),
7108
7176
  role: "system",
7109
- text: `\u26A0\uFE0F **[TIER LIMIT]** Gemma is only available on Free API tier. Auto-switched to Gemini 3 Flash Preview.`,
7177
+ text: `\u26A0\uFE0F${s}**[TIER LIMIT]** Auto-switched to Gemini 3 Flash Preview.`,
7110
7178
  isMeta: true
7111
7179
  }];
7112
7180
  });
7113
7181
  }
7114
- }, [apiTier, activeModel]);
7182
+ }, [apiTier]);
7115
7183
  const terminalEnv = useMemo2(() => {
7116
7184
  const isIDE = process.env.TERM_PROGRAM === "vscode" || !!process.env.VSC_TERMINAL_URL || !!process.env.INTELLIJ_TERMINAL_COMMAND_BLOCKS;
7117
7185
  return {
@@ -7611,11 +7679,20 @@ function App({ args = [] }) {
7611
7679
  {
7612
7680
  cmd: "/model",
7613
7681
  desc: "Switch AI model",
7614
- subs: [
7615
- { cmd: "gemma-4-31b-it", desc: apiTier === "Free" ? "Standard Default (Free, Recommended)" : "Standard Default (Free, Recommended) - Use Free API Key to use this model " },
7616
- { cmd: "gemini-3.1-pro-preview", desc: "Most Capable (Paid)" },
7617
- { cmd: "gemini-3-flash-preview", desc: "Fast & Lightweight (Paid, Limited Free quota)" },
7618
- { cmd: "gemini-3.5-flash", desc: "New (Paid, Limited Free quota)" }
7682
+ subs: apiTier === "Free" ? [
7683
+ {
7684
+ cmd: "gemma-4-31b-it",
7685
+ desc: "Standard Default (Free, Recommended)"
7686
+ }
7687
+ ] : [
7688
+ {
7689
+ cmd: "gemini-3-flash-preview",
7690
+ desc: "Fast & Lightweight (Paid, Limited Free quota)"
7691
+ },
7692
+ {
7693
+ cmd: "gemini-3.5-flash",
7694
+ desc: "New (Paid, Limited Free quota)"
7695
+ }
7619
7696
  ]
7620
7697
  },
7621
7698
  { cmd: "/settings", desc: "Configure system prefs" },
@@ -9355,34 +9432,37 @@ var init_app = __esm({
9355
9432
  const startIdx = match.index + match[0].length - 1;
9356
9433
  let balance = 0;
9357
9434
  let inString = null;
9358
- let isEscaped = false;
9359
9435
  let endIdx = -1;
9360
9436
  let closingParenIdx = -1;
9361
9437
  for (let i = startIdx; i < text.length; i++) {
9362
9438
  const char = text[i];
9363
- if (!inString && (char === '"' || char === "'" || char === "`")) {
9364
- inString = char;
9365
- isEscaped = false;
9366
- } else if (inString && char === inString && !isEscaped) {
9367
- inString = null;
9368
- }
9369
- if (!inString) {
9370
- if (char === "(") balance++;
9371
- else if (char === ")") balance--;
9372
- if (balance === 0) {
9373
- closingParenIdx = i;
9374
- let j = i + 1;
9375
- while (j < text.length && /\s/.test(text[j])) j++;
9376
- if (j < text.length && text[j] === "]") {
9377
- endIdx = j;
9378
- break;
9439
+ if (inString) {
9440
+ if (char === inString) {
9441
+ let backslashCount = 0;
9442
+ for (let j = i - 1; j >= 0 && text[j] === "\\"; j--) {
9443
+ backslashCount++;
9444
+ }
9445
+ if (backslashCount % 2 === 0) {
9446
+ inString = null;
9379
9447
  }
9380
9448
  }
9381
- }
9382
- if (char === "\\") {
9383
- isEscaped = !isEscaped;
9384
9449
  } else {
9385
- isEscaped = false;
9450
+ if (char === '"' || char === "'" || char === "`") {
9451
+ inString = char;
9452
+ } else if (char === "(") {
9453
+ balance++;
9454
+ } else if (char === ")") {
9455
+ balance--;
9456
+ if (balance === 0) {
9457
+ closingParenIdx = i;
9458
+ let j = i + 1;
9459
+ while (j < text.length && /\s/.test(text[j])) j++;
9460
+ if (j < text.length && text[j] === "]") {
9461
+ endIdx = j;
9462
+ break;
9463
+ }
9464
+ }
9465
+ }
9386
9466
  }
9387
9467
  }
9388
9468
  if (endIdx !== -1) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "fluxflow-cli",
3
- "version": "1.18.15",
3
+ "version": "1.18.17",
4
4
  "date": "2026-06-01",
5
5
  "description": "A high-fidelity agentic terminal assistant for the Flux Era.",
6
6
  "keywords": [