openfox 2.0.132 → 2.0.134

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 (85) hide show
  1. package/CHANGELOG.md +31 -0
  2. package/dist/CHANGELOG.md +31 -0
  3. package/dist/agent-defaults/code-reviewer.agent.md +1 -0
  4. package/dist/agent-defaults/explorer.agent.md +1 -0
  5. package/dist/agent-defaults/verifier.agent.md +1 -0
  6. package/dist/{chat-handler-T47GATL5.js → chat-handler-YCZE2XEJ.js} +23 -22
  7. package/dist/chunk-24YKXKCG.js +35 -0
  8. package/dist/chunk-2OMGR7LN.js +45 -0
  9. package/dist/{chunk-ZSBNXJZ5.js → chunk-5IXCCMFU.js} +342 -188
  10. package/dist/{chunk-MQMPIXON.js → chunk-5UMXFLET.js} +3 -3
  11. package/dist/{chunk-5JWJEZJ3.js → chunk-5UQ4CKOA.js} +2 -2
  12. package/dist/{chunk-GVOOOV7M.js → chunk-7HGBJFIJ.js} +44 -25
  13. package/dist/{chunk-7JVBDBXE.js → chunk-7QMWYNVF.js} +2 -2
  14. package/dist/{chunk-P57IBMK4.js → chunk-AATMPL7S.js} +4 -4
  15. package/dist/{chunk-ZL4IAFF3.js → chunk-BZND27IB.js} +3 -3
  16. package/dist/{chunk-FGNJMKDV.js → chunk-CSYOWFPU.js} +5 -5
  17. package/dist/{chunk-LQKXJPKP.js → chunk-CTWZPN7G.js} +5 -1
  18. package/dist/{chunk-BKMWZTNO.js → chunk-DWA4IE65.js} +14 -2
  19. package/dist/{chunk-RRUSYVQD.js → chunk-FAQDLL2X.js} +8 -8
  20. package/dist/{chunk-HCYSGLY2.js → chunk-HF3NDXB4.js} +1 -1
  21. package/dist/{chunk-6EZDW4JS.js → chunk-J3NMNYGM.js} +2 -2
  22. package/dist/{chunk-HXHPKGJE.js → chunk-J5HOUEPE.js} +614 -157
  23. package/dist/{chunk-RUFXKUOL.js → chunk-M4J2L4VH.js} +132 -45
  24. package/dist/{chunk-M5T4RDPJ.js → chunk-MEEUXRFL.js} +2 -2
  25. package/dist/{chunk-EOHEDEIH.js → chunk-MRE4OYKI.js} +69 -27
  26. package/dist/{chunk-MGEYAYGU.js → chunk-O3RCSKUH.js} +2 -2
  27. package/dist/{chunk-ELYHHEYL.js → chunk-ORCQ3EXQ.js} +2 -2
  28. package/dist/{chunk-FEIRWXLX.js → chunk-OZWHRBDY.js} +64 -17
  29. package/dist/{chunk-TACWRDDC.js → chunk-QDARWVQ2.js} +2 -2
  30. package/dist/{chunk-VXG3AFFY.js → chunk-QICVOQNX.js} +8 -8
  31. package/dist/chunk-QTLYD2FF.js +7 -0
  32. package/dist/{chunk-Y6ZGHOKM.js → chunk-YLVOU7T7.js} +4 -4
  33. package/dist/{chunk-GFW2HWJ6.js → chunk-YOPXAI2W.js} +37 -16
  34. package/dist/{chunk-CLDCHOEA.js → chunk-ZMK4VX7V.js} +2 -2
  35. package/dist/{chunk-KWAHD2JA.js → chunk-ZTBKMVV6.js} +2 -2
  36. package/dist/cli/dev.js +4 -1
  37. package/dist/cli/index.js +4 -1
  38. package/dist/{client-2K6PPPJJ.js → client-VVYOWXRR.js} +4 -4
  39. package/dist/{compactor-OEJAA2YP.js → compactor-PD6DQ4NY.js} +9 -9
  40. package/dist/{dynamic-context-NJZKAZE3.js → dynamic-context-WKEXQCTK.js} +10 -10
  41. package/dist/{events-ZJPRGVL2.js → events-3WSNI7XC.js} +6 -6
  42. package/dist/{folding-QRZOHY2I.js → folding-H7JTX6KI.js} +4 -4
  43. package/dist/{http-client-P4XTKAZA.js → http-client-A445WYZU.js} +3 -3
  44. package/dist/{install-VA2F6X6Z.js → install-AVTFA344.js} +64 -15
  45. package/dist/{launch-6I5ADTVT.js → launch-FJ65HRV4.js} +23 -22
  46. package/dist/{manager-TMBFBCQL.js → manager-ZACEUL5P.js} +4 -4
  47. package/dist/{mcp-YU7AM3UV.js → mcp-SQ4DOGPT.js} +22 -9
  48. package/dist/{orchestrator-GX22Y5EM.js → orchestrator-OT66EDXO.js} +22 -21
  49. package/dist/package.json +3 -1
  50. package/dist/{path-security-CBACXAMS.js → path-security-5CFMMULR.js} +10 -10
  51. package/dist/{platform-5LQXOZO3.js → platform-XPMZKAUB.js} +3 -3
  52. package/dist/{processor-FMEULCNQ.js → processor-CHMHMMIE.js} +37 -21
  53. package/dist/{project-creator-6AGQTNXB.js → project-creator-T3A4H3YV.js} +42 -29
  54. package/dist/{protocol-BMUoqwYH.d.ts → protocol-Nr_H1_oC.d.ts} +3 -1
  55. package/dist/{protocol-Y7MRKRUO.js → protocol-XO4ZROAU.js} +3 -3
  56. package/dist/provider/index.d.ts +4 -4
  57. package/dist/provider-JWUNG2TD.js +507 -0
  58. package/dist/{provider-manager-BO5ZBG3T.js → provider-manager-2KKZ37XJ.js} +5 -5
  59. package/dist/pwa-V5PFB4OQ.js +502 -0
  60. package/dist/{registry-CMSSZHDC.js → registry-BEIR7Y5G.js} +3 -3
  61. package/dist/{serve-BFGHUM4Y.js → serve-HSDVY37K.js} +47 -36
  62. package/dist/server/index.d.ts +3 -3
  63. package/dist/server/index.js +27 -26
  64. package/dist/{server-WPWUYB6I.js → server-3UVLECD5.js} +26 -25
  65. package/dist/{service-WKABQHKL.js → service-M77VWL2M.js} +97 -32
  66. package/dist/{service-O3LCO3TQ.js → service-XIUNS5XV.js} +7 -6
  67. package/dist/{session-overrides-OECQYRDK.js → session-overrides-Y5B4XQPU.js} +5 -5
  68. package/dist/{sessions-NMPX5ICI.js → sessions-IGINPPBP.js} +4 -4
  69. package/dist/{settings-MDCRNQBY.js → settings-ZJPM6PQV.js} +2 -2
  70. package/dist/shared/index.d.ts +31 -4
  71. package/dist/shared/index.js +16 -2
  72. package/dist/{tasks-WOC3QUFA.js → tasks-3JJWJJ3X.js} +34 -18
  73. package/dist/{tools-CW6POKUL.js → tools-WWIWD3O7.js} +20 -19
  74. package/dist/{types-CoY8Ka1C.d.ts → types-BlQjLBui.d.ts} +1 -1
  75. package/dist/{types-BIkpxjaj.d.ts → types-G10ho8PT.d.ts} +1 -1
  76. package/dist/update-Q6SH7UP2.js +76 -0
  77. package/dist/web/assets/index-C48qmBAI.js +313 -0
  78. package/dist/web/index.html +1 -1
  79. package/dist/web/sw.js +1 -1
  80. package/package.json +3 -1
  81. package/dist/chunk-55RHB5JB.js +0 -7
  82. package/dist/provider-NWRGNGS3.js +0 -403
  83. package/dist/pwa-2GRFSXD7.js +0 -363
  84. package/dist/update-VPCDKFLD.js +0 -49
  85. package/dist/web/assets/index-Bx5r3aJx.js +0 -310
@@ -24,10 +24,10 @@ import {
24
24
  terminalManager,
25
25
  tokenFromPassword,
26
26
  verifyPassword
27
- } from "./chunk-RUFXKUOL.js";
27
+ } from "./chunk-M4J2L4VH.js";
28
28
  import {
29
29
  TEMPLATE_VARIABLES
30
- } from "./chunk-GVOOOV7M.js";
30
+ } from "./chunk-7HGBJFIJ.js";
31
31
  import {
32
32
  createToolRegistry,
33
33
  devServerManager,
@@ -42,7 +42,7 @@ import {
42
42
  setMcpManagerForTools,
43
43
  setMcpTools,
44
44
  setNotifyMcpServersChanged
45
- } from "./chunk-HXHPKGJE.js";
45
+ } from "./chunk-J5HOUEPE.js";
46
46
  import {
47
47
  checkoutBranchFromSharedSource,
48
48
  deleteWorkspace,
@@ -86,12 +86,13 @@ import {
86
86
  saveCommandToProject,
87
87
  saveWorkflow,
88
88
  saveWorkflowToProject,
89
+ serverT,
89
90
  workflowExists
90
- } from "./chunk-FEIRWXLX.js";
91
+ } from "./chunk-OZWHRBDY.js";
91
92
  import {
92
93
  getSessionDisabledServers,
93
94
  setSessionDisabledServers
94
- } from "./chunk-TACWRDDC.js";
95
+ } from "./chunk-QDARWVQ2.js";
95
96
  import {
96
97
  createMcpTools
97
98
  } from "./chunk-JE7LW7Y6.js";
@@ -113,12 +114,12 @@ import {
113
114
  setSkillEnabled,
114
115
  skillExists,
115
116
  updateOwnedSkill
116
- } from "./chunk-BKMWZTNO.js";
117
+ } from "./chunk-DWA4IE65.js";
117
118
  import {
118
119
  ALWAYS_ALLOWED,
119
120
  ALWAYS_ALLOWED_FOR_SUBAGENTS,
120
121
  TOP_LEVEL_ONLY_TOOLS
121
- } from "./chunk-7JVBDBXE.js";
122
+ } from "./chunk-7QMWYNVF.js";
122
123
  import {
123
124
  EventEmitter,
124
125
  getPendingQuestionsForSession,
@@ -127,7 +128,7 @@ import {
127
128
  import {
128
129
  getPendingConfirmationsBySession,
129
130
  providePathConfirmation
130
- } from "./chunk-Y6ZGHOKM.js";
131
+ } from "./chunk-YLVOU7T7.js";
131
132
  import {
132
133
  combineEventsWithSnapshot,
133
134
  emitAssistantMessageStart,
@@ -145,10 +146,10 @@ import {
145
146
  getEventStore,
146
147
  getSessionState,
147
148
  initEventStore
148
- } from "./chunk-FGNJMKDV.js";
149
+ } from "./chunk-CSYOWFPU.js";
149
150
  import {
150
151
  buildMessagesFromStoredEvents
151
- } from "./chunk-M5T4RDPJ.js";
152
+ } from "./chunk-MEEUXRFL.js";
152
153
  import {
153
154
  clearWorkflowExecution,
154
155
  createSession,
@@ -174,7 +175,7 @@ import {
174
175
  updateSessionRunning,
175
176
  updateSessionWorkdir,
176
177
  updateWorkflowExecutionStatus
177
- } from "./chunk-KWAHD2JA.js";
178
+ } from "./chunk-ZTBKMVV6.js";
178
179
  import {
179
180
  agentExists,
180
181
  deleteAgent,
@@ -191,7 +192,7 @@ import {
191
192
  saveAgent,
192
193
  saveAgentToProject,
193
194
  setRuntimeConfig
194
- } from "./chunk-ELYHHEYL.js";
195
+ } from "./chunk-ORCQ3EXQ.js";
195
196
  import {
196
197
  findFileByInternalId,
197
198
  pathExists
@@ -199,23 +200,23 @@ import {
199
200
  import {
200
201
  createContextStateMessage,
201
202
  toClientSession
202
- } from "./chunk-P57IBMK4.js";
203
+ } from "./chunk-AATMPL7S.js";
203
204
  import {
204
205
  getPathSeparator,
205
206
  isAbsolutePath
206
- } from "./chunk-MGEYAYGU.js";
207
+ } from "./chunk-O3RCSKUH.js";
207
208
  import {
208
209
  createProviderManager,
209
210
  detectModel,
210
211
  getLlmStatus,
211
212
  parseDefaultModelSelection
212
- } from "./chunk-5JWJEZJ3.js";
213
+ } from "./chunk-5UQ4CKOA.js";
213
214
  import {
214
215
  buildOpenFoxMcpBootstrap
215
216
  } from "./chunk-YNMP647F.js";
