openfox 2.0.110 → 2.0.112

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 (80) hide show
  1. package/CHANGELOG.md +25 -0
  2. package/README.md +1 -0
  3. package/dist/CHANGELOG.md +25 -0
  4. package/dist/{ask-CJMU6EW7.js → ask-ZYPCJKZD.js} +3 -2
  5. package/dist/{chat-handler-UZ7WTT6D.js → chat-handler-BYXZIIV3.js} +23 -22
  6. package/dist/{chunk-VJWWJEBX.js → chunk-3UILDGOO.js} +9 -9
  7. package/dist/{chunk-GNFDD6LN.js → chunk-BOSKQI62.js} +3 -3
  8. package/dist/{chunk-D6ODGTSZ.js → chunk-C372UH7N.js} +2 -1
  9. package/dist/{chunk-4ZXRERIW.js → chunk-C5NQF2K4.js} +46 -4
  10. package/dist/{chunk-3HS72YIE.js → chunk-ERYUSG5C.js} +2 -2
  11. package/dist/{chunk-PU3IPUSW.js → chunk-FFPCVN5M.js} +45 -8
  12. package/dist/{chunk-KDQJOI2I.js → chunk-FSYRANYR.js} +2 -2
  13. package/dist/chunk-IJ53Y77N.js +142 -0
  14. package/dist/{chunk-ZJW3KOII.js → chunk-IYTDCPEQ.js} +293 -98
  15. package/dist/{chunk-WCQOHRUX.js → chunk-JDT63SSP.js} +2 -2
  16. package/dist/{chunk-VT2X3DMC.js → chunk-JNHKKUGJ.js} +2 -2
  17. package/dist/{chunk-JAX5OEMM.js → chunk-JURM3RPZ.js} +21 -4
  18. package/dist/chunk-LCLH6ZUL.js +43 -0
  19. package/dist/{chunk-6EV7X5MP.js → chunk-N4RTAGFY.js} +2 -2
  20. package/dist/{chunk-LXYNP7LL.js → chunk-NB2D6I64.js} +221 -5
  21. package/dist/{chunk-VKWVPQJ5.js → chunk-OAN4BXEW.js} +3 -1
  22. package/dist/{chunk-4R7G5JB6.js → chunk-P45RJGOT.js} +1 -1
  23. package/dist/chunk-P5AA7OYJ.js +7 -0
  24. package/dist/{chunk-E5HZKNTY.js → chunk-PCC4DBPF.js} +2 -2
  25. package/dist/{chunk-ACJNRPTO.js → chunk-QGXLZZBS.js} +29 -21
  26. package/dist/{chunk-UCYPPLVR.js → chunk-RAKPI4OE.js} +81 -70
  27. package/dist/{chunk-MM46DJJL.js → chunk-RISQXU32.js} +2 -2
  28. package/dist/{chunk-CQKRZ4WV.js → chunk-RKMP74BB.js} +4 -4
  29. package/dist/chunk-RSB4AR2A.js +108 -0
  30. package/dist/{chunk-VXKPZUCT.js → chunk-RT2A2RRL.js} +4 -2
  31. package/dist/{chunk-HK75Q3EA.js → chunk-SDGNV45R.js} +10 -10
  32. package/dist/{chunk-C5JJM72V.js → chunk-SVJFMZ2Q.js} +49 -5
  33. package/dist/{chunk-B5MH4HQ6.js → chunk-SYJMUIRC.js} +7 -3
  34. package/dist/{chunk-QRASX3HC.js → chunk-UAF2FOI5.js} +7 -7
  35. package/dist/{chunk-4HIFB7F5.js → chunk-XCK5IBO4.js} +37 -26
  36. package/dist/{chunk-5HMKLHTT.js → chunk-XWNCKIPO.js} +2 -2
  37. package/dist/{chunk-NORNB6IJ.js → chunk-Z56SEG4Z.js} +6 -6
  38. package/dist/cli/dev.js +1 -1
  39. package/dist/cli/index.js +1 -1
  40. package/dist/{client-LPNFUOPV.js → client-QNQTX5EA.js} +4 -4
  41. package/dist/{compactor-OSDLCGRC.js → compactor-X2KZ3XFU.js} +10 -9
  42. package/dist/{config-HX7FDKGJ.js → config-TW5FHQEM.js} +2 -2
  43. package/dist/{dynamic-context-WVA7HTEP.js → dynamic-context-ZRQO2FJN.js} +7 -7
  44. package/dist/{events-26J7BUSY.js → events-Y6XXQYFG.js} +7 -6
  45. package/dist/{folding-ZD4AMFNR.js → folding-Z4GNWRC3.js} +9 -6
  46. package/dist/{http-client-MQARNFY3.js → http-client-2GDKHZIG.js} +3 -3
  47. package/dist/{manager-RJH7EYIG.js → manager-HCMDFEQH.js} +4 -4
  48. package/dist/{model-overrides-BXMFIT47.js → model-overrides-O3ZYKFP7.js} +3 -3
  49. package/dist/oauth-provider-52YILVUJ.js +15 -0
  50. package/dist/oauth-store-XCFXV2VM.js +32 -0
  51. package/dist/{orchestrator-BW27C4K4.js → orchestrator-P5EUMC7E.js} +22 -21
  52. package/dist/package.json +13 -10
  53. package/dist/{path-security-AAZMH33K.js → path-security-525YLND3.js} +11 -9
  54. package/dist/{platform-EZJABX5J.js → platform-MEQUWG6U.js} +3 -3
  55. package/dist/{processor-FTCPHWBM.js → processor-UN4H4V7F.js} +22 -21
  56. package/dist/{protocol-_Gphic7p.d.ts → protocol-D6MISQyz.d.ts} +8 -3
  57. package/dist/{protocol-SPIJPOEN.js → protocol-FTHAR2YL.js} +4 -3
  58. package/dist/{provider-JS5P3HQ2.js → provider-3R4X62LW.js} +7 -7
  59. package/dist/{provider-manager-MWAIOX2A.js → provider-manager-W5N4XRE5.js} +5 -5
  60. package/dist/{registry-JJB5GXOM.js → registry-74KPZ5NV.js} +3 -3
  61. package/dist/{serve-XDZB4EJN.js → serve-WHFUNQ6Z.js} +32 -29
  62. package/dist/server/index.d.ts +15 -1
  63. package/dist/server/index.js +31 -28
  64. package/dist/server-7MOOJR2N.js +48 -0
  65. package/dist/{session-overrides-T47KXDDS.js → session-overrides-XH6I3COP.js} +5 -5
  66. package/dist/{sessions-YTWCOHI3.js → sessions-D772YTWL.js} +8 -4
  67. package/dist/{settings-2RZBMX5Y.js → settings-KO6DSJLD.js} +2 -2
  68. package/dist/shared/index.d.ts +1 -1
  69. package/dist/shared/index.js +1 -1
  70. package/dist/{tools-KPIYFL5A.js → tools-HTUTYMKI.js} +20 -19
  71. package/dist/{update-75QZJYKD.js → update-BRUFGGTW.js} +2 -2
  72. package/dist/{update-server-4I6LXE5K.js → update-server-LOOXIXDW.js} +2 -2
  73. package/dist/web/assets/{index-BmjVoqQT.js → index-Dukvfqm-.js} +83 -83
  74. package/dist/web/assets/{index-CyWbbpRP.css → index-nS1p0g8O.css} +1 -1
  75. package/dist/web/index.html +2 -2
  76. package/dist/web/sw.js +1 -1
  77. package/package.json +13 -10
  78. package/scripts/postinstall.mjs +8 -0
  79. package/dist/chunk-64374FPB.js +0 -7
  80. package/dist/server-R6DDJNF3.js +0 -47
