openfox 2.0.94 → 2.0.96

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 (58) hide show
  1. package/CHANGELOG.md +25 -0
  2. package/dist/CHANGELOG.md +25 -0
  3. package/dist/{chat-handler-Z7OCNJWO.js → chat-handler-5OJMACXB.js} +17 -17
  4. package/dist/{chunk-LSDJCJWA.js → chunk-3DAZIZ7E.js} +7 -7
  5. package/dist/{chunk-OHBY2673.js → chunk-3LRYZ7R3.js} +46 -3
  6. package/dist/{chunk-3WKAKOU4.js → chunk-3W6STALV.js} +2 -2
  7. package/dist/chunk-62QCBNPE.js +15 -0
  8. package/dist/chunk-7B3XSBRL.js +7 -0
  9. package/dist/{chunk-ZYDPYFRH.js → chunk-BG4EVBLJ.js} +6 -6
  10. package/dist/{chunk-MUNVSHL5.js → chunk-C3XL7X4E.js} +8 -8
  11. package/dist/{chunk-62X2MPO6.js → chunk-D3SXT3BL.js} +4 -4
  12. package/dist/{chunk-VYN37NXW.js → chunk-G5JFKTSR.js} +2 -2
  13. package/dist/{chunk-YJ5P33SE.js → chunk-HAFRPV7I.js} +12 -2
  14. package/dist/{chunk-FVV7TZC2.js → chunk-KNYPBXPW.js} +6 -5
  15. package/dist/{chunk-MC3MCMAF.js → chunk-KQPDU65K.js} +2 -2
  16. package/dist/{chunk-V4QTGYXL.js → chunk-LZW5LSVH.js} +5 -5
  17. package/dist/{chunk-OQXG4MS4.js → chunk-ML5ZU6VS.js} +236 -89
  18. package/dist/{chunk-P637C6X3.js → chunk-O2PLNJIU.js} +2 -2
  19. package/dist/{chunk-DLCMSSG3.js → chunk-O5YWFX7H.js} +22 -26
  20. package/dist/{chunk-KU3YUGAN.js → chunk-SJJVNSA6.js} +2 -2
  21. package/dist/{chunk-XNB3JWAR.js → chunk-TDHDLDGQ.js} +9 -19
  22. package/dist/{chunk-OQTLFO4R.js → chunk-URQQOUCS.js} +46 -3
  23. package/dist/{chunk-KNRE3DG4.js → chunk-WS7EY4CU.js} +34 -48
  24. package/dist/{chunk-5N5JXT7R.js → chunk-XLI6PDJG.js} +2 -2
  25. package/dist/{chunk-2BCQDYNA.js → chunk-YPBV47DH.js} +6 -9
  26. package/dist/{chunk-TSHJW7OC.js → chunk-ZIMGU5ZH.js} +2 -2
  27. package/dist/cli/dev.js +1 -1
  28. package/dist/cli/index.js +1 -1
  29. package/dist/{client-OBMJSTFN.js → client-RENSCJPZ.js} +3 -3
  30. package/dist/{compactor-RSEV7VYH.js → compactor-U7EUKEUE.js} +6 -6
  31. package/dist/{config-XIYAPMX3.js → config-M7RDIFC5.js} +4 -2
  32. package/dist/{dynamic-context-C3BWQ5GK.js → dynamic-context-TDB4G5CH.js} +4 -4
  33. package/dist/{events-SY5B4VED.js → events-4THEZWVL.js} +5 -5
  34. package/dist/{folding-O4OYOTPS.js → folding-OYBO2NTH.js} +3 -3
  35. package/dist/{http-client-3MOFAPO6.js → http-client-U6DVFL7F.js} +2 -2
  36. package/dist/{manager-UP3XMLKX.js → manager-53J5P4EZ.js} +2 -2
  37. package/dist/openFolder-Z27FEM5M.js +8 -0
  38. package/dist/{orchestrator-VSUL2C7G.js → orchestrator-MTCF2EPU.js} +14 -14
  39. package/dist/package.json +1 -1
  40. package/dist/{path-security-E55IEQHD.js → path-security-6GYETPWN.js} +6 -6
  41. package/dist/{processor-WP34IB3C.js → processor-HX4FXDDT.js} +14 -14
  42. package/dist/{provider-E5IP7RF7.js → provider-LZ3XMDX6.js} +6 -6
  43. package/dist/{provider-manager-FVIFMUTO.js → provider-manager-PBOF77RQ.js} +4 -4
  44. package/dist/{registry-XBEHPY7C.js → registry-QEOTM3IG.js} +2 -2
  45. package/dist/{serve-NZZVFNMA.js → serve-VGATDJX5.js} +23 -22
  46. package/dist/server/index.js +22 -21
  47. package/dist/{server-DYJTLAZS.js → server-4BHDA6PA.js} +17 -17
  48. package/dist/{session-overrides-QWD4V5KW.js → session-overrides-BQSE3V3F.js} +4 -4
  49. package/dist/{sessions-BT4PION7.js → sessions-AUDWMF55.js} +3 -3
  50. package/dist/{tools-YXOCUUKE.js → tools-I3BAXRVD.js} +12 -12
  51. package/dist/{update-5HWU675H.js → update-2Z6TXHFH.js} +2 -2
  52. package/dist/web/assets/{index-BlV1FebL.css → index-BG5sD2ez.css} +1 -1
  53. package/dist/web/assets/{index-DxAR7yc9.js → index-CsC_DrIa.js} +80 -73
  54. package/dist/web/index.html +2 -2
  55. package/dist/web/sw.js +1 -1
  56. package/dist/{workspace-IIRKILYL.js → workspace-2NDXTCVR.js} +2 -2
  57. package/package.json +1 -1
  58. package/dist/chunk-O4NHL6IN.js +0 -7
@@ -21,7 +21,10 @@ import {
21
21
  tokenFromPassword,
22
22
  verifyPassword,
23
23
  workflowExists
24
- } from "./chunk-KNRE3DG4.js";
24
+ } from "./chunk-WS7EY4CU.js";
25
+ import {
26
+ openFolder
27
+ } from "./chunk-62QCBNPE.js";
25
28
  import {
26
29
  createToolRegistry,
27
30
  devServerManager,
@@ -30,7 +33,7 @@ import {
30
33
  setMcpManagerForTools,
31
34
  setMcpTools,
32
35
  setNotifyMcpServersChanged
33
- } from "./chunk-DLCMSSG3.js";
36
+ } from "./chunk-O5YWFX7H.js";
34
37
  import {
35
38
  createMcpTools
36
39
  } from "./chunk-NWO6GRYE.js";
@@ -48,7 +51,7 @@ import {
48
51
  validateRef,
49
52
  validateWorkspaceName,
50
53
  workspaceExists
51
- } from "./chunk-62X2MPO6.js";
54
+ } from "./chunk-D3SXT3BL.js";
52
55
  import {
53
56
  deleteOwnedSkill,
54
57
  deleteProjectSkill,
@@ -67,11 +70,11 @@ import {
67
70
  setSkillEnabled,
68
71
  skillExists,
69
72
  updateOwnedSkill
70
- } from "./chunk-MC3MCMAF.js";
73
+ } from "./chunk-KQPDU65K.js";
71
74
  import {
72
75
  getSessionDisabledServers,
73
76
  setSessionDisabledServers
74
- } from "./chunk-5N5JXT7R.js";
77
+ } from "./chunk-XLI6PDJG.js";
75
78
  import {
76
79
  createContextStateMessage
77
80
  } from "./chunk-27SDWNKL.js";
