fluxflow-cli 1.18.4 → 1.18.6

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 +783 -613
  2. package/package.json +1 -1
package/dist/fluxflow.js CHANGED
@@ -97,7 +97,7 @@ var init_MultilineInput = __esm({
97
97
  };
98
98
  }
99
99
  return {
100
- preCursor: [{ value: showCursor && focus ? "\u2502" : "", type: "cursor" }],
100
+ preCursor: [{ value: showCursor && focus ? " " : "", type: "cursor" }],
101
101
  postCursor: []
102
102
  };
103
103
  }
@@ -119,7 +119,7 @@ var init_MultilineInput = __esm({
119
119
  preCursor: [
120
120
  { value: formattedBefore.slice(0, lineStart) },
121
121
  { value: formattedBefore.slice(lineStart), type: "highlight" },
122
- { value: showCursor && focus ? "\u2502" : "", type: "cursor" }
122
+ { value: showCursor && focus ? " " : "", type: "cursor" }
123
123
  ],
124
124
  postCursor: [
125
125
  { value: formattedAfter.slice(0, lineEnd), type: "highlight" },
@@ -135,7 +135,7 @@ var init_MultilineInput = __esm({
135
135
  type: "highlight"
136
136
  },
137
137
  { value: formatText(textBefore.slice(highlight.end)) },
138
- { value: showCursor && focus ? "\u2502" : "", type: "cursor" }
138
+ { value: showCursor && focus ? " " : "", type: "cursor" }
139
139
  ],
140
140
  postCursor: [
141
141
  {
@@ -191,7 +191,7 @@ var init_MultilineInput = __esm({
191
191
  ...textStyle,
192
192
  color: "cyan",
193
193
  bold: true,
194
- inverse: false
194
+ inverse: true
195
195
  };
196
196
  default:
197
197
  return textStyle;
@@ -450,7 +450,7 @@ var init_TerminalBox = __esm({
450
450
  };
451
451
  const cleanOutput = isPty ? processPTY(output) : (output || "").replace(/\r\n/g, "\n");
452
452
  const displayOutput = isPty ? cleanOutput : cleanOutput ? wrapText(cleanOutput, columns - 6) : "";
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)")));
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 }, 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
454
  });
455
455
  }
456
456
  });
@@ -997,6 +997,635 @@ var init_CommandMenu = __esm({
997
997
  }
998
998
  });
999
999
 