216
217
  import {
217
218
  VERSION
218
- } from "./chunk-55RHB5JB.js";
219
+ } from "./chunk-QTLYD2FF.js";
219
220
  import {
220
221
  deleteProject,
221
222
  getProject,
@@ -235,12 +236,12 @@ import {
235
236
  import {
236
237
  SessionNotFoundError,
237
238
  WorkspaceInUseError
238
- } from "./chunk-6EZDW4JS.js";
239
+ } from "./chunk-J3NMNYGM.js";
239
240
  import {
240
241
  deleteSetting,
241
242
  getSetting,
242
243
  setSetting
243
- } from "./chunk-LQKXJPKP.js";
244
+ } from "./chunk-CTWZPN7G.js";
244
245
  import {
245
246
  initDatabase
246
247
  } from "./chunk-JU757HVI.js";
@@ -253,7 +254,7 @@ import {
253
254
  } from "./chunk-K44MW7JJ.js";
254
255
  import {
255
256
  createServerMessage
256
- } from "./chunk-HCYSGLY2.js";
257
+ } from "./chunk-HF3NDXB4.js";
257
258
  import {
258
259
  getGlobalConfigDir
259
260
  } from "./chunk-CQGTEGKL.js";
@@ -1135,6 +1136,12 @@ function getPromptAwareToolResponse(prompt) {
1135
1136
  function getConversationAwareToolResponse(request) {
1136
1137
  const prompt = getLastUserPrompt(request);
1137
1138
  const conversationText = getConversationText(request);
1139
+ if (/If you have finished the task, call step_done\(\)/i.test(prompt)) {
1140
+ return {
1141
+ tools: [{ name: "step_done", arguments: {} }],
1142
+ response: "Finished the step."
1143
+ };
1144
+ }
1138
1145
  if (/Implement the task and make sure you fulfil the \d+ criteria\./i.test(prompt) || /Continue working on the acceptance criteria\./i.test(prompt)) {
1139
1146
  const tools = [];
1140
1147
  const completedCriteria = [];
@@ -3984,13 +3991,33 @@ var SessionManager = class {
3984
3991
  }
3985
3992
  } catch (innerErr) {
3986
3993
  throw new Error(
3987
- `Failed to create branch "${branch}" in workspace "${workspaceName}": ${innerErr instanceof Error ? innerErr.message : String(innerErr)}`
3994
+ serverT(
3995
+ {
3996
+ en: 'Failed to create branch "{{branch}}" in workspace "{{workspace}}": {{reason}}',
3997
+ fr: "\xC9chec de cr\xE9ation de la branche \xAB {{branch}} \xBB dans le workspace \xAB {{workspace}} \xBB : {{reason}}"
3998
+ },
3999
+ {
4000
+ branch,
4001
+ workspace: workspaceName,
4002
+ reason: innerErr instanceof Error ? innerErr.message : String(innerErr)
4003
+ }
4004
+ )
3988
4005
  );
3989
4006
  }
3990
4007
  });
3991
4008
  } catch (err) {
3992
4009
  throw new Error(
3993
- `Failed to apply branch "${branch}" to workspace "${workspaceName}": ${err instanceof Error ? err.message : String(err)}`
4010
+ serverT(
4011
+ {
4012
+ en: 'Failed to apply branch "{{branch}}" to workspace "{{workspace}}": {{reason}}',
4013
+ fr: "\xC9chec d\u2019application de la branche \xAB {{branch}} \xBB au workspace \xAB {{workspace}} \xBB : {{reason}}"
4014
+ },
4015
+ {
4016
+ branch,
4017
+ workspace: workspaceName,
4018
+ reason: err instanceof Error ? err.message : String(err)
4019
+ }
4020
+ )
3994
4021
  );
3995
4022
  }
3996
4023
  }
@@ -4369,8 +4396,16 @@ async function loadItemsForScope(config3, configDir, projectDir, scope) {
4369
4396
  var ID_REGEX = /^[a-z0-9-]+$/;
4370
4397
  function validateNameIdPrompt(body) {
4371
4398
  const meta = body["metadata"];
4372
- if (!meta?.["name"] || !body["prompt"]) return "Missing required fields: metadata.name, prompt";
4373
- if (meta["id"] && !ID_REGEX.test(String(meta["id"]))) return "ID must be lowercase alphanumeric with hyphens only";
4399
+ if (!meta?.["name"] || !body["prompt"])
4400
+ return serverT({
4401
+ en: "Missing required fields: metadata.name, prompt",
4402
+ fr: "Champs requis manquants : metadata.name, prompt"
4403
+ });
4404
+ if (meta["id"] && !ID_REGEX.test(String(meta["id"])))
4405
+ return serverT({
4406
+ en: "ID must be lowercase alphanumeric with hyphens only",
4407
+ fr: "L\u2019ID doit \xEAtre en minuscules alphanum\xE9riques, avec des tirets uniquement"
4408
+ });
4374
4409
  return null;
4375
4410
  }
4376
4411
  function getProjectItemPath(projectDir, dirName, id, ext) {
@@ -4410,7 +4445,7 @@ function createCrudRoutes(config3, configDir, projectDir) {
4410
4445
  const allDefaults = await config3.loadDefaults();
4411
4446
  const item = allDefaults.find((d) => d.metadata.id === id);
4412
4447
  if (!item) {
4413
- return res.status(404).json({ error: "Default not found" });
4448
+ return res.status(404).json({ error: serverT({ en: "Default not found", fr: "\xC9l\xE9ment par d\xE9faut introuvable" }) });
4414
4449
  }
4415
4450
  res.json(item);
4416
4451
  });
@@ -4418,6 +4453,7 @@ function createCrudRoutes(config3, configDir, projectDir) {
4418
4453
  const ids = config3.getDefaultIds ? await config3.getDefaultIds() : [];
4419
4454
  res.json({ ids });
4420
4455
  });