@@ -4,7 +4,7 @@ import {
4
4
  getEnabledSkillMetadata,
5
5
  isSkillEnabled,
6
6
  loadAllSkills
7
- } from "./chunk-GNFDD6LN.js";
7
+ } from "./chunk-BOSKQI62.js";
8
8
  import {
9
9
  TurnMetrics,
10
10
  consumeStreamGenerator,
@@ -19,21 +19,24 @@ import {
19
19
  COMPACTION_PROMPT,
20
20
  buildBasePrompt,
21
21
  computeEffectiveTools
22
- } from "./chunk-5HMKLHTT.js";
22
+ } from "./chunk-XWNCKIPO.js";
23
23
  import {
24
24
  startInspectProxy
25
25
  } from "./chunk-33Q7LCVD.js";
26
26
  import {
27
27
  checkAborted,
28
28
  createProcess,
29
+ createUtf8StreamDecoder,
30
+ decodeUtf8,
29
31
  getProcessLogs,
30
32
  getProcessStatus,
31
33
  getSessionProcesses,
34
+ sanitizeUtf8,
32
35
  spawnShell,
33
36
  spawnShellProcess,
34
37
  startProcessCommand,
35
38
  stopProcess
36
- } from "./chunk-C5JJM72V.js";
39
+ } from "./chunk-SVJFMZ2Q.js";
37
40
  import {
38
41
  getMaxPerSession,
39
42
  getSessionProcessCount,
@@ -44,7 +47,7 @@ import {
44
47
  } from "./chunk-JE7LW7Y6.js";
45
48
  import {
46
49
  applyMcpServerUpdate
47
- } from "./chunk-VKWVPQJ5.js";
50
+ } from "./chunk-OAN4BXEW.js";
48
51
  import {
49
52
  getGitBranch,
50
53
  isGitRepository,
@@ -52,33 +55,33 @@ import {
52
55
  } from "./chunk-FR5LUTLQ.js";
53
56
  import {
54
57
  getSessionDisabledServers
55
- } from "./chunk-WCQOHRUX.js";
58
+ } from "./chunk-JDT63SSP.js";
56
59
  import {
57
60
  PathAccessDeniedError,
58
61
  extractAbsolutePathsFromCommand,
59
62
  extractSensitivePathsFromCommand,
60
63
  registerPathConfirmation,
61
64
  requestPathAccess
62
- } from "./chunk-PU3IPUSW.js";
65
+ } from "./chunk-FFPCVN5M.js";
63
66
  import {
64
67
  getCurrentContextWindowId,
65
68
  getCurrentWindowMessageOptions,
66
69
  getEventStore
67
- } from "./chunk-LXYNP7LL.js";
70
+ } from "./chunk-NB2D6I64.js";
68
71
  import {
69
72
  createChatDoneMessage,
70
73
  createChatMessageMessage,
71
74
  createChatMessageUpdatedMessage,
72
75
  createChatPathConfirmationMessage,
73
76
  createQueueStateMessage
74
- } from "./chunk-B5MH4HQ6.js";
77
+ } from "./chunk-SYJMUIRC.js";
75
78
  import {
76
79
  AskUserInterrupt,
77
80
  askUserTool
78
- } from "./chunk-JAX5OEMM.js";
81
+ } from "./chunk-JURM3RPZ.js";
79
82
  import {
80
83
  resolveLLMClientForAgent
81
- } from "./chunk-MM46DJJL.js";
84
+ } from "./chunk-RISQXU32.js";
82
85
  import {
83
86
  buildContextMessagesFromEventHistory,
84
87
  foldContextState,
@@ -88,13 +91,13 @@ import {
88
91
  handleToolResult,
89
92
  reorderToolMessages,
90
93
  stripOrphanedToolCalls
91
- } from "./chunk-ACJNRPTO.js";
94
+ } from "./chunk-QGXLZZBS.js";
92
95
  import {
93
96
  findAgentById,
94
97
  getRuntimeConfig,
95
98
  getSubAgents,
96
99
  loadAllAgentsDefault
97
- } from "./chunk-VT2X3DMC.js";
100
+ } from "./chunk-JNHKKUGJ.js";
98
101
  import {
99
102
  modelSupportsVision
100
103
  } from "./chunk-V4IE7HJY.js";