1000
+ // src/utils/arg_parser.js
1001
+ var parseArgs;
1002
+ var init_arg_parser = __esm({
1003
+ "src/utils/arg_parser.js"() {
1004
+ parseArgs = (argsString) => {
1005
+ const args = {};
1006
+ if (!argsString) return args;
1007
+ let i = 0;
1008
+ while (i < argsString.length) {
1009
+ while (i < argsString.length && /[\s,]/.test(argsString[i])) i++;
1010
+ if (i >= argsString.length) break;
1011
+ let keyMatch = argsString.substring(i).match(/^(\w+)\s*=\s*/);
1012
+ if (!keyMatch) {
1013
+ i++;
1014
+ continue;
1015
+ }
1016
+ const key = keyMatch[1];
1017
+ i += keyMatch[0].length;
1018
+ let value = "";
1019
+ if (i < argsString.length && (argsString[i] === '"' || argsString[i] === "'" || argsString[i] === "`")) {
1020
+ const quote = argsString[i];
1021
+ i++;
1022
+ let start = i;
1023
+ let end = -1;
1024
+ let searchIndex = i;
1025
+ while (searchIndex < argsString.length) {
1026
+ let qIdx = argsString.indexOf(quote, searchIndex);
1027
+ if (qIdx === -1) break;
1028
+ if (argsString[qIdx - 1] === "\\" && argsString[qIdx - 2] !== "\\") {
1029
+ searchIndex = qIdx + 1;
1030
+ continue;
1031
+ }
1032
+ const after = argsString.substring(qIdx + 1).trim();
1033
+ const isLogicalEnd = after === "" || // End of entire string
1034
+ after.startsWith(",") || // Next argument separator
1035
+ /^(\w+)\s*=/.test(after) || // Next argument key=
1036
+ after.startsWith(")") && (after.length === 1 || /^\)\s*([,\]\s]|tool:)/i.test(after));
1037
+ if (isLogicalEnd) {
1038
+ end = qIdx;
1039
+ break;
1040
+ }
1041
+ searchIndex = qIdx + 1;
1042
+ }
1043
+ if (end !== -1) {
1044
+ value = argsString.substring(start, end);
1045
+ i = end + 1;
1046
+ } else {
1047
+ value = argsString.substring(start);
1048
+ i = argsString.length;
1049
+ }
1050
+ const isPathKey = key.toLowerCase().includes("path") || ["dest", "source", "to", "from"].includes(key.toLowerCase());
1051
+ if (isPathKey) {
1052
+ value = value.replace(/\\"/g, '"').replace(/\\'/g, "'").replace(/\\`/g, "`").replace(/\\\\/g, "\\");
1053
+ } else {
1054
+ try {
1055
+ if (value.includes("\\")) {
1056
+ const surgicalValue = value.replace(/(^|[^\\])"/g, '$1\\"');
1057
+ value = JSON.parse(`"${surgicalValue.replace(/\n/g, "\\n").replace(/\r/g, "\\r")}"`);
1058
+ }
1059
+ } catch (e) {
1060
+ value = value.replace(/\\"/g, '"').replace(/\\'/g, "'").replace(/\\`/g, "`").replace(/\\\\/g, "\\").replace(/\\n/g, "\n");
1061
+ }
1062
+ }
1063
+ } else if (i < argsString.length && argsString[i] === "[") {
1064
+ let balance = 0;
1065
+ let inString = null;
1066
+ let start = i;
1067
+ let end = -1;
1068
+ for (let j = i; j < argsString.length; j++) {
1069
+ const char = argsString[j];
1070
+ if (!inString && (char === '"' || char === "'" || char === "`")) {
1071
+ inString = char;
1072
+ } else if (inString && char === inString && argsString[j - 1] !== "\\") {
1073
+ inString = null;
1074
+ }
1075
+ if (!inString) {
1076
+ if (char === "[") balance++;
1077
+ else if (char === "]") balance--;
1078
+ if (balance === 0) {
1079
+ end = j;
1080
+ break;
1081
+ }
1082
+ }
1083
+ }
1084
+ if (end !== -1) {
1085
+ value = argsString.substring(start, end + 1);
1086
+ i = end + 1;
1087
+ try {
1088
+ let normalized = value.trim();
1089
+ if (normalized.startsWith("'") || normalized.includes("'")) {
1090
+ }
1091
+ } catch (e) {
1092
+ }
1093
+ } else {
1094
+ value = argsString.substring(start);
1095
+ i = argsString.length;
1096
+ }
1097
+ } else {
1098
+ let endMatch = argsString.substring(i).match(/([^,\s\)]+)/);
1099
+ if (endMatch) {
1100
+ value = endMatch[1];
1101
+ i += value.length;
1102
+ }
1103
+ }
1104
+ if (value === "true") value = true;
1105
+ else if (value === "false") value = false;
1106
+ else if (typeof value === "string" && !isNaN(value) && value.trim() !== "") value = Number(value);
1107
+ if (typeof value === "string" && (key.toLowerCase().includes("path") || ["dest", "source", "to", "from"].includes(key.toLowerCase()))) {
1108
+ value = value.replace(/\x0C/g, "\\f").replace(/\x0D/g, "\\r").replace(/\x0B/g, "\\v").replace(/\x08/g, "\\b");
1109
+ }
1110
+ args[key] = value;
1111
+ }
1112
+ return args;
1113
+ };
1114
+ }
1115
+ });
1116
+
1117
+ // src/data/main_tools.js
1118
+ import { execSync } from "child_process";
1119
+ var _isPsAvailable, isPsAvailable, TOOL_PROTOCOL;
1120
+ var init_main_tools = __esm({
1121
+ "src/data/main_tools.js"() {
1122
+ _isPsAvailable = null;
1123
+ isPsAvailable = () => {
1124
+ if (process.platform !== "win32") return false;
1125
+ if (_isPsAvailable !== null) return _isPsAvailable;
1126
+ try {
1127
+ execSync('powershell.exe -NoProfile -Command "exit"', { stdio: "ignore" });
1128
+ _isPsAvailable = true;
1129
+ } catch (e) {
1130
+ _isPsAvailable = false;
1131
+ }
1132
+ return _isPsAvailable;
1133
+ };
1134
+ TOOL_PROTOCOL = (mode, osDetected) => `
1135
+ -- TOOL DEFINITIONS --
1136
+ Access to internal tools. To call a tool, MUST use the exact syntax on a new line: [tool:functions.ToolName(args)]
1137
+ STRICT POLICY
1138
+ - **MAX 3 TOOL CALLS PER TURN. Next Turn, verify results, plan next**${mode === "Flux" ? "\n- **File Tools >> Code in chat**" : ""}
1139
+
1140
+ - COMMUNICATION TOOLS -
1141
+ 1. [tool:functions.Ask(question="...", optionA="option::description", ...MAX 4)]. Ambiguity Resolution. Mandatory Triggers: Path Divergence, Security, Risk Mitigation. ask >> finish
1142
+ Suggest best options; don't ask for preferences
1143
+
1144
+ - WEB TOOLS -
1145
+ 1. [tool:functions.WebSearch(query="...", limit=number)]. Limit 3-10. Proactive use for unknown topics${mode === "Flux" ? " or docs" : ""}
1146
+ 2. [tool:functions.WebScrape(url="...")]. Visit URL
1147
+
1148
+ ${mode === "Flux" ? `- PROJECT TOOLS (path = relative to CWD) -
1149
+ 1. [tool:functions.ReadFile(path="...", startLine=number, endLine=number)]. Supports images/docs. User gives image/doc: VIEW FIRST
1150
+ 2. [tool:functions.ReadFolder(path="...")]. Detailed DIR stats
1151
+ 3. [tool:functions.PatchFile(path="...", replaceContent1="exact string", newContent1="...", ...MAX 8)]. Surgical Patch. Unsure? ReadFile > guessing. Multiple blocks same file? Use replaceContent2, newContent2 etc.
1152
+ 4. [tool:functions.WriteFile(path="...", content="...")]. Creates/Overwrites. File Exist? PatchFile >> WriteFile. Verify Imports
1153
+ 5. [tool:functions.SearchKeyword(keyword="...", file="path/to/file")]. Global project search. If 'file' is provided, searches only that file. Finds definitions/logic without reading every file
1154
+ 6. [tool:functions.Run(command="...")]. Runs ${osDetected === "Windows" ? isPsAvailable() ? "WINDOWS POWERSHELL ONLY" : "WINDOWS CMD" : "Bash"} command. Destructive/Irreversible ops -> Ask user
1155
+ 7. [tool:functions.GenerateImage(path="... png", prompt="detailed", ratio="16:9, 9:16, 1:1")]. Usage: Mockups, PDF thumbnails, any visual content
1156
+ 8. [tool:functions.WritePDF(path="...", content="...", orientation="...")]. PROACTIVE A4 PAGE BREAKS MUST IN CSS. HTML/CSS for PREMIUM layout (100vh/vw)
1157
+ 9. [tool:functions.WriteDoc(path="...", content="...")]. A4 Word document
1158
+
1159
+ - VERIFY TOOL RESULT CONTENTS. Fix errors. No hallucinations
1160
+
1161
+ - Escape quotes: \\" for code strings
1162
+ - Literal escapes: Double-escape sequences (e.g., \\\\n, \\\\t)
1163
+ - File structure: Real newlines for code formatting`.trim() : `
1164
+ - FILE TOOLS ARE NOT AVAILABLE IN FLOW (Tell user,\` /mode flux\` if needed)`.trim()}
1165
+
1166
+ - Results: Passed as [TOOL RESULT] (system priority)
1167
+ - MAX Tool call stack: STRICTLY 3 per turn`.trim();
1168
+ }
1169
+ });
1170
+
1171
+ // src/tools/exec_command.js
1172
+ import { spawn } from "child_process";
1173
+ var pty, isPtyAvailable, stripAnsi, activeChildProcess, isActiveCommandPty, writeToActiveCommand, terminateActiveCommand, adjustWindowsCommand, exec_command, runStandardSpawn;
1174
+ var init_exec_command = __esm({
1175
+ async "src/tools/exec_command.js"() {
1176
+ init_arg_parser();
1177
+ init_main_tools();
1178
+ pty = null;
1179
+ try {
1180
+ const ptyModule = await import("node-pty");
1181
+ pty = ptyModule.default || ptyModule;
1182
+ } catch (err) {
1183
+ }
1184
+ isPtyAvailable = !!pty;
1185
+ stripAnsi = (str) => {
1186
+ if (typeof str !== "string") return str;
1187
+ return str.replace(/[\u001b\u009b][[()#;?]*(?:[0-9]{1,4}(?:;[0-9]{0,4})*)?[0-9A-ORZcf-nqry=><]/g, "");
1188
+ };
1189
+ activeChildProcess = null;
1190
+ isActiveCommandPty = false;
1191
+ writeToActiveCommand = (data) => {
1192
+ try {
1193
+ if (activeChildProcess) {
1194
+ if (isActiveCommandPty && typeof activeChildProcess.write === "function") {
1195
+ activeChildProcess.write(data);
1196
+ } else if (activeChildProcess.stdin && activeChildProcess.stdin.writable) {
1197
+ activeChildProcess.stdin.write(data);
1198
+ }
1199
+ }
1200
+ } catch (err) {
1201
+ }
1202
+ };
1203
+ terminateActiveCommand = () => {
1204
+ if (activeChildProcess) {
1205
+ try {
1206
+ if (isActiveCommandPty && typeof activeChildProcess.destroy === "function") {
1207
+ activeChildProcess.destroy();
1208
+ } else if (typeof activeChildProcess.kill === "function") {
1209
+ activeChildProcess.kill("SIGKILL");
1210
+ }
1211
+ } catch (err) {
1212
+ }
1213
+ activeChildProcess = null;
1214
+ isActiveCommandPty = false;
1215
+ }
1216
+ };
1217
+ adjustWindowsCommand = (command, usePowerShell = false) => {
1218
+ if (process.platform !== "win32") return command;
1219
+ const tokens = [];
1220
+ let current = "";
1221
+ let inQuote = null;
1222
+ let isEscaped = false;
1223
+ for (let i = 0; i < command.length; i++) {
1224
+ const char = command[i];
1225
+ if (isEscaped) {
1226
+ current += char;
1227
+ isEscaped = false;
1228
+ continue;
1229
+ }
1230
+ if (char === "\\") {
1231
+ if (command[i + 1] === " ") {
1232
+ current += " ";
1233
+ i++;
1234
+ continue;
1235
+ }
1236
+ current += char;
1237
+ isEscaped = true;
1238
+ continue;
1239
+ }
1240
+ if (inQuote) {
1241
+ if (char === inQuote) {
1242
+ inQuote = null;
1243
+ }
1244
+ current += char;
1245
+ } else {
1246
+ if (char === '"' || char === "'") {
1247
+ inQuote = char;
1248
+ current += char;
1249
+ } else if (char === ";" && !current.includes("://")) {
1250
+ if (current.length > 0) {
1251
+ tokens.push(current);
1252
+ current = "";
1253
+ }
1254
+ tokens.push(usePowerShell ? ";" : "&");
1255
+ } else if (char === "|" && !current.includes("://")) {
1256
+ if (current.length > 0) {
1257
+ tokens.push(current);
1258
+ current = "";
1259
+ }
1260
+ tokens.push("|");
1261
+ } else if (/\s/.test(char)) {
1262
+ if (current.length > 0) {
1263
+ tokens.push(current);
1264
+ current = "";
1265
+ }
1266
+ } else {
1267
+ current += char;
1268
+ }
1269
+ }
1270
+ }
1271
+ if (current.length > 0) {
1272
+ tokens.push(current);
1273
+ }
1274
+ const looksLikePath = (str) => {
1275
+ if (!str.includes("/")) return false;
1276
+ if (/^(https?|file|ftp):\/\//i.test(str)) return false;
1277
+ if (str.startsWith("/") && (str.match(/\//g) || []).length === 1) {
1278
+ return false;
1279
+ }
1280
+ if (/\s\/|\/\s/.test(str)) return false;
1281
+ if (/[\(\)\{\}\;\<\>\=\'\"]/.test(str)) return false;
1282
+ return true;
1283
+ };
1284
+ const translatedTokens = [];
1285
+ for (let i = 0; i < tokens.length; i++) {
1286
+ const token = tokens[i];
1287
+ if (token === "mkdir" && usePowerShell && isPsAvailable()) {
1288
+ const paths = [];
1289
+ let j = i + 1;
1290
+ while (j < tokens.length) {
1291
+ const nextToken = tokens[j];
1292
+ const controlOperators = [">", ">>", "<", "&", "&&", "|", "||", ";"];
1293
+ if (controlOperators.includes(nextToken)) {
1294
+ break;
1295
+ }
1296
+ if (nextToken !== "-p" && nextToken !== "--parents" && nextToken !== "-v" && nextToken !== "--verbose") {
1297
+ paths.push(nextToken);
1298
+ }
1299
+ j++;
1300
+ }
1301
+ if (paths.length > 0) {
1302
+ const processedPaths = paths.map((p) => {
1303
+ const unquoted = p.replace(/^['"]|['"]$/g, "");
1304
+ let newPath = p;
1305
+ if (looksLikePath(unquoted)) {
1306
+ newPath = p.replace(/\//g, "\\");
1307
+ }
1308
+ return newPath;
1309
+ });
1310
+ translatedTokens.push("New-Item", "-ItemType", "Directory", "-Force", "-Path", processedPaths.join(","));
1311
+ } else {
1312
+ translatedTokens.push("New-Item", "-ItemType", "Directory", "-Force");
1313
+ }
1314
+ i = j - 1;
1315
+ continue;
1316
+ }
1317
+ if (token === "rm" && usePowerShell && isPsAvailable()) {
1318
+ const paths = [];
1319
+ let recurse = false;
1320
+ let force = false;
1321
+ let j = i + 1;
1322
+ while (j < tokens.length) {
1323
+ const nextToken = tokens[j];
1324
+ const controlOperators = [">", ">>", "<", "&", "&&", "|", "||", ";"];
1325
+ if (controlOperators.includes(nextToken)) {
1326
+ break;
1327
+ }
1328
+ if (nextToken === "-rf" || nextToken === "-fr") {
1329
+ recurse = true;
1330
+ force = true;
1331
+ } else if (nextToken === "-r" || nextToken === "-R" || nextToken === "--recursive") {
1332
+ recurse = true;
1333
+ } else if (nextToken === "-f" || nextToken === "--force") {
1334
+ force = true;
1335
+ } else {
1336
+ paths.push(nextToken);
1337
+ }
1338
+ j++;
1339
+ }
1340
+ const args = ["Remove-Item"];
1341
+ if (recurse) args.push("-Recurse");
1342
+ if (force) args.push("-Force");
1343
+ if (paths.length > 0) {
1344
+ const processedPaths = paths.map((p) => {
1345
+ const unquoted = p.replace(/^['"]|['"]$/g, "");
1346
+ let newPath = p;
1347
+ if (looksLikePath(unquoted)) {
1348
+ newPath = p.replace(/\//g, "\\");
1349
+ }
1350
+ return newPath;
1351
+ });
1352
+ args.push("-Path", processedPaths.join(","));
1353
+ }
1354
+ translatedTokens.push(...args);
1355
+ i = j - 1;
1356
+ continue;
1357
+ }
1358
+ if (token === "cp" && usePowerShell && isPsAvailable()) {
1359
+ const paths = [];
1360
+ let recurse = false;
1361
+ let force = false;
1362
+ let j = i + 1;
1363
+ while (j < tokens.length) {
1364
+ const nextToken = tokens[j];
1365
+ const controlOperators = [">", ">>", "<", "&", "&&", "|", "||", ";"];
1366
+ if (controlOperators.includes(nextToken)) {
1367
+ break;
1368
+ }
1369
+ if (nextToken === "-r" || nextToken === "-R" || nextToken === "--recursive") {
1370
+ recurse = true;
1371
+ } else if (nextToken === "-f" || nextToken === "--force") {
1372
+ force = true;
1373
+ } else {
1374
+ paths.push(nextToken);
1375
+ }
1376
+ j++;
1377
+ }
1378
+ const args = ["Copy-Item"];
1379
+ if (recurse) args.push("-Recurse");
1380
+ if (force) args.push("-Force");
1381
+ if (paths.length > 0) {
1382
+ const processedPaths = paths.map((p) => {
1383
+ const unquoted = p.replace(/^['"]|['"]$/g, "");
1384
+ let newPath = p;
1385
+ if (looksLikePath(unquoted)) {
1386
+ newPath = p.replace(/\//g, "\\");
1387
+ }
1388
+ return newPath;
1389
+ });
1390
+ if (processedPaths.length > 1) {
1391
+ const dest = processedPaths.pop();
1392
+ args.push("-Path", processedPaths.join(","), "-Destination", dest);
1393
+ } else {
1394
+ args.push("-Path", processedPaths[0]);
1395
+ }
1396
+ }
1397
+ translatedTokens.push(...args);
1398
+ i = j - 1;
1399
+ continue;
1400
+ }
1401
+ if (token === "touch" && usePowerShell && isPsAvailable()) {
1402
+ const paths = [];
1403
+ let j = i + 1;
1404
+ while (j < tokens.length) {
1405
+ const nextToken = tokens[j];
1406
+ const controlOperators = [">", ">>", "<", "&", "&&", "|", "||", ";"];
1407
+ if (controlOperators.includes(nextToken)) {
1408
+ break;
1409
+ }
1410
+ paths.push(nextToken);
1411
+ j++;
1412
+ }
1413
+ if (paths.length > 0) {
1414
+ const processedPaths = paths.map((p) => {
1415
+ const unquoted = p.replace(/^['"]|['"]$/g, "");
1416
+ let newPath = p;
1417
+ if (looksLikePath(unquoted)) {
1418
+ newPath = p.replace(/\//g, "\\");
1419
+ }
1420
+ return newPath;
1421
+ });
1422
+ const psTouch = `(${processedPaths.join(", ")}) | ForEach-Object { if (Test-Path $_) { (Get-Item $_).LastWriteTime = [System.DateTime]::Now } else { $null | Out-File -FilePath $_ } }`;
1423
+ translatedTokens.push(psTouch);
1424
+ }
1425
+ i = j - 1;
1426
+ continue;
1427
+ }
1428
+ if (token === "|" && tokens[i + 1] === "tee") {
1429
+ if (tokens[i + 2] === "-a") {
1430
+ translatedTokens.push(">>");
1431
+ i += 2;
1432
+ } else {
1433
+ translatedTokens.push(">");
1434
+ i += 1;
1435
+ }
1436
+ continue;
1437
+ }
1438
+ if (token === "|" && tokens[i + 1] === "cat" && tokens[i + 2] === ">") {
1439
+ translatedTokens.push(">");
1440
+ i += 2;
1441
+ continue;
1442
+ }
1443
+ if (token === "|") {
1444
+ const nextToken = tokens[i + 1];
1445
+ if (nextToken) {
1446
+ const nextUnquoted = nextToken.replace(/^['"]|['"]$/g, "");
1447
+ const isWritableFile = /\.(txt|md|json|log|csv|html|css|py|js|xml|yaml|yml|pdf|docx|pptx|xlsx)$/i.test(nextUnquoted);
1448
+ if (looksLikePath(nextUnquoted) && isWritableFile) {
1449
+ translatedTokens.push(">");
1450
+ continue;
1451
+ }
1452
+ }
1453
+ }
1454
+ translatedTokens.push(token);
1455
+ }
1456
+ let inEchoArguments = false;
1457
+ const processedTokens = translatedTokens.map((token) => {
1458
+ if (token === "echo") {
1459
+ inEchoArguments = true;
1460
+ return token;
1461
+ }
1462
+ const controlOperators = [">", ">>", "<", "&", "&&", "|", "||", ";"];
1463
+ if (controlOperators.includes(token)) {
1464
+ inEchoArguments = false;
1465
+ }
1466
+ const hasOuterQuotes = /^['"]|['"]$/.test(token);
1467
+ let processed = token;
1468
+ if (inEchoArguments && hasOuterQuotes) {
1469
+ processed = token.replace(/^['"]|['"]$/g, "");
1470
+ }
1471
+ const currentHasOuterQuotes = /^['"]|['"]$/.test(processed);
1472
+ const unquoted = processed.replace(/^['"]|['"]$/g, "");
1473
+ if (looksLikePath(unquoted)) {
1474
+ processed = processed.replace(/\//g, "\\");
1475
+ }
1476
+ const finalUnquoted = processed.replace(/^['"]|['"]$/g, "");
1477
+ if (finalUnquoted.includes(" ") && !currentHasOuterQuotes) {
1478
+ processed = `"${finalUnquoted}"`;
1479
+ }
1480
+ return processed;
1481
+ });
1482
+ return processedTokens.join(" ");
1483
+ };
1484
+ exec_command = async (args, options = {}) => {
1485
+ const { command: rawCommand } = parseArgs(args);
1486
+ const { onChunk } = options;
1487
+ if (!rawCommand) return 'ERROR: Missing "command" argument for exec_command.';
1488
+ const isWin = process.platform === "win32";
1489
+ const systemSettings = options.systemSettings || {};
1490
+ const netEnv = {};
1491
+ if (systemSettings.networkAccess === false) {
1492
+ netEnv.HTTP_PROXY = "http://127.0.0.1:9999";
1493
+ netEnv.HTTPS_PROXY = "http://127.0.0.1:9999";
1494
+ netEnv.ALL_PROXY = "socks5://127.0.0.1:9999";
1495
+ netEnv.http_proxy = "http://127.0.0.1:9999";
1496
+ netEnv.https_proxy = "http://127.0.0.1:9999";
1497
+ netEnv.all_proxy = "socks5://127.0.0.1:9999";
1498
+ netEnv.NO_PROXY = "localhost,127.0.0.1";
1499
+ }
1500
+ return new Promise((resolve) => {
1501
+ const attempt = (usePowerShell) => {
1502
+ const command = adjustWindowsCommand(rawCommand, usePowerShell);
1503
+ const shell = isWin ? usePowerShell ? "powershell.exe" : "cmd.exe" : process.env.SHELL || "bash";
1504
+ const shellArgs = isWin ? usePowerShell ? ["-NoProfile", "-Command", command] : ["/c", command] : ["-c", command];
1505
+ if (pty) {
1506
+ try {
1507
+ const ptyProcess = pty.spawn(shell, shellArgs, {
1508
+ name: "xterm-256color",
1509
+ cols: options.cols || 120,
1510
+ rows: options.rows || 30,
1511
+ cwd: process.cwd(),
1512
+ env: {
1513
+ ...process.env,
1514
+ CI: "false",
1515
+ TERM: "xterm-256color",
1516
+ FORCE_COLOR: "1",
1517
+ ...netEnv
1518
+ }
1519
+ });
1520
+ activeChildProcess = ptyProcess;
1521
+ isActiveCommandPty = true;
1522
+ let output = "";
1523
+ ptyProcess.onData((data) => {
1524
+ output += data;
1525
+ if (onChunk) onChunk(data);
1526
+ });
1527
+ ptyProcess.onExit(({ exitCode }) => {
1528
+ activeChildProcess = null;
1529
+ const normalizedOutput = (output || "").replace(/\r\n/g, "\n").replace(/\r/g, "\n");
1530
+ const finalOutput = stripAnsi(normalizedOutput) || "Command executed with no output.";
1531
+ if (exitCode !== 0) {
1532
+ resolve(`ERROR: Command [${rawCommand}] failed with exit code [${exitCode}].
1533
+
1534
+ ${finalOutput}`);
1535
+ } else {
1536
+ resolve(`SUCCESS: Command [${rawCommand}] completed.
1537
+
1538
+ ${finalOutput}`);
1539
+ }
1540
+ });
1541
+ return true;
1542
+ } catch (err) {
1543
+ if (isWin && usePowerShell && err.code === "ENOENT") {
1544
+ return false;
1545
+ }
1546
+ runStandardSpawn(resolve, command, rawCommand, netEnv, onChunk, usePowerShell);
1547
+ return true;
1548
+ }
1549
+ } else {
1550
+ runStandardSpawn(resolve, command, rawCommand, netEnv, onChunk, usePowerShell);
1551
+ return true;
1552
+ }
1553
+ };
1554
+ if (isWin) {
1555
+ if (!attempt(true)) {
1556
+ attempt(false);
1557
+ }
1558
+ } else {
1559
+ attempt(false);
1560
+ }
1561
+ });
1562
+ };
1563
+ runStandardSpawn = (resolve, command, rawCommand, netEnv, onChunk, usePowerShell = true) => {
1564
+ const isWin = process.platform === "win32";
1565
+ const shell = isWin ? usePowerShell ? "powershell.exe" : "cmd.exe" : process.env.SHELL || "bash";
1566
+ const shellArgs = isWin ? usePowerShell ? ["-NoProfile", "-Command", command] : ["/c", command] : ["-c", command];
1567
+ const child = isWin ? spawn(shell, shellArgs, { cwd: process.cwd(), env: { ...process.env, ...netEnv } }) : spawn(command, {
1568
+ shell: true,
1569
+ cwd: process.cwd(),
1570
+ env: {
1571
+ ...process.env,
1572
+ CI: "false",
1573
+ TERM: "xterm-256color",
1574
+ FORCE_COLOR: "1",
1575
+ ...netEnv
1576
+ }
1577
+ });
1578
+ activeChildProcess = child;
1579
+ isActiveCommandPty = false;
1580
+ if (child.stdin) {
1581
+ child.stdin.on("error", () => {
1582
+ activeChildProcess = null;
1583
+ });
1584
+ }
1585
+ let stdout = "";
1586
+ let stderr = "";
1587
+ child.stdout.on("data", (data) => {
1588
+ const chunk = data.toString();
1589
+ stdout += chunk;
1590
+ if (onChunk) onChunk(chunk);
1591
+ });
1592
+ child.stderr.on("data", (data) => {
1593
+ const chunk = data.toString();
1594
+ stderr += chunk;
1595
+ if (onChunk) onChunk(chunk);
1596
+ });
1597
+ child.on("close", (code) => {
1598
+ activeChildProcess = null;
1599
+ const result = [];
1600
+ if (stdout) result.push(`STDOUT:
1601
+ ${stdout}`);
1602
+ if (stderr) result.push(`STDERR:
1603
+ ${stderr}`);
1604
+ if (code !== 0) result.push(`EXIT CODE: ${code}`);
1605
+ const rawOutput = result.join("\n\n") || "Command executed with no output.";
1606
+ const finalOutput = stripAnsi(rawOutput);
1607
+ if (code !== 0) {
1608
+ resolve(`ERROR: Command [${rawCommand}] failed with exit code [${code}].
1609
+
1610
+ ${finalOutput}`);
1611
+ } else {
1612
+ resolve(`SUCCESS: Command [${rawCommand}] completed.
1613
+
1614
+ ${finalOutput}`);
1615
+ }
1616
+ });
1617
+ child.on("error", (err) => {
1618
+ if (isWin && usePowerShell && err.code === "ENOENT") {
1619
+ const cmdCommand = adjustWindowsCommand(rawCommand, false);
1620
+ return runStandardSpawn(resolve, cmdCommand, rawCommand, netEnv, onChunk, false);
1621
+ }
1622
+ activeChildProcess = null;
1623
+ resolve(`ERROR: Failed to start command [${rawCommand}]: ${err.message}`);
1624
+ });
1625
+ };
1626
+ }
1627
+ });
1628
+
1000
1629
  // src/components/SettingsMenu.jsx
1001
1630
  import React6, { useState as useState3 } from "react";
1002
1631
  import { Box as Box6, Text as Text6, useInput as useInput2 } from "ink";
@@ -1230,6 +1859,8 @@ function SettingsMenu({
1230
1859
  }
1231
1860
  return "yellow";
1232
1861
  }
1862
+ if (item2.status?.startsWith("\u2713")) return "green";
1863
+ if (item2.status?.startsWith("\u26A0")) return "yellow";
1233
1864
  return item2.status === "ON" ? "green" : item2.status === "OFF" ? "red" : "yellow";
1234
1865
  };
1235
1866
  if (item.section && item.section !== lastSection) {
@@ -1264,6 +1895,11 @@ function SettingsMenu({
1264
1895
  )), /* @__PURE__ */ React6.createElement(Text6, { color: "gray", dimColor: true, italic: true }, " Comma separated \u2022 Press Enter to save, Esc to cancel")))
1265
1896
  );
1266
1897
  });
1898
+ if (currentCatId === "other") {
1899
+ elements.push(
1900
+ /* @__PURE__ */ React6.createElement(Box6, { key: "pty-notice", marginTop: 4, paddingX: 1 }, /* @__PURE__ */ React6.createElement(Text6, { color: isPtyAvailable ? "green" : "yellow" }, isPtyAvailable ? "\u2713 Advance Interactive Terminal Supported" : "\u26A0 Interactive Terminal is Limited"))
1901
+ );
1902
+ }
1267
1903
  if (hasConflict) {
1268
1904
  elements.push(
1269
1905
  /* @__PURE__ */ React6.createElement(Box6, { key: "conflict-warning", marginTop: 1, paddingX: 1 }, /* @__PURE__ */ React6.createElement(Text6, { color: "red", dimColor: true, italic: true }, "* Conflicting commands will be ignored and defaulted to highest priority"))
@@ -1274,7 +1910,8 @@ function SettingsMenu({
1274
1910
  }
1275
1911
  var CATEGORIES, getActivePreset, truncateCSV;
1276
1912
  var init_SettingsMenu = __esm({
1277
- "src/components/SettingsMenu.jsx"() {
1913
+ async "src/components/SettingsMenu.jsx"() {
1914
+ await init_exec_command();
1278
1915
  CATEGORIES = [
1279
1916
  { id: "memory", label: "\u{1F9E0} Memory", desc: "Manage system context & agent's memory" },
1280
1917
  { id: "security", label: "\u{1F512} Security", desc: "Configure permissions & data safety" },
@@ -1639,60 +2276,6 @@ var init_secrets = __esm({
1639
2276
  }
1640
2277
  });
1641
2278
 
1642
- // src/data/main_tools.js
1643
- import { execSync } from "child_process";
1644
- var _isPsAvailable, isPsAvailable, TOOL_PROTOCOL;
1645
- var init_main_tools = __esm({
1646
- "src/data/main_tools.js"() {
1647
- _isPsAvailable = null;
1648
- isPsAvailable = () => {
1649
- if (process.platform !== "win32") return false;
1650
- if (_isPsAvailable !== null) return _isPsAvailable;
1651
- try {
1652
- execSync('powershell.exe -NoProfile -Command "exit"', { stdio: "ignore" });
1653
- _isPsAvailable = true;
1654
- } catch (e) {
1655
- _isPsAvailable = false;
1656
- }
1657
- return _isPsAvailable;
1658
- };
1659
- TOOL_PROTOCOL = (mode, osDetected) => `
1660
- -- TOOL DEFINITIONS --
1661
- Access to internal tools. To call a tool, MUST use the exact syntax on a new line: [tool:functions.ToolName(args)]
1662
- STRICT POLICY
1663
- - **MAX 3 TOOL CALLS PER TURN. Next Turn, verify results, plan next**${mode === "Flux" ? "\n- **File Tools >> Code in chat**" : ""}
1664
-
1665
- - COMMUNICATION TOOLS -
1666
- 1. [tool:functions.Ask(question="...", optionA="option::description", ...MAX 4)]. Ambiguity Resolution. Mandatory Triggers: Path Divergence, Security, Risk Mitigation. ask >> finish
1667
- Suggest best options; don't ask for preferences
1668
-
1669
- - WEB TOOLS -
1670
- 1. [tool:functions.WebSearch(query="...", limit=number)]. Limit 3-10. Proactive use for unknown topics${mode === "Flux" ? " or docs" : ""}
1671
- 2. [tool:functions.WebScrape(url="...")]. Visit URL
1672
-
1673
- ${mode === "Flux" ? `- PROJECT TOOLS (path = relative to CWD) -
1674
- 1. [tool:functions.ReadFile(path="...", startLine=number, endLine=number)]. Supports images/docs. User gives image/doc: VIEW FIRST
1675
- 2. [tool:functions.ReadFolder(path="...")]. Detailed DIR stats
1676
- 3. [tool:functions.PatchFile(path="...", replaceContent1="exact string", newContent1="...", ...MAX 8)]. Surgical Patch. Unsure? ReadFile > guessing. Multiple blocks same file? Use replaceContent2, newContent2 etc.
1677
- 4. [tool:functions.WriteFile(path="...", content="...")]. Creates/Overwrites. File Exist? PatchFile >> WriteFile. Verify Imports
1678
- 5. [tool:functions.SearchKeyword(keyword="...", file="path/to/file")]. Global project search. If 'file' is provided, searches only that file. Finds definitions/logic without reading every file
1679
- 6. [tool:functions.Run(command="...")]. Runs ${osDetected === "Windows" ? isPsAvailable() ? "WINDOWS POWERSHELL" : "WINDOWS CMD" : "Bash"} command. Destructive/Irreversible ops -> Ask user
1680
- 7. [tool:functions.GenerateImage(path="... png", prompt="detailed", ratio="16:9, 9:16, 1:1")]. Usage: Mockups, PDF thumbnails, any visual content
1681
- 8. [tool:functions.WritePDF(path="...", content="...", orientation="...")]. PROACTIVE A4 PAGE BREAKS MUST IN CSS. HTML/CSS for PREMIUM layout (100vh/vw)
1682
- 9. [tool:functions.WriteDoc(path="...", content="...")]. A4 Word document
1683
-
1684
- - VERIFY TOOL RESULT CONTENTS. Fix errors. No hallucinations
1685
-
1686
- - Escape quotes: \\" for code strings
1687
- - Literal escapes: Double-escape sequences (e.g., \\\\n, \\\\t)
1688
- - File structure: Real newlines for code formatting`.trim() : `
1689
- - FILE TOOLS ARE NOT AVAILABLE IN FLOW (Tell user,\` /mode flux\` if needed)`.trim()}
1690
-
1691
- - Results: Passed as [TOOL RESULT] (system priority)
1692
- - MAX Tool call stack: STRICTLY 3 per turn`.trim();
1693
- }
1694
- });
1695
-
1696
2279
  // src/data/janitor_tools.js
1697
2280
  var JANITOR_TOOLS_PROTOCOL;
1698
2281
  var init_janitor_tools = __esm({
@@ -1804,6 +2387,14 @@ Check these first; These Files > Training Data. Safety rules apply
1804
2387
  Identity: Flux Flow (by Kushal Roy Chowdhury). Sassy${mode === "Flux" ? ", No Flirting, Respectful" : ", Friendly, Humorous, Sarcastic"}, CLI Agent
1805
2388
  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"}
1806
2389
 
2390
+ -- AGENT LOOP RULES (PRIORITY: HIGH) --
2391
+ - **MUST END WITH [turn: continue] to continue loop OR [turn: finish] to END loop**
2392
+ - Tool Called? No post tool response until [turn: continue]
2393
+ - NEVER USE [turn: continue] [turn:finish] together
2394
+
2395
+ SYSTEM PRIORITY: [SYSTEM], [TOOL RESULT]
2396
+ HIGH PRIORITY: [STEERING HINT]
2397
+
1807
2398
  -- THINKING RULES --
1808
2399
  ${thinkingConfig}
1809
2400
  ${thinkingLevel !== "Fast" ? `
@@ -1824,12 +2415,6 @@ ${projectContextBlock}
1824
2415
  - GFM Supported
1825
2416
  - Tables: Max 4 cols
1826
2417
  - NO LaTeX${mode === "Flux" ? "" : ". Kaomojis"}
1827
-
1828
- -- TURN RULES (PRIORITY: HIGH) --
1829
- - End with [turn: continue] to continue or [turn: finish] to finish agent loop (MUST INCLUDE EVERY RESPONSE)
1830
- - Tool Called? No post tool response until [turn: continue]
1831
- - Task Complete? End loop with [turn: finish]
1832
- - NEVER USE [turn: continue] [turn:finish] together
1833
2418
  [/SYSTEM]`.trim();
1834
2419
  };
1835
2420
  getJanitorInstruction = (userMemories = "", isMemoryEnabled = true, needTitle = true) => {
@@ -2667,134 +3252,17 @@ var init_usage = __esm({
2667
3252
  "High": 0.045,
2668
3253
  "Ultra": 0.0488,
2669
3254
  "Premium": 0.1
2670
- };
2671
- const cost = costs[imageSettings.quality] || 2e-3;
2672
- const stats = await getDailyUsage();
2673
- if (!stats.imageCalls) {
2674
- stats.imageCalls = [];
2675
- }
2676
- stats.imageCalls.push({
2677
- timestamp: Date.now(),
2678
- cost
2679
- });
2680
- queueFlush();
2681
- };
2682
- }
2683
- });
2684
-
2685
- // src/utils/arg_parser.js
2686
- var parseArgs;
2687
- var init_arg_parser = __esm({
2688
- "src/utils/arg_parser.js"() {
2689
- parseArgs = (argsString) => {
2690
- const args = {};
2691
- if (!argsString) return args;
2692
- let i = 0;
2693
- while (i < argsString.length) {
2694
- while (i < argsString.length && /[\s,]/.test(argsString[i])) i++;
2695
- if (i >= argsString.length) break;
2696
- let keyMatch = argsString.substring(i).match(/^(\w+)\s*=\s*/);
2697
- if (!keyMatch) {
2698
- i++;
2699
- continue;
2700
- }
2701
- const key = keyMatch[1];
2702
- i += keyMatch[0].length;
2703
- let value = "";
2704
- if (i < argsString.length && (argsString[i] === '"' || argsString[i] === "'" || argsString[i] === "`")) {
2705
- const quote = argsString[i];
2706
- i++;
2707
- let start = i;
2708
- let end = -1;
2709
- let searchIndex = i;
2710
- while (searchIndex < argsString.length) {
2711
- let qIdx = argsString.indexOf(quote, searchIndex);
2712
- if (qIdx === -1) break;
2713
- if (argsString[qIdx - 1] === "\\" && argsString[qIdx - 2] !== "\\") {
2714
- searchIndex = qIdx + 1;
2715
- continue;
2716
- }
2717
- const after = argsString.substring(qIdx + 1).trim();
2718
- const isLogicalEnd = after === "" || // End of entire string
2719
- after.startsWith(",") || // Next argument separator
2720
- /^(\w+)\s*=/.test(after) || // Next argument key=
2721
- after.startsWith(")") && (after.length === 1 || /^\)\s*([,\]\s]|tool:)/i.test(after));
2722
- if (isLogicalEnd) {
2723
- end = qIdx;
2724
- break;
2725
- }
2726
- searchIndex = qIdx + 1;
2727
- }
2728
- if (end !== -1) {
2729
- value = argsString.substring(start, end);
2730
- i = end + 1;
2731
- } else {
2732
- value = argsString.substring(start);
2733
- i = argsString.length;
2734
- }
2735
- const isPathKey = key.toLowerCase().includes("path") || ["dest", "source", "to", "from"].includes(key.toLowerCase());
2736
- if (isPathKey) {
2737
- value = value.replace(/\\"/g, '"').replace(/\\'/g, "'").replace(/\\`/g, "`").replace(/\\\\/g, "\\");
2738
- } else {
2739
- try {
2740
- if (value.includes("\\")) {
2741
- const surgicalValue = value.replace(/(^|[^\\])"/g, '$1\\"');
2742
- value = JSON.parse(`"${surgicalValue.replace(/\n/g, "\\n").replace(/\r/g, "\\r")}"`);
2743
- }
2744
- } catch (e) {
2745
- value = value.replace(/\\"/g, '"').replace(/\\'/g, "'").replace(/\\`/g, "`").replace(/\\\\/g, "\\").replace(/\\n/g, "\n");
2746
- }
2747
- }
2748
- } else if (i < argsString.length && argsString[i] === "[") {
2749
- let balance = 0;
2750
- let inString = null;
2751
- let start = i;
2752
- let end = -1;
2753
- for (let j = i; j < argsString.length; j++) {
2754
- const char = argsString[j];
2755
- if (!inString && (char === '"' || char === "'" || char === "`")) {
2756
- inString = char;
2757
- } else if (inString && char === inString && argsString[j - 1] !== "\\") {
2758
- inString = null;
2759
- }
2760
- if (!inString) {
2761
- if (char === "[") balance++;
2762
- else if (char === "]") balance--;
2763
- if (balance === 0) {
2764
- end = j;
2765
- break;
2766
- }
2767
- }
2768
- }
2769
- if (end !== -1) {
2770
- value = argsString.substring(start, end + 1);
2771
- i = end + 1;
2772
- try {
2773
- let normalized = value.trim();
2774
- if (normalized.startsWith("'") || normalized.includes("'")) {
2775
- }
2776
- } catch (e) {
2777
- }
2778
- } else {
2779
- value = argsString.substring(start);
2780
- i = argsString.length;
2781
- }
2782
- } else {
2783
- let endMatch = argsString.substring(i).match(/([^,\s\)]+)/);
2784
- if (endMatch) {
2785
- value = endMatch[1];
2786
- i += value.length;
2787
- }
2788
- }
2789
- if (value === "true") value = true;
2790
- else if (value === "false") value = false;
2791
- else if (typeof value === "string" && !isNaN(value) && value.trim() !== "") value = Number(value);
2792
- if (typeof value === "string" && (key.toLowerCase().includes("path") || ["dest", "source", "to", "from"].includes(key.toLowerCase()))) {
2793
- value = value.replace(/\x0C/g, "\\f").replace(/\x0D/g, "\\r").replace(/\x0B/g, "\\v").replace(/\x08/g, "\\b");
2794
- }
2795
- args[key] = value;
3255
+ };
3256
+ const cost = costs[imageSettings.quality] || 2e-3;
3257
+ const stats = await getDailyUsage();
3258
+ if (!stats.imageCalls) {
3259
+ stats.imageCalls = [];
2796
3260
  }
2797
- return args;
3261
+ stats.imageCalls.push({
3262
+ timestamp: Date.now(),
3263
+ cost
3264
+ });
3265
+ queueFlush();
2798
3266
  };
