openfox 2.0.133 → 2.0.135

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 (84) hide show
  1. package/CHANGELOG.md +30 -0
  2. package/dist/CHANGELOG.md +30 -0
  3. package/dist/{chat-handler-T47GATL5.js → chat-handler-WGDFMOOD.js} +23 -22
  4. package/dist/chunk-24YKXKCG.js +35 -0
  5. package/dist/chunk-2OMGR7LN.js +45 -0
  6. package/dist/{chunk-GFW2HWJ6.js → chunk-4R5GV7RW.js} +37 -16
  7. package/dist/{chunk-P5MSY7ZI.js → chunk-5H5NRWHA.js} +22 -17
  8. package/dist/{chunk-MQMPIXON.js → chunk-5UMXFLET.js} +3 -3
  9. package/dist/{chunk-5JWJEZJ3.js → chunk-5UQ4CKOA.js} +2 -2
  10. package/dist/{chunk-7JVBDBXE.js → chunk-7QMWYNVF.js} +2 -2
  11. package/dist/{chunk-P57IBMK4.js → chunk-AATMPL7S.js} +4 -4
  12. package/dist/{chunk-OUQZZEIQ.js → chunk-BIZFY3QP.js} +487 -210
  13. package/dist/{chunk-LQKXJPKP.js → chunk-CTWZPN7G.js} +5 -1
  14. package/dist/{chunk-BKMWZTNO.js → chunk-DWA4IE65.js} +14 -2
  15. package/dist/{chunk-HXHPKGJE.js → chunk-ESZQTFQP.js} +614 -157
  16. package/dist/{chunk-KWAHD2JA.js → chunk-F2MOHHXB.js} +15 -2
  17. package/dist/{chunk-A7CB4USC.js → chunk-GP3CLMPQ.js} +132 -45
  18. package/dist/{chunk-HCYSGLY2.js → chunk-HF3NDXB4.js} +1 -1
  19. package/dist/{chunk-Y6ZGHOKM.js → chunk-I5ODJKYM.js} +4 -4
  20. package/dist/{chunk-OMMPTN6X.js → chunk-IAT2LBIX.js} +69 -27
  21. package/dist/{chunk-6EZDW4JS.js → chunk-J3NMNYGM.js} +2 -2
  22. package/dist/{chunk-M5T4RDPJ.js → chunk-MEEUXRFL.js} +2 -2
  23. package/dist/{chunk-RRUSYVQD.js → chunk-NFEZATSN.js} +8 -8
  24. package/dist/{chunk-MGEYAYGU.js → chunk-O3RCSKUH.js} +2 -2
  25. package/dist/{chunk-ELYHHEYL.js → chunk-ORCQ3EXQ.js} +2 -2
  26. package/dist/{chunk-FEIRWXLX.js → chunk-OZWHRBDY.js} +64 -17
  27. package/dist/{chunk-FGNJMKDV.js → chunk-QZOV4OVN.js} +29 -5
  28. package/dist/{chunk-TACWRDDC.js → chunk-S67WIWUG.js} +2 -2
  29. package/dist/{chunk-ZL4IAFF3.js → chunk-UKIUQAQZ.js} +3 -3
  30. package/dist/{chunk-VXG3AFFY.js → chunk-VHLD6PCZ.js} +8 -8
  31. package/dist/chunk-WY3PWHWY.js +7 -0
  32. package/dist/{chunk-CLDCHOEA.js → chunk-ZMK4VX7V.js} +2 -2
  33. package/dist/cli/dev.js +4 -1
  34. package/dist/cli/index.js +4 -1
  35. package/dist/{client-2K6PPPJJ.js → client-VVYOWXRR.js} +4 -4
  36. package/dist/{compactor-OEJAA2YP.js → compactor-454UEIEX.js} +9 -9
  37. package/dist/{dynamic-context-NJZKAZE3.js → dynamic-context-LKC6JYLQ.js} +10 -10
  38. package/dist/{events-ZJPRGVL2.js → events-335XAKFK.js} +6 -6
  39. package/dist/export-import-3WMRLO4A.js +137 -0
  40. package/dist/{folding-QRZOHY2I.js → folding-H7JTX6KI.js} +4 -4
  41. package/dist/{http-client-P4XTKAZA.js → http-client-A445WYZU.js} +3 -3
  42. package/dist/{install-VA2F6X6Z.js → install-AVTFA344.js} +64 -15
  43. package/dist/{launch-UKXVO37B.js → launch-GJ7EHQRI.js} +23 -22
  44. package/dist/{manager-TMBFBCQL.js → manager-ZACEUL5P.js} +4 -4
  45. package/dist/{mcp-YU7AM3UV.js → mcp-SQ4DOGPT.js} +22 -9
  46. package/dist/{orchestrator-GX22Y5EM.js → orchestrator-JGJWTRO5.js} +22 -21
  47. package/dist/package.json +3 -1
  48. package/dist/{path-security-CBACXAMS.js → path-security-4LROI7F4.js} +10 -10
  49. package/dist/{platform-5LQXOZO3.js → platform-XPMZKAUB.js} +3 -3
  50. package/dist/{processor-V35OLKRV.js → processor-MSQP63ML.js} +22 -21
  51. package/dist/{project-creator-6AGQTNXB.js → project-creator-T3A4H3YV.js} +42 -29
  52. package/dist/{protocol-BMUoqwYH.d.ts → protocol-Nr_H1_oC.d.ts} +3 -1
  53. package/dist/{protocol-Y7MRKRUO.js → protocol-XO4ZROAU.js} +3 -3
  54. package/dist/provider/index.d.ts +4 -4
  55. package/dist/provider-JWUNG2TD.js +507 -0
  56. package/dist/{provider-manager-BO5ZBG3T.js → provider-manager-2KKZ37XJ.js} +5 -5
  57. package/dist/pwa-V5PFB4OQ.js +502 -0
  58. package/dist/{registry-CMSSZHDC.js → registry-BEIR7Y5G.js} +3 -3
  59. package/dist/{serve-XRVT3D7Z.js → serve-CW5C3CBZ.js} +47 -36
  60. package/dist/server/index.d.ts +18 -3
  61. package/dist/server/index.js +27 -26
  62. package/dist/{server-GXMZMPXI.js → server-ZHEB7XS2.js} +26 -25
  63. package/dist/{service-WKABQHKL.js → service-M77VWL2M.js} +97 -32
  64. package/dist/{service-O3LCO3TQ.js → service-XIUNS5XV.js} +7 -6
  65. package/dist/{session-overrides-OECQYRDK.js → session-overrides-LYW5PJ3R.js} +5 -5
  66. package/dist/{sessions-NMPX5ICI.js → sessions-AOK3AGHY.js} +6 -4
  67. package/dist/{settings-MDCRNQBY.js → settings-ZJPM6PQV.js} +2 -2
  68. package/dist/shared/index.d.ts +31 -4
  69. package/dist/shared/index.js +16 -2
  70. package/dist/{tasks-WOC3QUFA.js → tasks-3JJWJJ3X.js} +34 -18
  71. package/dist/{tools-CW6POKUL.js → tools-E63MOJBO.js} +20 -19
  72. package/dist/{types-CoY8Ka1C.d.ts → types-BlQjLBui.d.ts} +1 -1
  73. package/dist/{types-BIkpxjaj.d.ts → types-G10ho8PT.d.ts} +1 -1
  74. package/dist/update-XVXNSSDK.js +76 -0
  75. package/dist/web/assets/{index-Y300llHY.css → index-Bg_Z8i3F.css} +1 -1
  76. package/dist/web/assets/index-wTFCxQAw.js +313 -0
  77. package/dist/web/index.html +2 -2
  78. package/dist/web/sw.js +1 -1
  79. package/package.json +3 -1
  80. package/dist/chunk-JKGHTBEV.js +0 -7
  81. package/dist/provider-NWRGNGS3.js +0 -403
  82. package/dist/pwa-2GRFSXD7.js +0 -363
  83. package/dist/update-VC3Y3EOP.js +0 -49
  84. package/dist/web/assets/index-ATAQvBwl.js +0 -312
@@ -24,10 +24,10 @@ import {
24
24
  terminalManager,
25
25
  tokenFromPassword,
26
26
  verifyPassword
27
- } from "./chunk-A7CB4USC.js";
27
+ } from "./chunk-GP3CLMPQ.js";
28
28
  import {
29
29
  TEMPLATE_VARIABLES
30
- } from "./chunk-P5MSY7ZI.js";
30
+ } from "./chunk-5H5NRWHA.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-ESZQTFQP.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-S67WIWUG.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-I5ODJKYM.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-QZOV4OVN.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,
@@ -162,6 +163,7 @@ import {
162
163
  listSessions,
163
164
  listSessionsByProject,
164
165
  listSessionsLimited,
166
+ setSessionMessageCount,
165
167
  toggleFavorite,
166
168
  updateSessionBranch,
167
169
  updateSessionCachedPrompt,
@@ -174,7 +176,7 @@ import {
174
176
  updateSessionRunning,
175
177
  updateSessionWorkdir,
176
178
  updateWorkflowExecutionStatus
177
- } from "./chunk-KWAHD2JA.js";
179
+ } from "./chunk-F2MOHHXB.js";
178
180
  import {
179
181
  agentExists,
180
182
  deleteAgent,
@@ -191,7 +193,7 @@ import {
191
193
  saveAgent,
192
194
  saveAgentToProject,
193
195
  setRuntimeConfig
194
- } from "./chunk-ELYHHEYL.js";
196
+ } from "./chunk-ORCQ3EXQ.js";
195
197
  import {
196
198
  findFileByInternalId,
197
199
  pathExists
@@ -199,23 +201,23 @@ import {
199
201
  import {
200
202
  createContextStateMessage,
201
203
  toClientSession
202
- } from "./chunk-P57IBMK4.js";
204
+ } from "./chunk-AATMPL7S.js";
203
205
  import {
204
206
  getPathSeparator,
205
207
  isAbsolutePath
206
- } from "./chunk-MGEYAYGU.js";
208
+ } from "./chunk-O3RCSKUH.js";
207
209
  import {
208
210
  createProviderManager,
209
211
  detectModel,
210
212
  getLlmStatus,
211
213
  parseDefaultModelSelection
212
- } from "./chunk-5JWJEZJ3.js";
214
+ } from "./chunk-5UQ4CKOA.js";
213
215
  import {
214
216
  buildOpenFoxMcpBootstrap
215
217
  } from "./chunk-YNMP647F.js";
216
218
  import {
217
219
  VERSION
218
- } from "./chunk-JKGHTBEV.js";
220
+ } from "./chunk-WY3PWHWY.js";
219
221
  import {
220
222
  deleteProject,
221
223
  getProject,
@@ -235,12 +237,12 @@ import {
235
237
  import {
236
238
  SessionNotFoundError,
237
239
  WorkspaceInUseError
238
- } from "./chunk-6EZDW4JS.js";
240
+ } from "./chunk-J3NMNYGM.js";
239
241
  import {
240
242
  deleteSetting,
241
243
  getSetting,
242
244
  setSetting
243
- } from "./chunk-LQKXJPKP.js";
245
+ } from "./chunk-CTWZPN7G.js";
244
246
  import {
245
247
  initDatabase
246
248
  } from "./chunk-JU757HVI.js";
@@ -253,7 +255,7 @@ import {
253
255
  } from "./chunk-K44MW7JJ.js";
254
256
  import {
255
257
  createServerMessage
256
- } from "./chunk-HCYSGLY2.js";
258
+ } from "./chunk-HF3NDXB4.js";
257
259
  import {
258
260
  getGlobalConfigDir
259
261
  } from "./chunk-CQGTEGKL.js";
@@ -3095,6 +3097,94 @@ var SessionManager = class {
3095
3097
  this.emit({ type: "session_updated", session: this.requireSession(newSession.id) });
3096
3098
  return this.requireSession(newSession.id);
3097
3099
  }