@@ -104,14 +107,14 @@ import {
104
107
  getEventStore,
105
108
  getSessionState,
106
109
  initEventStore
107
- } from "./chunk-FVV7TZC2.js";
110
+ } from "./chunk-KNYPBXPW.js";
108
111
  import {
109
112
  getPathSeparator,
110
113
  isAbsolutePath
111
114
  } from "./chunk-NLN5LPQ4.js";
112
115
  import {
113
116
  VERSION
114
- } from "./chunk-O4NHL6IN.js";
117
+ } from "./chunk-7B3XSBRL.js";
115
118
  import {
116
119
  clearWorkflowExecution,
117
120
  createSession,
@@ -131,13 +134,14 @@ import {
131
134
  updateSessionRunning,
132
135
  updateSessionWorkdir,
133
136
  updateWorkflowExecutionStatus
134
- } from "./chunk-TSHJW7OC.js";
137
+ } from "./chunk-ZIMGU5ZH.js";
135
138
  import {
136
139
  agentExists,
137
140
  deleteAgent,
138
141
  deleteItemFromDir,
139
142
  deleteProjectAgent,
140
143
  findAgentById,
144
+ findFileByInternalId,
141
145
  getDefaultAgentIds,
142
146
  getDefaultIds,
143
147
  getTopLevelAgents,
@@ -153,13 +157,13 @@ import {
153
157
  saveAgentToProject,
154
158
  saveItemToDir,
155
159
  setRuntimeConfig
156
- } from "./chunk-OHBY2673.js";
160
+ } from "./chunk-3LRYZ7R3.js";
157
161
  import {
158
162
  createProviderManager,
159
163
  detectModel,
160
164
  getLlmStatus,
161
165
  parseDefaultModelSelection
162
- } from "./chunk-2BCQDYNA.js";
166
+ } from "./chunk-YPBV47DH.js";
163
167
  import {
164
168
  getModelProfile
165
169
  } from "./chunk-V4IE7HJY.js";
@@ -171,9 +175,8 @@ import {
171
175
  } from "./chunk-HNCM3D7Y.js";