4456
+ config3.extraRoutes?.(router);
4421
4457
  router.get("/:id", async (req, res) => {
4422
4458
  const { id } = req.params;
4423
4459
  const effectiveProjectDir = resolveProjectDir(req, projectDir);
@@ -4425,7 +4461,7 @@ function createCrudRoutes(config3, configDir, projectDir) {
4425
4461
  const items = await loadItemsForScope(config3, configDir, effectiveProjectDir, scope);
4426
4462
  const item = config3.findById(id, items);
4427
4463
  if (!item) {
4428
- return res.status(404).json({ error: "Not found" });
4464
+ return res.status(404).json({ error: serverT({ en: "Not found", fr: "Introuvable" }) });
4429
4465
  }
4430
4466
  res.json(item);
4431
4467
  });
@@ -4434,17 +4470,19 @@ function createCrudRoutes(config3, configDir, projectDir) {
4434
4470
  const meta = body["metadata"];
4435
4471
  const customError = config3.validateCreate?.(body);
4436
4472
  if (!meta?.["id"] || customError) {
4437
- return res.status(400).json({ error: customError ?? "Missing required fields" });
4473
+ return res.status(400).json({ error: customError ?? serverT({ en: "Missing required fields", fr: "Champs requis manquants" }) });
4438
4474
  }
4439
4475
  const id = String(meta["id"]);
4440
4476
  const destination = body["destination"] ?? "user";
4441
4477
  const effectiveProjectDir = resolveProjectDir(req, projectDir);
4442
4478
  if (destination === "project" && !effectiveProjectDir) {
4443
- return res.status(400).json({ error: "No project directory configured" });
4479
+ return res.status(400).json({ error: serverT({ en: "No project directory configured", fr: "Aucun r\xE9pertoire de projet configur\xE9" }) });
4444
4480
  }
4445
4481
  const exists = await config3.exists(configDir, id, effectiveProjectDir);
4446
4482
  if (exists) {
4447
- return res.status(409).json({ error: "An item with this ID already exists" });
4483
+ return res.status(409).json({
4484
+ error: serverT({ en: "An item with this ID already exists", fr: "Un \xE9l\xE9ment avec cet ID existe d\xE9j\xE0" })
4485
+ });
4448
4486
  }
4449
4487
  if (destination === "project") {
4450
4488
  await config3.saveToProject(effectiveProjectDir, body);
@@ -4459,7 +4497,7 @@ function createCrudRoutes(config3, configDir, projectDir) {
4459
4497
  const items = await config3.loadAll(configDir, effectiveProjectDir);
4460
4498
  const existing = config3.findById(id, items);
4461
4499
  if (!existing) {
4462
- return res.status(404).json({ error: "Not found" });
4500
+ return res.status(404).json({ error: serverT({ en: "Not found", fr: "Introuvable" }) });
4463
4501
  }
4464
4502
  const body = req.body;
4465
4503
  const meta = body["metadata"];
@@ -4485,7 +4523,7 @@ function createCrudRoutes(config3, configDir, projectDir) {
4485
4523
  const result = target === "project" ? await config3.deleteProject(effectiveProjectDir, id) : await config3.delete(configDir, id);
4486
4524
  if (!result.success) {
4487
4525
  return res.status(target === "project" ? 500 : 403).json({
4488
- error: target === "project" ? "Failed to delete project item" : result.reason ?? "Cannot delete this item"
4526
+ error: target === "project" ? serverT({ en: "Failed to delete project item", fr: "\xC9chec de suppression de l\u2019\xE9l\xE9ment de projet" }) : result.reason ?? serverT({ en: "Cannot delete this item", fr: "Impossible de supprimer cet \xE9l\xE9ment" })
4489
4527
  });
4490
4528
  }
4491
4529
  res.json({ success: true });
@@ -4496,7 +4534,7 @@ function createCrudRoutes(config3, configDir, projectDir) {
4496
4534
  const items = await config3.loadAll(configDir, effectiveProjectDir);
4497
4535
  const source = config3.findById(id, items);
4498
4536
  if (!source) {
4499
- return res.status(404).json({ error: "Not found" });
4537
+ return res.status(404).json({ error: serverT({ en: "Not found", fr: "Introuvable" }) });
4500
4538
  }
4501
4539
  const newId = `${id}-copy-${Date.now()}`;
4502
4540
  const duplicated = {
@@ -4505,14 +4543,16 @@ function createCrudRoutes(config3, configDir, projectDir) {
4505
4543
  };
4506
4544
  const destination = req.body.destination ?? "user";
4507
4545
  if (destination === "project") {
4508
- if (!effectiveProjectDir) return res.status(400).json({ error: "No project directory configured" });
4546
+ if (!effectiveProjectDir)
4547
+ return res.status(400).json({
4548
+ error: serverT({ en: "No project directory configured", fr: "Aucun r\xE9pertoire de projet configur\xE9" })
4549
+ });
4509
4550
  await config3.saveToProject(effectiveProjectDir, duplicated);
4510
4551
  } else {
4511
4552
  await config3.save(configDir, duplicated);
4512
4553
  }
4513
4554
  res.status(201).json(duplicated);
4514
4555
  });
4515
- config3.extraRoutes?.(router);
4516
4556
  return router;
4517
4557
  }
4518
4558
 
@@ -4619,13 +4659,16 @@ function createSkillRoutes(configDir, projectDir) {
4619
4659
  const router = Router2();
4620
4660
  router.put("/library", async (req, res) => {
4621
4661
  const path = req.body.path;
4622
- if (typeof path !== "string" || !path.trim()) return res.status(400).json({ error: "path is required" });
4662
+ if (typeof path !== "string" || !path.trim())
4663
+ return res.status(400).json({ error: serverT({ en: "path is required", fr: "path est requis" }) });
4623
4664
  try {
4624
4665
  const selected = await resolveLibrary(path);
4625
4666
  setSetting(SKILL_DIRECTORIES_SETTING, JSON.stringify([path]));
4626
4667
  res.json(selected);
4627
4668
  } catch (error) {
4628
- res.status(400).json({ error: error instanceof Error ? error.message : "Cannot use directory" });
4669
+ res.status(400).json({
4670
+ error: error instanceof Error ? error.message : serverT({ en: "Cannot use directory", fr: "Impossible d\u2019utiliser ce r\xE9pertoire" })
4671
+ });
4629
4672
  }
4630
4673
  });
4631
4674
  router.delete("/library", (_req, res) => {
@@ -4643,10 +4686,16 @@ function createSkillRoutes(configDir, projectDir) {
4643
4686
  const paths = JSON.parse(String(req.body["paths"] ?? "[]"));
4644
4687
  const files = req.files;
4645
4688
  if (!Array.isArray(paths) || paths.length !== files.length || paths.some((path) => typeof path !== "string")) {
4646
- return res.status(400).json({ error: "File path manifest does not match upload" });
4689
+ return res.status(400).json({
4690
+ error: serverT({
4691
+ en: "File path manifest does not match upload",
4692
+ fr: "Le manifeste des chemins de fichiers ne correspond pas \xE0 l\u2019envoi"
4693
+ })
4694
+ });
4647
4695
  }
4648
4696
  const totalBytes = files.reduce((total, file) => total + file.size, 0);
4649
- if (totalBytes > 50 * 1024 * 1024) return res.status(413).json({ error: "Package exceeds 50 MiB" });
4697
+ if (totalBytes > 50 * 1024 * 1024)
4698
+ return res.status(413).json({ error: serverT({ en: "Package exceeds 50 MiB", fr: "Le paquet d\xE9passe 50 Mio" }) });
4650
4699
  const installed = await installSkillPackage(
4651
4700
  library.resolvedPath,
4652
4701
  packageName,
@@ -4655,29 +4704,35 @@ function createSkillRoutes(configDir, projectDir) {
4655
4704
  res.status(201).json(installed);
4656
4705
  } catch (error) {
4657
4706
  const status = error instanceof SkillInstallError ? error.status : 400;
4658
- res.status(status).json({ error: error instanceof Error ? error.message : "Install failed" });
4707
+ res.status(status).json({
4708
+ error: error instanceof Error ? error.message : serverT({ en: "Install failed", fr: "\xC9chec de l\u2019installation" })
4709
+ });
4659
4710
  }
4660
4711
  });
4661
4712
  });
4662
4713
  router.post("/:id/toggle", async (req, res) => {
4663
4714
  const existing = await findSkillByIdForRequest(req, configDir, projectDir);
4664
- if (!existing) return res.status(404).json({ error: "Not found" });
4715
+ if (!existing) return res.status(404).json({ error: serverT({ en: "Not found", fr: "Introuvable" }) });
4665
4716
  const enabled = !isSkillEnabled(existing.metadata.id);
4666
4717
  setSkillEnabled(existing.metadata.id, enabled);
4667
4718
  res.json({ enabled });
4668
4719
  });
4669
4720
  router.put("/:id", async (req, res) => {
4670
4721
  const existing = await findSkillByIdForRequest(req, configDir, projectDir);
4671
- if (!existing) return res.status(404).json({ error: "Not found" });
4722
+ if (!existing) return res.status(404).json({ error: serverT({ en: "Not found", fr: "Introuvable" }) });
4672
4723
  const updated = await updateOwnedSkill(existing, req.body);
4673
- if (!updated) return res.status(403).json({ error: "This skill is read-only" });
4724
+ if (!updated)
4725
+ return res.status(403).json({ error: serverT({ en: "This skill is read-only", fr: "Cette comp\xE9tence est en lecture seule" }) });
4674
4726
  res.json(updated);
4675
4727
  });
4676
4728
  router.delete("/:id", async (req, res) => {
4677
4729
  const existing = await findSkillByIdForRequest(req, configDir, projectDir);
4678
- if (!existing) return res.status(404).json({ error: "Not found" });
4730
+ if (!existing) return res.status(404).json({ error: serverT({ en: "Not found", fr: "Introuvable" }) });
4679
4731
  const result = await deleteOwnedSkill(existing);
4680
- if (!result.success) return res.status(403).json({ error: result.reason ?? "Cannot delete this skill" });
4732
+ if (!result.success)
4733
+ return res.status(403).json({
4734
+ error: result.reason ?? serverT({ en: "Cannot delete this skill", fr: "Impossible de supprimer cette comp\xE9tence" })
4735
+ });
4681
4736
  res.json({ success: true });
4682
4737
  });
4683
4738
  router.use(createCrudRoutes(createConfig(configDir, projectDir), configDir, projectDir));
@@ -4761,7 +4816,12 @@ var config2 = {
4761
4816
  const { id } = req.params;
4762
4817
  const { providerId, model, reasoningEffort } = req.body;
4763
4818
  if (reasoningEffort !== void 0 && !isReasoningEffortValue(reasoningEffort)) {
4764
- return res.status(400).json({ error: `Unsupported reasoningEffort: ${reasoningEffort}` });
4819
+ return res.status(400).json({
4820
+ error: serverT(
4821
+ { en: "Unsupported reasoningEffort: {{value}}", fr: "reasoningEffort non pris en charge : {{value}}" },
4822
+ { value: String(reasoningEffort) }
4823
+ )
4824
+ });
4765
4825
  }
4766
4826
  if (providerId && model) {
4767
4827
  setAgentModelOverride(id, {
@@ -5589,7 +5649,7 @@ function createDevServerRoutes() {
5589
5649
  const router = Router5();
5590
5650
  router.get("/", async (req, res) => {
5591
5651
  const workdir = req.query["workdir"];
5592
- if (!workdir) return res.status(400).json({ error: "workdir required" });
5652
+ if (!workdir) return res.status(400).json({ error: serverT({ en: "workdir required", fr: "workdir requis" }) });
5593
5653
  const status = devServerManager.getStatus(workdir);
5594
5654
  if (!status.config) {
5595
5655
  const config3 = await devServerManager.loadConfig(workdir);
@@ -5603,37 +5663,41 @@ function createDevServerRoutes() {
5603
5663
  });
5604
5664
  router.post("/start", async (req, res) => {
5605
5665
  const workdir = req.query["workdir"];
5606
- if (!workdir) return res.status(400).json({ error: "workdir required" });
5666
+ if (!workdir) return res.status(400).json({ error: serverT({ en: "workdir required", fr: "workdir requis" }) });
5607
5667
  try {
5608
5668
  const status = await devServerManager.start(workdir);
5609
5669
  res.json(status);
5610
5670
  } catch (err) {
5611
- res.status(500).json({ error: err instanceof Error ? err.message : "Failed to start" });
5671
+ res.status(500).json({
5672
+ error: err instanceof Error ? err.message : serverT({ en: "Failed to start", fr: "\xC9chec du d\xE9marrage" })
5673
+ });
5612
5674
  }
5613
5675
  });
5614
5676
  router.post("/stop", async (req, res) => {
5615
5677
  const workdir = req.query["workdir"];
5616
- if (!workdir) return res.status(400).json({ error: "workdir required" });
5678
+ if (!workdir) return res.status(400).json({ error: serverT({ en: "workdir required", fr: "workdir requis" }) });
5617
5679
  try {
5618
5680
  const status = await devServerManager.stop(workdir);
5619
5681
  res.json(status);
5620
5682
  } catch (err) {
5621
- res.status(500).json({ error: err instanceof Error ? err.message : "Failed to stop" });
5683
+ res.status(500).json({ error: err instanceof Error ? err.message : serverT({ en: "Failed to stop", fr: "\xC9chec de l\u2019arr\xEAt" }) });
5622
5684
  }
5623
5685
  });
5624
5686
  router.post("/restart", async (req, res) => {
5625
5687
  const workdir = req.query["workdir"];
5626
- if (!workdir) return res.status(400).json({ error: "workdir required" });
5688
+ if (!workdir) return res.status(400).json({ error: serverT({ en: "workdir required", fr: "workdir requis" }) });
5627
5689
  try {
5628
5690
  const status = await devServerManager.restart(workdir);
5629
5691
  res.json(status);
5630
5692
  } catch (err) {
5631
- res.status(500).json({ error: err instanceof Error ? err.message : "Failed to restart" });
5693
+ res.status(500).json({
5694
+ error: err instanceof Error ? err.message : serverT({ en: "Failed to restart", fr: "\xC9chec du red\xE9marrage" })
5695
+ });
5632
5696
  }
5633
5697
  });
5634
5698
  router.get("/logs", (req, res) => {
5635
5699
  const workdir = req.query["workdir"];
5636
- if (!workdir) return res.status(400).json({ error: "workdir required" });
5700
+ if (!workdir) return res.status(400).json({ error: serverT({ en: "workdir required", fr: "workdir requis" }) });
5637
5701
  const offset = Math.max(0, parseInt(req.query["offset"]) || 0);
5638
5702
  const limit = Math.max(1, parseInt(req.query["limit"]) || Infinity);
5639
5703
  const result = devServerManager.getLogsSlice(workdir, offset, limit);
@@ -5641,43 +5705,51 @@ function createDevServerRoutes() {
5641
5705
  });
5642
5706
  router.post("/clear-logs", (req, res) => {
5643
5707
  const workdir = req.query["workdir"];
5644
- if (!workdir) return res.status(400).json({ error: "workdir required" });
5708
+ if (!workdir) return res.status(400).json({ error: serverT({ en: "workdir required", fr: "workdir requis" }) });
5645
5709
  try {
5646
5710
  devServerManager.clearLogs(workdir);
5647
5711
  res.json({ ok: true });
5648
5712
  } catch (err) {
5649
- res.status(500).json({ error: err instanceof Error ? err.message : "Failed to clear logs" });
5713
+ res.status(500).json({
5714
+ error: err instanceof Error ? err.message : serverT({ en: "Failed to clear logs", fr: "\xC9chec de l\u2019effacement des journaux" })
5715
+ });
5650
5716
  }
5651
5717
  });
5652
5718
  router.post("/insert-marker", (req, res) => {
5653
5719
  const workdir = req.query["workdir"];
5654
- if (!workdir) return res.status(400).json({ error: "workdir required" });
5720
+ if (!workdir) return res.status(400).json({ error: serverT({ en: "workdir required", fr: "workdir requis" }) });
5655
5721
  try {
5656
5722
  devServerManager.insertMarker(workdir);
5657
5723
  res.json({ ok: true });
5658
5724
  } catch (err) {
5659
- res.status(500).json({ error: err instanceof Error ? err.message : "Failed to insert marker" });
5725
+ res.status(500).json({
5726
+ error: err instanceof Error ? err.message : serverT({ en: "Failed to insert marker", fr: "\xC9chec de l\u2019insertion du marqueur" })
5727
+ });
5660
5728
  }
5661
5729
  });
5662
5730
  router.get("/config", async (req, res) => {
5663
5731
  const workdir = req.query["workdir"];
5664
- if (!workdir) return res.status(400).json({ error: "workdir required" });
5732
+ if (!workdir) return res.status(400).json({ error: serverT({ en: "workdir required", fr: "workdir requis" }) });
5665
5733
  const config3 = await devServerManager.loadConfig(workdir);
5666
5734
  res.json({ config: config3 });
5667
5735
  });
5668
5736
  router.post("/config", async (req, res) => {
5669
5737
  const workdir = req.query["workdir"];
5670
- if (!workdir) return res.status(400).json({ error: "workdir required" });
5738
+ if (!workdir) return res.status(400).json({ error: serverT({ en: "workdir required", fr: "workdir requis" }) });
5671
5739
  const { command, url, hotReload, disableInspect } = req.body;
5672
5740
  if (!command || !url) {
5673
- return res.status(400).json({ error: "command and url are required" });
5741
+ return res.status(400).json({
5742
+ error: serverT({ en: "command and url are required", fr: "command et url sont requis" })
5743
+ });
5674
5744
  }
5675
5745
  try {
5676
5746
  const config3 = { command, url, hotReload: hotReload ?? false, disableInspect: disableInspect ?? false };
5677
5747
  await devServerManager.saveConfig(workdir, config3);
5678
5748
  res.json({ config: config3 });
5679
5749
  } catch (err) {
5680
- res.status(500).json({ error: err instanceof Error ? err.message : "Failed to save config" });
5750
+ res.status(500).json({
5751
+ error: err instanceof Error ? err.message : serverT({ en: "Failed to save config", fr: "\xC9chec de l\u2019enregistrement de la configuration" })
5752
+ });
5681
5753
  }
5682
5754
  });
5683
5755
  return router;
@@ -5756,7 +5828,37 @@ async function checkDirExists(path) {
5756
5828
  }
5757
5829
  async function validatePathWritable(path) {
5758
5830
  if (await isWritable(path)) return null;
5759
- return "Workspace root directory exists but is not writable";
5831
+ return serverT({
5832
+ en: "Workspace root directory exists but is not writable",
5833
+ fr: "Le r\xE9pertoire racine du workspace existe mais n\u2019est pas accessible en \xE9criture"
5834
+ });
5835
+ }
5836
+ function rootDirBlockError(blockReason, displayPath, suggestion) {
5837
+ if (blockReason === "exact") {
5838
+ return suggestion ? serverT(
5839
+ {
5840
+ en: 'Cannot use "{{path}}" directly as workspace root. Use a subdirectory like "{{suggestion}}" instead.',
5841
+ fr: "Impossible d\u2019utiliser \xAB {{path}} \xBB directement comme racine du workspace. Utilisez plut\xF4t un sous-r\xE9pertoire comme \xAB {{suggestion}} \xBB."
5842
+ },
5843
+ { path: displayPath, suggestion }
5844
+ ) : serverT(
5845
+ {
5846
+ en: 'Cannot use "{{path}}" directly as workspace root. Use a subdirectory instead.',
5847
+ fr: "Impossible d\u2019utiliser \xAB {{path}} \xBB directement comme racine du workspace. Utilisez un sous-r\xE9pertoire \xE0 la place."
5848
+ },
5849
+ { path: displayPath }
5850
+ );
5851
+ }
5852
+ if (blockReason === "virtual_fs") {
5853
+ return serverT(
5854
+ {
5855
+ en: 'Cannot use paths under "{{path}}" for workspaces.',
5856
+ fr: "Impossible d\u2019utiliser des chemins sous \xAB {{path}} \xBB pour les workspaces."
5857
+ },
5858
+ { path: displayPath }
5859
+ );
5860
+ }
5861
+ return null;
5760
5862
  }
5761
5863
  async function findOrphanedWorkspaces(dir) {
5762
5864
  const results = [];
@@ -5784,7 +5886,7 @@ function createWorkspaceConfigRoutes(sessionManager) {
5784
5886
  const router = Router6();
5785
5887
  router.get("/config", async (req, res) => {
5786
5888
  const workdir = req.query["workdir"];
5787
- if (!workdir) return res.status(400).json({ error: "workdir required" });
5889
+ if (!workdir) return res.status(400).json({ error: serverT({ en: "workdir required", fr: "workdir requis" }) });
5788
5890
  const config3 = await loadWorkspaceConfig(workdir);
5789
5891
  const project = getProjectByWorkdir(workdir);
5790
5892
  const rootDir = project?.workspaceRootDir ?? void 0;
@@ -5794,16 +5896,28 @@ function createWorkspaceConfigRoutes(sessionManager) {
5794
5896
  });
5795
5897
  router.post("/config", async (req, res) => {
5796
5898
  const workdir = req.query["workdir"];
5797
- if (!workdir) return res.status(400).json({ error: "workdir required" });
5899
+ if (!workdir) return res.status(400).json({ error: serverT({ en: "workdir required", fr: "workdir requis" }) });
5798
5900
  const { setup, rootDir, mcpOverrides } = req.body;
5799
5901
  if (!Array.isArray(setup) && typeof rootDir !== "string" && mcpOverrides === void 0) {
5800
- return res.status(400).json({ error: "At least one of setup, rootDir, or mcpOverrides must be provided" });
5902
+ return res.status(400).json({
5903
+ error: serverT({
5904
+ en: "At least one of setup, rootDir, or mcpOverrides must be provided",
5905
+ fr: "Au moins un de setup, rootDir ou mcpOverrides doit \xEAtre fourni"
5906
+ })
5907
+ });
5801
5908
  }
5802
5909
  if (setup !== void 0 && !Array.isArray(setup)) {
5803
- return res.status(400).json({ error: "setup must be an array of strings" });
5910
+ return res.status(400).json({
5911
+ error: serverT({ en: "setup must be an array of strings", fr: "setup doit \xEAtre un tableau de cha\xEEnes" })
5912
+ });
5804
5913
  }
5805
5914
  if (mcpOverrides !== void 0 && (typeof mcpOverrides !== "object" || mcpOverrides === null || Array.isArray(mcpOverrides))) {
5806
- return res.status(400).json({ error: "mcpOverrides must be an object mapping server names to overrides" });
5915
+ return res.status(400).json({
5916
+ error: serverT({
5917
+ en: "mcpOverrides must be an object mapping server names to overrides",
5918
+ fr: "mcpOverrides doit \xEAtre un objet associant les noms de serveurs \xE0 des surcharges"
5919
+ })
5920
+ });
5807
5921
  }
5808
5922
  const existing = await loadWorkspaceConfig(workdir);
5809
5923
  const config3 = { ...existing };
@@ -5817,12 +5931,8 @@ function createWorkspaceConfigRoutes(sessionManager) {
5817
5931
  const resolvedPath = resolveRootDir(trimmed, workdir);
5818
5932
  const displayPath = formatRootDir(resolvedPath);
5819
5933
  const blockReason = getRootDirBlockReason(resolvedPath);
5820
- if (blockReason === "exact") {
5821
- return res.status(400).json({ error: `Cannot use "${displayPath}" directly as workspace root. Use a subdirectory instead.` });
5822
- }
5823
- if (blockReason === "virtual_fs") {
5824
- return res.status(400).json({ error: `Cannot use paths under "${displayPath}" for workspaces.` });
5825
- }
5934
+ const blockError = rootDirBlockError(blockReason, displayPath);
5935
+ if (blockError) return res.status(400).json({ error: blockError });
5826
5936
  const dirExists = await checkDirExists(resolvedPath);
5827
5937
  if (dirExists) {
5828
5938
  const writableErr = await validatePathWritable(resolvedPath);
@@ -5859,29 +5969,25 @@ function createWorkspaceConfigRoutes(sessionManager) {
5859
5969
  }
5860
5970
  res.json({ config: { ...config3, rootDir: savedRootDir ?? void 0 } });
5861
5971
  } catch (err) {
5862
- res.status(500).json({ error: err instanceof Error ? err.message : "Failed to save config" });
5972
+ res.status(500).json({
5973
+ error: err instanceof Error ? err.message : serverT({ en: "Failed to save config", fr: "\xC9chec de l\u2019enregistrement de la configuration" })
5974
+ });
5863
5975
  }
5864
5976
  });
5865
5977
  router.post("/config/validate", async (req, res) => {
5866
5978
  const { rootDir, workdir, projectName, createIfMissing } = req.body;
5867
5979
  if (!rootDir || typeof rootDir !== "string") {
5868
- return res.status(400).json({ error: "rootDir is required" });
5980
+ return res.status(400).json({ error: serverT({ en: "rootDir is required", fr: "rootDir est requis" }) });
5869
5981
  }
5870
5982
  if (!workdir || typeof workdir !== "string") {
5871
- return res.status(400).json({ error: "workdir is required" });
5983
+ return res.status(400).json({ error: serverT({ en: "workdir is required", fr: "workdir est requis" }) });
5872
5984
  }
5873
5985
  const resolvedPath = resolveRootDir(rootDir, workdir);
5874
5986
  const displayPath = formatRootDir(resolvedPath);
5875
5987
  const blockReason = getRootDirBlockReason(resolvedPath);
5876
- if (blockReason === "exact") {
5877
- const suggestion = typeof projectName === "string" ? suggestRootDirChild(resolvedPath, projectName) : void 0;
5878
- return res.status(400).json({
5879
- error: suggestion ? `Cannot use "${displayPath}" directly as workspace root. Use a subdirectory like "${suggestion}" instead.` : `Cannot use "${displayPath}" directly as workspace root. Use a subdirectory instead.`
5880
- });
5881
- }
5882
- if (blockReason === "virtual_fs") {
5883
- return res.status(400).json({ error: `Cannot use paths under "${displayPath}" for workspaces.` });
5884
- }
5988
+ const suggestion = typeof projectName === "string" ? suggestRootDirChild(resolvedPath, projectName) : void 0;
5989
+ const blockError = rootDirBlockError(blockReason, displayPath, suggestion);
5990
+ if (blockError) return res.status(400).json({ error: blockError });
5885
5991
  let dirExists = await checkDirExists(resolvedPath);
5886
5992
  if (dirExists) {
5887
5993
  const writableErr = await validatePathWritable(resolvedPath);
@@ -5940,7 +6046,7 @@ function createTerminalRoutes() {
5940
6046
  if (success) {
5941
6047
  res.status(204).send();
5942
6048
  } else {
5943
- res.status(404).json({ error: "Terminal not found" });
6049
+ res.status(404).json({ error: serverT({ en: "Terminal not found", fr: "Terminal introuvable" }) });
5944
6050
  }
5945
6051
  });
5946
6052
  router.get("/:id", (req, res) => {
@@ -5949,7 +6055,7 @@ function createTerminalRoutes() {
5949
6055
  if (session) {
5950
6056
  res.json({ id: session.id, workdir: session.workdir });
5951
6057
  } else {
5952
- res.status(404).json({ error: "Terminal not found" });
6058
+ res.status(404).json({ error: serverT({ en: "Terminal not found", fr: "Terminal introuvable" }) });
5953
6059
  }
5954
6060
  });
5955
6061
  return router;
@@ -5983,7 +6089,7 @@ function createDirectoryRoutes() {
5983
6089
  });
5984
6090
  } catch {
5985
6091
  res.status(400).json({
5986
- error: "Cannot read directory",
6092
+ error: serverT({ en: "Cannot read directory", fr: "Impossible de lire le r\xE9pertoire" }),
5987
6093
  current: DEFAULT_BASE_PATH,
5988
6094
  parent: null,
5989
6095
  directories: [],
@@ -6016,7 +6122,7 @@ function createFileSearchRoutes() {
6016
6122
  const results = await searchFiles(query, workdir);
6017
6123
  res.json(results);
6018
6124
  } catch {
6019
- res.status(500).json({ error: "File search failed" });
6125
+ res.status(500).json({ error: serverT({ en: "File search failed", fr: "\xC9chec de la recherche de fichiers" }) });
6020
6126
  }
6021
6127
  });
6022
6128
  return router;
@@ -6121,6 +6227,11 @@ async function checkAuth(req, opts) {
6121
6227
  }
6122
6228
  return true;
6123
6229
  }
6230
+ async function requireAuth(req, res, opts) {
6231
+ if (await checkAuth(req, opts)) return true;
6232
+ res.status(401).json({ error: serverT({ en: "Unauthorized", fr: "Non autoris\xE9" }) });
6233
+ return false;
6234
+ }
6124
6235
  function isDevMode() {
6125
6236
  return process.env["NODE_ENV"] === "development";
6126
6237
  }
@@ -6246,12 +6357,9 @@ function createAutoUpdateRoutes(options = {}) {
6246
6357
  }
6247
6358
  });
6248
6359
  router.post("/", async (req, res) => {
6249
- if (!await checkAuth(req, options)) {
6250
- res.status(401).json({ error: "Unauthorized" });
6251
- return;
6252
- }
6360
+ if (!await requireAuth(req, res, options)) return;
6253
6361
  if (updateInProgress) {
6254
- res.status(409).json({ error: "Update already in progress" });
6362
+ res.status(409).json({ error: serverT({ en: "Update already in progress", fr: "Une mise \xE0 jour est d\xE9j\xE0 en cours" }) });
6255
6363
  return;
6256
6364
  }
6257
6365
  updateInProgress = true;
@@ -6283,20 +6391,19 @@ function createAutoUpdateRoutes(options = {}) {
6283
6391
  const version = versionMatch?.[1] ?? VERSION;
6284
6392
  res.json({ success: true, version, isService });
6285
6393
  } else {
6286
- const error = exitCode === null ? "Update timed out" : stderr || stdout || "Update failed";
6394
+ const error = exitCode === null ? serverT({ en: "Update timed out", fr: "Mise \xE0 jour expir\xE9e" }) : stderr || stdout || serverT({ en: "Update failed", fr: "\xC9chec de la mise \xE0 jour" });
6287
6395
  res.json({ success: false, error, isService });
6288
6396
  }
6289
6397
  } catch (err) {
6290
- res.status(500).json({ error: err instanceof Error ? err.message : "Update failed to start" });
6398
+ res.status(500).json({
6399
+ error: err instanceof Error ? err.message : serverT({ en: "Update failed to start", fr: "\xC9chec du d\xE9marrage de la mise \xE0 jour" })
6400
+ });
6291
6401
  } finally {
6292
6402
  updateInProgress = false;
6293
6403
  }
6294
6404
  });
6295
6405
  router.post("/restart", async (req, res) => {
6296
- if (!await checkAuth(req, options)) {
6297
- res.status(401).json({ error: "Unauthorized" });
6298
- return;
6299
- }
6406
+ if (!await requireAuth(req, res, options)) return;
6300
6407
  try {
6301
6408
  const child = spawn2("openfox service restart", {
6302
6409
  detached: true,
@@ -6307,7 +6414,9 @@ function createAutoUpdateRoutes(options = {}) {
6307
6414
  child.unref();
6308
6415
  res.json({ success: true });
6309
6416
  } catch (err) {
6310
- res.status(500).json({ error: err instanceof Error ? err.message : "Failed to trigger restart" });
6417
+ res.status(500).json({
6418
+ error: err instanceof Error ? err.message : serverT({ en: "Failed to trigger restart", fr: "\xC9chec du d\xE9clenchement du red\xE9marrage" })
6419
+ });
6311
6420
  }
6312
6421
  });
6313
6422
  return router;
@@ -6320,13 +6429,19 @@ function createProviderAuthRoutes(config3, providerManager, registry) {
6320
6429
  function resolveAuthContext(providerId, res) {
6321
6430
  const provider = providerManager.getProviders().find((item) => item.id === providerId);
6322
6431
  if (!provider) {
6323
- res.status(404).json({ error: "Provider not found" });
6432
+ res.status(404).json({ error: serverT({ en: "Provider not found", fr: "Fournisseur introuvable" }) });
6324
6433
  return void 0;
6325
6434
  }
6326
6435
  return { provider, adapter: registry.getAuth(provider.authAdapter) };
6327
6436
  }
6328
6437
  function missingAuthPlugin(provider) {
6329
- return `Missing provider auth plugin: ${provider.authAdapter ?? "unknown"}`;
6438
+ return serverT(
6439
+ {
6440
+ en: "Missing provider auth plugin: {{adapter}}",
6441
+ fr: "Plugin d\u2019authentification du fournisseur manquant : {{adapter}}"
6442
+ },
6443
+ { adapter: provider.authAdapter ?? "unknown" }
6444
+ );
6330
6445
  }
6331
6446
  router.post("/:providerId/login", async (req, res) => {
6332
6447
  const context = resolveAuthContext(req.params.providerId, res);
@@ -6350,7 +6465,12 @@ function createProviderAuthRoutes(config3, providerManager, registry) {
6350
6465
  });
6351
6466
  res.json(challenge);
6352
6467
  } catch (error) {
6353
- res.status(502).json({ error: error instanceof Error ? error.message : "Unable to start provider login" });
6468
+ res.status(502).json({
6469
+ error: error instanceof Error ? error.message : serverT({
6470
+ en: "Unable to start provider login",
6471
+ fr: "Impossible de d\xE9marrer la connexion au fournisseur"
6472
+ })
6473
+ });
6354
6474
  }
6355
6475
  });
6356
6476
  router.get("/:providerId/status", async (req, res) => {
@@ -6587,15 +6707,15 @@ function createPluginRoutes(options) {
6587
6707
  router.post("/install", async (req, res) => {
6588
6708
  const { githubUrl } = req.body;
6589
6709
  if (!githubUrl || typeof githubUrl !== "string") {
6590
- return res.status(400).json({ error: "githubUrl is required" });
6710
+ return res.status(400).json({ error: serverT({ en: "githubUrl is required", fr: "githubUrl est requis" }) });
6591
6711
  }
6592
6712
  const parsed = githubUrl.match(/github\.com\/([^/]+)\/([^/]+?)(?:\/|$)/);
6593
6713
  if (!parsed) {
6594
- return res.status(400).json({ error: "Invalid GitHub URL" });
6714
+ return res.status(400).json({ error: serverT({ en: "Invalid GitHub URL", fr: "URL GitHub invalide" }) });
6595
6715
  }
6596
6716
  const repoName = parsed[2].replace(/\.git$/, "");
6597
6717
  if (!/^[a-zA-Z0-9_-]+$/.test(repoName)) {
6598
- return res.status(400).json({ error: "Invalid repository name" });
6718
+ return res.status(400).json({ error: serverT({ en: "Invalid repository name", fr: "Nom de d\xE9p\xF4t invalide" }) });
6599
6719
  }
6600
6720
  const pluginsDir = join8(getGlobalConfigDir(config3.mode ?? "production"), "plugins");
6601
6721
  const targetDir = join8(pluginsDir, repoName);
@@ -6603,7 +6723,12 @@ function createPluginRoutes(options) {
6603
6723
  try {
6604
6724
  await execFileP("mkdir", ["-p", pluginsDir], { timeout: 5e3 });
6605
6725
  } catch {
6606
- return res.status(500).json({ error: "Failed to create plugins directory" });
6726
+ return res.status(500).json({
6727
+ error: serverT({
6728
+ en: "Failed to create plugins directory",
6729
+ fr: "\xC9chec de la cr\xE9ation du r\xE9pertoire des plugins"
6730
+ })
6731
+ });
6607
6732
  }
6608
6733
  let gitOk = false;
6609
6734
  try {
@@ -6612,7 +6737,12 @@ function createPluginRoutes(options) {
6612
6737
  } catch {
6613
6738
  }
6614
6739
  if (!gitOk) {
6615
- return res.status(500).json({ error: "git is not installed or not found in PATH" });
6740
+ return res.status(500).json({
6741
+ error: serverT({
6742
+ en: "git is not installed or not found in PATH",
6743
+ fr: "git n\u2019est pas install\xE9 ou introuvable dans le PATH"
6744
+ })
6745
+ });
6616
6746
  }
6617
6747
  try {
6618
6748
  const cloneUrl = githubUrl.replace(/\/$/, "") + ".git";
@@ -6625,7 +6755,10 @@ function createPluginRoutes(options) {
6625
6755
  await execFileP("npm", ["install", "--no-audit", "--no-fund"], { cwd: targetDir, timeout: 12e4 });
6626
6756
  await execFileP("npm", ["run", "build"], { cwd: targetDir, timeout: 12e4 });
6627
6757
  } catch (err) {
6628
- loadError = "Failed to install/build plugin dependencies";
6758
+ loadError = serverT({
6759
+ en: "Failed to install/build plugin dependencies",
6760
+ fr: "\xC9chec de l\u2019installation/du build des d\xE9pendances du plugin"
6761
+ });
6629
6762
  logger2.error("Plugin build failed", { repoName, error: String(err) });
6630
6763
  }
6631
6764
  if (!loadError) {
@@ -6634,13 +6767,25 @@ function createPluginRoutes(options) {
6634
6767
  const pluginEntry = manifest.openfox?.plugin;
6635
6768
  const apiVersion = manifest.openfox?.apiVersion;
6636
6769
  if (!pluginEntry || !manifest.name) {
6637
- loadError = "Plugin package.json is missing openfox.plugin or name field";
6770
+ loadError = serverT({
6771
+ en: "Plugin package.json is missing openfox.plugin or name field",
6772
+ fr: "Le package.json du plugin ne contient pas le champ openfox.plugin ou name"
6773
+ });
6638
6774
  } else if (apiVersion !== 1) {
6639
- loadError = `Unsupported plugin API version: ${String(apiVersion)}`;
6775
+ loadError = serverT(
6776
+ {
6777
+ en: "Unsupported plugin API version: {{version}}",
6778
+ fr: "Version d\u2019API de plugin non prise en charge : {{version}}"
6779
+ },
6780
+ { version: String(apiVersion) }
6781
+ );
6640
6782
  } else {
6641
6783
  const mod = await import(pathToFileURL2(join8(targetDir, pluginEntry)).href);
6642
6784
  if (typeof mod.register !== "function") {
6643
- loadError = "Plugin does not export register(registry)";
6785
+ loadError = serverT({
6786
+ en: "Plugin does not export register(registry)",
6787
+ fr: "Le plugin n\u2019exporte pas register(registry)"
6788
+ });
6644
6789
  } else {
6645
6790
  const diagnostic = {
6646
6791
  packageName: manifest.name,
@@ -6674,14 +6819,14 @@ function createPluginRoutes(options) {
6674
6819
  }
6675
6820
  }
6676
6821
  } catch (err) {
6677
- loadError = err instanceof Error ? err.message : "Failed to load plugin";
6822
+ loadError = err instanceof Error ? err.message : serverT({ en: "Failed to load plugin", fr: "\xC9chec du chargement du plugin" });
6678
6823
  logger2.error("Plugin runtime load failed", { repoName, error: loadError });
6679
6824
  }
6680
6825
  }
6681
6826
  res.json({ success: true, loaded, loadError, path: targetDir });
6682
6827
  } catch (err) {
6683
6828
  await rm2(tmpDir, { recursive: true, force: true });
6684
- const msg = err instanceof Error ? err.message : "Clone failed";
6829
+ const msg = err instanceof Error ? err.message : serverT({ en: "Clone failed", fr: "\xC9chec du clonage" });
6685
6830
  logger2.error("Plugin install failed", { githubUrl, error: msg });
6686
6831
  res.status(500).json({ error: msg });
6687
6832
  }
@@ -6713,14 +6858,15 @@ function createPluginRoutes(options) {
6713
6858
  });
6714
6859
  router.get("/:name/open-folder", async (req, res) => {
6715
6860
  const name = req.params.name;
6716
- if (!/^[a-zA-Z0-9_-]+$/.test(name)) return res.status(400).json({ error: "Invalid plugin name" });
6861
+ if (!/^[a-zA-Z0-9_-]+$/.test(name))
6862
+ return res.status(400).json({ error: serverT({ en: "Invalid plugin name", fr: "Nom de plugin invalide" }) });
6717
6863
  const targetDir = join8(getGlobalConfigDir(config3.mode ?? "production"), "plugins", name);
6718
6864
  await openFolderRoute(targetDir, res);
6719
6865
  });
6720
6866
  router.delete("/:name", async (req, res) => {
6721
6867
  const name = req.params.name;
6722
6868
  if (!/^[a-zA-Z0-9_-]+$/.test(name)) {
6723
- return res.status(400).json({ error: "Invalid plugin name" });
6869
+ return res.status(400).json({ error: serverT({ en: "Invalid plugin name", fr: "Nom de plugin invalide" }) });
6724
6870
  }
6725
6871
  const targetDir = join8(getGlobalConfigDir(config3.mode ?? "production"), "plugins", name);
6726
6872
  try {
@@ -6730,7 +6876,9 @@ function createPluginRoutes(options) {
6730
6876
  }
6731
6877
  res.json({ success: true });
6732
6878
  } catch (err) {
6733
- res.status(500).json({ error: err instanceof Error ? err.message : "Failed to remove plugin" });
6879
+ res.status(500).json({
6880
+ error: err instanceof Error ? err.message : serverT({ en: "Failed to remove plugin", fr: "\xC9chec de la suppression du plugin" })
6881
+ });
6734
6882
  }
6735
6883
  });
6736
6884
  return router;
@@ -6743,11 +6891,16 @@ function registerSessionFavoriteRoute(router, sessionManager) {
6743
6891
  const id = req.params["id"];
6744
6892
  const { isFavorite } = req.body;
6745
6893
  if (typeof isFavorite !== "boolean") {
6746
- return res.status(400).json({ error: "isFavorite is required and must be a boolean" });
6894
+ return res.status(400).json({
6895
+ error: serverT({
6896
+ en: "isFavorite is required and must be a boolean",
6897
+ fr: "isFavorite est requis et doit \xEAtre un bool\xE9en"
6898
+ })
6899
+ });
6747
6900
  }
6748
6901
  const session = sessionManager.getSession(id);
6749
6902
  if (!session) {
6750
- return res.status(404).json({ error: "Session not found" });
6903
+ return res.status(404).json({ error: serverT({ en: "Session not found", fr: "Session introuvable" }) });
6751
6904
  }
6752
6905
  toggleFavorite(id, isFavorite);
6753
6906
  res.json({ success: true });
@@ -6804,7 +6957,7 @@ function detectWsl() {
6804
6957
  // src/server/index.ts
6805
6958
  var __dirname3 = dirname7(fileURLToPath6(import.meta.url));
6806
6959
  async function announceContextDrift(sessionManager, sessionIds) {
6807
- const { injectContextDriftRemindersForSessions } = await import("./dynamic-context-NJZKAZE3.js");
6960
+ const { injectContextDriftRemindersForSessions } = await import("./dynamic-context-WKEXQCTK.js");
6808
6961
  await injectContextDriftRemindersForSessions(sessionManager, sessionIds);
6809
6962
  }
6810
6963
  async function createServerHandle(config3) {
@@ -6911,7 +7064,7 @@ async function createServerHandle(config3) {
6911
7064
  toolRegistry = createToolRegistry();
6912
7065
  logger.info("MCP tools registered", { count: mcpTools.length });
6913
7066
  }
6914
- const { signalMcpReady } = await import("./server-WPWUYB6I.js");
7067
+ const { signalMcpReady } = await import("./server-3UVLECD5.js");
6915
7068
  signalMcpReady();
6916
7069
  });
6917
7070
  const app = express();
@@ -7022,9 +7175,9 @@ async function createServerHandle(config3) {
7022
7175
  if (!name || !workdir) {
7023
7176
  return res.status(400).json({ error: "name and workdir are required" });
7024
7177
  }
7025
- const { createDirectoryWithGit } = await import("./project-creator-6AGQTNXB.js");
7178
+ const { createProjectDirectory } = await import("./project-creator-T3A4H3YV.js");
7026
7179
  try {
7027
- const project = await createDirectoryWithGit(name, workdir);
7180
+ const project = await createProjectDirectory(name, workdir);
7028
7181
  res.status(201).json({ project });
7029
7182
  } catch (err) {
7030
7183
  const eaccError = err;
@@ -7126,9 +7279,9 @@ async function createServerHandle(config3) {
7126
7279
  const sessionFavoriteRouter = express.Router();
7127
7280
  registerSessionFavoriteRoute(sessionFavoriteRouter, sessionManager);
7128
7281
  app.use("/api", sessionFavoriteRouter);
7129
- const { createTasksService } = await import("./service-O3LCO3TQ.js");
7130
- const { registerTaskRoutes } = await import("./tasks-WOC3QUFA.js");
7131
- const { setTasksService } = await import("./tools-CW6POKUL.js");
7282
+ const { createTasksService } = await import("./service-XIUNS5XV.js");
7283
+ const { registerTaskRoutes } = await import("./tasks-3JJWJJ3X.js");
7284
+ const { setTasksService } = await import("./tools-WWIWD3O7.js");
7132
7285
  const tasksService = createTasksService({
7133
7286
  sessionManager,
7134
7287
  config: config3,
@@ -7160,7 +7313,7 @@ async function createServerHandle(config3) {
7160
7313
  }
7161
7314
  try {
7162
7315
  await checkoutBranch(project.workdir, branch);
7163
- const { updateSessionBranch: updateSessionBranch2 } = await import("./sessions-NMPX5ICI.js");
7316
+ const { updateSessionBranch: updateSessionBranch2 } = await import("./sessions-IGINPPBP.js");
7164
7317
  const allSessions = sessionManager.listSessions();
7165
7318
  for (const s of allSessions) {
7166
7319
  if (sessionManager.getEffectiveWorkdir(s.id) === project.workdir) {
@@ -7196,7 +7349,7 @@ async function createServerHandle(config3) {
7196
7349
  );
7197
7350
  }
7198
7351
  await createBranch(project.workdir, name, sb);
7199
- const { updateSessionBranch: updateSessionBranch2 } = await import("./sessions-NMPX5ICI.js");
7352
+ const { updateSessionBranch: updateSessionBranch2 } = await import("./sessions-IGINPPBP.js");
7200
7353
  const allSessions = sessionManager.listSessions();
7201
7354
  for (const s of allSessions) {
7202
7355
  if (sessionManager.getEffectiveWorkdir(s.id) === project.workdir) {
@@ -7228,7 +7381,7 @@ async function createServerHandle(config3) {
7228
7381
  if (!branch || typeof branch !== "string") return res.status(400).json({ error: "branch is required" });
7229
7382
  const effectiveWorkdir = sessionManager.getEffectiveWorkdir(req.params.id);
7230
7383
  const { checkoutBranch, validateRef: validateRef2 } = await import("./workspace-LM646OHC.js");
7231
- const { updateSessionBranch: updateSessionBranch2 } = await import("./sessions-NMPX5ICI.js");
7384
+ const { updateSessionBranch: updateSessionBranch2 } = await import("./sessions-IGINPPBP.js");
7232
7385
  try {
7233
7386
  await validateRef2(effectiveWorkdir, branch);
7234
7387
  await checkoutBranch(effectiveWorkdir, branch);
@@ -7271,7 +7424,7 @@ All file and git operations should use this branch.
7271
7424
  if (!name || typeof name !== "string") return res.status(400).json({ error: "name is required" });
7272
7425
  const effectiveWorkdir = sessionManager.getEffectiveWorkdir(req.params.id);
7273
7426
  const { validateRef: validateRef2 } = await import("./workspace-LM646OHC.js");
7274
- const { updateSessionBranch: updateSessionBranch2 } = await import("./sessions-NMPX5ICI.js");
7427
+ const { updateSessionBranch: updateSessionBranch2 } = await import("./sessions-IGINPPBP.js");
7275
7428
  try {
7276
7429
  await validateRef2(effectiveWorkdir, name);
7277
7430
  if (sourceBranch) {
@@ -7326,8 +7479,8 @@ All file and git operations should use this branch.
7326
7479
  res.json({ workspaces: workspacesList });
7327
7480
  });
7328
7481
  app.get("/api/sessions", async (req, res) => {
7329
- const { getRecentUserPromptsForSession } = await import("./events-ZJPRGVL2.js");
7330
- const { getPendingConfirmationsBySession: getPendingConfirmationsBySession2 } = await import("./path-security-CBACXAMS.js");
7482
+ const { getRecentUserPromptsForSession } = await import("./events-3WSNI7XC.js");
7483
+ const { getPendingConfirmationsBySession: getPendingConfirmationsBySession2 } = await import("./path-security-5CFMMULR.js");
7331
7484
  const projectId = req.query["projectId"];
7332
7485
  const rawLimit = req.query["limit"];
7333
7486
  const offset = parseInt(req.query["offset"]) || 0;
@@ -7382,7 +7535,7 @@ All file and git operations should use this branch.
7382
7535
  disabledServers = mcpManager.getAllServers().filter((s) => s.config.disabled).map((s) => s.name);
7383
7536
  }
7384
7537
  if (disabledServers.length > 0) {
7385
- const { setSessionDisabledServers: setSessionDisabledServers2 } = await import("./session-overrides-OECQYRDK.js");
7538
+ const { setSessionDisabledServers: setSessionDisabledServers2 } = await import("./session-overrides-Y5B4XQPU.js");
7386
7539
  setSessionDisabledServers2(session.id, disabledServers);
7387
7540
  }
7388
7541
  } catch {
@@ -7455,10 +7608,10 @@ All file and git operations should use this branch.
7455
7608
  }
7456
7609
  });
7457
7610
  app.get("/api/sessions/:id", async (req, res) => {
7458
- const { getEventStore: getEventStore2, combineEventsWithSnapshot: combineEventsWithSnapshot2 } = await import("./events-ZJPRGVL2.js");
7459
- const { buildMessagesFromStoredEvents: buildMessagesFromStoredEvents2, foldPendingConfirmations } = await import("./folding-QRZOHY2I.js");
7460
- const { getPendingQuestionsForSession: getPendingQuestionsForSession2 } = await import("./tools-CW6POKUL.js");
7461
- const { getMaxVisibleItems } = await import("./settings-MDCRNQBY.js");
7611
+ const { getEventStore: getEventStore2, combineEventsWithSnapshot: combineEventsWithSnapshot2 } = await import("./events-3WSNI7XC.js");
7612
+ const { buildMessagesFromStoredEvents: buildMessagesFromStoredEvents2, foldPendingConfirmations } = await import("./folding-H7JTX6KI.js");
7613
+ const { getPendingQuestionsForSession: getPendingQuestionsForSession2 } = await import("./tools-WWIWD3O7.js");
7614
+ const { getMaxVisibleItems } = await import("./settings-ZJPM6PQV.js");
7462
7615
  const session = sessionManager.getSession(req.params.id);
7463
7616
  if (!session) {
7464
7617
  return res.status(404).json({ error: "Session not found" });
@@ -7486,9 +7639,9 @@ All file and git operations should use this branch.
7486
7639
  });
7487
7640
  app.get("/api/sessions/:id/status", async (req, res) => {
7488
7641
  const { projectSessionStatus: projectSessionStatus2 } = await import("./session-status-UFO5IFI7.js");
7489
- const { getPendingQuestionsForSession: getPendingQuestionsForSession2 } = await import("./tools-CW6POKUL.js");
7490
- const { getEventStore: getEventStore2, combineEventsWithSnapshot: combineEventsWithSnapshot2 } = await import("./events-ZJPRGVL2.js");
7491
- const { foldPendingConfirmations } = await import("./folding-QRZOHY2I.js");
7642
+ const { getPendingQuestionsForSession: getPendingQuestionsForSession2 } = await import("./tools-WWIWD3O7.js");
7643
+ const { getEventStore: getEventStore2, combineEventsWithSnapshot: combineEventsWithSnapshot2 } = await import("./events-3WSNI7XC.js");
7644
+ const { foldPendingConfirmations } = await import("./folding-H7JTX6KI.js");
7492
7645
  const sessionId = req.params["id"];
7493
7646
  if (!sessionId) {
7494
7647
  return res.status(400).json({ error: "Session id is required" });
@@ -7518,8 +7671,8 @@ All file and git operations should use this branch.
7518
7671
  if (!session) {
7519
7672
  return res.status(404).json({ error: "Session not found" });
7520
7673
  }
7521
- const { stopSessionExecution } = await import("./chat-handler-T47GATL5.js");
7522
- const { cancelQuestionsForSession, cancelPathConfirmationsForSession } = await import("./tools-CW6POKUL.js");
7674
+ const { stopSessionExecution } = await import("./chat-handler-YCZE2XEJ.js");
7675
+ const { cancelQuestionsForSession, cancelPathConfirmationsForSession } = await import("./tools-WWIWD3O7.js");
7523
7676
  sessionManager.clearMessageQueue(sessionId);
7524
7677
  stopSessionExecution(sessionId, sessionManager);
7525
7678
  abortSession(sessionId);
@@ -7548,9 +7701,9 @@ All file and git operations should use this branch.
7548
7701
  res.json({ success: true });
7549
7702
  });
7550
7703
  app.post("/api/sessions/:id/provider", async (req, res) => {
7551
- const { getEventStore: getEventStore2, combineEventsWithSnapshot: combineEv } = await import("./events-ZJPRGVL2.js");
7552
- const { buildMessagesFromStoredEvents: buildMessagesFromStoredEvents2 } = await import("./folding-QRZOHY2I.js");
7553
- const { getMaxVisibleItems } = await import("./settings-MDCRNQBY.js");
7704
+ const { getEventStore: getEventStore2, combineEventsWithSnapshot: combineEv } = await import("./events-3WSNI7XC.js");
7705
+ const { buildMessagesFromStoredEvents: buildMessagesFromStoredEvents2 } = await import("./folding-H7JTX6KI.js");
7706
+ const { getMaxVisibleItems } = await import("./settings-ZJPM6PQV.js");
7554
7707
  const sessionId = req.params.id;
7555
7708
  const session = sessionManager.getSession(sessionId);
7556
7709
  if (!session) {
@@ -7578,9 +7731,9 @@ All file and git operations should use this branch.
7578
7731
  res.json({ session: toClientSession(updatedSession), messages, hiddenCount, contextState });
7579
7732
  });
7580
7733
  app.delete("/api/sessions/:id/provider", async (req, res) => {
7581
- const { getEventStore: getEventStore2, combineEventsWithSnapshot: combineEv } = await import("./events-ZJPRGVL2.js");
7582
- const { buildMessagesFromStoredEvents: buildMessagesFromStoredEvents2 } = await import("./folding-QRZOHY2I.js");
7583
- const { getMaxVisibleItems } = await import("./settings-MDCRNQBY.js");
7734
+ const { getEventStore: getEventStore2, combineEventsWithSnapshot: combineEv } = await import("./events-3WSNI7XC.js");
7735
+ const { buildMessagesFromStoredEvents: buildMessagesFromStoredEvents2 } = await import("./folding-H7JTX6KI.js");
7736
+ const { getMaxVisibleItems } = await import("./settings-ZJPM6PQV.js");
7584
7737
  const sessionId = req.params.id;
7585
7738
  const session = sessionManager.getSession(sessionId);
7586
7739
  if (!session) {
@@ -7710,9 +7863,9 @@ All file and git operations should use this branch.
7710
7863
  res.json({ success: true });
7711
7864
  });
7712
7865
  app.put("/api/sessions/:id/mode", async (req, res) => {
7713
- const { getEventStore: getEventStore2, combineEventsWithSnapshot: combineEv } = await import("./events-ZJPRGVL2.js");
7714
- const { buildMessagesFromStoredEvents: buildMessagesFromStoredEvents2 } = await import("./folding-QRZOHY2I.js");
7715
- const { getMaxVisibleItems } = await import("./settings-MDCRNQBY.js");
7866
+ const { getEventStore: getEventStore2, combineEventsWithSnapshot: combineEv } = await import("./events-3WSNI7XC.js");
7867
+ const { buildMessagesFromStoredEvents: buildMessagesFromStoredEvents2 } = await import("./folding-H7JTX6KI.js");
7868
+ const { getMaxVisibleItems } = await import("./settings-ZJPM6PQV.js");
7716
7869
  const sessionId = req.params.id;
7717
7870
  const session = sessionManager.getSession(sessionId);
7718
7871
  if (!session) {
@@ -7772,7 +7925,7 @@ All file and git operations should use this branch.
7772
7925
  setSessionDisabledServers(sessionId, disabledServers);
7773
7926
  const messages = session.messages ?? [];
7774
7927
  if (messages.length === 0) {
7775
- const { applyDynamicContext } = await import("./dynamic-context-NJZKAZE3.js");
7928
+ const { applyDynamicContext } = await import("./dynamic-context-WKEXQCTK.js");
7776
7929
  const modelName = session.providerModel ?? providerManager.getCurrentModel();
7777
7930
  await applyDynamicContext(sessionManager, sessionId, modelName);
7778
7931
  } else {
@@ -7806,7 +7959,7 @@ All file and git operations should use this branch.
7806
7959
  if (alwaysAllow !== void 0 && typeof alwaysAllow !== "boolean") {
7807
7960
  return res.status(400).json({ error: "alwaysAllow must be a boolean if provided" });
7808
7961
  }
7809
- const { providePathConfirmation: providePathConfirmation2, getConfirmationSessionId } = await import("./tools-CW6POKUL.js");
7962
+ const { providePathConfirmation: providePathConfirmation2, getConfirmationSessionId } = await import("./tools-WWIWD3O7.js");
7810
7963
  const pendingSessionId = getConfirmationSessionId(callId);
7811
7964
  if (!pendingSessionId) {
7812
7965
  return res.status(404).json({ error: "No pending path confirmation with that ID" });
@@ -7818,11 +7971,11 @@ All file and git operations should use this branch.
7818
7971
  if (!result.found) {
7819
7972
  return res.status(404).json({ error: "No pending path confirmation with that ID" });
7820
7973
  }
7821
- const { getEventStore: getEventStore2, combineEventsWithSnapshot: combineEvents } = await import("./events-ZJPRGVL2.js");
7822
- const { buildMessagesFromStoredEvents: buildMessagesFromStoredEvents2, foldPendingConfirmations } = await import("./folding-QRZOHY2I.js");
7823
- const { createSessionStateMessage } = await import("./protocol-Y7MRKRUO.js");
7824
- const { getPendingQuestionsForSession: getPendingQuestionsForSession2 } = await import("./tools-CW6POKUL.js");
7825
- const { getMaxVisibleItems } = await import("./settings-MDCRNQBY.js");
7974
+ const { getEventStore: getEventStore2, combineEventsWithSnapshot: combineEvents } = await import("./events-3WSNI7XC.js");
7975
+ const { buildMessagesFromStoredEvents: buildMessagesFromStoredEvents2, foldPendingConfirmations } = await import("./folding-H7JTX6KI.js");
7976
+ const { createSessionStateMessage } = await import("./protocol-XO4ZROAU.js");
7977
+ const { getPendingQuestionsForSession: getPendingQuestionsForSession2 } = await import("./tools-WWIWD3O7.js");
7978
+ const { getMaxVisibleItems } = await import("./settings-ZJPM6PQV.js");
7826
7979
  const eventStore = getEventStore2();
7827
7980
  const { snapshot, events: eventsSinceSnapshot } = eventStore.getEventsSinceSnapshot(sessionId);
7828
7981
  const events = combineEvents(sessionId, snapshot, eventsSinceSnapshot);
@@ -7859,7 +8012,7 @@ All file and git operations should use this branch.
7859
8012
  if (!skip && typeof answer !== "string") {
7860
8013
  return res.status(400).json({ error: "answer is required when not skipping" });
7861
8014
  }
7862
- const { provideAnswer: provideAnswer2 } = await import("./tools-CW6POKUL.js");
8015
+ const { provideAnswer: provideAnswer2 } = await import("./tools-WWIWD3O7.js");
7863
8016
  const found = provideAnswer2(callId, answer ?? "", skip ?? false);
7864
8017
  if (!found) {
7865
8018
  return res.status(404).json({ error: "No pending question with that ID" });
@@ -7892,7 +8045,7 @@ All file and git operations should use this branch.
7892
8045
  if (!session) {
7893
8046
  return res.status(404).json({ error: "Session not found" });
7894
8047
  }
7895
- const { getSetting: getSetting2, SETTINGS_KEYS } = await import("./settings-MDCRNQBY.js");
8048
+ const { getSetting: getSetting2, SETTINGS_KEYS } = await import("./settings-ZJPM6PQV.js");
7896
8049
  if (getSetting2(SETTINGS_KEYS.CACHE_WARMING) !== "true") {
7897
8050
  return res.json({ success: false, reason: "disabled" });
7898
8051
  }
@@ -7925,7 +8078,7 @@ All file and git operations should use this branch.
7925
8078
  backend: activeProvider?.backend ?? llmClient.getBackend(),
7926
8079
  model: llmClient.getModel()
7927
8080
  };
7928
- const { runAgentTurn, TurnMetrics } = await import("./orchestrator-GX22Y5EM.js");
8081
+ const { runAgentTurn, TurnMetrics } = await import("./orchestrator-OT66EDXO.js");
7929
8082
  runAgentTurn(
7930
8083
  {
7931
8084
  sessionManager,
@@ -7963,15 +8116,15 @@ All file and git operations should use this branch.
7963
8116
  if (!session) {
7964
8117
  return res.status(404).json({ error: "Session not found" });
7965
8118
  }
7966
- const { stopSessionExecution } = await import("./chat-handler-T47GATL5.js");
7967
- const { cancelQuestionsForSession, cancelPathConfirmationsForSession } = await import("./tools-CW6POKUL.js");
8119
+ const { stopSessionExecution } = await import("./chat-handler-YCZE2XEJ.js");
8120
+ const { cancelQuestionsForSession, cancelPathConfirmationsForSession } = await import("./tools-WWIWD3O7.js");
7968
8121
  const queuedMessages = sessionManager.getQueueState(sessionId);
7969
8122
  sessionManager.clearMessageQueue(sessionId);
7970
8123
  stopSessionExecution(sessionId, sessionManager);
7971
8124
  abortSession(sessionId);
7972
8125
  cancelQuestionsForSession(sessionId, "Session stopped by user");
7973
8126
  cancelPathConfirmationsForSession(sessionId, "Session stopped by user");
7974
- const eventStore = (await import("./events-ZJPRGVL2.js")).getEventStore();
8127
+ const eventStore = (await import("./events-3WSNI7XC.js")).getEventStore();
7975
8128
  eventStore.append(sessionId, { type: "running.changed", data: { isRunning: false } });
7976
8129
  res.json({ success: true, queuedMessages });
7977
8130
  });
@@ -7985,7 +8138,7 @@ All file and git operations should use this branch.
7985
8138
  if (typeof messageIndex !== "number" || messageIndex < 0) {
7986
8139
  return res.status(400).json({ error: "messageIndex must be a non-negative number" });
7987
8140
  }
7988
- const { truncateSessionMessages } = await import("./events-ZJPRGVL2.js");
8141
+ const { truncateSessionMessages } = await import("./events-3WSNI7XC.js");
7989
8142
  truncateSessionMessages(sessionId, messageIndex);
7990
8143
  res.json({ success: true });
7991
8144
  });
@@ -8005,8 +8158,8 @@ All file and git operations should use this branch.
8005
8158
  if (attachments !== void 0 && !Array.isArray(attachments)) {
8006
8159
  return res.status(400).json({ error: "attachments must be an array if provided" });
8007
8160
  }
8008
- const { getEventStore: getEventStore2 } = await import("./events-ZJPRGVL2.js");
8009
- const { buildMessagesFromStoredEvents: buildMessagesFromStoredEvents2 } = await import("./folding-QRZOHY2I.js");
8161
+ const { getEventStore: getEventStore2 } = await import("./events-3WSNI7XC.js");
8162
+ const { buildMessagesFromStoredEvents: buildMessagesFromStoredEvents2 } = await import("./folding-H7JTX6KI.js");
8010
8163
  const eventStore = getEventStore2();
8011
8164
  const events = eventStore.getEvents(sessionId);
8012
8165
  const { messages } = buildMessagesFromStoredEvents2(events);
@@ -8018,7 +8171,7 @@ All file and git operations should use this branch.
8018
8171
  if (msg.role !== "user" || msg.isSystemGenerated) {
8019
8172
  return res.status(400).json({ error: "Can only replay user messages" });
8020
8173
  }
8021
- const { truncateSessionMessages } = await import("./events-ZJPRGVL2.js");
8174
+ const { truncateSessionMessages } = await import("./events-3WSNI7XC.js");
8022
8175
  truncateSessionMessages(sessionId, msgIndex - 1);
8023
8176
  sessionManager.queueMessage(
8024
8177
  sessionId,
@@ -8080,7 +8233,7 @@ All file and git operations should use this branch.
8080
8233
  res.json({ accepted: true });
8081
8234
  });
8082
8235
  app.get("/api/settings", async (req, res) => {
8083
- const { getSetting: getSetting2, SETTINGS_DEFAULTS } = await import("./settings-MDCRNQBY.js");
8236
+ const { getSetting: getSetting2, SETTINGS_DEFAULTS } = await import("./settings-ZJPM6PQV.js");
8084
8237
  const keysParam = req.query["keys"];
8085
8238
  if (!keysParam) {
8086
8239
  return res.status(400).json({ error: "keys query parameter is required" });
@@ -8093,19 +8246,19 @@ All file and git operations should use this branch.
8093
8246
  res.json(result);
8094
8247
  });
8095
8248
  app.get("/api/settings/:key", async (req, res) => {
8096
- const { getSetting: getSetting2, SETTINGS_DEFAULTS } = await import("./settings-MDCRNQBY.js");
8249
+ const { getSetting: getSetting2, SETTINGS_DEFAULTS } = await import("./settings-ZJPM6PQV.js");
8097
8250
  const key = req.params.key;
8098
8251
  const value = getSetting2(key) ?? SETTINGS_DEFAULTS[key] ?? null;
8099
8252
  res.json({ key, value });
8100
8253
  });
8101
8254
  app.get("/api/settings/:key", async (req, res) => {
8102
- const { getSetting: getSetting2, SETTINGS_DEFAULTS } = await import("./settings-MDCRNQBY.js");
8255
+ const { getSetting: getSetting2, SETTINGS_DEFAULTS } = await import("./settings-ZJPM6PQV.js");
8103
8256
  const key = req.params.key;
8104
8257
  const value = getSetting2(key) ?? SETTINGS_DEFAULTS[key] ?? null;
8105
8258
  res.json({ key, value });
8106
8259
  });
8107
8260
  app.put("/api/settings/:key", async (req, res) => {
8108
- const { setSetting: setSetting2 } = await import("./settings-MDCRNQBY.js");
8261
+ const { setSetting: setSetting2 } = await import("./settings-ZJPM6PQV.js");
8109
8262
  const key = req.params.key;
8110
8263
  const { value } = req.body;
8111
8264
  if (value === void 0) {
@@ -8132,7 +8285,7 @@ All file and git operations should use this branch.
8132
8285
  }
8133
8286
  });
8134
8287
  app.get("/api/tools/shells", async (_req, res) => {
8135
- const { listAvailableShells } = await import("./platform-5LQXOZO3.js");
8288
+ const { listAvailableShells } = await import("./platform-XPMZKAUB.js");
8136
8289
  res.json({ shells: listAvailableShells() });
8137
8290
  });
8138
8291
  app.get("/api/config", async (_req, res) => {
@@ -8169,7 +8322,8 @@ All file and git operations should use this branch.
8169
8322
  activeProviderId: providerManager.getActiveProviderId(),
8170
8323
  defaultModelSelection: config3.defaultModelSelection,
8171
8324
  visionFallback,
8172
- platform: platformInfo
8325
+ platform: platformInfo,
8326
+ locale: (await import("./settings-ZJPM6PQV.js")).getSetting("display.locale") ?? "automatic"
8173
8327
  });
8174
8328
  });
8175
8329
  app.post("/api/model/refresh", async (_req, res) => {
@@ -8225,7 +8379,7 @@ All file and git operations should use this branch.
8225
8379
  }));
8226
8380
  }
8227
8381
  app.post("/api/proxy/test", async (_req, res) => {
8228
- const { getSetting: getSetting2, SETTINGS_KEYS } = await import("./settings-MDCRNQBY.js");
8382
+ const { getSetting: getSetting2, SETTINGS_KEYS } = await import("./settings-ZJPM6PQV.js");
8229
8383
  const proxyUrl = getSetting2(SETTINGS_KEYS.PROXY_URL);
8230
8384
  if (!proxyUrl) {
8231
8385
  return res.status(400).json({ success: false, error: "No proxy URL configured" });
@@ -8317,7 +8471,7 @@ All file and git operations should use this branch.
8317
8471
  }
8318
8472
  });
8319
8473
  app.post("/api/proxy/test", async (_req, res) => {
8320
- const { getSetting: getSetting2, SETTINGS_KEYS } = await import("./settings-MDCRNQBY.js");
8474
+ const { getSetting: getSetting2, SETTINGS_KEYS } = await import("./settings-ZJPM6PQV.js");
8321
8475
  const proxyUrl = getSetting2(SETTINGS_KEYS.PROXY_URL);
8322
8476
  if (!proxyUrl) {
8323
8477
  return res.status(400).json({ success: false, error: "No proxy URL configured" });
@@ -8344,7 +8498,7 @@ All file and git operations should use this branch.
8344
8498
  const backend = req.query["backend"];
8345
8499
  if (!url) return res.status(400).json({ error: "url is required" });
8346
8500
  try {
8347
- const { fetchModelsWithContext } = await import("./provider-manager-BO5ZBG3T.js");
8501
+ const { fetchModelsWithContext } = await import("./provider-manager-2KKZ37XJ.js");
8348
8502
  const { getModelProfile: getModelProfile2 } = await import("./profiles-EBCVFYG7.js");
8349
8503
  const { getCatalogEntry } = await import("./model-catalog-2PCKTYGW.js");
8350
8504
  const models = await fetchModelsWithContext(
@@ -8419,7 +8573,7 @@ All file and git operations should use this branch.
8419
8573
  const { getModelProfile: getModelProfile2 } = await import("./profiles-EBCVFYG7.js");
8420
8574
  const { getBackendCapabilities } = await import("./backend-NDBY3DAQ.js");
8421
8575
  const { buildNonStreamingCreateParams } = await import("./client-pure-FLKP6PTI.js");
8422
- const { OpenAIHttpClient } = await import("./http-client-P4XTKAZA.js");
8576
+ const { OpenAIHttpClient } = await import("./http-client-A445WYZU.js");
8423
8577
  const { ensureVersionPrefix } = await import("./url-utils-C5BM7NF7.js");
8424
8578
  const profile = getModelProfile2(model);
8425
8579
  const capabilities = getBackendCapabilities(backend || "unknown");
@@ -8836,7 +8990,7 @@ All file and git operations should use this branch.
8836
8990
  });
8837
8991
  async function rebuildMcpTools() {
8838
8992
  const { createMcpTools: createMcpTools2 } = await import("./tool-adapter-FJAFLDZA.js");
8839
- const { setMcpTools: setMcpTools2 } = await import("./tools-CW6POKUL.js");
8993
+ const { setMcpTools: setMcpTools2 } = await import("./tools-WWIWD3O7.js");
8840
8994
  const mcpTools = createMcpTools2(mcpManager);
8841
8995
  setMcpTools2(mcpTools);
8842
8996
  toolRegistry = createToolRegistry();
@@ -9266,13 +9420,13 @@ All file and git operations should use this branch.
9266
9420
  })
9267
9421
  );
9268
9422
  app.get("/api/sessions/:id/background-processes", async (req, res) => {
9269
- const { getSessionProcesses } = await import("./manager-TMBFBCQL.js");
9423
+ const { getSessionProcesses } = await import("./manager-ZACEUL5P.js");
9270
9424
  const sessionId = req.params.id;
9271
9425
  const processes = getSessionProcesses(sessionId);
9272
9426
  res.json({ processes });
9273
9427
  });
9274
9428
  app.post("/api/sessions/:id/background-process/:processId/stop", async (req, res) => {
9275
- const { stopProcess } = await import("./manager-TMBFBCQL.js");
9429
+ const { stopProcess } = await import("./manager-ZACEUL5P.js");
9276
9430
  const sessionId = req.params.id;
9277
9431
  const processId = req.params.processId;
9278
9432
  const session = sessionManager.getSession(sessionId);
@@ -9412,7 +9566,7 @@ All file and git operations should use this branch.
9412
9566
  );
9413
9567
  const wss = wssExports.wss;
9414
9568
  deferTasksBroadcast = (projectId, payload) => wssExports.broadcastForProject(projectId, "", { type: "tasks.update", payload });
9415
- const { launchWorkflowRun, abortRunnerRun } = await import("./launch-6I5ADTVT.js");
9569
+ const { launchWorkflowRun, abortRunnerRun } = await import("./launch-FJ65HRV4.js");
9416
9570
  deferTasksLaunchWorkflow = (sessionId, launch) => {
9417
9571
  const effective = sessionManager.resolveEffectiveProviderModel(sessionId);
9418
9572
  let llmClient = getLLMClient();
@@ -9457,7 +9611,7 @@ All file and git operations should use this branch.
9457
9611
  const state = sessionManager.getContextState(sessionId);
9458
9612
  wssExports.broadcastForSession(sessionId, createContextStateMessage(state));
9459
9613
  });
9460
- const { QueueProcessor } = await import("./processor-FMEULCNQ.js");
9614
+ const { QueueProcessor } = await import("./processor-CHMHMMIE.js");
9461
9615
  const queueProcessor = new QueueProcessor({
9462
9616
  sessionManager,
9463
9617
  providerManager,
@@ -9482,8 +9636,8 @@ All file and git operations should use this branch.
9482
9636
  sessionManager,
9483
9637
  listProjects: () => listProjects(),
9484
9638
  createProject: async (name, workdir) => {
9485
- const { createDirectoryWithGit } = await import("./project-creator-6AGQTNXB.js");
9486
- return createDirectoryWithGit(name, workdir);
9639
+ const { createProjectDirectory } = await import("./project-creator-T3A4H3YV.js");
9640
+ return createProjectDirectory(name, workdir);
9487
9641
  },
9488
9642
  deleteProject: (projectId) => {
9489
9643
  const project = getProject(projectId);
@@ -9499,8 +9653,8 @@ All file and git operations should use this branch.
9499
9653
  launchWorkflow: (sessionId, launch) => deferTasksLaunchWorkflow(sessionId, launch),
9500
9654
  stopSession: (sessionId) => {
9501
9655
  void (async () => {
9502
- const { stopSessionExecution } = await import("./chat-handler-T47GATL5.js");
9503
- const { cancelQuestionsForSession, cancelPathConfirmationsForSession } = await import("./tools-CW6POKUL.js");
9656
+ const { stopSessionExecution } = await import("./chat-handler-YCZE2XEJ.js");
9657
+ const { cancelQuestionsForSession, cancelPathConfirmationsForSession } = await import("./tools-WWIWD3O7.js");
9504
9658
  sessionManager.clearMessageQueue(sessionId);
9505
9659
  stopSessionExecution(sessionId, sessionManager);
9506
9660
  abortSession(sessionId);
@@ -9621,4 +9775,4 @@ export {
9621
9775
  createServerHandle,
9622
9776
  createServer
9623
9777
  };
9624
- //# sourceMappingURL=chunk-ZSBNXJZ5.js.map
9778
+ //# sourceMappingURL=chunk-5IXCCMFU.js.map