@@ -112,14 +115,14 @@ import {
112
115
  import {
113
116
  SETTINGS_KEYS,
114
117
  getSetting
115
- } from "./chunk-VXKPZUCT.js";
118
+ } from "./chunk-RT2A2RRL.js";
116
119
  import {
117
120
  logger
118
121
  } from "./chunk-K44MW7JJ.js";
119
122
  import {
120
123
  loadGlobalConfig,
121
124
  saveGlobalConfig
122
- } from "./chunk-D6ODGTSZ.js";
125
+ } from "./chunk-C372UH7N.js";
123
126
  import {
124
127
  getGlobalConfigDir
125
128
  } from "./chunk-CQGTEGKL.js";
@@ -136,7 +139,7 @@ async function requestUserConfirmation(context, toolLabel, desc) {
136
139
  if (context.dangerLevel === "dangerous") return Promise.resolve(true);
137
140
  if (toolLabel === "workspace" || toolLabel === "command") {
138
141
  try {
139
- const { getSetting: getSetting2, SETTINGS_KEYS: SETTINGS_KEYS2 } = await import("./settings-2RZBMX5Y.js");
142
+ const { getSetting: getSetting2, SETTINGS_KEYS: SETTINGS_KEYS2 } = await import("./settings-KO6DSJLD.js");
140
143
  if (getSetting2(SETTINGS_KEYS2.CONFIRM_ON_WORKSPACE_ACTIONS) !== "true") {
141
144
  return Promise.resolve(true);
142
145
  }
@@ -1053,9 +1056,30 @@ import stripAnsi from "strip-ansi";
1053
1056
 
1054
1057
  // src/server/tools/shell-tail.ts
1055
1058
  var TAIL_END_RE = /^(.*?)\s*\|\s*tail\s+(?:-n\s+)?-?(\d+)\s*$/;
1059
+ function hasTopLevelStatementSeparator(command) {
1060
+ let quote = null;
1061
+ for (let i = 0; i < command.length; i++) {
1062
+ const ch = command[i];
1063
+ if (ch === "\\") {
1064
+ i++;
1065
+ continue;
1066
+ }
1067
+ if (quote) {
1068
+ if (ch === quote) quote = null;
1069
+ continue;
1070
+ }
1071
+ if (ch === '"' || ch === "'" || ch === "`") {
1072
+ quote = ch;
1073
+ continue;
1074
+ }
1075
+ if (ch === ";" || ch === "\n") return true;
1076
+ }
1077
+ return false;
1078
+ }
1056
1079
  function stripTailPipe(command) {
1057
1080
  const trimmed = command.trim();
1058
1081
  if (!trimmed) return null;
1082
+ if (hasTopLevelStatementSeparator(trimmed)) return null;
1059
1083
  const match = trimmed.match(TAIL_END_RE);
1060
1084
  if (!match) return null;
1061
1085
  const beforeTail = match[1];
@@ -1219,13 +1243,13 @@ async function tryRtkRewrite(command) {
1219
1243
  stdio: ["ignore", "pipe", "pipe"],
1220
1244
  timeout: 2e3
1221
1245
  });
1222
- let stdout = "";
1246
+ const chunks = [];
1223
1247
  proc.stdout?.on("data", (data) => {
1224
- stdout += data.toString();
1248
+ chunks.push(data);
1225
1249
  });
1226
1250
  proc.on("error", reject);
1227
1251
  proc.on("close", (code) => {
1228
- if (code === 0 || code === 3) resolve5(stdout.trim());
1252
+ if (code === 0 || code === 3) resolve5(decodeUtf8(chunks).trim());
1229
1253
  else reject(new Error(`exit ${code}`));
1230
1254
  });
1231
1255
  });
@@ -1241,6 +1265,8 @@ function executeCommand(command, cwd, timeout, signal, onProgress) {
1241
1265
  return;
1242
1266
  }
1243
1267
  const proc = spawnShellProcess(command, cwd, signal, true);
1268
+ const stdoutDecoder = createUtf8StreamDecoder();
1269
+ const stderrDecoder = createUtf8StreamDecoder();
1244
1270
  let stdout = "";
1245
1271
  let stderr = "";
1246
1272
  let timedOut = false;
@@ -1258,39 +1284,35 @@ function executeCommand(command, cwd, timeout, signal, onProgress) {
1258
1284
  };
1259
1285
  signal?.addEventListener("abort", onAbort);
1260
1286
  proc.stdout?.on("data", (data) => {
1261
- const chunk = data.toString();
1262
- stdout += chunk;
1263
- onProgress?.(`[stdout] ${chunk}`);
1287
+ const text = stdoutDecoder.write(data);
1288
+ stdout += text;
1289
+ onProgress?.(`[stdout] ${text}`);
1264
1290
  });
1265
1291
  proc.stderr?.on("data", (data) => {
1266
- const chunk = data.toString();
1267
- stderr += chunk;
1268
- onProgress?.(`[stderr] ${chunk}`);
1292
+ const text = stderrDecoder.write(data);
1293
+ stderr += text;
1294
+ onProgress?.(`[stderr] ${text}`);
1269
1295
  });
1296
+ const settle = (exitCode, appendix) => {
1297
+ const out = (stdout + stdoutDecoder.end()).trim();
1298
+ resolve5({
1299
+ stdout: appendix ? out ? `${out}
1300
+
1301
+ ${appendix}` : appendix : out,
1302
+ stderr: (stderr + stderrDecoder.end()).trim(),
1303
+ exitCode
1304
+ });
1305
+ };
1270
1306
  proc.on("exit", () => {
1271
1307
  if (aborted) {
1272
1308
  clearTimeout(timer);
1273
1309
  signal?.removeEventListener("abort", onAbort);
1274
- let output = stdout.trim();
1275
- if (output) output += "\n\n";
1276
- output += "[interrupted by user]";
1277
- resolve5({
1278
- stdout: output,
1279
- stderr: stderr.trim(),
1280
- exitCode: 130
1281
- });
1310
+ settle(130, "[interrupted by user]");
1282
1311
  } else if (timedOut) {
1283
1312
  clearTimeout(timer);
1284
1313
  signal?.removeEventListener("abort", onAbort);
1285
- let output = stdout.trim();
1286
- if (output) output += "\n\n";
1287
- output += `[Exit code: 124]
1288
- [Process timed out after ${timeout}ms]`;
1289
- resolve5({
1290
- stdout: output,
1291
- stderr: stderr.trim(),
1292
- exitCode: 124
1293
- });
1314
+ settle(124, `[Exit code: 124]
1315
+ [Process timed out after ${timeout}ms]`);
1294
1316
  }
1295
1317
  });
1296
1318
  proc.on("close", (code) => {
@@ -1298,33 +1320,15 @@ function executeCommand(command, cwd, timeout, signal, onProgress) {
1298
1320
  clearTimeout(timer);
1299
1321
  signal?.removeEventListener("abort", onAbort);
1300
1322
  if (timedOut) {
1301
- let output = stdout.trim();
1302
- if (output) output += "\n\n";
1303
- output += `[Exit code: 124]
1304
- [Process timed out after ${timeout}ms]`;
1305
- resolve5({
1306
- stdout: output,
1307
- stderr: stderr.trim(),
1308
- exitCode: 124
1309
- });
1323
+ settle(124, `[Exit code: 124]
1324
+ [Process timed out after ${timeout}ms]`);
1310
1325
  return;
1311
1326
  }
1312
1327
  if (aborted) {
1313
- let output = stdout.trim();
1314
- if (output) output += "\n\n";
1315
- output += "[interrupted by user]";
1316
- resolve5({
1317
- stdout: output,
1318
- stderr: stderr.trim(),
1319
- exitCode: 130
1320
- });
1328
+ settle(130, "[interrupted by user]");
1321
1329
  return;
1322
1330
  }
1323
- resolve5({
1324
- stdout: stdout.trim(),
1325
- stderr: stderr.trim(),
1326
- exitCode: code ?? 1
1327
- });
1331
+ settle(code ?? 1);
1328
1332
  });
1329
1333
  proc.on("error", (error) => {
1330
1334
  clearTimeout(timer);
@@ -1559,7 +1563,7 @@ async function executeTools(assistantMsgId, toolCalls, ctx, append) {
1559
1563
  data: { callId: error.callId, question: error.question, type: error.type, options: error.options }
1560
1564
  });
1561
1565
  append(createChatDoneEvent(assistantMsgId, "waiting_for_user"));
1562
- const { awaitAnswer } = await import("./ask-CJMU6EW7.js");
1566
+ const { awaitAnswer } = await import("./ask-ZYPCJKZD.js");
1563
1567
  const answerPromise = awaitAnswer(error.callId);
1564
1568
  if (!answerPromise) {
1565
1569
  throw new Error(`No pending question found for callId: ${error.callId}`);
@@ -1645,11 +1649,18 @@ async function executeTools(assistantMsgId, toolCalls, ctx, append) {
1645
1649
  if (toolCall.name === "step_done" && toolResult.success) {
1646
1650
  stepDoneCalled = true;
1647
1651
  }
1648
- const content = stripAnsi2(
1652
+ const rawContent = stripAnsi2(
1649
1653
  toolResult.success ? toolResult.output ?? "Success" : toolResult.output ? `${toolResult.output}
1650
1654
 
1651
1655
  Error: ${toolResult.error}` : `Error: ${toolResult.error}`
1652
1656
  );
1657
+ const { clean: content, corrupted } = sanitizeUtf8(rawContent);
1658
+ if (corrupted) {
1659
+ logger.warn("Tool result contained invalid UTF-8 (U+FFFD); sanitized before sending to the LLM", {
1660
+ toolCallId: toolCall.id,
1661
+ tool: toolCall.name
1662
+ });
1663
+ }
1653
1664
  append(createToolResultEvent(assistantMsgId, toolCall.id, toolResult));
1654
1665
  return {
1655
1666
  toolCall,
@@ -1919,7 +1930,7 @@ ${CONTINUE_PROMPT}` : CONTINUE_PROMPT;
1919
1930
  sessionManager.setCurrentContextSize(sessionId, result.usage.promptTokens, config.subAgentMetadata?.subAgentId);
1920
1931
  if (!compacting) {
1921
1932
  const contextState2 = sessionManager.getContextState(sessionId);
1922
- const { shouldCompact, appendCompactionPrompt } = await import("./compactor-OSDLCGRC.js");
1933
+ const { shouldCompact, appendCompactionPrompt } = await import("./compactor-X2KZ3XFU.js");
1923
1934
  if (shouldCompact(
1924
1935
  contextState2.currentTokens,
1925
1936
  contextState2.maxTokens,
@@ -2289,7 +2300,7 @@ async function describeImageFromDataUrl(dataUrl, visionModel, options) {
2289
2300
  // src/server/context/image-processor.ts
2290
2301
  async function loadVisionModelFromGlobalConfig() {
2291
2302
  try {
2292
- const { loadGlobalConfig: loadGlobalConfig2, resolveVisionFallback } = await import("./config-HX7FDKGJ.js");
2303
+ const { loadGlobalConfig: loadGlobalConfig2, resolveVisionFallback } = await import("./config-TW5FHQEM.js");
2293
2304
  const runtimeConfig = getRuntimeConfig();
2294
2305
  const mode = runtimeConfig.mode ?? "production";
2295
2306
  const globalConfig = await loadGlobalConfig2(mode);
@@ -2907,7 +2918,7 @@ var callSubAgentTool = {
2907
2918
  };
2908
2919
  }
2909
2920
  try {
2910
- const { getToolRegistryForAgent: getToolRegistryForAgent2 } = await import("./tools-KPIYFL5A.js");
2921
+ const { getToolRegistryForAgent: getToolRegistryForAgent2 } = await import("./tools-HTUTYMKI.js");
2911
2922
  const toolRegistry = getToolRegistryForAgent2(agentDef);
2912
2923
  const turnMetrics = new TurnMetrics();
2913
2924
  const result = await executeSubAgent({
@@ -3929,7 +3940,7 @@ var mcpConfigTool = createTool(
3929
3940
  mcpNotifyChanged?.(sessionId);
3930
3941
  }
3931
3942
  async function rebuildTools() {
3932
- const { setMcpTools: setMcpTools2 } = await import("./tools-KPIYFL5A.js");
3943
+ const { setMcpTools: setMcpTools2 } = await import("./tools-HTUTYMKI.js");
3933
3944
  const mcpTools = createMcpTools(mcpManagerForTools);
3934
3945
  setMcpTools2(mcpTools);
3935
3946
  }
@@ -4624,4 +4635,4 @@ export {
4624
4635
  getToolRegistryForAgent,
4625
4636
  createToolRegistry
4626
4637
  };
4627
- //# sourceMappingURL=chunk-UCYPPLVR.js.map
4638
+ //# sourceMappingURL=chunk-RAKPI4OE.js.map
@@ -2,7 +2,7 @@ import {
2
2
  SETTINGS_KEYS,
3
3
  getSetting,
4
4
  setSetting
5
- } from "./chunk-VXKPZUCT.js";
5
+ } from "./chunk-RT2A2RRL.js";
6
6
 
7
7
  // src/server/agents/model-overrides.ts
8
8
  import { z } from "zod";
@@ -69,4 +69,4 @@ export {
69
69
  setAgentModelOverride,
70
70
  resolveLLMClientForAgent
71
71
  };
72
- //# sourceMappingURL=chunk-MM46DJJL.js.map
72
+ //# sourceMappingURL=chunk-RISQXU32.js.map
@@ -3,10 +3,10 @@ import {
3
3
  } from "./chunk-JR54MDZI.js";
4
4
  import {
5
5
  COMPACTION_PROMPT
6
- } from "./chunk-5HMKLHTT.js";
6
+ } from "./chunk-XWNCKIPO.js";
7
7
  import {
8
8
  getCurrentWindowMessageOptions
9
- } from "./chunk-LXYNP7LL.js";
9
+ } from "./chunk-NB2D6I64.js";
10
10
 
11
11
  // src/server/context/compactor.ts
12
12
  function appendCompactionPrompt(sessionId, append) {
@@ -22,7 +22,7 @@ function appendCompactionPrompt(sessionId, append) {
22
22
  append({ type: "message.done", data: { messageId: compactPromptMsgId } });
23
23
  }
24
24
  var COMPACTION_HEADROOM_TOKENS = 5e3;
25
- var COMPACTION_MAX_RATIO = 0.85;
25
+ var COMPACTION_MAX_RATIO = 0.95;
26
26
  function shouldCompact(currentTokens, maxTokens, threshold) {
27
27
  if (threshold <= 0) return false;
28
28
  const ceilingRatio = Math.min(1, Math.max(0, (maxTokens - COMPACTION_HEADROOM_TOKENS) / maxTokens));
@@ -36,4 +36,4 @@ export {
36
36
  COMPACTION_MAX_RATIO,
37
37
  shouldCompact
38
38
  };
39
- //# sourceMappingURL=chunk-CQKRZ4WV.js.map
39
+ //# sourceMappingURL=chunk-RKMP74BB.js.map
@@ -0,0 +1,108 @@
1
+ import {
2
+ clearMcpOAuthEntry,
3
+ clearMcpOAuthTokens,
4
+ readMcpOAuthEntry,
5
+ saveMcpOAuthClientInformation,
6
+ saveMcpOAuthCodeVerifier,
7
+ saveMcpOAuthState,
8
+ saveMcpOAuthTokens
9
+ } from "./chunk-IJ53Y77N.js";
10
+
11
+ // src/server/mcp/oauth-provider.ts
12
+ import { randomBytes } from "crypto";
13
+ var CALLBACK_PATH = "/api/mcp/oauth/callback";
14
+ var serverPort = 10369;
15
+ function setMcpOAuthServerPort(port) {
16
+ serverPort = port;
17
+ }
18
+ function getMcpOAuthRedirectUri() {
19
+ const publicUrl = process.env["OPENFOX_PUBLIC_URL"];
20
+ if (!publicUrl) return `http://127.0.0.1:${serverPort}${CALLBACK_PATH}`;
21
+ let base;
22
+ try {
23
+ base = new URL(publicUrl);
24
+ } catch {
25
+ throw new Error("OPENFOX_PUBLIC_URL is not a valid URL");
26
+ }
27
+ if (base.protocol !== "http:" && base.protocol !== "https:") {
28
+ throw new Error("OPENFOX_PUBLIC_URL must be an http or https URL");
29
+ }
30
+ base.pathname = `${base.pathname.replace(/\/+$/, "")}${CALLBACK_PATH}`;
31
+ base.search = "";
32
+ base.hash = "";
33
+ return base.toString();
34
+ }
35
+ var McpOAuthProvider = class {
36
+ constructor(serverName, serverUrl, redirectUri = getMcpOAuthRedirectUri()) {
37
+ this.serverName = serverName;
38
+ this.serverUrl = serverUrl;
39
+ this.redirectUri = redirectUri;
40
+ }
41
+ serverName;
42
+ serverUrl;
43
+ redirectUri;
44
+ authorizationUrl = null;
45
+ get redirectUrl() {
46
+ return this.redirectUri;
47
+ }
48
+ get clientMetadata() {
49
+ return {
50
+ client_name: "OpenFox",
51
+ redirect_uris: [this.redirectUri],
52
+ grant_types: ["authorization_code", "refresh_token"],
53
+ response_types: ["code"]
54
+ };
55
+ }
56
+ /** Set once the SDK has built an authorization URL, null while the stored tokens still work. */
57
+ get pendingAuthorizationUrl() {
58
+ return this.authorizationUrl;
59
+ }
60
+ async state() {
61
+ const value = randomBytes(32).toString("base64url");
62
+ await saveMcpOAuthState(this.serverName, this.serverUrl, value);
63
+ return value;
64
+ }
65
+ async clientInformation() {
66
+ const entry = await readMcpOAuthEntry(this.serverName, this.serverUrl);
67
+ return entry?.clientInformation;
68
+ }
69
+ async saveClientInformation(clientInformation) {
70
+ await saveMcpOAuthClientInformation(this.serverName, this.serverUrl, clientInformation);
71
+ }
72
+ async tokens() {
73
+ const entry = await readMcpOAuthEntry(this.serverName, this.serverUrl);
74
+ return entry?.tokens;
75
+ }
76
+ async saveTokens(tokens) {
77
+ await saveMcpOAuthTokens(this.serverName, this.serverUrl, tokens);
78
+ }
79
+ redirectToAuthorization(authorizationUrl) {
80
+ this.authorizationUrl = authorizationUrl;
81
+ }
82
+ async saveCodeVerifier(codeVerifier) {
83
+ await saveMcpOAuthCodeVerifier(this.serverName, this.serverUrl, codeVerifier);
84
+ }
85
+ async codeVerifier() {
86
+ const entry = await readMcpOAuthEntry(this.serverName, this.serverUrl);
87
+ if (!entry?.codeVerifier) {
88
+ throw new Error("No stored PKCE verifier for this server, start the authorization again");
89
+ }
90
+ return entry.codeVerifier;
91
+ }
92
+ /** Lets the SDK recover on its own when the server rejects the stored client or grant. */
93
+ async invalidateCredentials(scope) {
94
+ if (scope === "discovery") return;
95
+ if (scope === "all" || scope === "client") {
96
+ await clearMcpOAuthEntry(this.serverName);
97
+ return;
98
+ }
99
+ await clearMcpOAuthTokens(this.serverName, this.serverUrl);
100
+ }
101
+ };
102
+
103
+ export {
104
+ setMcpOAuthServerPort,
105
+ getMcpOAuthRedirectUri,
106
+ McpOAuthProvider
107
+ };
108
+ //# sourceMappingURL=chunk-RSB4AR2A.js.map
@@ -37,6 +37,7 @@ var SETTINGS_KEYS = {
37
37
  TOOLS_SHELL: "tools.shell",
38
38
  CONFIRM_ON_WORKSPACE_ACTIONS: "tools.confirmOnWorkspaceActions",
39
39
  FEATURES_PER_SESSION_MCP: "features.perSessionMcp",
40
+ MAINTENANCE_SNAPSHOT_STREAMS_MIGRATED: "maintenance.snapshotStreamsMigratedV1",
40
41
  PROXY_URL: "network.proxyUrl",
41
42
  DEFAULT_AGENT: "agent.defaultAgent",
42
43
  AGENT_MODEL_OVERRIDES: "agent.modelOverrides"
@@ -76,7 +77,8 @@ var SETTINGS_DEFAULTS = {
76
77
  [SETTINGS_KEYS.TOOLS_USE_RTK]: "false",
77
78
  [SETTINGS_KEYS.TOOLS_SHELL]: "cmd",
78
79
  [SETTINGS_KEYS.CONFIRM_ON_WORKSPACE_ACTIONS]: "false",
79
- [SETTINGS_KEYS.FEATURES_PER_SESSION_MCP]: "false"
80
+ [SETTINGS_KEYS.FEATURES_PER_SESSION_MCP]: "false",
81
+ [SETTINGS_KEYS.MAINTENANCE_SNAPSHOT_STREAMS_MIGRATED]: "false"
80
82
  };
81
83
  function getSetting(key) {
82
84
  try {
@@ -129,4 +131,4 @@ export {
129
131
  getAllSettings,
130
132
  getMaxVisibleItems
131
133
  };
132
- //# sourceMappingURL=chunk-VXKPZUCT.js.map
134
+ //# sourceMappingURL=chunk-RT2A2RRL.js.map
@@ -2,18 +2,18 @@ import {
2
2
  buildCachedPrompt,
3
3
  computeDynamicContextHash,
4
4
  getToolFingerprint
5
- } from "./chunk-NORNB6IJ.js";
5
+ } from "./chunk-Z56SEG4Z.js";
6
6
  import {
7
7
  createAssemblyResult,
8
8
  getConversationMessages,
9
9
  getToolRegistryForAgent,
10
10
  processEventsForConversation,
11
11
  runTopLevelAgentLoop
12
- } from "./chunk-UCYPPLVR.js";
12
+ } from "./chunk-RAKPI4OE.js";
13
13
  import {
14
14
  getAllInstructions,
15
15
  getEnabledSkillMetadata
16
- } from "./chunk-GNFDD6LN.js";
16
+ } from "./chunk-BOSKQI62.js";
17
17
  import {
18
18
  TurnMetrics,
19
19
  createChatDoneEvent,
@@ -22,24 +22,24 @@ import {
22
22
  import {
23
23
  buildAgentReminder,
24
24
  buildAgentSmallReminder
25
- } from "./chunk-5HMKLHTT.js";
25
+ } from "./chunk-XWNCKIPO.js";
26
26
  import {
27
27
  PathAccessDeniedError
28
- } from "./chunk-PU3IPUSW.js";
28
+ } from "./chunk-FFPCVN5M.js";
29
29
  import {
30
30
  getCurrentContextWindowId,
31
31
  getCurrentWindowMessageOptions,
32
32
  getEventStore
33
- } from "./chunk-LXYNP7LL.js";
33
+ } from "./chunk-NB2D6I64.js";
34
34
  import {
35
35
  buildSnapshotFromSessionState
36
- } from "./chunk-ACJNRPTO.js";
36
+ } from "./chunk-QGXLZZBS.js";
37
37
  import {
38
38
  findAgentById,
39
39
  getRuntimeConfig,
40
40
  loadAllAgentsDefault,
41
41
  resolveDefaultAgentId
42
- } from "./chunk-VT2X3DMC.js";
42
+ } from "./chunk-JNHKKUGJ.js";
43
43
  import {
44
44
  logger
45
45
  } from "./chunk-K44MW7JJ.js";
@@ -49,7 +49,7 @@ import {
49
49
 
50
50
  // src/server/chat/orchestrator.ts
51
51
  async function buildRetryPatterns() {
52
- const { getSetting, SETTINGS_KEYS } = await import("./settings-2RZBMX5Y.js");
52
+ const { getSetting, SETTINGS_KEYS } = await import("./settings-KO6DSJLD.js");
53
53
  const raw = getSetting(SETTINGS_KEYS.RETRY_PATTERNS);
54
54
  if (!raw) {
55
55
  const oldXmlProtection = getSetting("llm.disableXmlProtection");
@@ -319,4 +319,4 @@ export {
319
319
  runChatTurn,
320
320
  runAgentTurn
321
321
  };
322
- //# sourceMappingURL=chunk-HK75Q3EA.js.map
322
+ //# sourceMappingURL=chunk-SDGNV45R.js.map
@@ -11,11 +11,11 @@ import {
11
11
  } from "./chunk-I72ACQ6R.js";
12
12
  import {
13
13
  getPlatformShell
14
- } from "./chunk-6EV7X5MP.js";
14
+ } from "./chunk-N4RTAGFY.js";
15
15
  import {
16
16
  SETTINGS_KEYS,
17
17
  getSetting
18
- } from "./chunk-VXKPZUCT.js";
18
+ } from "./chunk-RT2A2RRL.js";
19
19
 
20
20
  // src/server/utils/shell.ts
21
21
  import { spawn } from "child_process";
@@ -48,6 +48,23 @@ function spawnShellProcess(command, cwd, _signal, detached = false) {
48
48
  return spawnShell(command, { cwd, detached });
49
49
  }
50
50
 
51
+ // src/server/utils/utf8.ts
52
+ import { StringDecoder } from "string_decoder";
53
+ function decodeUtf8(chunks) {
54
+ return Buffer.concat([...chunks]).toString("utf8");
55
+ }
56
+ function createUtf8StreamDecoder() {
57
+ const decoder = new StringDecoder("utf8");
58
+ return {
59
+ write: (chunk) => decoder.write(chunk),
60
+ end: () => decoder.end()
61
+ };
62
+ }
63
+ function sanitizeUtf8(content) {
64
+ if (!content.includes("\uFFFD")) return { clean: content, corrupted: false };
65
+ return { clean: content.replaceAll("\uFFFD", "?"), corrupted: true };
66
+ }
67
+
51
68
  // src/server/tools/background-process/manager.ts
52
69
  var listeners = /* @__PURE__ */ new Set();
53
70
  function onProcessEvent(callback) {
@@ -88,8 +105,10 @@ function startProcessCommand(processId, sessionId, command, cwd) {
88
105
  payload: { processId, name: proc.name, pid: child.pid ?? null, status: "running" },
89
106
  sessionId
90
107
  });
108
+ const stdoutDecoder = createUtf8StreamDecoder();
109
+ const stderrDecoder = createUtf8StreamDecoder();
91
110
  child.stdout?.on("data", (chunk) => {
92
- const text = chunk.toString();
111
+ const text = stdoutDecoder.write(chunk);
93
112
  appendLog(processId, text, "stdout");
94
113
  emitProcessEvent(processId, {
95
114
  type: "backgroundProcess.output",
@@ -98,7 +117,7 @@ function startProcessCommand(processId, sessionId, command, cwd) {
98
117
  });
99
118
  });
100
119
  child.stderr?.on("data", (chunk) => {
101
- const text = chunk.toString();
120
+ const text = stderrDecoder.write(chunk);
102
121
  appendLog(processId, text, "stderr");
103
122
  emitProcessEvent(processId, {
104
123
  type: "backgroundProcess.output",
@@ -106,6 +125,28 @@ function startProcessCommand(processId, sessionId, command, cwd) {
106
125
  sessionId
107
126
  });
108
127
  });
128
+ child.stdout?.on("close", () => {
129
+ const rest = stdoutDecoder.end();
130
+ if (rest) {
131
+ appendLog(processId, rest, "stdout");
132
+ emitProcessEvent(processId, {
133
+ type: "backgroundProcess.output",
134
+ payload: { processId, stream: "stdout", content: rest },
135
+ sessionId
136
+ });
137
+ }
138
+ });
139
+ child.stderr?.on("close", () => {
140
+ const rest = stderrDecoder.end();
141
+ if (rest) {
142
+ appendLog(processId, rest, "stderr");
143
+ emitProcessEvent(processId, {
144
+ type: "backgroundProcess.output",
145
+ payload: { processId, stream: "stderr", content: rest },
146
+ sessionId
147
+ });
148
+ }
149
+ });
109
150
  child.on("exit", (code, signal) => {
110
151
  updateStatus(processId, sessionId, "exited", code ?? (signal ? 1 : null));
111
152
  emitProcessEvent(processId, {
@@ -155,6 +196,9 @@ export {
155
196
  checkAborted,
156
197
  spawnShell,
157
198
  spawnShellProcess,
199
+ decodeUtf8,
200
+ createUtf8StreamDecoder,
201
+ sanitizeUtf8,
158
202
  onProcessEvent,
159
203
  createProcess2 as createProcess,
160
204
  startProcessCommand,
@@ -163,4 +207,4 @@ export {
163
207
  getSessionProcesses2 as getSessionProcesses,
164
208
  getProcessLogs
165
209
  };
166
- //# sourceMappingURL=chunk-C5JJM72V.js.map
210
+ //# sourceMappingURL=chunk-SVJFMZ2Q.js.map