172
176
  import {
173
177
  SessionNotFoundError,
174
- WorkspaceInUseError,
175
- proxyFetch
176
- } from "./chunk-XNB3JWAR.js";
178
+ WorkspaceInUseError
179
+ } from "./chunk-TDHDLDGQ.js";
177
180
  import {
178
181
  deleteSetting,
179
182
  getSetting,
@@ -2973,7 +2976,16 @@ var SessionManager = class {
2973
2976
  */
2974
2977
  updateWorkflowStep(sessionId, executionId, stepId, stepName, workflowId, workflowName, workflowColor) {
2975
2978
  updateWorkflowExecutionStatus(executionId, "running", stepId, stepName);
2976
- emitWorkflowExecutionChanged(sessionId, executionId, workflowId, workflowName, workflowColor, "running", stepName);
2979
+ emitWorkflowExecutionChanged(
2980
+ sessionId,
2981
+ executionId,
2982
+ workflowId,
2983
+ workflowName,
2984
+ workflowColor,
2985
+ "running",
2986
+ stepId,
2987
+ stepName
2988
+ );
2977
2989
  const updatedSession = this.requireSession(sessionId);
2978
2990
  this.emit({ type: "session_updated", session: updatedSession });
2979
2991
  }
@@ -2982,7 +2994,16 @@ var SessionManager = class {
2982
2994
  */
2983
2995
  waitAtStep(sessionId, executionId, stepId, stepName, stepOutput, workflowId, workflowName, workflowColor) {
2984
2996
  updateWorkflowExecutionStatus(executionId, "waiting", stepId, stepName, stepOutput);
2985
- emitWorkflowExecutionChanged(sessionId, executionId, workflowId, workflowName, workflowColor, "waiting", stepName);
2997
+ emitWorkflowExecutionChanged(
2998
+ sessionId,
2999
+ executionId,
3000
+ workflowId,
3001
+ workflowName,
3002
+ workflowColor,
3003
+ "waiting",
3004
+ stepId,
3005
+ stepName
3006
+ );
2986
3007
  this.setPhase(sessionId, "waiting");
2987
3008
  const updatedSession = this.requireSession(sessionId);
2988
3009
  this.emit({ type: "session_updated", session: updatedSession });
@@ -3001,6 +3022,7 @@ var SessionManager = class {
3001
3022
  workflowName,
3002
3023
  workflowColor,
3003
3024
  "running",
3025
+ row.current_step_id ?? void 0,
3004
3026
  row.current_step_name ?? void 0
3005
3027
  );
3006
3028
  const updatedSession = this.requireSession(sessionId);
@@ -3902,7 +3924,10 @@ function getProjectItemPath(projectDir, dirName, id, ext) {
3902
3924
  }
3903
3925
  async function isProjectItem(projectDir, dirName, id, ext) {
3904
3926
  if (!projectDir) return false;
3905
- return pathExists(getProjectItemPath(projectDir, dirName, id, ext));
3927
+ if (await pathExists(getProjectItemPath(projectDir, dirName, id, ext))) return true;
3928
+ const dir = join3(projectDir, ".openfox", dirName);
3929
+ const found = await findFileByInternalId(dir, id, ext);
3930
+ return found !== null;
3906
3931
  }
3907
3932
  function createCrudRoutes(config3, configDir, projectDir) {
3908
3933
  const router = Router();
@@ -5148,7 +5173,7 @@ function createProviderAuthRoutes(config3, providerManager, registry) {
5148
5173
  try {
5149
5174
  const { challenge, completion } = await adapter.beginLogin({ providerId: provider.id });
5150
5175
  void completion.then(async ({ credentialRef }) => {
5151
- const { loadGlobalConfig, saveGlobalConfig, updateProvider } = await import("./config-XIYAPMX3.js");
5176
+ const { loadGlobalConfig, saveGlobalConfig, updateProvider } = await import("./config-M7RDIFC5.js");
5152
5177
  const globalConfig = await loadGlobalConfig(config3.mode ?? "production", config3.globalConfigPath);
5153
5178
  const updatedConfig = updateProvider(globalConfig, provider.id, { credentialRef, authAdapter: adapter.id });
5154
5179
  await saveGlobalConfig(config3.mode ?? "production", updatedConfig, config3.globalConfigPath);
@@ -5182,7 +5207,7 @@ function createProviderAuthRoutes(config3, providerManager, registry) {
5182
5207
  if (!context) return;
5183
5208
  const { provider, adapter } = context;
5184
5209
  if (provider.credentialRef && adapter) await adapter.logout(provider.credentialRef);
5185
- const { loadGlobalConfig, saveGlobalConfig } = await import("./config-XIYAPMX3.js");
5210
+ const { loadGlobalConfig, saveGlobalConfig } = await import("./config-M7RDIFC5.js");
5186
5211
  const globalConfig = await loadGlobalConfig(config3.mode ?? "production", config3.globalConfigPath);
5187
5212
  const updatedConfig = {
5188
5213
  ...globalConfig,
@@ -5358,15 +5383,12 @@ import { fileURLToPath as fileURLToPath6, pathToFileURL as pathToFileURL2 } from
5358
5383
  import { dirname as dirname7, resolve as resolve7, join as join9 } from "path";
5359
5384
  import { existsSync } from "fs";
5360
5385
  import { readFile as readFile3, readdir as readdir4, rm as rm2, rename as rename2 } from "fs/promises";
5361
- import { platform } from "os";
5362
5386
  import { execFile } from "child_process";
5363
5387
  import { promisify } from "util";
5364
5388
  var execFileP = promisify(execFile);
5365
- async function openFolder(dir, res) {
5389
+ async function openFolderRoute(dir, res) {
5366
5390
  try {
5367
- await execFileP("mkdir", ["-p", dir], { timeout: 5e3 });
5368
- const cmd = platform() === "darwin" ? "open" : platform() === "win32" ? "explorer" : "xdg-open";
5369
- await execFileP(cmd, [dir], { timeout: 5e3 });
5391
+ await openFolder(dir);
5370
5392
  res.json({ success: true });
5371
5393
  } catch (err) {
5372
5394
  res.status(500).json({ error: err instanceof Error ? err.message : "Failed to open folder" });
@@ -5520,13 +5542,13 @@ function createPluginRoutes(options) {
5520
5542
  });
5521
5543
  router.get("/open-folder", async (_req, res) => {
5522
5544
  const pluginsDir = join9(getGlobalConfigDir(config3.mode ?? "production"), "plugins");
5523
- await openFolder(pluginsDir, res);
5545
+ await openFolderRoute(pluginsDir, res);
5524
5546
  });
5525
5547
  router.get("/:name/open-folder", async (req, res) => {
5526
5548
  const name = req.params.name;
5527
5549
  if (!/^[a-zA-Z0-9_-]+$/.test(name)) return res.status(400).json({ error: "Invalid plugin name" });
5528
5550
  const targetDir = join9(getGlobalConfigDir(config3.mode ?? "production"), "plugins", name);
5529
- await openFolder(targetDir, res);
5551
+ await openFolderRoute(targetDir, res);
5530
5552
  });
5531
5553
  router.delete("/:name", async (req, res) => {
5532
5554
  const name = req.params.name;
@@ -5662,7 +5684,7 @@ async function createServerHandle(config3) {
5662
5684
  const mcpManager = new McpManager({
5663
5685
  onToolsDiscovered: async (name, tools) => {
5664
5686
  try {
5665
- const { loadGlobalConfig, saveGlobalConfig } = await import("./config-XIYAPMX3.js");
5687
+ const { loadGlobalConfig, saveGlobalConfig } = await import("./config-M7RDIFC5.js");
5666
5688
  const mode = config3.mode ?? "production";
5667
5689
  const globalConfig = await loadGlobalConfig(mode, config3.globalConfigPath);
5668
5690
  const mcpServers2 = {
@@ -5693,7 +5715,7 @@ async function createServerHandle(config3) {
5693
5715
  setMcpTools(mcpTools);
5694
5716
  logger.info("MCP tools registered", { count: mcpTools.length });
5695
5717
  }
5696
- const { signalMcpReady } = await import("./server-DYJTLAZS.js");
5718
+ const { signalMcpReady } = await import("./server-4BHDA6PA.js");
5697
5719
  signalMcpReady();
5698
5720
  });
5699
5721
  const app = express();
@@ -5832,6 +5854,20 @@ async function createServerHandle(config3) {
5832
5854
  }
5833
5855
  res.json({ project });
5834
5856
  });
5857
+ app.get("/api/projects/:id/open-folder", async (req, res) => {
5858
+ const { getProject: getProject2 } = await import("./projects-M5XKC7O6.js");
5859
+ const project = getProject2(req.params.id);
5860
+ if (!project) {
5861
+ return res.status(404).json({ error: "Project not found" });
5862
+ }
5863
+ try {
5864
+ const { openFolder: openFolder2 } = await import("./openFolder-Z27FEM5M.js");
5865
+ await openFolder2(project.workdir);
5866
+ res.json({ success: true });
5867
+ } catch (err) {
5868
+ res.status(500).json({ error: err instanceof Error ? err.message : "Failed to open folder" });
5869
+ }
5870
+ });
5835
5871
  app.put("/api/projects/:id", async (req, res) => {
5836
5872
  const { updateProject: updateProject2 } = await import("./projects-M5XKC7O6.js");
5837
5873
  const { name, customInstructions, dangerLevel } = req.body;
@@ -5870,7 +5906,7 @@ async function createServerHandle(config3) {
5870
5906
  const { getProject: getProject2 } = await import("./projects-M5XKC7O6.js");
5871
5907
  const project = getProject2(req.params.id);
5872
5908
  if (!project) return res.status(404).json({ error: "Project not found" });
5873
- const { listBranches } = await import("./workspace-IIRKILYL.js");
5909
+ const { listBranches } = await import("./workspace-2NDXTCVR.js");
5874
5910
  const branches = await listBranches(project.workdir);
5875
5911
  res.json({ branches });
5876
5912
  });
@@ -5880,13 +5916,13 @@ async function createServerHandle(config3) {
5880
5916
  if (!project) return res.status(404).json({ error: "Project not found" });
5881
5917
  const { branch } = req.body;
5882
5918
  if (!branch || typeof branch !== "string") return res.status(400).json({ error: "branch is required" });
5883
- const { checkoutBranch, isGitRepository } = await import("./workspace-IIRKILYL.js");
5919
+ const { checkoutBranch, isGitRepository } = await import("./workspace-2NDXTCVR.js");
5884
5920
  if (!await isGitRepository(project.workdir)) {
5885
5921
  return res.status(400).json({ error: "Project is not a git repository" });
5886
5922
  }
5887
5923
  try {
5888
5924
  await checkoutBranch(project.workdir, branch);
5889
- const { updateSessionBranch: updateSessionBranch2 } = await import("./sessions-BT4PION7.js");
5925
+ const { updateSessionBranch: updateSessionBranch2 } = await import("./sessions-AUDWMF55.js");
5890
5926
  const allSessions = sessionManager.listSessions();
5891
5927
  for (const s of allSessions) {
5892
5928
  if (sessionManager.getEffectiveWorkdir(s.id) === project.workdir) {
@@ -5905,7 +5941,7 @@ async function createServerHandle(config3) {
5905
5941
  if (!project) return res.status(404).json({ error: "Project not found" });
5906
5942
  const { name, sourceBranch } = req.body;
5907
5943
  if (!name || typeof name !== "string") return res.status(400).json({ error: "name is required" });
5908
- const { createBranch, resolveAndValidateSourceBranch: resolveAndValidateSourceBranch2, validateRef: validateRef2, getDefaultBranch, isGitRepository } = await import("./workspace-IIRKILYL.js");
5944
+ const { createBranch, resolveAndValidateSourceBranch: resolveAndValidateSourceBranch2, validateRef: validateRef2, getDefaultBranch, isGitRepository } = await import("./workspace-2NDXTCVR.js");
5909
5945
  if (!await isGitRepository(project.workdir)) {
5910
5946
  return res.status(400).json({ error: "Project is not a git repository" });
5911
5947
  }
@@ -5922,7 +5958,7 @@ async function createServerHandle(config3) {
5922
5958
  );
5923
5959
  }
5924
5960
  await createBranch(project.workdir, name, sb);
5925
- const { updateSessionBranch: updateSessionBranch2 } = await import("./sessions-BT4PION7.js");
5961
+ const { updateSessionBranch: updateSessionBranch2 } = await import("./sessions-AUDWMF55.js");
5926
5962
  const allSessions = sessionManager.listSessions();
5927
5963
  for (const s of allSessions) {
5928
5964
  if (sessionManager.getEffectiveWorkdir(s.id) === project.workdir) {
@@ -5939,7 +5975,7 @@ async function createServerHandle(config3) {
5939
5975
  const session = sessionManager.getSession(req.params.id);
5940
5976
  if (!session) return res.status(404).json({ error: "Session not found" });
5941
5977
  const effectiveWorkdir = sessionManager.getEffectiveWorkdir(req.params.id);
5942
- const { listBranches, getDefaultBranch } = await import("./workspace-IIRKILYL.js");
5978
+ const { listBranches, getDefaultBranch } = await import("./workspace-2NDXTCVR.js");
5943
5979
  const [branches, defaultBranch] = await Promise.all([
5944
5980
  listBranches(effectiveWorkdir),
5945
5981
  getDefaultBranch(session.workdir)
@@ -5953,8 +5989,8 @@ async function createServerHandle(config3) {
5953
5989
  const { branch } = req.body;
5954
5990
  if (!branch || typeof branch !== "string") return res.status(400).json({ error: "branch is required" });
5955
5991
  const effectiveWorkdir = sessionManager.getEffectiveWorkdir(req.params.id);
5956
- const { checkoutBranch, validateRef: validateRef2 } = await import("./workspace-IIRKILYL.js");
5957
- const { updateSessionBranch: updateSessionBranch2 } = await import("./sessions-BT4PION7.js");
5992
+ const { checkoutBranch, validateRef: validateRef2 } = await import("./workspace-2NDXTCVR.js");
5993
+ const { updateSessionBranch: updateSessionBranch2 } = await import("./sessions-AUDWMF55.js");
5958
5994
  try {
5959
5995
  await validateRef2(effectiveWorkdir, branch);
5960
5996
  await checkoutBranch(effectiveWorkdir, branch);
@@ -5996,16 +6032,16 @@ All file and git operations should use this branch.
5996
6032
  const { name, sourceBranch } = req.body;
5997
6033
  if (!name || typeof name !== "string") return res.status(400).json({ error: "name is required" });
5998
6034
  const effectiveWorkdir = sessionManager.getEffectiveWorkdir(req.params.id);
5999
- const { validateRef: validateRef2 } = await import("./workspace-IIRKILYL.js");
6000
- const { updateSessionBranch: updateSessionBranch2 } = await import("./sessions-BT4PION7.js");
6035
+ const { validateRef: validateRef2 } = await import("./workspace-2NDXTCVR.js");
6036
+ const { updateSessionBranch: updateSessionBranch2 } = await import("./sessions-AUDWMF55.js");
6001
6037
  try {
6002
6038
  await validateRef2(effectiveWorkdir, name);
6003
6039
  if (sourceBranch) {
6004
- const { resolveAndValidateSourceBranch: resolveAndValidateSourceBranch2, createBranch } = await import("./workspace-IIRKILYL.js");
6040
+ const { resolveAndValidateSourceBranch: resolveAndValidateSourceBranch2, createBranch } = await import("./workspace-2NDXTCVR.js");
6005
6041
  const sb = await resolveAndValidateSourceBranch2(effectiveWorkdir, sourceBranch, session.workdir);
6006
6042
  await createBranch(effectiveWorkdir, name, sb);
6007
6043
  } else {
6008
- const { createBranch, getDefaultBranch, resolveAndValidateSourceBranch: resolveAndValidateSourceBranch2 } = await import("./workspace-IIRKILYL.js");
6044
+ const { createBranch, getDefaultBranch, resolveAndValidateSourceBranch: resolveAndValidateSourceBranch2 } = await import("./workspace-2NDXTCVR.js");
6009
6045
  const defaultBranch = await getDefaultBranch(session.workdir);
6010
6046
  const sb = await resolveAndValidateSourceBranch2(effectiveWorkdir, defaultBranch, session.workdir);
6011
6047
  await createBranch(effectiveWorkdir, name, sb);
@@ -6046,14 +6082,14 @@ All file and git operations should use this branch.
6046
6082
  const { getProject: getProject2 } = await import("./projects-M5XKC7O6.js");
6047
6083
  const project = getProject2(req.params.id);
6048
6084
  if (!project) return res.status(404).json({ error: "Project not found" });
6049
- const { listWorkspaces } = await import("./workspace-IIRKILYL.js");
6085
+ const { listWorkspaces } = await import("./workspace-2NDXTCVR.js");
6050
6086
  const all = await listWorkspaces(project.name, project.workdir);
6051
6087
  const workspacesList = all.filter((ws) => ws.path !== project.workdir);
6052
6088
  res.json({ workspaces: workspacesList });
6053
6089
  });
6054
6090
  app.get("/api/sessions", async (req, res) => {
6055
- const { getRecentUserPromptsForSession } = await import("./events-SY5B4VED.js");
6056
- const { getPendingConfirmationsBySession } = await import("./path-security-E55IEQHD.js");
6091
+ const { getRecentUserPromptsForSession } = await import("./events-4THEZWVL.js");
6092
+ const { getPendingConfirmationsBySession } = await import("./path-security-6GYETPWN.js");
6057
6093
  const projectId = req.query["projectId"];
6058
6094
  const limit = Math.min(parseInt(req.query["limit"]) || 20, 100);
6059
6095
  const offset = parseInt(req.query["offset"]) || 0;
@@ -6099,7 +6135,7 @@ All file and git operations should use this branch.
6099
6135
  disabledServers = mcpManager.getAllServers().filter((s) => s.config.disabled).map((s) => s.name);
6100
6136
  }
6101
6137
  if (disabledServers.length > 0) {
6102
- const { setSessionDisabledServers: setSessionDisabledServers2 } = await import("./session-overrides-QWD4V5KW.js");
6138
+ const { setSessionDisabledServers: setSessionDisabledServers2 } = await import("./session-overrides-BQSE3V3F.js");
6103
6139
  setSessionDisabledServers2(session.id, disabledServers);
6104
6140
  }
6105
6141
  } catch {
@@ -6136,7 +6172,7 @@ All file and git operations should use this branch.
6136
6172
  if (!target || typeof target !== "string") return res.status(400).json({ error: "target is required" });
6137
6173
  const project = sessionManager.getProject(session.projectId);
6138
6174
  if (!project) return res.status(404).json({ error: "Project not found" });
6139
- const { isGitRepository } = await import("./workspace-IIRKILYL.js");
6175
+ const { isGitRepository } = await import("./workspace-2NDXTCVR.js");
6140
6176
  if (!await isGitRepository(project.workdir)) {
6141
6177
  return res.status(400).json({ error: "Project is not a git repository" });
6142
6178
  }
@@ -6154,7 +6190,7 @@ All file and git operations should use this branch.
6154
6190
  if (!target || typeof target !== "string") return res.status(400).json({ error: "target is required" });
6155
6191
  const project = sessionManager.getProject(session.projectId);
6156
6192
  if (!project) return res.status(404).json({ error: "Project not found" });
6157
- const { isGitRepository } = await import("./workspace-IIRKILYL.js");
6193
+ const { isGitRepository } = await import("./workspace-2NDXTCVR.js");
6158
6194
  if (!await isGitRepository(project.workdir)) {
6159
6195
  return res.status(400).json({ error: "Project is not a git repository" });
6160
6196
  }
@@ -6172,9 +6208,9 @@ All file and git operations should use this branch.
6172
6208
  }
6173
6209
  });
6174
6210
  app.get("/api/sessions/:id", async (req, res) => {
6175
- const { getEventStore: getEventStore2, combineEventsWithSnapshot } = await import("./events-SY5B4VED.js");
6176
- const { buildMessagesFromStoredEvents, foldPendingConfirmations } = await import("./folding-O4OYOTPS.js");
6177
- const { getPendingQuestionsForSession } = await import("./tools-YXOCUUKE.js");
6211
+ const { getEventStore: getEventStore2, combineEventsWithSnapshot } = await import("./events-4THEZWVL.js");
6212
+ const { buildMessagesFromStoredEvents, foldPendingConfirmations } = await import("./folding-OYBO2NTH.js");
6213
+ const { getPendingQuestionsForSession } = await import("./tools-I3BAXRVD.js");
6178
6214
  const { getMaxVisibleItems } = await import("./settings-2WVGUPYV.js");
6179
6215
  const session = sessionManager.getSession(req.params.id);
6180
6216
  if (!session) {
@@ -6207,8 +6243,8 @@ All file and git operations should use this branch.
6207
6243
  if (!session) {
6208
6244
  return res.status(404).json({ error: "Session not found" });
6209
6245
  }
6210
- const { stopSessionExecution } = await import("./chat-handler-Z7OCNJWO.js");
6211
- const { cancelQuestionsForSession, cancelPathConfirmationsForSession } = await import("./tools-YXOCUUKE.js");
6246
+ const { stopSessionExecution } = await import("./chat-handler-5OJMACXB.js");
6247
+ const { cancelQuestionsForSession, cancelPathConfirmationsForSession } = await import("./tools-I3BAXRVD.js");
6212
6248
  sessionManager.clearMessageQueue(sessionId);
6213
6249
  stopSessionExecution(sessionId, sessionManager);
6214
6250
  abortSession(sessionId);
@@ -6237,8 +6273,8 @@ All file and git operations should use this branch.
6237
6273
  res.json({ success: true });
6238
6274
  });
6239
6275
  app.post("/api/sessions/:id/provider", async (req, res) => {
6240
- const { getEventStore: getEventStore2, combineEventsWithSnapshot: combineEv } = await import("./events-SY5B4VED.js");
6241
- const { buildMessagesFromStoredEvents } = await import("./folding-O4OYOTPS.js");
6276
+ const { getEventStore: getEventStore2, combineEventsWithSnapshot: combineEv } = await import("./events-4THEZWVL.js");
6277
+ const { buildMessagesFromStoredEvents } = await import("./folding-OYBO2NTH.js");
6242
6278
  const { getMaxVisibleItems } = await import("./settings-2WVGUPYV.js");
6243
6279
  const sessionId = req.params.id;
6244
6280
  const session = sessionManager.getSession(sessionId);
@@ -6274,7 +6310,7 @@ All file and git operations should use this branch.
6274
6310
  if (!result.success) {
6275
6311
  return res.status(500).json({ error: result.error ?? "Failed to set default model" });
6276
6312
  }
6277
- const { loadGlobalConfig, saveGlobalConfig, setDefaultModelSelection } = await import("./config-XIYAPMX3.js");
6313
+ const { loadGlobalConfig, saveGlobalConfig, setDefaultModelSelection } = await import("./config-M7RDIFC5.js");
6278
6314
  const globalConfig = await loadGlobalConfig(config3.mode ?? "production", config3.globalConfigPath);
6279
6315
  const updatedConfig = setDefaultModelSelection(globalConfig, providerId, model);
6280
6316
  await saveGlobalConfig(config3.mode ?? "production", updatedConfig, config3.globalConfigPath);
@@ -6352,8 +6388,8 @@ All file and git operations should use this branch.
6352
6388
  res.json({ success: true });
6353
6389
  });
6354
6390
  app.put("/api/sessions/:id/mode", async (req, res) => {
6355
- const { getEventStore: getEventStore2, combineEventsWithSnapshot: combineEv } = await import("./events-SY5B4VED.js");
6356
- const { buildMessagesFromStoredEvents } = await import("./folding-O4OYOTPS.js");
6391
+ const { getEventStore: getEventStore2, combineEventsWithSnapshot: combineEv } = await import("./events-4THEZWVL.js");
6392
+ const { buildMessagesFromStoredEvents } = await import("./folding-OYBO2NTH.js");
6357
6393
  const { getMaxVisibleItems } = await import("./settings-2WVGUPYV.js");
6358
6394
  const sessionId = req.params.id;
6359
6395
  const session = sessionManager.getSession(sessionId);
@@ -6440,7 +6476,7 @@ All file and git operations should use this branch.
6440
6476
  if (alwaysAllow !== void 0 && typeof alwaysAllow !== "boolean") {
6441
6477
  return res.status(400).json({ error: "alwaysAllow must be a boolean if provided" });
6442
6478
  }
6443
- const { providePathConfirmation, getConfirmationSessionId } = await import("./tools-YXOCUUKE.js");
6479
+ const { providePathConfirmation, getConfirmationSessionId } = await import("./tools-I3BAXRVD.js");
6444
6480
  const pendingSessionId = getConfirmationSessionId(callId);
6445
6481
  if (!pendingSessionId) {
6446
6482
  return res.status(404).json({ error: "No pending path confirmation with that ID" });
@@ -6452,10 +6488,10 @@ All file and git operations should use this branch.
6452
6488
  if (!result.found) {
6453
6489
  return res.status(404).json({ error: "No pending path confirmation with that ID" });
6454
6490
  }
6455
- const { getEventStore: getEventStore2, combineEventsWithSnapshot: combineEvents } = await import("./events-SY5B4VED.js");
6456
- const { buildMessagesFromStoredEvents, foldPendingConfirmations } = await import("./folding-O4OYOTPS.js");
6491
+ const { getEventStore: getEventStore2, combineEventsWithSnapshot: combineEvents } = await import("./events-4THEZWVL.js");
6492
+ const { buildMessagesFromStoredEvents, foldPendingConfirmations } = await import("./folding-OYBO2NTH.js");
6457
6493
  const { createSessionStateMessage } = await import("./protocol-YDNGGADL.js");
6458
- const { getPendingQuestionsForSession } = await import("./tools-YXOCUUKE.js");
6494
+ const { getPendingQuestionsForSession } = await import("./tools-I3BAXRVD.js");
6459
6495
  const { getMaxVisibleItems } = await import("./settings-2WVGUPYV.js");
6460
6496
  const eventStore = getEventStore2();
6461
6497
  const { snapshot, events: eventsSinceSnapshot } = eventStore.getEventsSinceSnapshot(sessionId);
@@ -6492,7 +6528,7 @@ All file and git operations should use this branch.
6492
6528
  if (!skip && typeof answer !== "string") {
6493
6529
  return res.status(400).json({ error: "answer is required when not skipping" });
6494
6530
  }
6495
- const { provideAnswer } = await import("./tools-YXOCUUKE.js");
6531
+ const { provideAnswer } = await import("./tools-I3BAXRVD.js");
6496
6532
  const found = provideAnswer(callId, answer ?? "", skip ?? false);
6497
6533
  if (!found) {
6498
6534
  return res.status(404).json({ error: "No pending question with that ID" });
@@ -6557,7 +6593,7 @@ All file and git operations should use this branch.
6557
6593
  backend: activeProvider?.backend ?? llmClient.getBackend(),
6558
6594
  model: llmClient.getModel()
6559
6595
  };
6560
- const { runAgentTurn, TurnMetrics } = await import("./orchestrator-VSUL2C7G.js");
6596
+ const { runAgentTurn, TurnMetrics } = await import("./orchestrator-MTCF2EPU.js");
6561
6597
  runAgentTurn(
6562
6598
  {
6563
6599
  sessionManager,
@@ -6595,15 +6631,15 @@ All file and git operations should use this branch.
6595
6631
  if (!session) {
6596
6632
  return res.status(404).json({ error: "Session not found" });
6597
6633
  }
6598
- const { stopSessionExecution } = await import("./chat-handler-Z7OCNJWO.js");
6599
- const { cancelQuestionsForSession, cancelPathConfirmationsForSession } = await import("./tools-YXOCUUKE.js");
6634
+ const { stopSessionExecution } = await import("./chat-handler-5OJMACXB.js");
6635
+ const { cancelQuestionsForSession, cancelPathConfirmationsForSession } = await import("./tools-I3BAXRVD.js");
6600
6636
  const queuedMessages = sessionManager.getQueueState(sessionId);
6601
6637
  sessionManager.clearMessageQueue(sessionId);
6602
6638
  stopSessionExecution(sessionId, sessionManager);
6603
6639
  abortSession(sessionId);
6604
6640
  cancelQuestionsForSession(sessionId, "Session stopped by user");
6605
6641
  cancelPathConfirmationsForSession(sessionId, "Session stopped by user");
6606
- const eventStore = (await import("./events-SY5B4VED.js")).getEventStore();
6642
+ const eventStore = (await import("./events-4THEZWVL.js")).getEventStore();
6607
6643
  eventStore.append(sessionId, { type: "running.changed", data: { isRunning: false } });
6608
6644
  res.json({ success: true, queuedMessages });
6609
6645
  });
@@ -6617,7 +6653,7 @@ All file and git operations should use this branch.
6617
6653
  if (typeof messageIndex !== "number" || messageIndex < 0) {
6618
6654
  return res.status(400).json({ error: "messageIndex must be a non-negative number" });
6619
6655
  }
6620
- const { truncateSessionMessages } = await import("./events-SY5B4VED.js");
6656
+ const { truncateSessionMessages } = await import("./events-4THEZWVL.js");
6621
6657
  truncateSessionMessages(sessionId, messageIndex);
6622
6658
  res.json({ success: true });
6623
6659
  });
@@ -6634,8 +6670,8 @@ All file and git operations should use this branch.
6634
6670
  if (content !== void 0 && (typeof content !== "string" || !content.trim())) {
6635
6671
  return res.status(400).json({ error: "content must be a non-empty string if provided" });
6636
6672
  }
6637
- const { getEventStore: getEventStore2 } = await import("./events-SY5B4VED.js");
6638
- const { buildMessagesFromStoredEvents } = await import("./folding-O4OYOTPS.js");
6673
+ const { getEventStore: getEventStore2 } = await import("./events-4THEZWVL.js");
6674
+ const { buildMessagesFromStoredEvents } = await import("./folding-OYBO2NTH.js");
6639
6675
  const eventStore = getEventStore2();
6640
6676
  const events = eventStore.getEvents(sessionId);
6641
6677
  const { messages } = buildMessagesFromStoredEvents(events);
@@ -6647,7 +6683,7 @@ All file and git operations should use this branch.
6647
6683
  if (msg.role !== "user" || msg.isSystemGenerated) {
6648
6684
  return res.status(400).json({ error: "Can only replay user messages" });
6649
6685
  }
6650
- const { truncateSessionMessages } = await import("./events-SY5B4VED.js");
6686
+ const { truncateSessionMessages } = await import("./events-4THEZWVL.js");
6651
6687
  truncateSessionMessages(sessionId, msgIndex - 1);
6652
6688
  sessionManager.queueMessage(sessionId, "asap", content ?? msg.content, msg.attachments, msg.messageKind);
6653
6689
  res.json({ success: true });
@@ -6764,7 +6800,7 @@ All file and git operations should use this branch.
6764
6800
  let visionFallback;
6765
6801
  let globalWorkdir;
6766
6802
  try {
6767
- const { loadGlobalConfig, getVisionFallback } = await import("./config-XIYAPMX3.js");
6803
+ const { loadGlobalConfig, getVisionFallback } = await import("./config-M7RDIFC5.js");
6768
6804
  const globalConfig = await loadGlobalConfig(config3.mode ?? "production", config3.globalConfigPath);
6769
6805
  const fallback = getVisionFallback(globalConfig);
6770
6806
  if (fallback) {
@@ -6773,7 +6809,8 @@ All file and git operations should use this branch.
6773
6809
  url: fallback.url ?? "http://localhost:11434",
6774
6810
  model: fallback.model ?? "qwen3.5:0.8b",
6775
6811
  timeout: fallback.timeout ?? 120,
6776
- backend: fallback.backend ?? "ollama"
6812
+ backend: fallback.backend ?? "ollama",
6813
+ ...fallback.providerModelRef ? { providerModelRef: fallback.providerModelRef } : {}
6777
6814
  };
6778
6815
  }
6779
6816
  globalWorkdir = globalConfig.workspace?.workdir;
@@ -6843,6 +6880,28 @@ All file and git operations should use this branch.
6843
6880
  ...m.selected !== void 0 && { selected: m.selected }
6844
6881
  }));
6845
6882
  }
6883
+ app.post("/api/proxy/test", async (_req, res) => {
6884
+ const { getSetting: getSetting2, SETTINGS_KEYS } = await import("./settings-2WVGUPYV.js");
6885
+ const proxyUrl = getSetting2(SETTINGS_KEYS.PROXY_URL);
6886
+ if (!proxyUrl) {
6887
+ return res.status(400).json({ success: false, error: "No proxy URL configured" });
6888
+ }
6889
+ try {
6890
+ const response = await fetch("http://example.com", {
6891
+ signal: AbortSignal.timeout(1e4)
6892
+ });
6893
+ if (!response.ok) {
6894
+ return res.status(400).json({ success: false, error: `Proxy returned HTTP ${response.status}` });
6895
+ }
6896
+ return res.json({ success: true, message: "Proxy connection OK" });
6897
+ } catch (error) {
6898
+ const message = error instanceof Error ? error.message : "Connection failed";
6899
+ if (error instanceof DOMException && error.name === "AbortError") {
6900
+ return res.status(400).json({ success: false, error: "Connection timed out" });
6901
+ }
6902
+ return res.status(400).json({ success: false, error: message });
6903
+ }
6904
+ });
6846
6905
  app.post("/api/providers/test", async (req, res) => {
6847
6906
  const { url, backend: reqBackend } = req.body;
6848
6907
  if (!url) {
@@ -6920,7 +6979,7 @@ All file and git operations should use this branch.
6920
6979
  return res.status(400).json({ success: false, error: "No proxy URL configured" });
6921
6980
  }
6922
6981
  try {
6923
- const response = await proxyFetch("http://example.com", {
6982
+ const response = await fetch("http://example.com", {
6924
6983
  signal: AbortSignal.timeout(1e4)
6925
6984
  });
6926
6985
  if (!response.ok) {
@@ -6941,7 +7000,7 @@ All file and git operations should use this branch.
6941
7000
  const backend = req.query["backend"];
6942
7001
  if (!url) return res.status(400).json({ error: "url is required" });
6943
7002
  try {
6944
- const { fetchModelsWithContext } = await import("./provider-manager-FVIFMUTO.js");
7003
+ const { fetchModelsWithContext } = await import("./provider-manager-PBOF77RQ.js");
6945
7004
  const { getModelProfile: getModelProfile2 } = await import("./profiles-5J7F4BML.js");
6946
7005
  const models = await fetchModelsWithContext(
6947
7006
  url,
@@ -7012,7 +7071,7 @@ All file and git operations should use this branch.
7012
7071
  const { getModelProfile: getModelProfile2 } = await import("./profiles-5J7F4BML.js");
7013
7072
  const { getBackendCapabilities } = await import("./backend-P3GHHLHJ.js");
7014
7073
  const { buildNonStreamingCreateParams } = await import("./client-pure-5YE5WFJP.js");
7015
- const { OpenAIHttpClient } = await import("./http-client-3MOFAPO6.js");
7074
+ const { OpenAIHttpClient } = await import("./http-client-U6DVFL7F.js");
7016
7075
  const { ensureVersionPrefix } = await import("./url-utils-SAJP7AEX.js");
7017
7076
  const profile = getModelProfile2(model);
7018
7077
  const capabilities = getBackendCapabilities(backend || "unknown");
@@ -7081,7 +7140,7 @@ All file and git operations should use this branch.
7081
7140
  return res.status(400).json({ error: "name, url, and backend are required" });
7082
7141
  }
7083
7142
  try {
7084
- const { loadGlobalConfig, saveGlobalConfig, addProvider, setDefaultModelSelection } = await import("./config-XIYAPMX3.js");
7143
+ const { loadGlobalConfig, saveGlobalConfig, addProvider, setDefaultModelSelection } = await import("./config-M7RDIFC5.js");
7085
7144
  const globalConfig = await loadGlobalConfig(config3.mode ?? "production", config3.globalConfigPath);
7086
7145
  const providerBackend = backend;
7087
7146
  const providerModels = modelConfigs?.length ? buildModelConfigs(modelConfigs) : model ? [{ id: model, contextWindow: 2e5, source: "user" }] : [];
@@ -7121,12 +7180,13 @@ All file and git operations should use this branch.
7121
7180
  app.post("/api/init/config", async (req, res) => {
7122
7181
  const { workdir, visionFallback } = req.body;
7123
7182
  try {
7124
- const { loadGlobalConfig, saveGlobalConfig } = await import("./config-XIYAPMX3.js");
7183
+ const { loadGlobalConfig, saveGlobalConfig } = await import("./config-M7RDIFC5.js");
7125
7184
  const globalConfig = await loadGlobalConfig(config3.mode ?? "production", config3.globalConfigPath);
7185
+ const updatedVf = visionFallback ? { ...globalConfig.visionFallback, ...visionFallback } : globalConfig.visionFallback;
7126
7186
  const updatedConfig = {
7127
7187
  ...globalConfig,
7128
7188
  workspace: workdir ? { workdir } : globalConfig.workspace,
7129
- visionFallback: visionFallback ?? globalConfig.visionFallback
7189
+ visionFallback: updatedVf
7130
7190
  };
7131
7191
  await saveGlobalConfig(config3.mode ?? "production", updatedConfig, config3.globalConfigPath);
7132
7192
  res.json({ success: true });
@@ -7137,6 +7197,93 @@ All file and git operations should use this branch.
7137
7197
  });
7138
7198
  }
7139
7199
  });
7200
+ app.put("/api/config/vision-fallback", async (req, res) => {
7201
+ const { z } = await import("zod");
7202
+ const visionFallbackUpdateSchema = z.object({
7203
+ enabled: z.boolean().optional(),
7204
+ url: z.string().optional(),
7205
+ model: z.string().optional(),
7206
+ timeout: z.number().positive().optional(),
7207
+ backend: z.enum(["ollama", "openai"]).optional(),
7208
+ providerModelRef: z.string().optional()
7209
+ });
7210
+ const parsed = visionFallbackUpdateSchema.safeParse(req.body);
7211
+ if (!parsed.success) {
7212
+ res.status(400).json({ success: false, error: parsed.error.issues.map((i) => i.message).join(", ") });
7213
+ return;
7214
+ }
7215
+ const updates = parsed.data;
7216
+ try {
7217
+ const { loadGlobalConfig, saveGlobalConfig } = await import("./config-M7RDIFC5.js");
7218
+ const globalConfig = await loadGlobalConfig(config3.mode ?? "production", config3.globalConfigPath);
7219
+ const filteredUpdates = Object.fromEntries(Object.entries(updates).filter(([, v]) => v !== void 0));
7220
+ const updatedConfig = {
7221
+ ...globalConfig,
7222
+ visionFallback: {
7223
+ ...globalConfig.visionFallback ?? {
7224
+ enabled: false,
7225
+ url: "http://localhost:11434",
7226
+ model: "qwen3.5:0.8b",
7227
+ timeout: 120,
7228
+ backend: "ollama"
7229
+ },
7230
+ ...filteredUpdates
7231
+ }
7232
+ };
7233
+ await saveGlobalConfig(config3.mode ?? "production", updatedConfig, config3.globalConfigPath);
7234
+ res.json({ success: true });
7235
+ } catch (error) {
7236
+ res.status(500).json({
7237
+ success: false,
7238
+ error: error instanceof Error ? error.message : "Failed to save vision fallback config"
7239
+ });
7240
+ }
7241
+ });
7242
+ app.post("/api/config/vision-fallback/test", async (req, res) => {
7243
+ const { z } = await import("zod");
7244
+ const testSchema = z.object({
7245
+ url: z.string().optional(),
7246
+ model: z.string().optional(),
7247
+ backend: z.enum(["ollama", "openai"]).optional(),
7248
+ providerModelRef: z.string().optional(),
7249
+ timeout: z.number().positive().optional()
7250
+ });
7251
+ const parsed = testSchema.safeParse(req.body);
7252
+ if (!parsed.success) {
7253
+ res.status(400).json({ success: false, error: parsed.error.issues.map((i) => i.message).join(", ") });
7254
+ return;
7255
+ }
7256
+ const testConfig = parsed.data;
7257
+ try {
7258
+ const { resolveVisionFallback } = await import("./config-M7RDIFC5.js");
7259
+ const { loadGlobalConfig } = await import("./config-M7RDIFC5.js");
7260
+ const globalConfig = await loadGlobalConfig(config3.mode ?? "production", config3.globalConfigPath);
7261
+ const filteredTestConfig = Object.fromEntries(Object.entries(testConfig).filter(([, v]) => v !== void 0));
7262
+ const testVisionFallback = {
7263
+ ...globalConfig.visionFallback ?? {
7264
+ enabled: true,
7265
+ url: "http://localhost:11434",
7266
+ model: "qwen3.5:0.8b",
7267
+ timeout: 120,
7268
+ backend: "ollama"
7269
+ },
7270
+ ...filteredTestConfig,
7271
+ enabled: true
7272
+ };
7273
+ const testGlobalConfig = { ...globalConfig, visionFallback: testVisionFallback };
7274
+ const resolved = resolveVisionFallback(testGlobalConfig);
7275
+ if (resolved) {
7276
+ res.json({
7277
+ success: true,
7278
+ description: `Config valid: ${resolved.model} @ ${resolved.baseUrl} (${resolved.backend})`
7279
+ });
7280
+ } else {
7281
+ res.json({ success: false, error: "Could not resolve vision model config. Check your settings." });
7282
+ }
7283
+ } catch (error) {
7284
+ res.json({ success: false, error: error instanceof Error ? error.message : "Test failed" });
7285
+ }
7286
+ });
7140
7287
  app.use("/api/plugins", createPluginRoutes({ config: config3, providerAdapters, pluginDiagnostics, logger }));
7141
7288
  app.get("/api/plugins", (_req, res) => res.json({ plugins: pluginDiagnostics }));
7142
7289
  app.get("/api/provider-presets", (_req, res) => res.json({ presets: providerAdapters.getPresets() }));
@@ -7160,7 +7307,7 @@ All file and git operations should use this branch.
7160
7307
  });
7161
7308
  app.delete("/api/providers/:id", async (req, res) => {
7162
7309
  const { id } = req.params;
7163
- const { loadGlobalConfig, saveGlobalConfig, removeProvider } = await import("./config-XIYAPMX3.js");
7310
+ const { loadGlobalConfig, saveGlobalConfig, removeProvider } = await import("./config-M7RDIFC5.js");
7164
7311
  const globalConfig = await loadGlobalConfig(config3.mode ?? "production", config3.globalConfigPath);
7165
7312
  const updatedConfig = removeProvider(globalConfig, id);
7166
7313
  await saveGlobalConfig(config3.mode ?? "production", updatedConfig, config3.globalConfigPath);
@@ -7172,7 +7319,7 @@ All file and git operations should use this branch.
7172
7319
  const { id } = req.params;
7173
7320
  const { isLocal } = req.body;
7174
7321
  try {
7175
- const { loadGlobalConfig, saveGlobalConfig, updateProvider } = await import("./config-XIYAPMX3.js");
7322
+ const { loadGlobalConfig, saveGlobalConfig, updateProvider } = await import("./config-M7RDIFC5.js");
7176
7323
  const globalConfig = await loadGlobalConfig(config3.mode ?? "production", config3.globalConfigPath);
7177
7324
  const provider = globalConfig.providers.find((p) => p.id === id);
7178
7325
  if (!provider) {
@@ -7203,7 +7350,7 @@ All file and git operations should use this branch.
7203
7350
  transportAdapter
7204
7351
  } = req.body;
7205
7352
  try {
7206
- const { loadGlobalConfig, saveGlobalConfig, updateProvider } = await import("./config-XIYAPMX3.js");
7353
+ const { loadGlobalConfig, saveGlobalConfig, updateProvider } = await import("./config-M7RDIFC5.js");
7207
7354
  const globalConfig = await loadGlobalConfig(config3.mode ?? "production", config3.globalConfigPath);
7208
7355
  const provider = globalConfig.providers.find((p) => p.id === id);
7209
7356
  if (!provider) {
@@ -7243,7 +7390,7 @@ All file and git operations should use this branch.
7243
7390
  return res.status(400).json({ error: result.error });
7244
7391
  }
7245
7392
  const llmClient = getLLMClient();
7246
- const { loadGlobalConfig, saveGlobalConfig, setDefaultModelSelection } = await import("./config-XIYAPMX3.js");
7393
+ const { loadGlobalConfig, saveGlobalConfig, setDefaultModelSelection } = await import("./config-M7RDIFC5.js");
7247
7394
  const globalConfig = await loadGlobalConfig(config3.mode ?? "production", config3.globalConfigPath);
7248
7395
  const updatedConfig = setDefaultModelSelection(globalConfig, id, llmClient.getModel());
7249
7396
  await saveGlobalConfig(config3.mode ?? "production", updatedConfig, config3.globalConfigPath);
@@ -7270,7 +7417,7 @@ All file and git operations should use this branch.
7270
7417
  });
7271
7418
  async function rebuildMcpTools() {
7272
7419
  const { createMcpTools: createMcpTools2 } = await import("./tool-adapter-MOGEI6TP.js");
7273
- const { setMcpTools: setMcpTools2 } = await import("./tools-YXOCUUKE.js");
7420
+ const { setMcpTools: setMcpTools2 } = await import("./tools-I3BAXRVD.js");
7274
7421
  const mcpTools = createMcpTools2(mcpManager);
7275
7422
  setMcpTools2(mcpTools);
7276
7423
  }
@@ -7340,7 +7487,7 @@ All file and git operations should use this branch.
7340
7487
  };
7341
7488
  await mcpManager.addServer(name, serverCfg);
7342
7489
  const server = mcpManager.getServer(name);
7343
- const { loadGlobalConfig, saveGlobalConfig } = await import("./config-XIYAPMX3.js");
7490
+ const { loadGlobalConfig, saveGlobalConfig } = await import("./config-M7RDIFC5.js");
7344
7491
  const globalConfig = await loadGlobalConfig(config3.mode ?? "production", config3.globalConfigPath);
7345
7492
  const updatedMcpServers = { ...globalConfig.mcpServers ?? {}, [name]: serverCfg };
7346
7493
  await saveGlobalConfig(
@@ -7398,7 +7545,7 @@ All file and git operations should use this branch.
7398
7545
  return res.status(400).json({ error: "disabled must be a boolean" });
7399
7546
  }
7400
7547
  try {
7401
- const { loadGlobalConfig, saveGlobalConfig } = await import("./config-XIYAPMX3.js");
7548
+ const { loadGlobalConfig, saveGlobalConfig } = await import("./config-M7RDIFC5.js");
7402
7549
  const { applyMcpServerUpdate } = await import("./update-server-4I6LXE5K.js");
7403
7550
  const globalConfig = await loadGlobalConfig(config3.mode ?? "production", config3.globalConfigPath);
7404
7551
  const mcpServers2 = { ...globalConfig.mcpServers ?? {} };
@@ -7444,7 +7591,7 @@ All file and git operations should use this branch.
7444
7591
  return res.status(404).json({ error: `MCP server '${name}' not found` });
7445
7592
  }
7446
7593
  mcpManager.removeServer(name);
7447
- const { loadGlobalConfig, saveGlobalConfig } = await import("./config-XIYAPMX3.js");
7594
+ const { loadGlobalConfig, saveGlobalConfig } = await import("./config-M7RDIFC5.js");
7448
7595
  const globalConfig = await loadGlobalConfig(config3.mode ?? "production", config3.globalConfigPath);
7449
7596
  const updatedMcpServers = { ...globalConfig.mcpServers ?? {} };
7450
7597
  delete updatedMcpServers[name];
@@ -7474,7 +7621,7 @@ All file and git operations should use this branch.
7474
7621
  await mcpManager.setToolEnabled(name, toolName, enabled);
7475
7622
  const server = mcpManager.getServer(name);
7476
7623
  if (server) {
7477
- const { loadGlobalConfig, saveGlobalConfig } = await import("./config-XIYAPMX3.js");
7624
+ const { loadGlobalConfig, saveGlobalConfig } = await import("./config-M7RDIFC5.js");
7478
7625
  const globalConfig = await loadGlobalConfig(config3.mode ?? "production", config3.globalConfigPath);
7479
7626
  const mcpServers2 = { ...globalConfig.mcpServers ?? {} };
7480
7627
  const serverCfg = mcpServers2[name];
@@ -7526,13 +7673,13 @@ All file and git operations should use this branch.
7526
7673
  })
7527
7674
  );
7528
7675
  app.get("/api/sessions/:id/background-processes", async (req, res) => {
7529
- const { getSessionProcesses } = await import("./manager-UP3XMLKX.js");
7676
+ const { getSessionProcesses } = await import("./manager-53J5P4EZ.js");
7530
7677
  const sessionId = req.params.id;
7531
7678
  const processes = getSessionProcesses(sessionId);
7532
7679
  res.json({ processes });
7533
7680
  });
7534
7681
  app.post("/api/sessions/:id/background-process/:processId/stop", async (req, res) => {
7535
- const { stopProcess } = await import("./manager-UP3XMLKX.js");
7682
+ const { stopProcess } = await import("./manager-53J5P4EZ.js");
7536
7683
  const sessionId = req.params.id;
7537
7684
  const processId = req.params.processId;
7538
7685
  const session = sessionManager.getSession(sessionId);
@@ -7677,7 +7824,7 @@ All file and git operations should use this branch.
7677
7824
  const state = sessionManager.getContextState(sessionId);
7678
7825
  wssExports.broadcastForSession(sessionId, createContextStateMessage(state));
7679
7826
  });
7680
- const { QueueProcessor } = await import("./processor-WP34IB3C.js");
7827
+ const { QueueProcessor } = await import("./processor-HX4FXDDT.js");
7681
7828
  const queueProcessor = new QueueProcessor({
7682
7829
  sessionManager,
7683
7830
  providerManager,
@@ -7761,4 +7908,4 @@ export {
7761
7908
  createServerHandle,
7762
7909
  createServer
7763
7910
  };
7764
- //# sourceMappingURL=chunk-OQXG4MS4.js.map
7911
+ //# sourceMappingURL=chunk-ML5ZU6VS.js.map