2799
3267
  }
2800
3268
  });
@@ -3324,433 +3792,109 @@ var init_update_file = __esm({
3324
3792
  }
3325
3793
  if (matches.length > 1) {
3326
3794
  results.push({ success: false, error: `Block ${i + 1}: Found ${matches.length} matches (must be unique).` });
3327
- continue;
3328
- }
3329
- const startPos = matches[0].index;
3330
- const firstMatchContent = matches[0][0];
3331
- const lineStart = currentFileContent.lastIndexOf("\n", startPos) + 1;
3332
- const leadingContext = currentFileContent.substring(lineStart, startPos);
3333
- const finalReplacement = adjustIndentation(content_to_add, firstMatchContent, leadingContext);
3334
- const allOriginalLines = currentFileContent.split("\n");
3335
- const patchStartLine = currentFileContent.substring(0, startPos).split("\n").length;
3336
- const patchOldLines = firstMatchContent.split("\n");
3337
- const contextBefore = [];
3338
- for (let j = Math.max(0, patchStartLine - 4); j < patchStartLine - 1; j++) {
3339
- contextBefore.push({ num: j + 1, text: allOriginalLines[j] });
3340
- }
3341
- const contextAfter = [];
3342
- const patchEndLineIdx = patchStartLine + patchOldLines.length - 1;
3343
- for (let j = patchEndLineIdx; j < Math.min(allOriginalLines.length, patchEndLineIdx + 3); j++) {
3344
- contextAfter.push({ num: j + 1, text: allOriginalLines[j] });
3345
- }
3346
- results.push({
3347
- success: true,
3348
- startPos,
3349
- oldContent: firstMatchContent,
3350
- newContent: finalReplacement,
3351
- originalStartLine: patchStartLine,
3352
- contextBefore,
3353
- contextAfter
3354
- });
3355
- currentFileContent = currentFileContent.substring(0, startPos) + finalReplacement + currentFileContent.substring(startPos + firstMatchContent.length);
3356
- totalInstances++;
3357
- }
3358
- if (totalInstances === 0) {
3359
- return `ERROR: Failed to apply any patches to [${targetPath}].
3360
- ${results.map((r) => r.error).join("\n")}`;
3361
- }
3362
- fs10.writeFileSync(absolutePath, currentFileContent, "utf8");
3363
- let diffText = `SUCCESS: File [${targetPath}] updated. [${totalInstances}/${patchPairs.length}] blocks applied.
3364
-
3365
- `;
3366
- diffText += `[DIFF_START]
3367
- `;
3368
- const terminalWidth = process.stdout.columns || 100;
3369
- const separatorLine = "\u2550".repeat(Math.max(20, terminalWidth - 12));
3370
- const allLinesFinal = currentFileContent.split("\n");
3371
- const successfulPatches = results.filter((r) => r.success);
3372
- successfulPatches.forEach((res, idx) => {
3373
- if (idx === 0) {
3374
- res.contextBefore.forEach((ctx) => {
3375
- diffText += `[UI_CONTEXT] ${ctx.num} |${ctx.text}
3376
- `;
3377
- });
3378
- } else {
3379
- const prev = successfulPatches[idx - 1];
3380
- const prevLinesCount = prev.newContent.split("\n").length;
3381
- const prevEndLine = prev.originalStartLine + prevLinesCount - 1;
3382
- const gap = res.originalStartLine - prevEndLine - 1;
3383
- if (gap >= 1 && gap < 12) {
3384
- for (let j = prevEndLine; j < res.originalStartLine - 1; j++) {
3385
- diffText += `[UI_CONTEXT] ${j + 1} |${allLinesFinal[j]}
3386
- `;
3387
- }
3388
- } else if (gap >= 12) {
3389
- prev.contextAfter.forEach((ctx) => {
3390
- diffText += `[UI_CONTEXT] ${ctx.num} |${ctx.text}
3391
- `;
3392
- });
3393
- diffText += `[UI_CONTEXT] ${separatorLine}
3394
- `;
3395
- res.contextBefore.forEach((ctx) => {
3396
- diffText += `[UI_CONTEXT] ${ctx.num} |${ctx.text}
3397
- `;
3398
- });
3399
- }
3400
- }
3401
- const oldLines = res.oldContent.split("\n");
3402
- const newLines = res.newContent.split("\n");
3403
- oldLines.forEach((line, i) => {
3404
- diffText += `-${res.originalStartLine + i}|${line}
3405
- `;
3406
- });
3407
- newLines.forEach((line, i) => {
3408
- diffText += `+${res.originalStartLine + i}|${line}
3409
- `;
3410
- });
3411
- if (idx === successfulPatches.length - 1) {
3412
- res.contextAfter.forEach((ctx) => {
3413
- diffText += `[UI_CONTEXT] ${ctx.num} |${ctx.text}
3414
- `;
3415
- });
3416
- }
3417
- });
3418
- diffText += `[DIFF_END]`;
3419
- const errors = results.filter((r) => !r.success);
3420
- if (errors.length > 0) {
3421
- diffText += `
3422
-
3423
- \u26A0\uFE0F WARNING: Some blocks failed:
3424
- ${errors.map((e) => ` \u2022 ${e.error}`).join("\n")}`;
3425
- }
3426
- return diffText;
3427
- } catch (err) {
3428
- return `ERROR: Failed to update file [${targetPath}]: ${err.message}`;
3429
- }
3430
- };
3431
- }
3432
- });
3433
-
3434
- // src/tools/exec_command.js
3435
- import { spawn } from "child_process";
3436
- var pty, activeChildProcess, isActiveCommandPty, writeToActiveCommand, terminateActiveCommand, adjustWindowsCommand, exec_command, runStandardSpawn;
3437
- var init_exec_command = __esm({
3438
- async "src/tools/exec_command.js"() {
3439
- init_arg_parser();
3440
- init_main_tools();
3441
- pty = null;
3442
- try {
3443
- const ptyModule = await import("node-pty");
3444
- pty = ptyModule.default || ptyModule;
3445
- } catch (err) {
3446
- }
3447
- activeChildProcess = null;
3448
- isActiveCommandPty = false;
3449
- writeToActiveCommand = (data) => {
3450
- try {
3451
- if (activeChildProcess) {
3452
- if (isActiveCommandPty && typeof activeChildProcess.write === "function") {
3453
- activeChildProcess.write(data);
3454
- } else if (activeChildProcess.stdin && activeChildProcess.stdin.writable) {
3455
- activeChildProcess.stdin.write(data);
3456
- }
3457
- }
3458
- } catch (err) {
3459
- }
3460
- };
3461
- terminateActiveCommand = () => {
3462
- if (activeChildProcess) {
3463
- try {
3464
- if (isActiveCommandPty && typeof activeChildProcess.destroy === "function") {
3465
- activeChildProcess.destroy();
3466
- } else if (typeof activeChildProcess.kill === "function") {
3467
- activeChildProcess.kill("SIGKILL");
3468
- }
3469
- } catch (err) {
3470
- }
3471
- activeChildProcess = null;
3472
- isActiveCommandPty = false;
3473
- }
3474
- };
3475
- adjustWindowsCommand = (command, usePowerShell = false) => {
3476
- if (process.platform !== "win32") return command;
3477
- const tokens = [];
3478
- let current = "";
3479
- let inQuote = null;
3480
- let isEscaped = false;
3481
- for (let i = 0; i < command.length; i++) {
3482
- const char = command[i];
3483
- if (isEscaped) {
3484
- current += char;
3485
- isEscaped = false;
3486
- continue;
3487
- }
3488
- if (char === "\\") {
3489
- if (command[i + 1] === " ") {
3490
- current += " ";
3491
- i++;
3492
- continue;
3493
- }
3494
- current += char;
3495
- isEscaped = true;
3496
- continue;
3497
- }
3498
- if (inQuote) {
3499
- if (char === inQuote) {
3500
- inQuote = null;
3501
- }
3502
- current += char;
3503
- } else {
3504
- if (char === '"' || char === "'") {
3505
- inQuote = char;
3506
- current += char;
3507
- } else if (char === ";" && !current.includes("://")) {
3508
- if (current.length > 0) {
3509
- tokens.push(current);
3510
- current = "";
3511
- }
3512
- tokens.push(usePowerShell ? ";" : "&");
3513
- } else if (char === "|" && !current.includes("://")) {
3514
- if (current.length > 0) {
3515
- tokens.push(current);
3516
- current = "";
3517
- }
3518
- tokens.push("|");
3519
- } else if (/\s/.test(char)) {
3520
- if (current.length > 0) {
3521
- tokens.push(current);
3522
- current = "";
3523
- }
3524
- } else {
3525
- current += char;
3526
- }
3527
- }
3528
- }
3529
- if (current.length > 0) {
3530
- tokens.push(current);
3531
- }
3532
- const looksLikePath = (str) => {
3533
- if (!str.includes("/")) return false;
3534
- if (/^(https?|file|ftp):\/\//i.test(str)) return false;
3535
- if (str.startsWith("/") && (str.match(/\//g) || []).length === 1) {
3536
- return false;
3537
- }
3538
- if (/\s\/|\/\s/.test(str)) return false;
3539
- if (/[\(\)\{\}\;\<\>\=\'\"]/.test(str)) return false;
3540
- return true;
3541
- };
3542
- let inMkdir = false;
3543
- const translatedTokens = [];
3544
- for (let i = 0; i < tokens.length; i++) {
3545
- const token = tokens[i];
3546
- if (token === "mkdir" && usePowerShell && isPsAvailable()) {
3547
- inMkdir = true;
3548
- }
3549
- if (inMkdir) {
3550
- const controlOperators = [">", ">>", "<", "&", "&&", "|", "||", ";"];
3551
- if (controlOperators.includes(token)) {
3552
- inMkdir = false;
3553
- } else if (token === "-p" || token === "--parents") {
3554
- translatedTokens.push("-Force");
3555
- continue;
3556
- }
3557
- }
3558
- if (token === "|" && tokens[i + 1] === "tee") {
3559
- if (tokens[i + 2] === "-a") {
3560
- translatedTokens.push(">>");
3561
- i += 2;
3562
- } else {
3563
- translatedTokens.push(">");
3564
- i += 1;
3565
- }
3566
- continue;
3567
- }
3568
- if (token === "|" && tokens[i + 1] === "cat" && tokens[i + 2] === ">") {
3569
- translatedTokens.push(">");
3570
- i += 2;
3571
- continue;
3572
- }
3573
- if (token === "|") {
3574
- const nextToken = tokens[i + 1];
3575
- if (nextToken) {
3576
- const nextUnquoted = nextToken.replace(/^['"]|['"]$/g, "");
3577
- const isWritableFile = /\.(txt|md|json|log|csv|html|css|py|js|xml|yaml|yml|pdf|docx|pptx|xlsx)$/i.test(nextUnquoted);
3578
- if (looksLikePath(nextUnquoted) && isWritableFile) {
3579
- translatedTokens.push(">");
3580
- continue;
3581
- }
3795
+ continue;
3582
3796
  }
3797
+ const startPos = matches[0].index;
3798
+ const firstMatchContent = matches[0][0];
3799
+ const lineStart = currentFileContent.lastIndexOf("\n", startPos) + 1;
3800
+ const leadingContext = currentFileContent.substring(lineStart, startPos);
3801
+ const finalReplacement = adjustIndentation(content_to_add, firstMatchContent, leadingContext);
3802
+ const allOriginalLines = currentFileContent.split("\n");
3803
+ const patchStartLine = currentFileContent.substring(0, startPos).split("\n").length;
3804
+ const patchOldLines = firstMatchContent.split("\n");
3805
+ const contextBefore = [];
3806
+ for (let j = Math.max(0, patchStartLine - 4); j < patchStartLine - 1; j++) {
3807
+ contextBefore.push({ num: j + 1, text: allOriginalLines[j] });
3808
+ }
3809
+ const contextAfter = [];
3810
+ const patchEndLineIdx = patchStartLine + patchOldLines.length - 1;
3811
+ for (let j = patchEndLineIdx; j < Math.min(allOriginalLines.length, patchEndLineIdx + 3); j++) {
3812
+ contextAfter.push({ num: j + 1, text: allOriginalLines[j] });
3813
+ }
3814
+ results.push({
3815
+ success: true,
3816
+ startPos,
3817
+ oldContent: firstMatchContent,
3818
+ newContent: finalReplacement,
3819
+ originalStartLine: patchStartLine,
3820
+ contextBefore,
3821
+ contextAfter
3822
+ });
3823
+ currentFileContent = currentFileContent.substring(0, startPos) + finalReplacement + currentFileContent.substring(startPos + firstMatchContent.length);
3824
+ totalInstances++;
3583
3825
  }
3584
- translatedTokens.push(token);
3585
- }
3586
- let inEchoArguments = false;
3587
- const processedTokens = translatedTokens.map((token) => {
3588
- if (token === "echo") {
3589
- inEchoArguments = true;
3590
- return token;
3591
- }
3592
- const controlOperators = [">", ">>", "<", "&", "&&", "|", "||", ";"];
3593
- if (controlOperators.includes(token)) {
3594
- inEchoArguments = false;
3595
- }
3596
- const hasOuterQuotes = /^['"]|['"]$/.test(token);
3597
- let processed = token;
3598
- if (inEchoArguments && hasOuterQuotes) {
3599
- processed = token.replace(/^['"]|['"]$/g, "");
3600
- }
3601
- const currentHasOuterQuotes = /^['"]|['"]$/.test(processed);
3602
- const unquoted = processed.replace(/^['"]|['"]$/g, "");
3603
- if (looksLikePath(unquoted)) {
3604
- processed = processed.replace(/\//g, "\\");
3605
- }
3606
- const finalUnquoted = processed.replace(/^['"]|['"]$/g, "");
3607
- if (finalUnquoted.includes(" ") && !currentHasOuterQuotes) {
3608
- processed = `"${finalUnquoted}"`;
3826
+ if (totalInstances === 0) {
3827
+ return `ERROR: Failed to apply any patches to [${targetPath}].
3828
+ ${results.map((r) => r.error).join("\n")}`;
3609
3829
  }
3610
- return processed;
3611
- });
3612
- return processedTokens.join(" ");
3613
- };
3614
- exec_command = async (args, options = {}) => {
3615
- const { command: rawCommand } = parseArgs(args);
3616
- const { onChunk } = options;
3617
- if (!rawCommand) return 'ERROR: Missing "command" argument for exec_command.';
3618
- const isWin = process.platform === "win32";
3619
- const systemSettings = options.systemSettings || {};
3620
- const netEnv = {};
3621
- if (systemSettings.networkAccess === false) {
3622
- netEnv.HTTP_PROXY = "http://127.0.0.1:9999";
3623
- netEnv.HTTPS_PROXY = "http://127.0.0.1:9999";
3624
- netEnv.ALL_PROXY = "socks5://127.0.0.1:9999";
3625
- netEnv.http_proxy = "http://127.0.0.1:9999";
3626
- netEnv.https_proxy = "http://127.0.0.1:9999";
3627
- netEnv.all_proxy = "socks5://127.0.0.1:9999";
3628
- netEnv.NO_PROXY = "localhost,127.0.0.1";
3629
- }
3630
- return new Promise((resolve) => {
3631
- const attempt = (usePowerShell) => {
3632
- const command = adjustWindowsCommand(rawCommand, usePowerShell);
3633
- const shell = isWin ? usePowerShell ? "powershell.exe" : "cmd.exe" : process.env.SHELL || "bash";
3634
- const shellArgs = isWin ? usePowerShell ? ["-NoProfile", "-Command", command] : ["/c", command] : ["-c", command];
3635
- if (pty) {
3636
- try {
3637
- const ptyProcess = pty.spawn(shell, shellArgs, {
3638
- name: "xterm-256color",
3639
- cols: options.cols || 120,
3640
- rows: options.rows || 30,
3641
- cwd: process.cwd(),
3642
- env: {
3643
- ...process.env,
3644
- CI: "false",
3645
- TERM: "xterm-256color",
3646
- FORCE_COLOR: "1",
3647
- ...netEnv
3648
- }
3649
- });
3650
- activeChildProcess = ptyProcess;
3651
- isActiveCommandPty = true;
3652
- let output = "";
3653
- ptyProcess.onData((data) => {
3654
- output += data;
3655
- if (onChunk) onChunk(data);
3656
- });
3657
- ptyProcess.onExit(({ exitCode }) => {
3658
- activeChildProcess = null;
3659
- const normalizedOutput = (output || "").replace(/\r\n/g, "\n").replace(/\r/g, "\n");
3660
- const finalOutput = normalizedOutput || "Command executed with no output.";
3661
- if (exitCode !== 0) {
3662
- resolve(`ERROR: Command [${rawCommand}] failed with exit code [${exitCode}].
3663
-
3664
- ${finalOutput}`);
3665
- } else {
3666
- resolve(`SUCCESS: Command [${rawCommand}] completed.
3830
+ fs10.writeFileSync(absolutePath, currentFileContent, "utf8");
3831
+ let diffText = `SUCCESS: File [${targetPath}] updated. [${totalInstances}/${patchPairs.length}] blocks applied.
3667
3832
 
3668
- ${finalOutput}`);
3669
- }
3670
- });
3671
- return true;
3672
- } catch (err) {
3673
- if (isWin && usePowerShell && err.code === "ENOENT") {
3674
- return false;
3833
+ `;
3834
+ diffText += `[DIFF_START]
3835
+ `;
3836
+ const terminalWidth = process.stdout.columns || 100;
3837
+ const separatorLine = "\u2550".repeat(Math.max(20, terminalWidth - 12));
3838
+ const allLinesFinal = currentFileContent.split("\n");
3839
+ const successfulPatches = results.filter((r) => r.success);
3840
+ successfulPatches.forEach((res, idx) => {
3841
+ if (idx === 0) {
3842
+ res.contextBefore.forEach((ctx) => {
3843
+ diffText += `[UI_CONTEXT] ${ctx.num} |${ctx.text}
3844
+ `;
3845
+ });
3846
+ } else {
3847
+ const prev = successfulPatches[idx - 1];
3848
+ const prevLinesCount = prev.newContent.split("\n").length;
3849
+ const prevEndLine = prev.originalStartLine + prevLinesCount - 1;
3850
+ const gap = res.originalStartLine - prevEndLine - 1;
3851
+ if (gap >= 1 && gap < 12) {
3852
+ for (let j = prevEndLine; j < res.originalStartLine - 1; j++) {
3853
+ diffText += `[UI_CONTEXT] ${j + 1} |${allLinesFinal[j]}
3854
+ `;
3675
3855
  }
3676
- runStandardSpawn(resolve, command, rawCommand, netEnv, onChunk, usePowerShell);
3677
- return true;
3856
+ } else if (gap >= 12) {
3857
+ prev.contextAfter.forEach((ctx) => {
3858
+ diffText += `[UI_CONTEXT] ${ctx.num} |${ctx.text}
3859
+ `;
3860
+ });
3861
+ diffText += `[UI_CONTEXT] ${separatorLine}
3862
+ `;
3863
+ res.contextBefore.forEach((ctx) => {
3864
+ diffText += `[UI_CONTEXT] ${ctx.num} |${ctx.text}
3865
+ `;
3866
+ });
3678
3867
  }
3679
- } else {
3680
- runStandardSpawn(resolve, command, rawCommand, netEnv, onChunk, usePowerShell);
3681
- return true;
3682
3868
  }
3683
- };
3684
- if (isWin) {
3685
- if (!attempt(true)) {
3686
- attempt(false);
3869
+ const oldLines = res.oldContent.split("\n");
3870
+ const newLines = res.newContent.split("\n");
3871
+ oldLines.forEach((line, i) => {
3872
+ diffText += `-${res.originalStartLine + i}|${line}
3873
+ `;
3874
+ });
3875
+ newLines.forEach((line, i) => {
3876
+ diffText += `+${res.originalStartLine + i}|${line}
3877
+ `;
3878
+ });
3879
+ if (idx === successfulPatches.length - 1) {
3880
+ res.contextAfter.forEach((ctx) => {
3881
+ diffText += `[UI_CONTEXT] ${ctx.num} |${ctx.text}
3882
+ `;
3883
+ });
3687
3884
  }
3688
- } else {
3689
- attempt(false);
3690
- }
3691
- });
3692
- };
3693
- runStandardSpawn = (resolve, command, rawCommand, netEnv, onChunk, usePowerShell = true) => {
3694
- const isWin = process.platform === "win32";
3695
- const shell = isWin ? usePowerShell ? "powershell.exe" : "cmd.exe" : process.env.SHELL || "bash";
3696
- const shellArgs = isWin ? usePowerShell ? ["-NoProfile", "-Command", command] : ["/c", command] : ["-c", command];
3697
- const child = isWin ? spawn(shell, shellArgs, { cwd: process.cwd(), env: { ...process.env, ...netEnv } }) : spawn(command, {
3698
- shell: true,
3699
- cwd: process.cwd(),
3700
- env: {
3701
- ...process.env,
3702
- CI: "false",
3703
- TERM: "xterm-256color",
3704
- FORCE_COLOR: "1",
3705
- ...netEnv
3706
- }
3707
- });
3708
- activeChildProcess = child;
3709
- isActiveCommandPty = false;
3710
- if (child.stdin) {
3711
- child.stdin.on("error", () => {
3712
- activeChildProcess = null;
3713
3885
  });
3714
- }
3715
- let stdout = "";
3716
- let stderr = "";
3717
- child.stdout.on("data", (data) => {
3718
- const chunk = data.toString();
3719
- stdout += chunk;
3720
- if (onChunk) onChunk(chunk);
3721
- });
3722
- child.stderr.on("data", (data) => {
3723
- const chunk = data.toString();
3724
- stderr += chunk;
3725
- if (onChunk) onChunk(chunk);
3726
- });
3727
- child.on("close", (code) => {
3728
- activeChildProcess = null;
3729
- const result = [];
3730
- if (stdout) result.push(`STDOUT:
3731
- ${stdout}`);
3732
- if (stderr) result.push(`STDERR:
3733
- ${stderr}`);
3734
- if (code !== 0) result.push(`EXIT CODE: ${code}`);
3735
- const finalOutput = result.join("\n\n") || "Command executed with no output.";
3736
- if (code !== 0) {
3737
- resolve(`ERROR: Command [${rawCommand}] failed with exit code [${code}].
3738
-
3739
- ${finalOutput}`);
3740
- } else {
3741
- resolve(`SUCCESS: Command [${rawCommand}] completed.
3886
+ diffText += `[DIFF_END]`;
3887
+ const errors = results.filter((r) => !r.success);
3888
+ if (errors.length > 0) {
3889
+ diffText += `
3742
3890
 
3743
- ${finalOutput}`);
3744
- }
3745
- });
3746
- child.on("error", (err) => {
3747
- if (isWin && usePowerShell && err.code === "ENOENT") {
3748
- const cmdCommand = adjustWindowsCommand(rawCommand, false);
3749
- return runStandardSpawn(resolve, cmdCommand, rawCommand, netEnv, onChunk, false);
3891
+ \u26A0\uFE0F WARNING: Some blocks failed:
3892
+ ${errors.map((e) => ` \u2022 ${e.error}`).join("\n")}`;
3750
3893
  }
3751
- activeChildProcess = null;
3752
- resolve(`ERROR: Failed to start command [${rawCommand}]: ${err.message}`);
3753
- });
3894
+ return diffText;
3895
+ } catch (err) {
3896
+ return `ERROR: Failed to update file [${targetPath}]: ${err.message}`;
3897
+ }
3754
3898
  };
3755
3899
  }
3756
3900
  });
@@ -4640,7 +4784,7 @@ var init_tools = __esm({
4640
4784
  import { GoogleGenAI, ThinkingLevel, HarmBlockThreshold, HarmCategory } from "@google/genai";
4641
4785
  import path15 from "path";
4642
4786
  import fs16 from "fs";
4643
- var client, TERMINATION_SIGNAL, signalTermination, TOOL_LABELS2, getToolDetail, runJanitorTask, getActiveToolContext, getContextSafeText, contextSafeReplace, getSanitizedText, detectToolCalls, initAI, consolidatePastMemories, getAIStream;
4787
+ var client, TERMINATION_SIGNAL, stripAnsi2, signalTermination, TOOL_LABELS2, getToolDetail, runJanitorTask, getActiveToolContext, getContextSafeText, contextSafeReplace, getSanitizedText, detectToolCalls, initAI, consolidatePastMemories, getAIStream;
4644
4788
  var init_ai = __esm({
4645
4789
  async "src/utils/ai.js"() {
4646
4790
  init_prompts();
@@ -4654,6 +4798,10 @@ var init_ai = __esm({
4654
4798
  init_revert();
4655
4799
  client = null;
4656
4800
  TERMINATION_SIGNAL = false;
4801
+ stripAnsi2 = (str) => {
4802
+ if (typeof str !== "string") return str;
4803
+ return str.replace(/[\u001b\u009b][[()#;?]*(?:[0-9]{1,4}(?:;[0-9]{0,4})*)?[0-9A-ORZcf-nqry=><]/g, "");
4804
+ };
4657
4805
  signalTermination = () => {
4658
4806
  TERMINATION_SIGNAL = true;
4659
4807
  };
@@ -4693,7 +4841,7 @@ var init_ai = __esm({
4693
4841
  const persistentStorage = readEncryptedJson(MEMORIES_FILE, []);
4694
4842
  const janitorUserMemories = persistentStorage.map((m) => `- [${m.id}]: ${m.memory}`).join("\n");
4695
4843
  const janitorContents = history.slice(0, -1).filter((msg) => msg.text && !msg.text.includes("[TOOL RESULT]") && !msg.text.includes("OBSERVATION:") && !msg.isMeta && !msg.isLogo && !String(msg.id).startsWith("welcome") && !String(msg.id).startsWith("logo")).slice(-14).map((msg) => {
4696
- let processedText = msg.text.replace(/\[tool:functions\..*?\]/g, "").replace(/(?:<think>|\[think\])[\s\S]*?(?:<\/think>|\[\/think\])/g, "").replace(/\[Prompted on:.*?\]/g, "").replace(/\[METADATA \(PRIORITY: DYNAMIC\)\] Time: ([^|\n]+)/g, (match, p1) => {
4844
+ let processedText = stripAnsi2(msg.text).replace(/\[tool:functions\..*?\]/g, "").replace(/(?:<think>|\[think\])[\s\S]*?(?:<\/think>|\[\/think\])/g, "").replace(/\[Prompted on:.*?\]/g, "").replace(/\[METADATA \(PRIORITY: DYNAMIC\)\] Time: ([^|\n]+)/g, (match, p1) => {
4697
4845
  return `[METADATA (PRIORITY: DYNAMIC)] Time: ${p1.replace(/:\d{2}/g, "")}`;
4698
4846
  }).replace(/\[turn: continue\]/g, "").replace(/\[turn: finish\]/g, "").replace(/\[TOOL RESULTS\]/g, "").replace(/\[tool results\]/g, "").replace(/\r?\n\r?\n/g, "\n").replace(/\n\n/g, "\n").replace(/\\n\\n/g, "").trim();
4699
4847
  const limit = msg.role === "user" ? USER_CONTEXT_LENGTH : AGENT_CONTEXT_LENGTH;
@@ -6826,6 +6974,11 @@ function App({ args = [] }) {
6826
6974
  isTruncated: startIdx > 0
6827
6975
  };
6828
6976
  }, [messages, terminalSize.columns, terminalSize.rows]);
6977
+ const isTerminalWaitingForInput = useMemo2(() => {
6978
+ if (!activeCommand || !execOutput) return false;
6979
+ const lastChunk = execOutput.trim();
6980
+ return lastChunk.endsWith("?") || lastChunk.endsWith(":") || /\[[yYnN/]+\]\s*$/.test(lastChunk);
6981
+ }, [activeCommand, execOutput]);
6829
6982
  const terminalWidth = stdout?.columns || 80;
6830
6983
  const wrapWidth = Math.max(20, terminalWidth - 10);
6831
6984
  const wrappedLinesCount = input.split(/\r?\n/).reduce((acc, line) => {
@@ -6849,6 +7002,23 @@ function App({ args = [] }) {
6849
7002
  writeToActiveCommand("\b \b");
6850
7003
  setExecOutput((prev) => prev.slice(0, -1));
6851
7004
  }
7005
+ } else if (key.upArrow) {
7006
+ writeToActiveCommand(key.shift ? "\x1B[1;2A" : "\x1B[A");
7007
+ } else if (key.downArrow) {
7008
+ writeToActiveCommand(key.shift ? "\x1B[1;2B" : "\x1B[B");
7009
+ } else if (key.rightArrow) {
7010
+ writeToActiveCommand(key.shift ? "\x1B[1;2C" : "\x1B[C");
7011
+ } else if (key.leftArrow) {
7012
+ writeToActiveCommand(key.shift ? "\x1B[1;2D" : "\x1B[D");
7013
+ } else if (key.escape) {
7014
+ writeToActiveCommand("\x1B");
7015
+ } else if (key.ctrl && inputText) {
7016
+ const charCode = inputText.toLowerCase().charCodeAt(0);
7017
+ if (charCode >= 97 && charCode <= 122) {
7018
+ writeToActiveCommand(String.fromCharCode(charCode - 96));
7019
+ } else {
7020
+ writeToActiveCommand(inputText);
7021
+ }
6852
7022
  } else if (inputText) {
6853
7023
  writeToActiveCommand(inputText);
6854
7024
  if (!isActiveCommandPty) setExecOutput((prev) => prev + inputText);
@@ -8745,7 +8915,7 @@ Selection: ${val}`,
8745
8915
  newline: (key) => key.return && key.shift || key.return && key.ctrl || key.return && key.leftAlt || key.return && key.rightAlt
8746
8916
  }
8747
8917
  }
8748
- )))) : /* @__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" }, " 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(
8918
+ )))) : /* @__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(
8749
8919
  MultilineInput,
8750
8920
  {
8751
8921
  key: `input-${inputKey}`,
@@ -8857,7 +9027,7 @@ var init_app = __esm({
8857
9027
  init_ChatLayout();
8858
9028
  init_StatusBar();
8859
9029
  init_CommandMenu();
8860
- init_SettingsMenu();
9030
+ await init_SettingsMenu();
8861
9031
  init_ProfileForm();
8862
9032
  init_AskUserModal();
8863
9033
  init_secrets();