3100
+ /**
3101
+ * Import a session from an export document into a target project.
3102
+ *
3103
+ * The cached layout (system prompt, tools, hash) is restored verbatim so the
3104
+ * provider-side prefix cache stays valid, and the event history is replayed
3105
+ * as-is. Drift between the original environment's cached layout and the
3106
+ * target environment (system prompt, tools) is announced via injected
3107
+ * <system-reminder> messages, followed by an import marker reminder.
3108
+ *
3109
+ * @param projectId - Target project (the session is created there)
3110
+ * @param rawPayload - Exported session document (validated)
3111
+ * @returns The imported session
3112
+ * @throws Error for invalid payloads or unknown project
3113
+ */
3114
+ async importSession(projectId, rawPayload) {
3115
+ const { parseSessionExport, IMPORTED_SESSION_REMINDER, SESSION_EXPORT_VERSION } = await import("./export-import-3WMRLO4A.js");
3116
+ const { injectContextDriftReminders, getToolSetFingerprint } = await import("./dynamic-context-LKC6JYLQ.js");
3117
+ const { loadAllAgentsDefault: loadAllAgentsDefault2, resolveDefaultAgentId } = await import("./registry-BEIR7Y5G.js");
3118
+ const payload = parseSessionExport(rawPayload);
3119
+ if (payload.version !== SESSION_EXPORT_VERSION) {
3120
+ throw new Error(`Unsupported session export version: ${payload.version}`);
3121
+ }
3122
+ const project = getProject(projectId);
3123
+ if (!project) {
3124
+ throw new Error(`Project not found: ${projectId}`);
3125
+ }
3126
+ if (!payload.events.some((event) => event.type === "session.initialized")) {
3127
+ throw new Error("Invalid session export: missing session.initialized event");
3128
+ }
3129
+ const providers = this.providerManager.getProviders();
3130
+ const providerId = payload.session.providerId ?? null;
3131
+ const providerModel = payload.session.providerModel ?? null;
3132
+ let resolvedProviderId = null;
3133
+ let resolvedProviderModel = null;
3134
+ if (providerId && providers.some((p) => p.id === providerId)) {
3135
+ resolvedProviderId = providerId;
3136
+ resolvedProviderModel = providerModel;
3137
+ } else if (providerId && payload.source?.providerBackend && payload.source.providerUrl) {
3138
+ const normalizeUrl = (url) => url.replace(/\/+$/, "");
3139
+ const sourceBackend = payload.source.providerBackend;
3140
+ const sourceUrl = normalizeUrl(payload.source.providerUrl);
3141
+ const urlMatch = providers.find(
3142
+ (p) => p.backend === sourceBackend && p.url !== void 0 && normalizeUrl(p.url) === sourceUrl && providerModel !== null && p.models.some((m) => m.id === providerModel || m.apiModelId === providerModel)
3143
+ );
3144
+ if (urlMatch) {
3145
+ resolvedProviderId = urlMatch.id;
3146
+ resolvedProviderModel = providerModel;
3147
+ }
3148
+ }
3149
+ const session = createSession(
3150
+ projectId,
3151
+ project.workdir,
3152
+ payload.session.title,
3153
+ resolvedProviderId,
3154
+ resolvedProviderModel
3155
+ );
3156
+ const eventStore = getEventStore();
3157
+ eventStore.importEvents(session.id, payload.events);
3158
+ const agents = await loadAllAgentsDefault2(project.workdir);
3159
+ const restoredMode = getSessionState(session.id)?.mode ?? session.mode;
3160
+ if (!agents.some((agent) => agent.metadata.id === restoredMode)) {
3161
+ this.setMode(session.id, resolveDefaultAgentId(projectId));
3162
+ }
3163
+ if (payload.cachedLayout) {
3164
+ updateSessionCachedPrompt(
3165
+ session.id,
3166
+ payload.cachedLayout.systemPrompt,
3167
+ payload.cachedLayout.tools,
3168
+ payload.cachedLayout.hash,
3169
+ payload.cachedLayout.promptHash
3170
+ );
3171
+ this.setAnnouncedPromptHash(session.id, payload.cachedLayout.promptHash ?? payload.cachedLayout.hash);
3172
+ this.setAnnouncedToolFingerprint(session.id, getToolSetFingerprint(payload.cachedLayout.tools));
3173
+ this.markWarmedUp(session.id);
3174
+ }
3175
+ await injectContextDriftReminders(this, session.id);
3176
+ emitUserMessage(session.id, IMPORTED_SESSION_REMINDER, {
3177
+ isSystemGenerated: true,
3178
+ messageKind: "auto-prompt",
3179
+ metadata: { type: "session-import", name: "Session Imported", color: "#6b7280", kind: "reminder" }
3180
+ });
3181
+ const state = getSessionState(session.id);
3182
+ if (state) {
3183
+ setSessionMessageCount(session.id, state.messages.length);
3184
+ }
3185
+ this.emit({ type: "session_created", session: this.requireSession(session.id) });
3186
+ return this.requireSession(session.id);
3187
+ }
3098
3188
  /**
3099
3189
  * Get a session by ID. Returns null if not found.
3100
3190
  * Session state is derived from EventStore.
@@ -3990,13 +4080,33 @@ var SessionManager = class {
3990
4080
  }
3991
4081
  } catch (innerErr) {
3992
4082
  throw new Error(
3993
- `Failed to create branch "${branch}" in workspace "${workspaceName}": ${innerErr instanceof Error ? innerErr.message : String(innerErr)}`
4083
+ serverT(
4084
+ {
4085
+ en: 'Failed to create branch "{{branch}}" in workspace "{{workspace}}": {{reason}}',
4086
+ fr: "\xC9chec de cr\xE9ation de la branche \xAB {{branch}} \xBB dans le workspace \xAB {{workspace}} \xBB : {{reason}}"
4087
+ },
4088
+ {
4089
+ branch,
4090
+ workspace: workspaceName,
4091
+ reason: innerErr instanceof Error ? innerErr.message : String(innerErr)
4092
+ }
4093
+ )
3994
4094
  );
3995
4095
  }
3996
4096
  });
3997
4097
  } catch (err) {
3998
4098
  throw new Error(
3999
- `Failed to apply branch "${branch}" to workspace "${workspaceName}": ${err instanceof Error ? err.message : String(err)}`
4099
+ serverT(
4100
+ {
4101
+ en: 'Failed to apply branch "{{branch}}" to workspace "{{workspace}}": {{reason}}',
4102
+ fr: "\xC9chec d\u2019application de la branche \xAB {{branch}} \xBB au workspace \xAB {{workspace}} \xBB : {{reason}}"
4103
+ },
4104
+ {
4105
+ branch,
4106
+ workspace: workspaceName,
4107
+ reason: err instanceof Error ? err.message : String(err)
4108
+ }
4109
+ )
4000
4110
  );
4001
4111
  }
4002
4112
  }
@@ -4375,8 +4485,16 @@ async function loadItemsForScope(config3, configDir, projectDir, scope) {
4375
4485
  var ID_REGEX = /^[a-z0-9-]+$/;
4376
4486
  function validateNameIdPrompt(body) {
4377
4487
  const meta = body["metadata"];
4378
- if (!meta?.["name"] || !body["prompt"]) return "Missing required fields: metadata.name, prompt";
4379
- if (meta["id"] && !ID_REGEX.test(String(meta["id"]))) return "ID must be lowercase alphanumeric with hyphens only";
4488
+ if (!meta?.["name"] || !body["prompt"])
4489
+ return serverT({
4490
+ en: "Missing required fields: metadata.name, prompt",
4491
+ fr: "Champs requis manquants : metadata.name, prompt"
4492
+ });
4493
+ if (meta["id"] && !ID_REGEX.test(String(meta["id"])))
4494
+ return serverT({
4495
+ en: "ID must be lowercase alphanumeric with hyphens only",
4496
+ fr: "L\u2019ID doit \xEAtre en minuscules alphanum\xE9riques, avec des tirets uniquement"
4497
+ });
4380
4498
  return null;
4381
4499
  }
4382
4500
  function getProjectItemPath(projectDir, dirName, id, ext) {
@@ -4416,7 +4534,7 @@ function createCrudRoutes(config3, configDir, projectDir) {
4416
4534
  const allDefaults = await config3.loadDefaults();
4417
4535
  const item = allDefaults.find((d) => d.metadata.id === id);
4418
4536
  if (!item) {
4419
- return res.status(404).json({ error: "Default not found" });
4537
+ return res.status(404).json({ error: serverT({ en: "Default not found", fr: "\xC9l\xE9ment par d\xE9faut introuvable" }) });
4420
4538
  }
4421
4539
  res.json(item);
4422
4540
  });
@@ -4432,7 +4550,7 @@ function createCrudRoutes(config3, configDir, projectDir) {
4432
4550
  const items = await loadItemsForScope(config3, configDir, effectiveProjectDir, scope);
4433
4551
  const item = config3.findById(id, items);
4434
4552
  if (!item) {
4435
- return res.status(404).json({ error: "Not found" });
4553
+ return res.status(404).json({ error: serverT({ en: "Not found", fr: "Introuvable" }) });
4436
4554
  }
4437
4555
  res.json(item);
4438
4556
  });
@@ -4441,17 +4559,19 @@ function createCrudRoutes(config3, configDir, projectDir) {
4441
4559
  const meta = body["metadata"];
4442
4560
  const customError = config3.validateCreate?.(body);
4443
4561
  if (!meta?.["id"] || customError) {
4444
- return res.status(400).json({ error: customError ?? "Missing required fields" });
4562
+ return res.status(400).json({ error: customError ?? serverT({ en: "Missing required fields", fr: "Champs requis manquants" }) });
4445
4563
  }
4446
4564
  const id = String(meta["id"]);
4447
4565
  const destination = body["destination"] ?? "user";
4448
4566
  const effectiveProjectDir = resolveProjectDir(req, projectDir);
4449
4567
  if (destination === "project" && !effectiveProjectDir) {
4450
- return res.status(400).json({ error: "No project directory configured" });
4568
+ return res.status(400).json({ error: serverT({ en: "No project directory configured", fr: "Aucun r\xE9pertoire de projet configur\xE9" }) });
4451
4569
  }
4452
4570
  const exists = await config3.exists(configDir, id, effectiveProjectDir);
4453
4571
  if (exists) {
4454
- return res.status(409).json({ error: "An item with this ID already exists" });
4572
+ return res.status(409).json({
4573
+ error: serverT({ en: "An item with this ID already exists", fr: "Un \xE9l\xE9ment avec cet ID existe d\xE9j\xE0" })
4574
+ });
4455
4575
  }
4456
4576
  if (destination === "project") {
4457
4577
  await config3.saveToProject(effectiveProjectDir, body);
@@ -4466,7 +4586,7 @@ function createCrudRoutes(config3, configDir, projectDir) {
4466
4586
  const items = await config3.loadAll(configDir, effectiveProjectDir);
4467
4587
  const existing = config3.findById(id, items);
4468
4588
  if (!existing) {
4469
- return res.status(404).json({ error: "Not found" });
4589
+ return res.status(404).json({ error: serverT({ en: "Not found", fr: "Introuvable" }) });
4470
4590
  }
4471
4591
  const body = req.body;
4472
4592
  const meta = body["metadata"];
@@ -4492,7 +4612,7 @@ function createCrudRoutes(config3, configDir, projectDir) {
4492
4612
  const result = target === "project" ? await config3.deleteProject(effectiveProjectDir, id) : await config3.delete(configDir, id);
4493
4613
  if (!result.success) {
4494
4614
  return res.status(target === "project" ? 500 : 403).json({
4495
- error: target === "project" ? "Failed to delete project item" : result.reason ?? "Cannot delete this item"
4615
+ 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" })
4496
4616
  });
4497
4617
  }
4498
4618
  res.json({ success: true });
@@ -4503,7 +4623,7 @@ function createCrudRoutes(config3, configDir, projectDir) {
4503
4623
  const items = await config3.loadAll(configDir, effectiveProjectDir);
4504
4624
  const source = config3.findById(id, items);
4505
4625
  if (!source) {
4506
- return res.status(404).json({ error: "Not found" });
4626
+ return res.status(404).json({ error: serverT({ en: "Not found", fr: "Introuvable" }) });
4507
4627
  }
4508
4628
  const newId = `${id}-copy-${Date.now()}`;
4509
4629
  const duplicated = {
@@ -4512,7 +4632,10 @@ function createCrudRoutes(config3, configDir, projectDir) {
4512
4632
  };
4513
4633
  const destination = req.body.destination ?? "user";
4514
4634
  if (destination === "project") {
4515
- if (!effectiveProjectDir) return res.status(400).json({ error: "No project directory configured" });
4635
+ if (!effectiveProjectDir)
4636
+ return res.status(400).json({
4637
+ error: serverT({ en: "No project directory configured", fr: "Aucun r\xE9pertoire de projet configur\xE9" })
4638
+ });
4516
4639
  await config3.saveToProject(effectiveProjectDir, duplicated);
4517
4640
  } else {
4518
4641
  await config3.save(configDir, duplicated);
@@ -4625,13 +4748,16 @@ function createSkillRoutes(configDir, projectDir) {
4625
4748
  const router = Router2();
4626
4749
  router.put("/library", async (req, res) => {
4627
4750
  const path = req.body.path;
4628
- if (typeof path !== "string" || !path.trim()) return res.status(400).json({ error: "path is required" });
4751
+ if (typeof path !== "string" || !path.trim())
4752
+ return res.status(400).json({ error: serverT({ en: "path is required", fr: "path est requis" }) });
4629
4753
  try {
4630
4754
  const selected = await resolveLibrary(path);
4631
4755
  setSetting(SKILL_DIRECTORIES_SETTING, JSON.stringify([path]));
4632
4756
  res.json(selected);
4633
4757
  } catch (error) {
4634
- res.status(400).json({ error: error instanceof Error ? error.message : "Cannot use directory" });
4758
+ res.status(400).json({
4759
+ error: error instanceof Error ? error.message : serverT({ en: "Cannot use directory", fr: "Impossible d\u2019utiliser ce r\xE9pertoire" })
4760
+ });
4635
4761
  }
4636
4762
  });
4637
4763
  router.delete("/library", (_req, res) => {
@@ -4649,10 +4775,16 @@ function createSkillRoutes(configDir, projectDir) {
4649
4775
  const paths = JSON.parse(String(req.body["paths"] ?? "[]"));
4650
4776
  const files = req.files;
4651
4777
  if (!Array.isArray(paths) || paths.length !== files.length || paths.some((path) => typeof path !== "string")) {
4652
- return res.status(400).json({ error: "File path manifest does not match upload" });
4778
+ return res.status(400).json({
4779
+ error: serverT({
4780
+ en: "File path manifest does not match upload",
4781
+ fr: "Le manifeste des chemins de fichiers ne correspond pas \xE0 l\u2019envoi"
4782
+ })
4783
+ });
4653
4784
  }
4654
4785
  const totalBytes = files.reduce((total, file) => total + file.size, 0);
4655
- if (totalBytes > 50 * 1024 * 1024) return res.status(413).json({ error: "Package exceeds 50 MiB" });
4786
+ if (totalBytes > 50 * 1024 * 1024)
4787
+ return res.status(413).json({ error: serverT({ en: "Package exceeds 50 MiB", fr: "Le paquet d\xE9passe 50 Mio" }) });
4656
4788
  const installed = await installSkillPackage(
4657
4789
  library.resolvedPath,
4658
4790
  packageName,
@@ -4661,29 +4793,35 @@ function createSkillRoutes(configDir, projectDir) {
4661
4793
  res.status(201).json(installed);
4662
4794
  } catch (error) {
4663
4795
  const status = error instanceof SkillInstallError ? error.status : 400;
4664
- res.status(status).json({ error: error instanceof Error ? error.message : "Install failed" });
4796
+ res.status(status).json({
4797
+ error: error instanceof Error ? error.message : serverT({ en: "Install failed", fr: "\xC9chec de l\u2019installation" })
4798
+ });
4665
4799
  }
4666
4800
  });
4667
4801
  });
4668
4802
  router.post("/:id/toggle", async (req, res) => {
4669
4803
  const existing = await findSkillByIdForRequest(req, configDir, projectDir);
4670
- if (!existing) return res.status(404).json({ error: "Not found" });
4804
+ if (!existing) return res.status(404).json({ error: serverT({ en: "Not found", fr: "Introuvable" }) });
4671
4805
  const enabled = !isSkillEnabled(existing.metadata.id);
4672
4806
  setSkillEnabled(existing.metadata.id, enabled);
4673
4807
  res.json({ enabled });
4674
4808
  });
4675
4809
  router.put("/:id", async (req, res) => {
4676
4810
  const existing = await findSkillByIdForRequest(req, configDir, projectDir);
4677
- if (!existing) return res.status(404).json({ error: "Not found" });
4811
+ if (!existing) return res.status(404).json({ error: serverT({ en: "Not found", fr: "Introuvable" }) });
4678
4812
  const updated = await updateOwnedSkill(existing, req.body);
4679
- if (!updated) return res.status(403).json({ error: "This skill is read-only" });
4813
+ if (!updated)
4814
+ return res.status(403).json({ error: serverT({ en: "This skill is read-only", fr: "Cette comp\xE9tence est en lecture seule" }) });
4680
4815
  res.json(updated);
4681
4816
  });
4682
4817
  router.delete("/:id", async (req, res) => {
4683
4818
  const existing = await findSkillByIdForRequest(req, configDir, projectDir);
4684
- if (!existing) return res.status(404).json({ error: "Not found" });
4819
+ if (!existing) return res.status(404).json({ error: serverT({ en: "Not found", fr: "Introuvable" }) });
4685
4820
  const result = await deleteOwnedSkill(existing);
4686
- if (!result.success) return res.status(403).json({ error: result.reason ?? "Cannot delete this skill" });
4821
+ if (!result.success)
4822
+ return res.status(403).json({
4823
+ error: result.reason ?? serverT({ en: "Cannot delete this skill", fr: "Impossible de supprimer cette comp\xE9tence" })
4824
+ });
4687
4825
  res.json({ success: true });
4688
4826
  });
4689
4827
  router.use(createCrudRoutes(createConfig(configDir, projectDir), configDir, projectDir));
@@ -4767,7 +4905,12 @@ var config2 = {
4767
4905
  const { id } = req.params;
4768
4906
  const { providerId, model, reasoningEffort } = req.body;
4769
4907
  if (reasoningEffort !== void 0 && !isReasoningEffortValue(reasoningEffort)) {
4770
- return res.status(400).json({ error: `Unsupported reasoningEffort: ${reasoningEffort}` });
4908
+ return res.status(400).json({
4909
+ error: serverT(
4910
+ { en: "Unsupported reasoningEffort: {{value}}", fr: "reasoningEffort non pris en charge : {{value}}" },
4911
+ { value: String(reasoningEffort) }
4912
+ )
4913
+ });
4771
4914
  }
4772
4915
  if (providerId && model) {
4773
4916
  setAgentModelOverride(id, {
@@ -5595,7 +5738,7 @@ function createDevServerRoutes() {
5595
5738
  const router = Router5();
5596
5739
  router.get("/", async (req, res) => {
5597
5740
  const workdir = req.query["workdir"];
5598
- if (!workdir) return res.status(400).json({ error: "workdir required" });
5741
+ if (!workdir) return res.status(400).json({ error: serverT({ en: "workdir required", fr: "workdir requis" }) });
5599
5742
  const status = devServerManager.getStatus(workdir);
5600
5743
  if (!status.config) {
5601
5744
  const config3 = await devServerManager.loadConfig(workdir);
@@ -5609,37 +5752,41 @@ function createDevServerRoutes() {
5609
5752
  });
5610
5753
  router.post("/start", async (req, res) => {
5611
5754
  const workdir = req.query["workdir"];
5612
- if (!workdir) return res.status(400).json({ error: "workdir required" });
5755
+ if (!workdir) return res.status(400).json({ error: serverT({ en: "workdir required", fr: "workdir requis" }) });
5613
5756
  try {
5614
5757
  const status = await devServerManager.start(workdir);
5615
5758
  res.json(status);
5616
5759
  } catch (err) {
5617
- res.status(500).json({ error: err instanceof Error ? err.message : "Failed to start" });
5760
+ res.status(500).json({
5761
+ error: err instanceof Error ? err.message : serverT({ en: "Failed to start", fr: "\xC9chec du d\xE9marrage" })
5762
+ });
5618
5763
  }
5619
5764
  });
5620
5765
  router.post("/stop", async (req, res) => {
5621
5766
  const workdir = req.query["workdir"];
5622
- if (!workdir) return res.status(400).json({ error: "workdir required" });
5767
+ if (!workdir) return res.status(400).json({ error: serverT({ en: "workdir required", fr: "workdir requis" }) });
5623
5768
  try {
5624
5769
  const status = await devServerManager.stop(workdir);
5625
5770
  res.json(status);
5626
5771
  } catch (err) {
5627
- res.status(500).json({ error: err instanceof Error ? err.message : "Failed to stop" });
5772
+ res.status(500).json({ error: err instanceof Error ? err.message : serverT({ en: "Failed to stop", fr: "\xC9chec de l\u2019arr\xEAt" }) });
5628
5773
  }
5629
5774
  });
5630
5775
  router.post("/restart", async (req, res) => {
5631
5776
  const workdir = req.query["workdir"];
5632
- if (!workdir) return res.status(400).json({ error: "workdir required" });
5777
+ if (!workdir) return res.status(400).json({ error: serverT({ en: "workdir required", fr: "workdir requis" }) });
5633
5778
  try {
5634
5779
  const status = await devServerManager.restart(workdir);
5635
5780
  res.json(status);
5636
5781
  } catch (err) {
5637
- res.status(500).json({ error: err instanceof Error ? err.message : "Failed to restart" });
5782
+ res.status(500).json({
5783
+ error: err instanceof Error ? err.message : serverT({ en: "Failed to restart", fr: "\xC9chec du red\xE9marrage" })
5784
+ });
5638
5785
  }
5639
5786
  });
5640
5787
  router.get("/logs", (req, res) => {
5641
5788
  const workdir = req.query["workdir"];
5642
- if (!workdir) return res.status(400).json({ error: "workdir required" });
5789
+ if (!workdir) return res.status(400).json({ error: serverT({ en: "workdir required", fr: "workdir requis" }) });
5643
5790
  const offset = Math.max(0, parseInt(req.query["offset"]) || 0);
5644
5791
  const limit = Math.max(1, parseInt(req.query["limit"]) || Infinity);
5645
5792
  const result = devServerManager.getLogsSlice(workdir, offset, limit);
@@ -5647,43 +5794,51 @@ function createDevServerRoutes() {
5647
5794
  });
5648
5795
  router.post("/clear-logs", (req, res) => {
5649
5796
  const workdir = req.query["workdir"];
5650
- if (!workdir) return res.status(400).json({ error: "workdir required" });
5797
+ if (!workdir) return res.status(400).json({ error: serverT({ en: "workdir required", fr: "workdir requis" }) });
5651
5798
  try {
5652
5799
  devServerManager.clearLogs(workdir);
5653
5800
  res.json({ ok: true });
5654
5801
  } catch (err) {
5655
- res.status(500).json({ error: err instanceof Error ? err.message : "Failed to clear logs" });
5802
+ res.status(500).json({
5803
+ error: err instanceof Error ? err.message : serverT({ en: "Failed to clear logs", fr: "\xC9chec de l\u2019effacement des journaux" })
5804
+ });
5656
5805
  }
5657
5806
  });
5658
5807
  router.post("/insert-marker", (req, res) => {
5659
5808
  const workdir = req.query["workdir"];
5660
- if (!workdir) return res.status(400).json({ error: "workdir required" });
5809
+ if (!workdir) return res.status(400).json({ error: serverT({ en: "workdir required", fr: "workdir requis" }) });
5661
5810
  try {
5662
5811
  devServerManager.insertMarker(workdir);
5663
5812
  res.json({ ok: true });
5664
5813
  } catch (err) {
5665
- res.status(500).json({ error: err instanceof Error ? err.message : "Failed to insert marker" });
5814
+ res.status(500).json({
5815
+ error: err instanceof Error ? err.message : serverT({ en: "Failed to insert marker", fr: "\xC9chec de l\u2019insertion du marqueur" })
5816
+ });
5666
5817
  }
5667
5818
  });
5668
5819
  router.get("/config", async (req, res) => {
5669
5820
  const workdir = req.query["workdir"];
5670
- if (!workdir) return res.status(400).json({ error: "workdir required" });
5821
+ if (!workdir) return res.status(400).json({ error: serverT({ en: "workdir required", fr: "workdir requis" }) });
5671
5822
  const config3 = await devServerManager.loadConfig(workdir);
5672
5823
  res.json({ config: config3 });
5673
5824
  });
5674
5825
  router.post("/config", async (req, res) => {
5675
5826
  const workdir = req.query["workdir"];
5676
- if (!workdir) return res.status(400).json({ error: "workdir required" });
5827
+ if (!workdir) return res.status(400).json({ error: serverT({ en: "workdir required", fr: "workdir requis" }) });
5677
5828
  const { command, url, hotReload, disableInspect } = req.body;
5678
5829
  if (!command || !url) {
5679
- return res.status(400).json({ error: "command and url are required" });
5830
+ return res.status(400).json({
5831
+ error: serverT({ en: "command and url are required", fr: "command et url sont requis" })
5832
+ });
5680
5833
  }
5681
5834
  try {
5682
5835
  const config3 = { command, url, hotReload: hotReload ?? false, disableInspect: disableInspect ?? false };
5683
5836
  await devServerManager.saveConfig(workdir, config3);
5684
5837
  res.json({ config: config3 });
5685
5838
  } catch (err) {
5686
- res.status(500).json({ error: err instanceof Error ? err.message : "Failed to save config" });
5839
+ res.status(500).json({
5840
+ error: err instanceof Error ? err.message : serverT({ en: "Failed to save config", fr: "\xC9chec de l\u2019enregistrement de la configuration" })
5841
+ });
5687
5842
  }
5688
5843
  });
5689
5844
  return router;
@@ -5762,7 +5917,37 @@ async function checkDirExists(path) {
5762
5917
  }
5763
5918
  async function validatePathWritable(path) {
5764
5919
  if (await isWritable(path)) return null;
5765
- return "Workspace root directory exists but is not writable";
5920
+ return serverT({
5921
+ en: "Workspace root directory exists but is not writable",
5922
+ fr: "Le r\xE9pertoire racine du workspace existe mais n\u2019est pas accessible en \xE9criture"
5923
+ });
5924
+ }
5925
+ function rootDirBlockError(blockReason, displayPath, suggestion) {
5926
+ if (blockReason === "exact") {
5927
+ return suggestion ? serverT(
5928
+ {
5929
+ en: 'Cannot use "{{path}}" directly as workspace root. Use a subdirectory like "{{suggestion}}" instead.',
5930
+ fr: "Impossible d\u2019utiliser \xAB {{path}} \xBB directement comme racine du workspace. Utilisez plut\xF4t un sous-r\xE9pertoire comme \xAB {{suggestion}} \xBB."
5931
+ },
5932
+ { path: displayPath, suggestion }
5933
+ ) : serverT(
5934
+ {
5935
+ en: 'Cannot use "{{path}}" directly as workspace root. Use a subdirectory instead.',
5936
+ fr: "Impossible d\u2019utiliser \xAB {{path}} \xBB directement comme racine du workspace. Utilisez un sous-r\xE9pertoire \xE0 la place."
5937
+ },
5938
+ { path: displayPath }
5939
+ );
5940
+ }
5941
+ if (blockReason === "virtual_fs") {
5942
+ return serverT(
5943
+ {
5944
+ en: 'Cannot use paths under "{{path}}" for workspaces.',
5945
+ fr: "Impossible d\u2019utiliser des chemins sous \xAB {{path}} \xBB pour les workspaces."
5946
+ },
5947
+ { path: displayPath }
5948
+ );
5949
+ }
5950
+ return null;
5766
5951
  }
5767
5952
  async function findOrphanedWorkspaces(dir) {
5768
5953
  const results = [];
@@ -5790,7 +5975,7 @@ function createWorkspaceConfigRoutes(sessionManager) {
5790
5975
  const router = Router6();
5791
5976
  router.get("/config", async (req, res) => {
5792
5977
  const workdir = req.query["workdir"];
5793
- if (!workdir) return res.status(400).json({ error: "workdir required" });
5978
+ if (!workdir) return res.status(400).json({ error: serverT({ en: "workdir required", fr: "workdir requis" }) });
5794
5979
  const config3 = await loadWorkspaceConfig(workdir);
5795
5980
  const project = getProjectByWorkdir(workdir);
5796
5981
  const rootDir = project?.workspaceRootDir ?? void 0;
@@ -5800,16 +5985,28 @@ function createWorkspaceConfigRoutes(sessionManager) {
5800
5985
  });
5801
5986
  router.post("/config", async (req, res) => {
5802
5987
  const workdir = req.query["workdir"];
5803
- if (!workdir) return res.status(400).json({ error: "workdir required" });
5988
+ if (!workdir) return res.status(400).json({ error: serverT({ en: "workdir required", fr: "workdir requis" }) });
5804
5989
  const { setup, rootDir, mcpOverrides } = req.body;
5805
5990
  if (!Array.isArray(setup) && typeof rootDir !== "string" && mcpOverrides === void 0) {
5806
- return res.status(400).json({ error: "At least one of setup, rootDir, or mcpOverrides must be provided" });
5991
+ return res.status(400).json({
5992
+ error: serverT({
5993
+ en: "At least one of setup, rootDir, or mcpOverrides must be provided",
5994
+ fr: "Au moins un de setup, rootDir ou mcpOverrides doit \xEAtre fourni"
5995
+ })
5996
+ });
5807
5997
  }
5808
5998
  if (setup !== void 0 && !Array.isArray(setup)) {
5809
- return res.status(400).json({ error: "setup must be an array of strings" });
5999
+ return res.status(400).json({
6000
+ error: serverT({ en: "setup must be an array of strings", fr: "setup doit \xEAtre un tableau de cha\xEEnes" })
6001
+ });
5810
6002
  }
5811
6003
  if (mcpOverrides !== void 0 && (typeof mcpOverrides !== "object" || mcpOverrides === null || Array.isArray(mcpOverrides))) {
5812
- return res.status(400).json({ error: "mcpOverrides must be an object mapping server names to overrides" });
6004
+ return res.status(400).json({
6005
+ error: serverT({
6006
+ en: "mcpOverrides must be an object mapping server names to overrides",
6007
+ fr: "mcpOverrides doit \xEAtre un objet associant les noms de serveurs \xE0 des surcharges"
6008
+ })
6009
+ });
5813
6010
  }
5814
6011
  const existing = await loadWorkspaceConfig(workdir);
5815
6012
  const config3 = { ...existing };
@@ -5823,12 +6020,8 @@ function createWorkspaceConfigRoutes(sessionManager) {
5823
6020
  const resolvedPath = resolveRootDir(trimmed, workdir);
5824
6021
  const displayPath = formatRootDir(resolvedPath);
5825
6022
  const blockReason = getRootDirBlockReason(resolvedPath);
5826
- if (blockReason === "exact") {
5827
- return res.status(400).json({ error: `Cannot use "${displayPath}" directly as workspace root. Use a subdirectory instead.` });
5828
- }
5829
- if (blockReason === "virtual_fs") {
5830
- return res.status(400).json({ error: `Cannot use paths under "${displayPath}" for workspaces.` });
5831
- }
6023
+ const blockError = rootDirBlockError(blockReason, displayPath);
6024
+ if (blockError) return res.status(400).json({ error: blockError });
5832
6025
  const dirExists = await checkDirExists(resolvedPath);
5833
6026
  if (dirExists) {
5834
6027
  const writableErr = await validatePathWritable(resolvedPath);
@@ -5865,29 +6058,25 @@ function createWorkspaceConfigRoutes(sessionManager) {
5865
6058
  }
5866
6059
  res.json({ config: { ...config3, rootDir: savedRootDir ?? void 0 } });
5867
6060
  } catch (err) {
5868
- res.status(500).json({ error: err instanceof Error ? err.message : "Failed to save config" });
6061
+ res.status(500).json({
6062
+ error: err instanceof Error ? err.message : serverT({ en: "Failed to save config", fr: "\xC9chec de l\u2019enregistrement de la configuration" })
6063
+ });
5869
6064
  }
5870
6065
  });
5871
6066
  router.post("/config/validate", async (req, res) => {
5872
6067
  const { rootDir, workdir, projectName, createIfMissing } = req.body;
5873
6068
  if (!rootDir || typeof rootDir !== "string") {
5874
- return res.status(400).json({ error: "rootDir is required" });
6069
+ return res.status(400).json({ error: serverT({ en: "rootDir is required", fr: "rootDir est requis" }) });
5875
6070
  }
5876
6071
  if (!workdir || typeof workdir !== "string") {
5877
- return res.status(400).json({ error: "workdir is required" });
6072
+ return res.status(400).json({ error: serverT({ en: "workdir is required", fr: "workdir est requis" }) });
5878
6073
  }
5879
6074
  const resolvedPath = resolveRootDir(rootDir, workdir);
5880
6075
  const displayPath = formatRootDir(resolvedPath);
5881
6076
  const blockReason = getRootDirBlockReason(resolvedPath);
5882
- if (blockReason === "exact") {
5883
- const suggestion = typeof projectName === "string" ? suggestRootDirChild(resolvedPath, projectName) : void 0;
5884
- return res.status(400).json({
5885
- 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.`
5886
- });
5887
- }
5888
- if (blockReason === "virtual_fs") {
5889
- return res.status(400).json({ error: `Cannot use paths under "${displayPath}" for workspaces.` });
5890
- }
6077
+ const suggestion = typeof projectName === "string" ? suggestRootDirChild(resolvedPath, projectName) : void 0;
6078
+ const blockError = rootDirBlockError(blockReason, displayPath, suggestion);
6079
+ if (blockError) return res.status(400).json({ error: blockError });
5891
6080
  let dirExists = await checkDirExists(resolvedPath);
5892
6081
  if (dirExists) {
5893
6082
  const writableErr = await validatePathWritable(resolvedPath);
@@ -5946,7 +6135,7 @@ function createTerminalRoutes() {
5946
6135
  if (success) {
5947
6136
  res.status(204).send();
5948
6137
  } else {
5949
- res.status(404).json({ error: "Terminal not found" });
6138
+ res.status(404).json({ error: serverT({ en: "Terminal not found", fr: "Terminal introuvable" }) });
5950
6139
  }
5951
6140
  });
5952
6141
  router.get("/:id", (req, res) => {
@@ -5955,7 +6144,7 @@ function createTerminalRoutes() {
5955
6144
  if (session) {
5956
6145
  res.json({ id: session.id, workdir: session.workdir });
5957
6146
  } else {
5958
- res.status(404).json({ error: "Terminal not found" });
6147
+ res.status(404).json({ error: serverT({ en: "Terminal not found", fr: "Terminal introuvable" }) });
5959
6148
  }
5960
6149
  });
5961
6150
  return router;
@@ -5989,7 +6178,7 @@ function createDirectoryRoutes() {
5989
6178
  });
5990
6179
  } catch {
5991
6180
  res.status(400).json({
5992
- error: "Cannot read directory",
6181
+ error: serverT({ en: "Cannot read directory", fr: "Impossible de lire le r\xE9pertoire" }),
5993
6182
  current: DEFAULT_BASE_PATH,
5994
6183
  parent: null,
5995
6184
  directories: [],
@@ -6022,7 +6211,7 @@ function createFileSearchRoutes() {
6022
6211
  const results = await searchFiles(query, workdir);
6023
6212
  res.json(results);
6024
6213
  } catch {
6025
- res.status(500).json({ error: "File search failed" });
6214
+ res.status(500).json({ error: serverT({ en: "File search failed", fr: "\xC9chec de la recherche de fichiers" }) });
6026
6215
  }
6027
6216
  });
6028
6217
  return router;
@@ -6127,6 +6316,11 @@ async function checkAuth(req, opts) {
6127
6316
  }
6128
6317
  return true;
6129
6318
  }
6319
+ async function requireAuth(req, res, opts) {
6320
+ if (await checkAuth(req, opts)) return true;
6321
+ res.status(401).json({ error: serverT({ en: "Unauthorized", fr: "Non autoris\xE9" }) });
6322
+ return false;
6323
+ }
6130
6324
  function isDevMode() {
6131
6325
  return process.env["NODE_ENV"] === "development";
6132
6326
  }
@@ -6252,12 +6446,9 @@ function createAutoUpdateRoutes(options = {}) {
6252
6446
  }
6253
6447
  });
6254
6448
  router.post("/", async (req, res) => {
6255
- if (!await checkAuth(req, options)) {
6256
- res.status(401).json({ error: "Unauthorized" });
6257
- return;
6258
- }
6449
+ if (!await requireAuth(req, res, options)) return;
6259
6450
  if (updateInProgress) {
6260
- res.status(409).json({ error: "Update already in progress" });
6451
+ res.status(409).json({ error: serverT({ en: "Update already in progress", fr: "Une mise \xE0 jour est d\xE9j\xE0 en cours" }) });
6261
6452
  return;
6262
6453
  }
6263
6454
  updateInProgress = true;
@@ -6289,20 +6480,19 @@ function createAutoUpdateRoutes(options = {}) {
6289
6480
  const version = versionMatch?.[1] ?? VERSION;
6290
6481
  res.json({ success: true, version, isService });
6291
6482
  } else {
6292
- const error = exitCode === null ? "Update timed out" : stderr || stdout || "Update failed";
6483
+ 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" });
6293
6484
  res.json({ success: false, error, isService });
6294
6485
  }
6295
6486
  } catch (err) {
6296
- res.status(500).json({ error: err instanceof Error ? err.message : "Update failed to start" });
6487
+ res.status(500).json({
6488
+ error: err instanceof Error ? err.message : serverT({ en: "Update failed to start", fr: "\xC9chec du d\xE9marrage de la mise \xE0 jour" })
6489
+ });
6297
6490
  } finally {
6298
6491
  updateInProgress = false;
6299
6492
  }
6300
6493
  });
6301
6494
  router.post("/restart", async (req, res) => {
6302
- if (!await checkAuth(req, options)) {
6303
- res.status(401).json({ error: "Unauthorized" });
6304
- return;
6305
- }
6495
+ if (!await requireAuth(req, res, options)) return;
6306
6496
  try {
6307
6497
  const child = spawn2("openfox service restart", {
6308
6498
  detached: true,
@@ -6313,7 +6503,9 @@ function createAutoUpdateRoutes(options = {}) {
6313
6503
  child.unref();
6314
6504
  res.json({ success: true });
6315
6505
  } catch (err) {
6316
- res.status(500).json({ error: err instanceof Error ? err.message : "Failed to trigger restart" });
6506
+ res.status(500).json({
6507
+ error: err instanceof Error ? err.message : serverT({ en: "Failed to trigger restart", fr: "\xC9chec du d\xE9clenchement du red\xE9marrage" })
6508
+ });
6317
6509
  }
6318
6510
  });
6319
6511
  return router;
@@ -6326,13 +6518,19 @@ function createProviderAuthRoutes(config3, providerManager, registry) {
6326
6518
  function resolveAuthContext(providerId, res) {
6327
6519
  const provider = providerManager.getProviders().find((item) => item.id === providerId);
6328
6520
  if (!provider) {
6329
- res.status(404).json({ error: "Provider not found" });
6521
+ res.status(404).json({ error: serverT({ en: "Provider not found", fr: "Fournisseur introuvable" }) });
6330
6522
  return void 0;
6331
6523
  }
6332
6524
  return { provider, adapter: registry.getAuth(provider.authAdapter) };
6333
6525
  }
6334
6526
  function missingAuthPlugin(provider) {
6335
- return `Missing provider auth plugin: ${provider.authAdapter ?? "unknown"}`;
6527
+ return serverT(
6528
+ {
6529
+ en: "Missing provider auth plugin: {{adapter}}",
6530
+ fr: "Plugin d\u2019authentification du fournisseur manquant : {{adapter}}"
6531
+ },
6532
+ { adapter: provider.authAdapter ?? "unknown" }
6533
+ );
6336
6534
  }
6337
6535
  router.post("/:providerId/login", async (req, res) => {
6338
6536
  const context = resolveAuthContext(req.params.providerId, res);
@@ -6356,7 +6554,12 @@ function createProviderAuthRoutes(config3, providerManager, registry) {
6356
6554
  });
6357
6555
  res.json(challenge);
6358
6556
  } catch (error) {
6359
- res.status(502).json({ error: error instanceof Error ? error.message : "Unable to start provider login" });
6557
+ res.status(502).json({
6558
+ error: error instanceof Error ? error.message : serverT({
6559
+ en: "Unable to start provider login",
6560
+ fr: "Impossible de d\xE9marrer la connexion au fournisseur"
6561
+ })
6562
+ });
6360
6563
  }
6361
6564
  });
6362
6565
  router.get("/:providerId/status", async (req, res) => {
@@ -6593,15 +6796,15 @@ function createPluginRoutes(options) {
6593
6796
  router.post("/install", async (req, res) => {
6594
6797
  const { githubUrl } = req.body;
6595
6798
  if (!githubUrl || typeof githubUrl !== "string") {
6596
- return res.status(400).json({ error: "githubUrl is required" });
6799
+ return res.status(400).json({ error: serverT({ en: "githubUrl is required", fr: "githubUrl est requis" }) });
6597
6800
  }
6598
6801
  const parsed = githubUrl.match(/github\.com\/([^/]+)\/([^/]+?)(?:\/|$)/);
6599
6802
  if (!parsed) {
6600
- return res.status(400).json({ error: "Invalid GitHub URL" });
6803
+ return res.status(400).json({ error: serverT({ en: "Invalid GitHub URL", fr: "URL GitHub invalide" }) });
6601
6804
  }
6602
6805
  const repoName = parsed[2].replace(/\.git$/, "");
6603
6806
  if (!/^[a-zA-Z0-9_-]+$/.test(repoName)) {
6604
- return res.status(400).json({ error: "Invalid repository name" });
6807
+ return res.status(400).json({ error: serverT({ en: "Invalid repository name", fr: "Nom de d\xE9p\xF4t invalide" }) });
6605
6808
  }
6606
6809
  const pluginsDir = join8(getGlobalConfigDir(config3.mode ?? "production"), "plugins");
6607
6810
  const targetDir = join8(pluginsDir, repoName);
@@ -6609,7 +6812,12 @@ function createPluginRoutes(options) {
6609
6812
  try {
6610
6813
  await execFileP("mkdir", ["-p", pluginsDir], { timeout: 5e3 });
6611
6814
  } catch {
6612
- return res.status(500).json({ error: "Failed to create plugins directory" });
6815
+ return res.status(500).json({
6816
+ error: serverT({
6817
+ en: "Failed to create plugins directory",
6818
+ fr: "\xC9chec de la cr\xE9ation du r\xE9pertoire des plugins"
6819
+ })
6820
+ });
6613
6821
  }
6614
6822
  let gitOk = false;
6615
6823
  try {
@@ -6618,7 +6826,12 @@ function createPluginRoutes(options) {
6618
6826
  } catch {
6619
6827
  }
6620
6828
  if (!gitOk) {
6621
- return res.status(500).json({ error: "git is not installed or not found in PATH" });
6829
+ return res.status(500).json({
6830
+ error: serverT({
6831
+ en: "git is not installed or not found in PATH",
6832
+ fr: "git n\u2019est pas install\xE9 ou introuvable dans le PATH"
6833
+ })
6834
+ });
6622
6835
  }
6623
6836
  try {
6624
6837
  const cloneUrl = githubUrl.replace(/\/$/, "") + ".git";
@@ -6631,7 +6844,10 @@ function createPluginRoutes(options) {
6631
6844
  await execFileP("npm", ["install", "--no-audit", "--no-fund"], { cwd: targetDir, timeout: 12e4 });
6632
6845
  await execFileP("npm", ["run", "build"], { cwd: targetDir, timeout: 12e4 });
6633
6846
  } catch (err) {
6634
- loadError = "Failed to install/build plugin dependencies";
6847
+ loadError = serverT({
6848
+ en: "Failed to install/build plugin dependencies",
6849
+ fr: "\xC9chec de l\u2019installation/du build des d\xE9pendances du plugin"
6850
+ });
6635
6851
  logger2.error("Plugin build failed", { repoName, error: String(err) });
6636
6852
  }
6637
6853
  if (!loadError) {
@@ -6640,13 +6856,25 @@ function createPluginRoutes(options) {
6640
6856
  const pluginEntry = manifest.openfox?.plugin;
6641
6857
  const apiVersion = manifest.openfox?.apiVersion;
6642
6858
  if (!pluginEntry || !manifest.name) {
6643
- loadError = "Plugin package.json is missing openfox.plugin or name field";
6859
+ loadError = serverT({
6860
+ en: "Plugin package.json is missing openfox.plugin or name field",
6861
+ fr: "Le package.json du plugin ne contient pas le champ openfox.plugin ou name"
6862
+ });
6644
6863
  } else if (apiVersion !== 1) {
6645
- loadError = `Unsupported plugin API version: ${String(apiVersion)}`;
6864
+ loadError = serverT(
6865
+ {
6866
+ en: "Unsupported plugin API version: {{version}}",
6867
+ fr: "Version d\u2019API de plugin non prise en charge : {{version}}"
6868
+ },
6869
+ { version: String(apiVersion) }
6870
+ );
6646
6871
  } else {
6647
6872
  const mod = await import(pathToFileURL2(join8(targetDir, pluginEntry)).href);
6648
6873
  if (typeof mod.register !== "function") {
6649
- loadError = "Plugin does not export register(registry)";
6874
+ loadError = serverT({
6875
+ en: "Plugin does not export register(registry)",
6876
+ fr: "Le plugin n\u2019exporte pas register(registry)"
6877
+ });
6650
6878
  } else {
6651
6879
  const diagnostic = {
6652
6880
  packageName: manifest.name,
@@ -6680,14 +6908,14 @@ function createPluginRoutes(options) {
6680
6908
  }
6681
6909
  }
6682
6910
  } catch (err) {
6683
- loadError = err instanceof Error ? err.message : "Failed to load plugin";
6911
+ loadError = err instanceof Error ? err.message : serverT({ en: "Failed to load plugin", fr: "\xC9chec du chargement du plugin" });
6684
6912
  logger2.error("Plugin runtime load failed", { repoName, error: loadError });
6685
6913
  }
6686
6914
  }
6687
6915
  res.json({ success: true, loaded, loadError, path: targetDir });
6688
6916
  } catch (err) {
6689
6917
  await rm2(tmpDir, { recursive: true, force: true });
6690
- const msg = err instanceof Error ? err.message : "Clone failed";
6918
+ const msg = err instanceof Error ? err.message : serverT({ en: "Clone failed", fr: "\xC9chec du clonage" });
6691
6919
  logger2.error("Plugin install failed", { githubUrl, error: msg });
6692
6920
  res.status(500).json({ error: msg });
6693
6921
  }
@@ -6719,14 +6947,15 @@ function createPluginRoutes(options) {
6719
6947
  });
6720
6948
  router.get("/:name/open-folder", async (req, res) => {
6721
6949
  const name = req.params.name;
6722
- if (!/^[a-zA-Z0-9_-]+$/.test(name)) return res.status(400).json({ error: "Invalid plugin name" });
6950
+ if (!/^[a-zA-Z0-9_-]+$/.test(name))
6951
+ return res.status(400).json({ error: serverT({ en: "Invalid plugin name", fr: "Nom de plugin invalide" }) });
6723
6952
  const targetDir = join8(getGlobalConfigDir(config3.mode ?? "production"), "plugins", name);
6724
6953
  await openFolderRoute(targetDir, res);
6725
6954
  });
6726
6955
  router.delete("/:name", async (req, res) => {
6727
6956
  const name = req.params.name;
6728
6957
  if (!/^[a-zA-Z0-9_-]+$/.test(name)) {
6729
- return res.status(400).json({ error: "Invalid plugin name" });
6958
+ return res.status(400).json({ error: serverT({ en: "Invalid plugin name", fr: "Nom de plugin invalide" }) });
6730
6959
  }
6731
6960
  const targetDir = join8(getGlobalConfigDir(config3.mode ?? "production"), "plugins", name);
6732
6961
  try {
@@ -6736,7 +6965,9 @@ function createPluginRoutes(options) {
6736
6965
  }
6737
6966
  res.json({ success: true });
6738
6967
  } catch (err) {
6739
- res.status(500).json({ error: err instanceof Error ? err.message : "Failed to remove plugin" });
6968
+ res.status(500).json({
6969
+ error: err instanceof Error ? err.message : serverT({ en: "Failed to remove plugin", fr: "\xC9chec de la suppression du plugin" })
6970
+ });
6740
6971
  }
6741
6972
  });
6742
6973
  return router;
@@ -6749,11 +6980,16 @@ function registerSessionFavoriteRoute(router, sessionManager) {
6749
6980
  const id = req.params["id"];
6750
6981
  const { isFavorite } = req.body;
6751
6982
  if (typeof isFavorite !== "boolean") {
6752
- return res.status(400).json({ error: "isFavorite is required and must be a boolean" });
6983
+ return res.status(400).json({
6984
+ error: serverT({
6985
+ en: "isFavorite is required and must be a boolean",
6986
+ fr: "isFavorite est requis et doit \xEAtre un bool\xE9en"
6987
+ })
6988
+ });
6753
6989
  }
6754
6990
  const session = sessionManager.getSession(id);
6755
6991
  if (!session) {
6756
- return res.status(404).json({ error: "Session not found" });
6992
+ return res.status(404).json({ error: serverT({ en: "Session not found", fr: "Session introuvable" }) });
6757
6993
  }
6758
6994
  toggleFavorite(id, isFavorite);
6759
6995
  res.json({ success: true });
@@ -6810,7 +7046,7 @@ function detectWsl() {
6810
7046
  // src/server/index.ts
6811
7047
  var __dirname3 = dirname7(fileURLToPath6(import.meta.url));
6812
7048
  async function announceContextDrift(sessionManager, sessionIds) {
6813
- const { injectContextDriftRemindersForSessions } = await import("./dynamic-context-NJZKAZE3.js");
7049
+ const { injectContextDriftRemindersForSessions } = await import("./dynamic-context-LKC6JYLQ.js");
6814
7050
  await injectContextDriftRemindersForSessions(sessionManager, sessionIds);
6815
7051
  }
6816
7052
  async function createServerHandle(config3) {
@@ -6917,7 +7153,7 @@ async function createServerHandle(config3) {
6917
7153
  toolRegistry = createToolRegistry();
6918
7154
  logger.info("MCP tools registered", { count: mcpTools.length });
6919
7155
  }
6920
- const { signalMcpReady } = await import("./server-GXMZMPXI.js");
7156
+ const { signalMcpReady } = await import("./server-ZHEB7XS2.js");
6921
7157
  signalMcpReady();
6922
7158
  });
6923
7159
  const app = express();
@@ -7028,9 +7264,9 @@ async function createServerHandle(config3) {
7028
7264
  if (!name || !workdir) {
7029
7265
  return res.status(400).json({ error: "name and workdir are required" });
7030
7266
  }
7031
- const { createDirectoryWithGit } = await import("./project-creator-6AGQTNXB.js");
7267
+ const { createProjectDirectory } = await import("./project-creator-T3A4H3YV.js");
7032
7268
  try {
7033
- const project = await createDirectoryWithGit(name, workdir);
7269
+ const project = await createProjectDirectory(name, workdir);
7034
7270
  res.status(201).json({ project });
7035
7271
  } catch (err) {
7036
7272
  const eaccError = err;
@@ -7132,9 +7368,9 @@ async function createServerHandle(config3) {
7132
7368
  const sessionFavoriteRouter = express.Router();
7133
7369
  registerSessionFavoriteRoute(sessionFavoriteRouter, sessionManager);
7134
7370
  app.use("/api", sessionFavoriteRouter);
7135
- const { createTasksService } = await import("./service-O3LCO3TQ.js");
7136
- const { registerTaskRoutes } = await import("./tasks-WOC3QUFA.js");
7137
- const { setTasksService } = await import("./tools-CW6POKUL.js");
7371
+ const { createTasksService } = await import("./service-XIUNS5XV.js");
7372
+ const { registerTaskRoutes } = await import("./tasks-3JJWJJ3X.js");
7373
+ const { setTasksService } = await import("./tools-E63MOJBO.js");
7138
7374
  const tasksService = createTasksService({
7139
7375
  sessionManager,
7140
7376
  config: config3,
@@ -7166,7 +7402,7 @@ async function createServerHandle(config3) {
7166
7402
  }
7167
7403
  try {
7168
7404
  await checkoutBranch(project.workdir, branch);
7169
- const { updateSessionBranch: updateSessionBranch2 } = await import("./sessions-NMPX5ICI.js");
7405
+ const { updateSessionBranch: updateSessionBranch2 } = await import("./sessions-AOK3AGHY.js");
7170
7406
  const allSessions = sessionManager.listSessions();
7171
7407
  for (const s of allSessions) {
7172
7408
  if (sessionManager.getEffectiveWorkdir(s.id) === project.workdir) {
@@ -7202,7 +7438,7 @@ async function createServerHandle(config3) {
7202
7438
  );
7203
7439
  }
7204
7440
  await createBranch(project.workdir, name, sb);
7205
- const { updateSessionBranch: updateSessionBranch2 } = await import("./sessions-NMPX5ICI.js");
7441
+ const { updateSessionBranch: updateSessionBranch2 } = await import("./sessions-AOK3AGHY.js");
7206
7442
  const allSessions = sessionManager.listSessions();
7207
7443
  for (const s of allSessions) {
7208
7444
  if (sessionManager.getEffectiveWorkdir(s.id) === project.workdir) {
@@ -7234,7 +7470,7 @@ async function createServerHandle(config3) {
7234
7470
  if (!branch || typeof branch !== "string") return res.status(400).json({ error: "branch is required" });
7235
7471
  const effectiveWorkdir = sessionManager.getEffectiveWorkdir(req.params.id);
7236
7472
  const { checkoutBranch, validateRef: validateRef2 } = await import("./workspace-LM646OHC.js");
7237
- const { updateSessionBranch: updateSessionBranch2 } = await import("./sessions-NMPX5ICI.js");
7473
+ const { updateSessionBranch: updateSessionBranch2 } = await import("./sessions-AOK3AGHY.js");
7238
7474
  try {
7239
7475
  await validateRef2(effectiveWorkdir, branch);
7240
7476
  await checkoutBranch(effectiveWorkdir, branch);
@@ -7277,7 +7513,7 @@ All file and git operations should use this branch.
7277
7513
  if (!name || typeof name !== "string") return res.status(400).json({ error: "name is required" });
7278
7514
  const effectiveWorkdir = sessionManager.getEffectiveWorkdir(req.params.id);
7279
7515
  const { validateRef: validateRef2 } = await import("./workspace-LM646OHC.js");
7280
- const { updateSessionBranch: updateSessionBranch2 } = await import("./sessions-NMPX5ICI.js");
7516
+ const { updateSessionBranch: updateSessionBranch2 } = await import("./sessions-AOK3AGHY.js");
7281
7517
  try {
7282
7518
  await validateRef2(effectiveWorkdir, name);
7283
7519
  if (sourceBranch) {
@@ -7332,8 +7568,8 @@ All file and git operations should use this branch.
7332
7568
  res.json({ workspaces: workspacesList });
7333
7569
  });
7334
7570
  app.get("/api/sessions", async (req, res) => {
7335
- const { getRecentUserPromptsForSession } = await import("./events-ZJPRGVL2.js");
7336
- const { getPendingConfirmationsBySession: getPendingConfirmationsBySession2 } = await import("./path-security-CBACXAMS.js");
7571
+ const { getRecentUserPromptsForSession } = await import("./events-335XAKFK.js");
7572
+ const { getPendingConfirmationsBySession: getPendingConfirmationsBySession2 } = await import("./path-security-4LROI7F4.js");
7337
7573
  const projectId = req.query["projectId"];
7338
7574
  const rawLimit = req.query["limit"];
7339
7575
  const offset = parseInt(req.query["offset"]) || 0;
@@ -7369,6 +7605,31 @@ All file and git operations should use this branch.
7369
7605
  app.get("/api/sessions/home", (_req, res) => {
7370
7606
  res.json({ sessions: sessionManager.listHomeSessions() });
7371
7607
  });
7608
+ function buildSessionCreatedMessage(session) {
7609
+ return {
7610
+ type: "session.created",
7611
+ sessionId: session.id,
7612
+ payload: {
7613
+ session: {
7614
+ id: session.id,
7615
+ projectId: session.projectId,
7616
+ title: session.metadata.title,
7617
+ workdir: session.workdir,
7618
+ workspace: session.workspace,
7619
+ mode: session.mode,
7620
+ phase: session.phase,
7621
+ isRunning: session.isRunning,
7622
+ providerId: session.providerId,
7623
+ providerModel: session.providerModel,
7624
+ createdAt: session.createdAt,
7625
+ updatedAt: session.updatedAt,
7626
+ criteriaCount: session.criteria.length,
7627
+ criteriaCompleted: session.criteria.filter((c) => c.status.type === "passed").length,
7628
+ messageCount: session.messageCount ?? session.messages.length
7629
+ }
7630
+ }
7631
+ };
7632
+ }
7372
7633
  app.post("/api/sessions", async (req, res) => {
7373
7634
  const { projectId, title } = req.body;
7374
7635
  if (!projectId) {
@@ -7388,34 +7649,12 @@ All file and git operations should use this branch.
7388
7649
  disabledServers = mcpManager.getAllServers().filter((s) => s.config.disabled).map((s) => s.name);
7389
7650
  }
7390
7651
  if (disabledServers.length > 0) {
7391
- const { setSessionDisabledServers: setSessionDisabledServers2 } = await import("./session-overrides-OECQYRDK.js");
7652
+ const { setSessionDisabledServers: setSessionDisabledServers2 } = await import("./session-overrides-LYW5PJ3R.js");
7392
7653
  setSessionDisabledServers2(session.id, disabledServers);
7393
7654
  }
7394
7655
  } catch {
7395
7656
  }
7396
- wssExports.broadcastForProject(projectId, session.id, {
7397
- type: "session.created",
7398
- sessionId: session.id,
7399
- payload: {
7400
- session: {
7401
- id: session.id,
7402
- projectId: session.projectId,
7403
- title: session.metadata.title,
7404
- workdir: session.workdir,
7405
- workspace: session.workspace,
7406
- mode: session.mode,
7407
- phase: session.phase,
7408
- isRunning: session.isRunning,
7409
- providerId: session.providerId,
7410
- providerModel: session.providerModel,
7411
- createdAt: session.createdAt,
7412
- updatedAt: session.updatedAt,
7413
- criteriaCount: session.criteria.length,
7414
- criteriaCompleted: session.criteria.filter((c) => c.status.type === "passed").length,
7415
- messageCount: session.messageCount ?? session.messages.length
7416
- }
7417
- }
7418
- });
7657
+ wssExports.broadcastForProject(projectId, session.id, buildSessionCreatedMessage(session));
7419
7658
  res.status(201).json({ session: toClientSession(session) });
7420
7659
  });
7421
7660
  app.post("/api/sessions/:id/switch-workspace", async (req, res) => {
@@ -7461,10 +7700,10 @@ All file and git operations should use this branch.
7461
7700
  }
7462
7701
  });
7463
7702
  app.get("/api/sessions/:id", async (req, res) => {
7464
- const { getEventStore: getEventStore2, combineEventsWithSnapshot: combineEventsWithSnapshot2 } = await import("./events-ZJPRGVL2.js");
7465
- const { buildMessagesFromStoredEvents: buildMessagesFromStoredEvents2, foldPendingConfirmations } = await import("./folding-QRZOHY2I.js");
7466
- const { getPendingQuestionsForSession: getPendingQuestionsForSession2 } = await import("./tools-CW6POKUL.js");
7467
- const { getMaxVisibleItems } = await import("./settings-MDCRNQBY.js");
7703
+ const { getEventStore: getEventStore2, combineEventsWithSnapshot: combineEventsWithSnapshot2 } = await import("./events-335XAKFK.js");
7704
+ const { buildMessagesFromStoredEvents: buildMessagesFromStoredEvents2, foldPendingConfirmations } = await import("./folding-H7JTX6KI.js");
7705
+ const { getPendingQuestionsForSession: getPendingQuestionsForSession2 } = await import("./tools-E63MOJBO.js");
7706
+ const { getMaxVisibleItems } = await import("./settings-ZJPM6PQV.js");
7468
7707
  const session = sessionManager.getSession(req.params.id);
7469
7708
  if (!session) {
7470
7709
  return res.status(404).json({ error: "Session not found" });
@@ -7492,9 +7731,9 @@ All file and git operations should use this branch.
7492
7731
  });
7493
7732
  app.get("/api/sessions/:id/status", async (req, res) => {
7494
7733
  const { projectSessionStatus: projectSessionStatus2 } = await import("./session-status-UFO5IFI7.js");
7495
- const { getPendingQuestionsForSession: getPendingQuestionsForSession2 } = await import("./tools-CW6POKUL.js");
7496
- const { getEventStore: getEventStore2, combineEventsWithSnapshot: combineEventsWithSnapshot2 } = await import("./events-ZJPRGVL2.js");
7497
- const { foldPendingConfirmations } = await import("./folding-QRZOHY2I.js");
7734
+ const { getPendingQuestionsForSession: getPendingQuestionsForSession2 } = await import("./tools-E63MOJBO.js");
7735
+ const { getEventStore: getEventStore2, combineEventsWithSnapshot: combineEventsWithSnapshot2 } = await import("./events-335XAKFK.js");
7736
+ const { foldPendingConfirmations } = await import("./folding-H7JTX6KI.js");
7498
7737
  const sessionId = req.params["id"];
7499
7738
  if (!sessionId) {
7500
7739
  return res.status(400).json({ error: "Session id is required" });
@@ -7524,8 +7763,8 @@ All file and git operations should use this branch.
7524
7763
  if (!session) {
7525
7764
  return res.status(404).json({ error: "Session not found" });
7526
7765
  }
7527
- const { stopSessionExecution } = await import("./chat-handler-T47GATL5.js");
7528
- const { cancelQuestionsForSession, cancelPathConfirmationsForSession } = await import("./tools-CW6POKUL.js");
7766
+ const { stopSessionExecution } = await import("./chat-handler-WGDFMOOD.js");
7767
+ const { cancelQuestionsForSession, cancelPathConfirmationsForSession } = await import("./tools-E63MOJBO.js");
7529
7768
  sessionManager.clearMessageQueue(sessionId);
7530
7769
  stopSessionExecution(sessionId, sessionManager);
7531
7770
  abortSession(sessionId);
@@ -7554,9 +7793,9 @@ All file and git operations should use this branch.
7554
7793
  res.json({ success: true });
7555
7794
  });
7556
7795
  app.post("/api/sessions/:id/provider", async (req, res) => {
7557
- const { getEventStore: getEventStore2, combineEventsWithSnapshot: combineEv } = await import("./events-ZJPRGVL2.js");
7558
- const { buildMessagesFromStoredEvents: buildMessagesFromStoredEvents2 } = await import("./folding-QRZOHY2I.js");
7559
- const { getMaxVisibleItems } = await import("./settings-MDCRNQBY.js");
7796
+ const { getEventStore: getEventStore2, combineEventsWithSnapshot: combineEv } = await import("./events-335XAKFK.js");
7797
+ const { buildMessagesFromStoredEvents: buildMessagesFromStoredEvents2 } = await import("./folding-H7JTX6KI.js");
7798
+ const { getMaxVisibleItems } = await import("./settings-ZJPM6PQV.js");
7560
7799
  const sessionId = req.params.id;
7561
7800
  const session = sessionManager.getSession(sessionId);
7562
7801
  if (!session) {
@@ -7584,9 +7823,9 @@ All file and git operations should use this branch.
7584
7823
  res.json({ session: toClientSession(updatedSession), messages, hiddenCount, contextState });
7585
7824
  });
7586
7825
  app.delete("/api/sessions/:id/provider", async (req, res) => {
7587
- const { getEventStore: getEventStore2, combineEventsWithSnapshot: combineEv } = await import("./events-ZJPRGVL2.js");
7588
- const { buildMessagesFromStoredEvents: buildMessagesFromStoredEvents2 } = await import("./folding-QRZOHY2I.js");
7589
- const { getMaxVisibleItems } = await import("./settings-MDCRNQBY.js");
7826
+ const { getEventStore: getEventStore2, combineEventsWithSnapshot: combineEv } = await import("./events-335XAKFK.js");
7827
+ const { buildMessagesFromStoredEvents: buildMessagesFromStoredEvents2 } = await import("./folding-H7JTX6KI.js");
7828
+ const { getMaxVisibleItems } = await import("./settings-ZJPM6PQV.js");
7590
7829
  const sessionId = req.params.id;
7591
7830
  const session = sessionManager.getSession(sessionId);
7592
7831
  if (!session) {
@@ -7716,9 +7955,9 @@ All file and git operations should use this branch.
7716
7955
  res.json({ success: true });
7717
7956
  });
7718
7957
  app.put("/api/sessions/:id/mode", async (req, res) => {
7719
- const { getEventStore: getEventStore2, combineEventsWithSnapshot: combineEv } = await import("./events-ZJPRGVL2.js");
7720
- const { buildMessagesFromStoredEvents: buildMessagesFromStoredEvents2 } = await import("./folding-QRZOHY2I.js");
7721
- const { getMaxVisibleItems } = await import("./settings-MDCRNQBY.js");
7958
+ const { getEventStore: getEventStore2, combineEventsWithSnapshot: combineEv } = await import("./events-335XAKFK.js");
7959
+ const { buildMessagesFromStoredEvents: buildMessagesFromStoredEvents2 } = await import("./folding-H7JTX6KI.js");
7960
+ const { getMaxVisibleItems } = await import("./settings-ZJPM6PQV.js");
7722
7961
  const sessionId = req.params.id;
7723
7962
  const session = sessionManager.getSession(sessionId);
7724
7963
  if (!session) {
@@ -7778,7 +8017,7 @@ All file and git operations should use this branch.
7778
8017
  setSessionDisabledServers(sessionId, disabledServers);
7779
8018
  const messages = session.messages ?? [];
7780
8019
  if (messages.length === 0) {
7781
- const { applyDynamicContext } = await import("./dynamic-context-NJZKAZE3.js");
8020
+ const { applyDynamicContext } = await import("./dynamic-context-LKC6JYLQ.js");
7782
8021
  const modelName = session.providerModel ?? providerManager.getCurrentModel();
7783
8022
  await applyDynamicContext(sessionManager, sessionId, modelName);
7784
8023
  } else {
@@ -7812,7 +8051,7 @@ All file and git operations should use this branch.
7812
8051
  if (alwaysAllow !== void 0 && typeof alwaysAllow !== "boolean") {
7813
8052
  return res.status(400).json({ error: "alwaysAllow must be a boolean if provided" });
7814
8053
  }
7815
- const { providePathConfirmation: providePathConfirmation2, getConfirmationSessionId } = await import("./tools-CW6POKUL.js");
8054
+ const { providePathConfirmation: providePathConfirmation2, getConfirmationSessionId } = await import("./tools-E63MOJBO.js");
7816
8055
  const pendingSessionId = getConfirmationSessionId(callId);
7817
8056
  if (!pendingSessionId) {
7818
8057
  return res.status(404).json({ error: "No pending path confirmation with that ID" });
@@ -7824,11 +8063,11 @@ All file and git operations should use this branch.
7824
8063
  if (!result.found) {
7825
8064
  return res.status(404).json({ error: "No pending path confirmation with that ID" });
7826
8065
  }
7827
- const { getEventStore: getEventStore2, combineEventsWithSnapshot: combineEvents } = await import("./events-ZJPRGVL2.js");
7828
- const { buildMessagesFromStoredEvents: buildMessagesFromStoredEvents2, foldPendingConfirmations } = await import("./folding-QRZOHY2I.js");
7829
- const { createSessionStateMessage } = await import("./protocol-Y7MRKRUO.js");
7830
- const { getPendingQuestionsForSession: getPendingQuestionsForSession2 } = await import("./tools-CW6POKUL.js");
7831
- const { getMaxVisibleItems } = await import("./settings-MDCRNQBY.js");
8066
+ const { getEventStore: getEventStore2, combineEventsWithSnapshot: combineEvents } = await import("./events-335XAKFK.js");
8067
+ const { buildMessagesFromStoredEvents: buildMessagesFromStoredEvents2, foldPendingConfirmations } = await import("./folding-H7JTX6KI.js");
8068
+ const { createSessionStateMessage } = await import("./protocol-XO4ZROAU.js");
8069
+ const { getPendingQuestionsForSession: getPendingQuestionsForSession2 } = await import("./tools-E63MOJBO.js");
8070
+ const { getMaxVisibleItems } = await import("./settings-ZJPM6PQV.js");
7832
8071
  const eventStore = getEventStore2();
7833
8072
  const { snapshot, events: eventsSinceSnapshot } = eventStore.getEventsSinceSnapshot(sessionId);
7834
8073
  const events = combineEvents(sessionId, snapshot, eventsSinceSnapshot);
@@ -7865,7 +8104,7 @@ All file and git operations should use this branch.
7865
8104
  if (!skip && typeof answer !== "string") {
7866
8105
  return res.status(400).json({ error: "answer is required when not skipping" });
7867
8106
  }
7868
- const { provideAnswer: provideAnswer2 } = await import("./tools-CW6POKUL.js");
8107
+ const { provideAnswer: provideAnswer2 } = await import("./tools-E63MOJBO.js");
7869
8108
  const found = provideAnswer2(callId, answer ?? "", skip ?? false);
7870
8109
  if (!found) {
7871
8110
  return res.status(404).json({ error: "No pending question with that ID" });
@@ -7898,7 +8137,7 @@ All file and git operations should use this branch.
7898
8137
  if (!session) {
7899
8138
  return res.status(404).json({ error: "Session not found" });
7900
8139
  }
7901
- const { getSetting: getSetting2, SETTINGS_KEYS } = await import("./settings-MDCRNQBY.js");
8140
+ const { getSetting: getSetting2, SETTINGS_KEYS } = await import("./settings-ZJPM6PQV.js");
7902
8141
  if (getSetting2(SETTINGS_KEYS.CACHE_WARMING) !== "true") {
7903
8142
  return res.json({ success: false, reason: "disabled" });
7904
8143
  }
@@ -7931,7 +8170,7 @@ All file and git operations should use this branch.
7931
8170
  backend: activeProvider?.backend ?? llmClient.getBackend(),
7932
8171
  model: llmClient.getModel()
7933
8172
  };
7934
- const { runAgentTurn, TurnMetrics } = await import("./orchestrator-GX22Y5EM.js");
8173
+ const { runAgentTurn, TurnMetrics } = await import("./orchestrator-JGJWTRO5.js");
7935
8174
  runAgentTurn(
7936
8175
  {
7937
8176
  sessionManager,
@@ -7969,15 +8208,15 @@ All file and git operations should use this branch.
7969
8208
  if (!session) {
7970
8209
  return res.status(404).json({ error: "Session not found" });
7971
8210
  }
7972
- const { stopSessionExecution } = await import("./chat-handler-T47GATL5.js");
7973
- const { cancelQuestionsForSession, cancelPathConfirmationsForSession } = await import("./tools-CW6POKUL.js");
8211
+ const { stopSessionExecution } = await import("./chat-handler-WGDFMOOD.js");
8212
+ const { cancelQuestionsForSession, cancelPathConfirmationsForSession } = await import("./tools-E63MOJBO.js");
7974
8213
  const queuedMessages = sessionManager.getQueueState(sessionId);
7975
8214
  sessionManager.clearMessageQueue(sessionId);
7976
8215
  stopSessionExecution(sessionId, sessionManager);
7977
8216
  abortSession(sessionId);
7978
8217
  cancelQuestionsForSession(sessionId, "Session stopped by user");
7979
8218
  cancelPathConfirmationsForSession(sessionId, "Session stopped by user");
7980
- const eventStore = (await import("./events-ZJPRGVL2.js")).getEventStore();
8219
+ const eventStore = (await import("./events-335XAKFK.js")).getEventStore();
7981
8220
  eventStore.append(sessionId, { type: "running.changed", data: { isRunning: false } });
7982
8221
  res.json({ success: true, queuedMessages });
7983
8222
  });
@@ -7991,7 +8230,7 @@ All file and git operations should use this branch.
7991
8230
  if (typeof messageIndex !== "number" || messageIndex < 0) {
7992
8231
  return res.status(400).json({ error: "messageIndex must be a non-negative number" });
7993
8232
  }
7994
- const { truncateSessionMessages } = await import("./events-ZJPRGVL2.js");
8233
+ const { truncateSessionMessages } = await import("./events-335XAKFK.js");
7995
8234
  truncateSessionMessages(sessionId, messageIndex);
7996
8235
  res.json({ success: true });
7997
8236
  });
@@ -8011,8 +8250,8 @@ All file and git operations should use this branch.
8011
8250
  if (attachments !== void 0 && !Array.isArray(attachments)) {
8012
8251
  return res.status(400).json({ error: "attachments must be an array if provided" });
8013
8252
  }
8014
- const { getEventStore: getEventStore2 } = await import("./events-ZJPRGVL2.js");
8015
- const { buildMessagesFromStoredEvents: buildMessagesFromStoredEvents2 } = await import("./folding-QRZOHY2I.js");
8253
+ const { getEventStore: getEventStore2 } = await import("./events-335XAKFK.js");
8254
+ const { buildMessagesFromStoredEvents: buildMessagesFromStoredEvents2 } = await import("./folding-H7JTX6KI.js");
8016
8255
  const eventStore = getEventStore2();
8017
8256
  const events = eventStore.getEvents(sessionId);
8018
8257
  const { messages } = buildMessagesFromStoredEvents2(events);
@@ -8024,7 +8263,7 @@ All file and git operations should use this branch.
8024
8263
  if (msg.role !== "user" || msg.isSystemGenerated) {
8025
8264
  return res.status(400).json({ error: "Can only replay user messages" });
8026
8265
  }
8027
- const { truncateSessionMessages } = await import("./events-ZJPRGVL2.js");
8266
+ const { truncateSessionMessages } = await import("./events-335XAKFK.js");
8028
8267
  truncateSessionMessages(sessionId, msgIndex - 1);
8029
8268
  sessionManager.queueMessage(
8030
8269
  sessionId,
@@ -8059,6 +8298,43 @@ All file and git operations should use this branch.
8059
8298
  return res.status(500).json({ error: message });
8060
8299
  }
8061
8300
  });
8301
+ app.get("/api/sessions/:id/export", async (req, res) => {
8302
+ const sessionId = req.params.id;
8303
+ const session = sessionManager.getSession(sessionId);
8304
+ if (!session) {
8305
+ return res.status(404).json({ error: "Session not found" });
8306
+ }
8307
+ try {
8308
+ const { buildSessionExport } = await import("./export-import-3WMRLO4A.js");
8309
+ const payload = buildSessionExport(sessionManager, sessionId);
8310
+ const filename = `${(payload.session.title ?? "session").replace(/[^a-zA-Z0-9-_]/g, "_")}.openfox-session.json`;
8311
+ res.setHeader("Content-Disposition", `attachment; filename="${filename}"`);
8312
+ return res.json(payload);
8313
+ } catch (err) {
8314
+ const message = err instanceof Error ? err.message : String(err);
8315
+ return res.status(500).json({ error: message });
8316
+ }
8317
+ });
8318
+ app.post("/api/sessions/import", async (req, res) => {
8319
+ const { projectId, payload } = req.body;
8320
+ if (typeof projectId !== "string" || !projectId) {
8321
+ return res.status(400).json({ error: "projectId is required" });
8322
+ }
8323
+ if (payload === void 0 || payload === null) {
8324
+ return res.status(400).json({ error: "payload is required" });
8325
+ }
8326
+ try {
8327
+ const newSession = await sessionManager.importSession(projectId, payload);
8328
+ wssExports.broadcastForProject(projectId, newSession.id, buildSessionCreatedMessage(newSession));
8329
+ return res.status(201).json({ session: toClientSession(newSession) });
8330
+ } catch (err) {
8331
+ const message = err instanceof Error ? err.message : String(err);
8332
+ if (message.includes("Project not found")) {
8333
+ return res.status(404).json({ error: message });
8334
+ }
8335
+ return res.status(400).json({ error: message });
8336
+ }
8337
+ });
8062
8338
  app.post("/api/sessions/:id/chat", async (req, res) => {
8063
8339
  const sessionId = req.params.id;
8064
8340
  const session = sessionManager.getSession(sessionId);
@@ -8086,7 +8362,7 @@ All file and git operations should use this branch.
8086
8362
  res.json({ accepted: true });
8087
8363
  });
8088
8364
  app.get("/api/settings", async (req, res) => {
8089
- const { getSetting: getSetting2, SETTINGS_DEFAULTS } = await import("./settings-MDCRNQBY.js");
8365
+ const { getSetting: getSetting2, SETTINGS_DEFAULTS } = await import("./settings-ZJPM6PQV.js");
8090
8366
  const keysParam = req.query["keys"];
8091
8367
  if (!keysParam) {
8092
8368
  return res.status(400).json({ error: "keys query parameter is required" });
@@ -8099,19 +8375,19 @@ All file and git operations should use this branch.
8099
8375
  res.json(result);
8100
8376
  });
8101
8377
  app.get("/api/settings/:key", async (req, res) => {
8102
- const { getSetting: getSetting2, SETTINGS_DEFAULTS } = await import("./settings-MDCRNQBY.js");
8378
+ const { getSetting: getSetting2, SETTINGS_DEFAULTS } = await import("./settings-ZJPM6PQV.js");
8103
8379
  const key = req.params.key;
8104
8380
  const value = getSetting2(key) ?? SETTINGS_DEFAULTS[key] ?? null;
8105
8381
  res.json({ key, value });
8106
8382
  });
8107
8383
  app.get("/api/settings/:key", async (req, res) => {
8108
- const { getSetting: getSetting2, SETTINGS_DEFAULTS } = await import("./settings-MDCRNQBY.js");
8384
+ const { getSetting: getSetting2, SETTINGS_DEFAULTS } = await import("./settings-ZJPM6PQV.js");
8109
8385
  const key = req.params.key;
8110
8386
  const value = getSetting2(key) ?? SETTINGS_DEFAULTS[key] ?? null;
8111
8387
  res.json({ key, value });
8112
8388
  });
8113
8389
  app.put("/api/settings/:key", async (req, res) => {
8114
- const { setSetting: setSetting2 } = await import("./settings-MDCRNQBY.js");
8390
+ const { setSetting: setSetting2 } = await import("./settings-ZJPM6PQV.js");
8115
8391
  const key = req.params.key;
8116
8392
  const { value } = req.body;
8117
8393
  if (value === void 0) {
@@ -8138,7 +8414,7 @@ All file and git operations should use this branch.
8138
8414
  }
8139
8415
  });
8140
8416
  app.get("/api/tools/shells", async (_req, res) => {
8141
- const { listAvailableShells } = await import("./platform-5LQXOZO3.js");
8417
+ const { listAvailableShells } = await import("./platform-XPMZKAUB.js");
8142
8418
  res.json({ shells: listAvailableShells() });
8143
8419
  });
8144
8420
  app.get("/api/config", async (_req, res) => {
@@ -8175,7 +8451,8 @@ All file and git operations should use this branch.
8175
8451
  activeProviderId: providerManager.getActiveProviderId(),
8176
8452
  defaultModelSelection: config3.defaultModelSelection,
8177
8453
  visionFallback,
8178
- platform: platformInfo
8454
+ platform: platformInfo,
8455
+ locale: (await import("./settings-ZJPM6PQV.js")).getSetting("display.locale") ?? "automatic"
8179
8456
  });
8180
8457
  });
8181
8458
  app.post("/api/model/refresh", async (_req, res) => {
@@ -8231,7 +8508,7 @@ All file and git operations should use this branch.
8231
8508
  }));
8232
8509
  }
8233
8510
  app.post("/api/proxy/test", async (_req, res) => {
8234
- const { getSetting: getSetting2, SETTINGS_KEYS } = await import("./settings-MDCRNQBY.js");
8511
+ const { getSetting: getSetting2, SETTINGS_KEYS } = await import("./settings-ZJPM6PQV.js");
8235
8512
  const proxyUrl = getSetting2(SETTINGS_KEYS.PROXY_URL);
8236
8513
  if (!proxyUrl) {
8237
8514
  return res.status(400).json({ success: false, error: "No proxy URL configured" });
@@ -8323,7 +8600,7 @@ All file and git operations should use this branch.
8323
8600
  }
8324
8601
  });
8325
8602
  app.post("/api/proxy/test", async (_req, res) => {
8326
- const { getSetting: getSetting2, SETTINGS_KEYS } = await import("./settings-MDCRNQBY.js");
8603
+ const { getSetting: getSetting2, SETTINGS_KEYS } = await import("./settings-ZJPM6PQV.js");
8327
8604
  const proxyUrl = getSetting2(SETTINGS_KEYS.PROXY_URL);
8328
8605
  if (!proxyUrl) {
8329
8606
  return res.status(400).json({ success: false, error: "No proxy URL configured" });
@@ -8350,7 +8627,7 @@ All file and git operations should use this branch.
8350
8627
  const backend = req.query["backend"];
8351
8628
  if (!url) return res.status(400).json({ error: "url is required" });
8352
8629
  try {
8353
- const { fetchModelsWithContext } = await import("./provider-manager-BO5ZBG3T.js");
8630
+ const { fetchModelsWithContext } = await import("./provider-manager-2KKZ37XJ.js");
8354
8631
  const { getModelProfile: getModelProfile2 } = await import("./profiles-EBCVFYG7.js");
8355
8632
  const { getCatalogEntry } = await import("./model-catalog-2PCKTYGW.js");
8356
8633
  const models = await fetchModelsWithContext(
@@ -8425,7 +8702,7 @@ All file and git operations should use this branch.
8425
8702
  const { getModelProfile: getModelProfile2 } = await import("./profiles-EBCVFYG7.js");
8426
8703
  const { getBackendCapabilities } = await import("./backend-NDBY3DAQ.js");
8427
8704
  const { buildNonStreamingCreateParams } = await import("./client-pure-FLKP6PTI.js");
8428
- const { OpenAIHttpClient } = await import("./http-client-P4XTKAZA.js");
8705
+ const { OpenAIHttpClient } = await import("./http-client-A445WYZU.js");
8429
8706
  const { ensureVersionPrefix } = await import("./url-utils-C5BM7NF7.js");
8430
8707
  const profile = getModelProfile2(model);
8431
8708
  const capabilities = getBackendCapabilities(backend || "unknown");
@@ -8842,7 +9119,7 @@ All file and git operations should use this branch.
8842
9119
  });
8843
9120
  async function rebuildMcpTools() {
8844
9121
  const { createMcpTools: createMcpTools2 } = await import("./tool-adapter-FJAFLDZA.js");
8845
- const { setMcpTools: setMcpTools2 } = await import("./tools-CW6POKUL.js");
9122
+ const { setMcpTools: setMcpTools2 } = await import("./tools-E63MOJBO.js");
8846
9123
  const mcpTools = createMcpTools2(mcpManager);
8847
9124
  setMcpTools2(mcpTools);
8848
9125
  toolRegistry = createToolRegistry();
@@ -9272,13 +9549,13 @@ All file and git operations should use this branch.
9272
9549
  })
9273
9550
  );
9274
9551
  app.get("/api/sessions/:id/background-processes", async (req, res) => {
9275
- const { getSessionProcesses } = await import("./manager-TMBFBCQL.js");
9552
+ const { getSessionProcesses } = await import("./manager-ZACEUL5P.js");
9276
9553
  const sessionId = req.params.id;
9277
9554
  const processes = getSessionProcesses(sessionId);
9278
9555
  res.json({ processes });
9279
9556
  });
9280
9557
  app.post("/api/sessions/:id/background-process/:processId/stop", async (req, res) => {
9281
- const { stopProcess } = await import("./manager-TMBFBCQL.js");
9558
+ const { stopProcess } = await import("./manager-ZACEUL5P.js");
9282
9559
  const sessionId = req.params.id;
9283
9560
  const processId = req.params.processId;
9284
9561
  const session = sessionManager.getSession(sessionId);
@@ -9418,7 +9695,7 @@ All file and git operations should use this branch.
9418
9695
  );
9419
9696
  const wss = wssExports.wss;
9420
9697
  deferTasksBroadcast = (projectId, payload) => wssExports.broadcastForProject(projectId, "", { type: "tasks.update", payload });
9421
- const { launchWorkflowRun, abortRunnerRun } = await import("./launch-UKXVO37B.js");
9698
+ const { launchWorkflowRun, abortRunnerRun } = await import("./launch-GJ7EHQRI.js");
9422
9699
  deferTasksLaunchWorkflow = (sessionId, launch) => {
9423
9700
  const effective = sessionManager.resolveEffectiveProviderModel(sessionId);
9424
9701
  let llmClient = getLLMClient();
@@ -9463,7 +9740,7 @@ All file and git operations should use this branch.
9463
9740
  const state = sessionManager.getContextState(sessionId);
9464
9741
  wssExports.broadcastForSession(sessionId, createContextStateMessage(state));
9465
9742
  });
9466
- const { QueueProcessor } = await import("./processor-V35OLKRV.js");
9743
+ const { QueueProcessor } = await import("./processor-MSQP63ML.js");
9467
9744
  const queueProcessor = new QueueProcessor({
9468
9745
  sessionManager,
9469
9746
  providerManager,
@@ -9488,8 +9765,8 @@ All file and git operations should use this branch.
9488
9765
  sessionManager,
9489
9766
  listProjects: () => listProjects(),
9490
9767
  createProject: async (name, workdir) => {
9491
- const { createDirectoryWithGit } = await import("./project-creator-6AGQTNXB.js");
9492
- return createDirectoryWithGit(name, workdir);
9768
+ const { createProjectDirectory } = await import("./project-creator-T3A4H3YV.js");
9769
+ return createProjectDirectory(name, workdir);
9493
9770
  },
9494
9771
  deleteProject: (projectId) => {
9495
9772
  const project = getProject(projectId);
@@ -9505,8 +9782,8 @@ All file and git operations should use this branch.
9505
9782
  launchWorkflow: (sessionId, launch) => deferTasksLaunchWorkflow(sessionId, launch),
9506
9783
  stopSession: (sessionId) => {
9507
9784
  void (async () => {
9508
- const { stopSessionExecution } = await import("./chat-handler-T47GATL5.js");
9509
- const { cancelQuestionsForSession, cancelPathConfirmationsForSession } = await import("./tools-CW6POKUL.js");
9785
+ const { stopSessionExecution } = await import("./chat-handler-WGDFMOOD.js");
9786
+ const { cancelQuestionsForSession, cancelPathConfirmationsForSession } = await import("./tools-E63MOJBO.js");
9510
9787
  sessionManager.clearMessageQueue(sessionId);
9511
9788
  stopSessionExecution(sessionId, sessionManager);
9512
9789
  abortSession(sessionId);
@@ -9627,4 +9904,4 @@ export {
9627
9904
  createServerHandle,
9628
9905
  createServer
9629
9906
  };
9630
- //# sourceMappingURL=chunk-OUQZZEIQ.js.map
9907
+ //# sourceMappingURL=chunk-BIZFY3QP.js.map