openfox 2.0.66 → 2.0.67

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 (33) hide show
  1. package/dist/{chat-handler-ZRDNSLOG.js → chat-handler-72DFHK5K.js} +11 -10
  2. package/dist/{chunk-OE5B44P6.js → chunk-2GRUQN2B.js} +209 -137
  3. package/dist/{chunk-WNA5VPZG.js → chunk-4QBDV6LX.js} +16 -13
  4. package/dist/{chunk-ZUM2ZJOX.js → chunk-B6JUWVTK.js} +54 -16
  5. package/dist/{chunk-R7EED6ZU.js → chunk-MQHMT5WF.js} +2 -2
  6. package/dist/{chunk-UBIHP5Z7.js → chunk-PYRH4G2J.js} +7 -33
  7. package/dist/{chunk-BGTEIA2S.js → chunk-TFCHWMOJ.js} +23 -30
  8. package/dist/{chunk-R4UTFE63.js → chunk-TJO4QFDQ.js} +7 -4
  9. package/dist/{chunk-OBK3I4KD.js → chunk-VLV3XWZS.js} +57 -3
  10. package/dist/chunk-X5DOUA3Z.js +66 -0
  11. package/dist/{chunk-PVRSNXD4.js → chunk-XUPKS5FL.js} +5 -3
  12. package/dist/{chunk-3ACDQKK6.js → chunk-YU6DZAVA.js} +27 -48
  13. package/dist/{chunk-5V5DM5E4.js → chunk-ZLON3JTI.js} +2 -2
  14. package/dist/cli/dev.js +1 -1
  15. package/dist/cli/index.js +1 -1
  16. package/dist/{compactor-V43WJ3WX.js → compactor-74CZVUWI.js} +5 -3
  17. package/dist/{inspect-proxy-PKMDR47R.js → inspect-proxy-OVEFBJ26.js} +2 -2
  18. package/dist/{manager-344C5JLZ.js → manager-JXYRGR6B.js} +6 -2
  19. package/dist/{orchestrator-LZQTDOWM.js → orchestrator-FEMPJOZD.js} +11 -12
  20. package/dist/package.json +2 -1
  21. package/dist/platform-AB3GIEGO.js +21 -0
  22. package/dist/{processor-7KAXESY5.js → processor-QB3NMRMO.js} +11 -10
  23. package/dist/{serve-HGHFN3D2.js → serve-32FAA4FX.js} +14 -13
  24. package/dist/server/index.js +13 -12
  25. package/dist/{server-W42ENYFX.js → server-OYE7GERR.js} +13 -12
  26. package/dist/{settings-ZZ6AKFPD.js → settings-6ZPWOBWL.js} +2 -2
  27. package/dist/{tools-2EB7C6H2.js → tools-INWP6FGV.js} +10 -9
  28. package/dist/web/assets/{index-B0Q5uK2h.css → index-BELeAs12.css} +1 -1
  29. package/dist/web/assets/{index-BhQN93bI.js → index-C3n65CNu.js} +76 -76
  30. package/dist/web/index.html +2 -2
  31. package/dist/web/sw.js +1 -1
  32. package/dist/{worktree-EIF75WGF.js → worktree-6U45P63P.js} +6 -2
  33. package/package.json +2 -1
@@ -21,7 +21,7 @@ import {
21
21
  tokenFromPassword,
22
22
  verifyPassword,
23
23
  workflowExists
24
- } from "./chunk-ZUM2ZJOX.js";
24
+ } from "./chunk-B6JUWVTK.js";
25
25
  import {
26
26
  agentExists,
27
27
  createToolRegistry,
@@ -66,22 +66,22 @@ import {
66
66
  setSkillEnabled,
67
67
  skillExists,
68
68
  updateOwnedSkill
69
- } from "./chunk-3ACDQKK6.js";
69
+ } from "./chunk-YU6DZAVA.js";
70
70
  import {
71
71
  ALWAYS_ALLOWED,
72
72
  ALWAYS_ALLOWED_FOR_SUBAGENTS,
73
73
  TOP_LEVEL_ONLY_TOOLS
74
- } from "./chunk-R4UTFE63.js";
74
+ } from "./chunk-TJO4QFDQ.js";
75
75
  import {
76
- getPathSeparator,
77
- isAbsolutePath
78
- } from "./chunk-BGTEIA2S.js";
76
+ getProject
77
+ } from "./chunk-KXVFHMSM.js";
79
78
  import {
80
79
  createMcpTools
81
80
  } from "./chunk-NWO6GRYE.js";
82
81
  import {
83
- ensureWorktree
84
- } from "./chunk-OBK3I4KD.js";
82
+ ensureWorktree,
83
+ syncIgnoredAssets
84
+ } from "./chunk-VLV3XWZS.js";
85
85
  import {
86
86
  createSession,
87
87
  deleteSession,
@@ -113,20 +113,21 @@ import {
113
113
  import {
114
114
  createContextStateMessage
115
115
  } from "./chunk-F4PMNP7S.js";
116
+ import {
117
+ getPathSeparator,
118
+ isAbsolutePath
119
+ } from "./chunk-X5DOUA3Z.js";
116
120
  import {
117
121
  deleteSetting,
118
122
  getSetting,
119
123
  setSetting
120
- } from "./chunk-PVRSNXD4.js";
121
- import {
122
- EventEmitter
123
- } from "./chunk-EU3WWTFH.js";
124
- import {
125
- getProject
126
- } from "./chunk-KXVFHMSM.js";
124
+ } from "./chunk-XUPKS5FL.js";
127
125
  import {
128
126
  initDatabase
129
127
  } from "./chunk-GMXKJGJ2.js";
128
+ import {
129
+ EventEmitter
130
+ } from "./chunk-EU3WWTFH.js";
130
131
  import {
131
132
  createProviderManager,
132
133
  detectModel,
@@ -161,8 +162,8 @@ import express from "express";
161
162
  import cors from "cors";
162
163
  import { createServer as createHttpServer } from "http";
163
164
  import { fileURLToPath as fileURLToPath6 } from "url";
164
- import { dirname as dirname7, resolve as resolve5, join as join8 } from "path";
165
- import { readFile as readFile3 } from "fs/promises";
165
+ import { dirname as dirname7, resolve as resolve6, join as join9 } from "path";
166
+ import { readFile as readFile4 } from "fs/promises";
166
167
  import { createServer as createViteServer } from "vite";
167
168
 
168
169
  // src/server/llm/mock.ts
@@ -1603,6 +1604,35 @@ var McpManager = class {
1603
1604
  }
1604
1605
  };
1605
1606
 
1607
+ // src/server/git/worktree-config.ts
1608
+ import { readFile, writeFile, mkdir } from "fs/promises";
1609
+ import { resolve, join } from "path";
1610
+ var CONFIG_FILENAME = ".openfox/worktree.json";
1611
+ function getConfigPath(workdir) {
1612
+ return join(resolve(workdir), CONFIG_FILENAME);
1613
+ }
1614
+ async function loadWorktreeConfig(workdir) {
1615
+ try {
1616
+ const configPath = getConfigPath(workdir);
1617
+ const raw = await readFile(configPath, "utf-8");
1618
+ const parsed = JSON.parse(raw);
1619
+ if (!parsed.ignoredAssets) return null;
1620
+ return {
1621
+ ignoredAssets: parsed.ignoredAssets,
1622
+ overrides: parsed.overrides ?? void 0
1623
+ };
1624
+ } catch {
1625
+ return null;
1626
+ }
1627
+ }
1628
+ async function saveWorktreeConfig(workdir, config3) {
1629
+ const resolved = resolve(workdir);
1630
+ const dirPath = join(resolved, ".openfox");
1631
+ await mkdir(dirPath, { recursive: true });
1632
+ const configPath = getConfigPath(workdir);
1633
+ await writeFile(configPath, JSON.stringify(config3, null, 2) + "\n", "utf-8");
1634
+ }
1635
+
1606
1636
  // src/server/lsp/server.ts
1607
1637
  import { spawn } from "child_process";
1608
1638
  import { extname } from "path";
@@ -1925,19 +1955,19 @@ var LspServer = class {
1925
1955
  */
1926
1956
  async getDiagnosticsWithWait(path, timeoutMs = DIAGNOSTIC_WAIT_MS) {
1927
1957
  if (this.openDocuments.has(path)) {
1928
- return new Promise((resolve6) => {
1958
+ return new Promise((resolve7) => {
1929
1959
  const existing = this.diagnostics.get(path);
1930
1960
  if (existing !== void 0) {
1931
1961
  setTimeout(() => {
1932
- resolve6(this.diagnostics.get(path) ?? []);
1962
+ resolve7(this.diagnostics.get(path) ?? []);
1933
1963
  }, 100);
1934
1964
  return;
1935
1965
  }
1936
1966
  const timeout = setTimeout(() => {
1937
1967
  this.pendingDiagnostics.delete(path);
1938
- resolve6(this.diagnostics.get(path) ?? []);
1968
+ resolve7(this.diagnostics.get(path) ?? []);
1939
1969
  }, timeoutMs);
1940
- this.pendingDiagnostics.set(path, { resolve: resolve6, timeout });
1970
+ this.pendingDiagnostics.set(path, { resolve: resolve7, timeout });
1941
1971
  });
1942
1972
  }
1943
1973
  return this.diagnostics.get(path) ?? [];
@@ -2148,14 +2178,14 @@ import { readFileSync as readFileSync2 } from "fs";
2148
2178
 
2149
2179
  // src/server/utils/which.ts
2150
2180
  import { access, constants } from "fs/promises";
2151
- import { join, dirname } from "path";
2181
+ import { join as join2, dirname } from "path";
2152
2182
  import { fileURLToPath as fileURLToPath2 } from "url";
2153
2183
  var __dirname = dirname(fileURLToPath2(import.meta.url));
2154
2184
  function getBundledBinPaths() {
2155
2185
  const paths = [];
2156
- paths.push(join(process.cwd(), "node_modules", ".bin"));
2157
- paths.push(join(__dirname, "..", "..", "..", "node_modules", ".bin"));
2158
- paths.push(join(__dirname, "..", "..", "..", "..", "node_modules", ".bin"));
2186
+ paths.push(join2(process.cwd(), "node_modules", ".bin"));
2187
+ paths.push(join2(__dirname, "..", "..", "..", "node_modules", ".bin"));
2188
+ paths.push(join2(__dirname, "..", "..", "..", "..", "node_modules", ".bin"));
2159
2189
  return paths;
2160
2190
  }
2161
2191
  async function existsExecutable(path) {
@@ -2174,13 +2204,13 @@ async function which(command, workdir) {
2174
2204
  return null;
2175
2205
  }
2176
2206
  for (const binDir of getBundledBinPaths()) {
2177
- const fullPath = join(binDir, command);
2207
+ const fullPath = join2(binDir, command);
2178
2208
  if (await existsExecutable(fullPath)) {
2179
2209
  return fullPath;
2180
2210
  }
2181
2211
  }
2182
2212
  if (workdir) {
2183
- const projectBin = join(workdir, "node_modules", ".bin", command);
2213
+ const projectBin = join2(workdir, "node_modules", ".bin", command);
2184
2214
  if (await existsExecutable(projectBin)) {
2185
2215
  return projectBin;
2186
2216
  }
@@ -2189,7 +2219,7 @@ async function which(command, workdir) {
2189
2219
  const paths = pathEnv.split(getPathSeparator());
2190
2220
  for (const dir of paths) {
2191
2221
  if (!dir) continue;
2192
- const fullPath = join(dir, command);
2222
+ const fullPath = join2(dir, command);
2193
2223
  if (await existsExecutable(fullPath)) {
2194
2224
  return fullPath;
2195
2225
  }
@@ -2201,9 +2231,9 @@ async function which(command, workdir) {
2201
2231
  import { extname as extname2, basename } from "path";
2202
2232
  import { readFileSync } from "fs";
2203
2233
  import { fileURLToPath as fileURLToPath3 } from "url";
2204
- import { dirname as dirname2, resolve } from "path";
2234
+ import { dirname as dirname2, resolve as resolve2 } from "path";
2205
2235
  var __dirname2 = dirname2(fileURLToPath3(import.meta.url));
2206
- var languagesJson = JSON.parse(readFileSync(resolve(__dirname2, "languages.json"), "utf-8"));
2236
+ var languagesJson = JSON.parse(readFileSync(resolve2(__dirname2, "languages.json"), "utf-8"));
2207
2237
  var LANGUAGES = languagesJson;
2208
2238
  var extensionToLanguage = /* @__PURE__ */ new Map();
2209
2239
  for (const lang of LANGUAGES) {
@@ -3181,6 +3211,10 @@ var SessionManager = class {
3181
3211
  if (!project) throw new Error(`Project not found: ${session.projectId}`);
3182
3212
  if (session.worktree) throw new Error("Session already has a worktree");
3183
3213
  const result = await ensureWorktree(project.workdir, name);
3214
+ const wtConfig = await loadWorktreeConfig(project.workdir);
3215
+ if (wtConfig) {
3216
+ await syncIgnoredAssets(project.workdir, result.path, wtConfig);
3217
+ }
3184
3218
  updateSessionWorkdir(sessionId, project.workdir, result.path);
3185
3219
  try {
3186
3220
  await shutdownLspManager(sessionId);
@@ -3245,6 +3279,11 @@ All file and git operations should use this directory.
3245
3279
  if (!project) throw new Error(`Project not found: ${session.projectId}`);
3246
3280
  const closedPath = session.worktree;
3247
3281
  const branchName = closedPath.includes("/worktrees/") ? closedPath.split("/worktrees/")[1] ?? closedPath : closedPath;
3282
+ try {
3283
+ await devServerManager.stop(closedPath);
3284
+ } catch (err) {
3285
+ logger.error("Error stopping dev server for worktree close", { sessionId, worktree: closedPath, error: err });
3286
+ }
3248
3287
  updateSessionWorkdir(sessionId, project.workdir, null);
3249
3288
  try {
3250
3289
  await shutdownLspManager(sessionId);
@@ -3367,15 +3406,15 @@ Operating in the original project directory at ${project.workdir}.
3367
3406
  // src/server/routes/skills.ts
3368
3407
  import { Router as Router2 } from "express";
3369
3408
  import multer from "multer";
3370
- import { access as access2, mkdir as mkdir2, realpath, stat } from "fs/promises";
3409
+ import { access as access2, mkdir as mkdir3, realpath, stat } from "fs/promises";
3371
3410
  import { constants as constants2 } from "fs";
3372
3411
  import { homedir } from "os";
3373
- import { isAbsolute as isAbsolute2, join as join4, resolve as resolve2 } from "path";
3412
+ import { isAbsolute as isAbsolute2, join as join5, resolve as resolve3 } from "path";
3374
3413
 
3375
3414
  // src/server/skills/installer.ts
3376
3415
  import { randomUUID } from "crypto";
3377
- import { mkdir, readFile, rename, rm, writeFile } from "fs/promises";
3378
- import { dirname as dirname3, isAbsolute, join as join2 } from "path";
3416
+ import { mkdir as mkdir2, readFile as readFile2, rename, rm, writeFile as writeFile2 } from "fs/promises";
3417
+ import { dirname as dirname3, isAbsolute, join as join3 } from "path";
3379
3418
  import matter from "gray-matter";
3380
3419
  var SkillInstallError = class extends Error {
3381
3420
  constructor(message, status) {
@@ -3407,17 +3446,17 @@ async function installSkillPackage(libraryDir, packageName, files) {
3407
3446
  totalBytes += file.content.byteLength;
3408
3447
  }
3409
3448
  if (totalBytes > 50 * 1024 * 1024) throw new SkillInstallError("Package exceeds 50 MiB", 413);
3410
- const destination = join2(libraryDir, packageName);
3449
+ const destination = join3(libraryDir, packageName);
3411
3450
  if (await pathExists(destination)) throw new SkillInstallError("A package with this name already exists", 409);
3412
- const staging = join2(libraryDir, `.${packageName}.openfox-upload-${randomUUID()}`);
3451
+ const staging = join3(libraryDir, `.${packageName}.openfox-upload-${randomUUID()}`);
3413
3452
  try {
3414
- await mkdir(staging, { recursive: false });
3453
+ await mkdir2(staging, { recursive: false });
3415
3454
  for (const file of files) {
3416
- const target = join2(staging, file.path);
3417
- await mkdir(dirname3(target), { recursive: true });
3418
- await writeFile(target, file.content);
3455
+ const target = join3(staging, file.path);
3456
+ await mkdir2(dirname3(target), { recursive: true });
3457
+ await writeFile2(target, file.content);
3419
3458
  }
3420
- const parsed = matter(await readFile(join2(staging, "SKILL.md"), "utf-8"));
3459
+ const parsed = matter(await readFile2(join3(staging, "SKILL.md"), "utf-8"));
3421
3460
  const name = typeof parsed.data["name"] === "string" ? parsed.data["name"].trim() : "";
3422
3461
  const description = typeof parsed.data["description"] === "string" ? parsed.data["description"].trim() : "";
3423
3462
  if (!name || !description || !parsed.content.trim()) {
@@ -3434,7 +3473,7 @@ async function installSkillPackage(libraryDir, packageName, files) {
3434
3473
 
3435
3474
  // src/server/routes/crud-helpers.ts
3436
3475
  import { Router } from "express";
3437
- import { join as join3 } from "path";
3476
+ import { join as join4 } from "path";
3438
3477
  function computeOverrideIds(defaults, userItems) {
3439
3478
  return userItems.filter((u) => defaults.some((d) => d.metadata.id === u.metadata.id)).map((u) => u.metadata.id);
3440
3479
  }
@@ -3446,7 +3485,7 @@ function validateNameIdPrompt(body) {
3446
3485
  return null;
3447
3486
  }
3448
3487
  function getProjectItemPath(projectDir, dirName, id, ext) {
3449
- return join3(projectDir, ".openfox", dirName, `${id}${ext}`);
3488
+ return join4(projectDir, ".openfox", dirName, `${id}${ext}`);
3450
3489
  }
3451
3490
  async function isProjectItem(projectDir, dirName, id, ext) {
3452
3491
  if (!projectDir) return false;
@@ -3591,7 +3630,7 @@ var upload = multer({
3591
3630
  });
3592
3631
  function expandHome(path) {
3593
3632
  if (path === "~") return homedir();
3594
- return path.startsWith("~/") ? join4(homedir(), path.slice(2)) : path;
3633
+ return path.startsWith("~/") ? join5(homedir(), path.slice(2)) : path;
3595
3634
  }
3596
3635
  function configuredDirectory() {
3597
3636
  const raw = getSetting(SKILL_DIRECTORIES_SETTING);
@@ -3604,13 +3643,13 @@ function configuredDirectory() {
3604
3643
  }
3605
3644
  }
3606
3645
  function defaultLibrary(configDir) {
3607
- const path = resolve2(configDir, "skills");
3646
+ const path = resolve3(configDir, "skills");
3608
3647
  return { configuredPath: path, resolvedPath: path, available: true, custom: false };
3609
3648
  }
3610
3649
  async function resolveLibrary(path) {
3611
3650
  const expanded = expandHome(path);
3612
3651
  if (!isAbsolute2(expanded)) throw new Error("Selected path must be absolute");
3613
- const absolute = resolve2(expanded);
3652
+ const absolute = resolve3(expanded);
3614
3653
  const info = await stat(absolute);
3615
3654
  if (!info.isDirectory()) throw new Error("Selected path is not a directory");
3616
3655
  await access2(absolute, constants2.R_OK);
@@ -3699,7 +3738,7 @@ function createSkillRoutes(configDir, projectDir) {
3699
3738
  try {
3700
3739
  const configured = configuredDirectory();
3701
3740
  const library = configured ? await resolveLibrary(configured) : defaultLibrary(configDir);
3702
- await mkdir2(library.resolvedPath, { recursive: true });
3741
+ await mkdir3(library.resolvedPath, { recursive: true });
3703
3742
  const packageName = String(req.body["packageName"] ?? "");
3704
3743
  const paths = JSON.parse(String(req.body["paths"] ?? "[]"));
3705
3744
  const files = req.files;
@@ -3749,19 +3788,19 @@ function createSkillRoutes(configDir, projectDir) {
3749
3788
  }
3750
3789
 
3751
3790
  // src/server/commands/registry.ts
3752
- import { writeFile as writeFile2, mkdir as mkdir3, unlink } from "fs/promises";
3753
- import { join as join5, dirname as dirname4 } from "path";
3791
+ import { writeFile as writeFile3, mkdir as mkdir4, unlink } from "fs/promises";
3792
+ import { join as join6, dirname as dirname4 } from "path";
3754
3793
  import { fileURLToPath as fileURLToPath4 } from "url";
3755
3794
  import matter2 from "gray-matter";
3756
3795
  var __bundleDir = dirname4(fileURLToPath4(import.meta.url));
3757
- var DEFAULTS_DIR = join5(__bundleDir, "defaults");
3758
- var DEFAULTS_DIR_ALT = join5(__bundleDir, "command-defaults");
3796
+ var DEFAULTS_DIR = join6(__bundleDir, "defaults");
3797
+ var DEFAULTS_DIR_ALT = join6(__bundleDir, "command-defaults");
3759
3798
  var COMMAND_EXTENSION = ".command.md";
3760
3799
  function getCommandsDir(configDir) {
3761
- return join5(configDir, "commands");
3800
+ return join6(configDir, "commands");
3762
3801
  }
3763
3802
  function getProjectCommandsDir(projectDir) {
3764
- return join5(projectDir, ".openfox", "commands");
3803
+ return join6(projectDir, ".openfox", "commands");
3765
3804
  }
3766
3805
  async function loadDefaultCommands() {
3767
3806
  let defaults = await loadItemsFromDir(DEFAULTS_DIR, {
@@ -3818,19 +3857,19 @@ function findCommandById(commandId, commands) {
3818
3857
  return commands.find((c) => c.metadata.id === commandId);
3819
3858
  }
3820
3859
  async function commandExists(configDir, commandId, projectDir) {
3821
- if (await pathExists(join5(getCommandsDir(configDir), `${commandId}${COMMAND_EXTENSION}`))) return true;
3822
- if (projectDir && await pathExists(join5(getProjectCommandsDir(projectDir), `${commandId}${COMMAND_EXTENSION}`)))
3860
+ if (await pathExists(join6(getCommandsDir(configDir), `${commandId}${COMMAND_EXTENSION}`))) return true;
3861
+ if (projectDir && await pathExists(join6(getProjectCommandsDir(projectDir), `${commandId}${COMMAND_EXTENSION}`)))
3823
3862
  return true;
3824
3863
  return false;
3825
3864
  }
3826
3865
  async function saveCommand(configDir, command) {
3827
3866
  const commandsDir = getCommandsDir(configDir);
3828
3867
  if (!await pathExists(commandsDir)) {
3829
- await mkdir3(commandsDir, { recursive: true });
3868
+ await mkdir4(commandsDir, { recursive: true });
3830
3869
  }
3831
- const filePath = join5(commandsDir, `${command.metadata.id}${COMMAND_EXTENSION}`);
3870
+ const filePath = join6(commandsDir, `${command.metadata.id}${COMMAND_EXTENSION}`);
3832
3871
  const content = matter2.stringify(command.prompt, command.metadata);
3833
- await writeFile2(filePath, content, "utf-8");
3872
+ await writeFile3(filePath, content, "utf-8");
3834
3873
  }
3835
3874
  async function saveCommandToProject(projectDir, command) {
3836
3875
  await saveItemToDir(
@@ -3848,7 +3887,7 @@ async function deleteCommand(configDir, commandId) {
3848
3887
  if (isDefault) {
3849
3888
  return { success: false, reason: "Cannot delete built-in defaults" };
3850
3889
  }
3851
- const filePath = join5(getCommandsDir(configDir), `${commandId}${COMMAND_EXTENSION}`);
3890
+ const filePath = join6(getCommandsDir(configDir), `${commandId}${COMMAND_EXTENSION}`);
3852
3891
  try {
3853
3892
  await unlink(filePath);
3854
3893
  return { success: true };
@@ -4028,10 +4067,38 @@ function createDevServerRoutes() {
4028
4067
  return router;
4029
4068
  }
4030
4069
 
4031
- // src/server/routes/terminals.ts
4070
+ // src/server/routes/worktree-config.ts
4032
4071
  import { Router as Router5 } from "express";
4033
- function createTerminalRoutes() {
4072
+ function createWorktreeConfigRoutes() {
4034
4073
  const router = Router5();
4074
+ router.get("/config", async (req, res) => {
4075
+ const workdir = req.query["workdir"];
4076
+ if (!workdir) return res.status(400).json({ error: "workdir required" });
4077
+ const config3 = await loadWorktreeConfig(workdir);
4078
+ res.json({ config: config3 });
4079
+ });
4080
+ router.post("/config", async (req, res) => {
4081
+ const workdir = req.query["workdir"];
4082
+ if (!workdir) return res.status(400).json({ error: "workdir required" });
4083
+ const { ignoredAssets, overrides } = req.body;
4084
+ if (!ignoredAssets || !["symlink", "copy", "skip"].includes(ignoredAssets)) {
4085
+ return res.status(400).json({ error: "ignoredAssets must be one of: symlink, copy, skip" });
4086
+ }
4087
+ try {
4088
+ const config3 = { ignoredAssets, overrides: overrides ?? void 0 };
4089
+ await saveWorktreeConfig(workdir, config3);
4090
+ res.json({ config: config3 });
4091
+ } catch (err) {
4092
+ res.status(500).json({ error: err instanceof Error ? err.message : "Failed to save config" });
4093
+ }
4094
+ });
4095
+ return router;
4096
+ }
4097
+
4098
+ // src/server/routes/terminals.ts
4099
+ import { Router as Router6 } from "express";
4100
+ function createTerminalRoutes() {
4101
+ const router = Router6();
4035
4102
  router.get("/", (req, res) => {
4036
4103
  const projectId = req.query["projectId"];
4037
4104
  const sessions = projectId ? terminalManager.getByProject(projectId) : [];
@@ -4070,20 +4137,20 @@ function createTerminalRoutes() {
4070
4137
  }
4071
4138
 
4072
4139
  // src/server/routes/directories.ts
4073
- import { Router as Router6 } from "express";
4140
+ import { Router as Router7 } from "express";
4074
4141
  import { readdir } from "fs/promises";
4075
- import { resolve as resolve3, join as join6, dirname as dirname5, basename as basename2 } from "path";
4142
+ import { resolve as resolve4, join as join7, dirname as dirname5, basename as basename2 } from "path";
4076
4143
  function createDirectoryRoutes() {
4077
- const router = Router6();
4144
+ const router = Router7();
4078
4145
  const DEFAULT_BASE_PATH = process.cwd();
4079
4146
  router.get("/", async (req, res) => {
4080
4147
  const path = req.query["path"] || DEFAULT_BASE_PATH;
4081
4148
  try {
4082
- const resolvedPath = resolve3(path);
4149
+ const resolvedPath = resolve4(path);
4083
4150
  const entries = await readdir(resolvedPath, { withFileTypes: true });
4084
4151
  const directories = entries.filter((entry) => entry.isDirectory()).map((entry) => ({
4085
4152
  name: entry.name,
4086
- path: join6(resolvedPath, entry.name)
4153
+ path: join7(resolvedPath, entry.name)
4087
4154
  })).sort((a, b) => a.name.localeCompare(b.name));
4088
4155
  const parent = dirname5(resolvedPath);
4089
4156
  const hasParent = parent !== resolvedPath;
@@ -4107,10 +4174,10 @@ function createDirectoryRoutes() {
4107
4174
  }
4108
4175
 
4109
4176
  // src/server/routes/file-search.ts
4110
- import { Router as Router7 } from "express";
4177
+ import { Router as Router8 } from "express";
4111
4178
  import fg from "fast-glob";
4112
4179
  function createFileSearchRoutes() {
4113
- const router = Router7();
4180
+ const router = Router8();
4114
4181
  router.get("/", async (req, res) => {
4115
4182
  const query = req.query["q"] || "";
4116
4183
  const workdir = req.query["workdir"] || process.cwd();
@@ -4186,11 +4253,11 @@ function fuzzyScore(filePath, query) {
4186
4253
  }
4187
4254
 
4188
4255
  // src/server/routes/auto-update.ts
4189
- import { Router as Router8 } from "express";
4256
+ import { Router as Router9 } from "express";
4190
4257
  import { spawn as spawn2 } from "child_process";
4191
4258
 
4192
4259
  // src/constants.ts
4193
- var VERSION = "2.0.66";
4260
+ var VERSION = "2.0.67";
4194
4261
 
4195
4262
  // src/server/routes/auto-update.ts
4196
4263
  var updateInProgress = false;
@@ -4208,12 +4275,12 @@ async function checkAuth(req, opts) {
4208
4275
  return true;
4209
4276
  }
4210
4277
  function createAutoUpdateRoutes(options = {}) {
4211
- const router = Router8();
4278
+ const router = Router9();
4212
4279
  router.get("/check", async (_req, res) => {
4213
4280
  const isService = isRunningAsService();
4214
4281
  const current = VERSION;
4215
4282
  try {
4216
- const latest = await new Promise((resolve6, reject) => {
4283
+ const latest = await new Promise((resolve7, reject) => {
4217
4284
  const child = spawn2("npm", ["view", "openfox", "version"], {
4218
4285
  stdio: ["ignore", "pipe", "pipe"],
4219
4286
  windowsHide: true
@@ -4224,7 +4291,7 @@ function createAutoUpdateRoutes(options = {}) {
4224
4291
  });
4225
4292
  child.on("close", (code) => {
4226
4293
  if (code === 0) {
4227
- resolve6(stdout.trim());
4294
+ resolve7(stdout.trim());
4228
4295
  } else {
4229
4296
  reject(new Error(`npm view exited with code ${code}`));
4230
4297
  }
@@ -4268,9 +4335,9 @@ function createAutoUpdateRoutes(options = {}) {
4268
4335
  const timeout = setTimeout(() => {
4269
4336
  child.kill();
4270
4337
  }, UPDATE_TIMEOUT);
4271
- const exitCode = await new Promise((resolve6) => {
4272
- child.on("close", resolve6);
4273
- child.on("error", () => resolve6(1));
4338
+ const exitCode = await new Promise((resolve7) => {
4339
+ child.on("close", resolve7);
4340
+ child.on("error", () => resolve7(1));
4274
4341
  });
4275
4342
  clearTimeout(timeout);
4276
4343
  if (exitCode === 0) {
@@ -4308,9 +4375,9 @@ function createAutoUpdateRoutes(options = {}) {
4308
4375
  }
4309
4376
 
4310
4377
  // src/server/routes/provider-auth.ts
4311
- import { Router as Router9 } from "express";
4378
+ import { Router as Router10 } from "express";
4312
4379
  function createProviderAuthRoutes(config3, providerManager, registry) {
4313
- const router = Router9();
4380
+ const router = Router10();
4314
4381
  function resolveAuthContext(providerId, res) {
4315
4382
  const provider = providerManager.getProviders().find((item) => item.id === providerId);
4316
4383
  if (!provider) {
@@ -4439,8 +4506,8 @@ var ProviderRegistry = class {
4439
4506
  };
4440
4507
 
4441
4508
  // src/server/providers/plugins/loader.ts
4442
- import { readdir as readdir2, readFile as readFile2, stat as stat2 } from "fs/promises";
4443
- import { dirname as dirname6, join as join7, resolve as resolve4 } from "path";
4509
+ import { readdir as readdir2, readFile as readFile3, stat as stat2 } from "fs/promises";
4510
+ import { dirname as dirname6, join as join8, resolve as resolve5 } from "path";
4444
4511
  import { fileURLToPath as fileURLToPath5, pathToFileURL } from "url";
4445
4512
  async function packageDirectories(root) {
4446
4513
  let entries;
@@ -4451,13 +4518,13 @@ async function packageDirectories(root) {
4451
4518
  }
4452
4519
  const directories = [];
4453
4520
  for (const entry of entries) {
4454
- const entryPath = join7(root, entry.name);
4521
+ const entryPath = join8(root, entry.name);
4455
4522
  const isDirectory = entry.isDirectory() || entry.isSymbolicLink() && (await stat2(entryPath).catch(() => void 0))?.isDirectory();
4456
4523
  if (!isDirectory) continue;
4457
4524
  if (entry.name.startsWith("@")) {
4458
4525
  const scoped = await readdir2(entryPath, { withFileTypes: true }).catch(() => []);
4459
4526
  for (const child of scoped) {
4460
- const childPath = join7(entryPath, child.name);
4527
+ const childPath = join8(entryPath, child.name);
4461
4528
  const childIsDirectory = child.isDirectory() || child.isSymbolicLink() && (await stat2(childPath).catch(() => void 0))?.isDirectory();
4462
4529
  if (childIsDirectory) directories.push(childPath);
4463
4530
  }
@@ -4470,19 +4537,19 @@ async function packageDirectories(root) {
4470
4537
  async function loadProviderPlugins(options) {
4471
4538
  const moduleDirectory = dirname6(fileURLToPath5(import.meta.url));
4472
4539
  const roots = [
4473
- join7(options.configDirectory, "plugins"),
4474
- join7(options.cwd ?? process.cwd(), "node_modules"),
4475
- resolve4(moduleDirectory, "node_modules"),
4476
- resolve4(moduleDirectory, "../../../../node_modules")
4540
+ join8(options.configDirectory, "plugins"),
4541
+ join8(options.cwd ?? process.cwd(), "node_modules"),
4542
+ resolve5(moduleDirectory, "node_modules"),
4543
+ resolve5(moduleDirectory, "../../../../node_modules")
4477
4544
  ];
4478
4545
  const seen = /* @__PURE__ */ new Set();
4479
4546
  const diagnostics = [];
4480
4547
  for (const root of roots) {
4481
4548
  for (const packageDir of await packageDirectories(root)) {
4482
- const manifestPath = join7(packageDir, "package.json");
4549
+ const manifestPath = join8(packageDir, "package.json");
4483
4550
  let manifest;
4484
4551
  try {
4485
- manifest = JSON.parse(await readFile2(manifestPath, "utf8"));
4552
+ manifest = JSON.parse(await readFile3(manifestPath, "utf8"));
4486
4553
  } catch {
4487
4554
  continue;
4488
4555
  }
@@ -4520,7 +4587,7 @@ async function loadProviderPlugins(options) {
4520
4587
  }
4521
4588
  };
4522
4589
  try {
4523
- const module = await import(pathToFileURL(join7(packageDir, plugin)).href);
4590
+ const module = await import(pathToFileURL(join8(packageDir, plugin)).href);
4524
4591
  if (typeof module.register !== "function") throw new Error("Plugin does not export register(registry)");
4525
4592
  await module.register(trackingRegistry);
4526
4593
  diagnostic.loaded = true;
@@ -4630,7 +4697,7 @@ async function createServerHandle(config3) {
4630
4697
  setMcpTools(mcpTools);
4631
4698
  logger.info("MCP tools registered", { count: mcpTools.length });
4632
4699
  }
4633
- const { signalMcpReady } = await import("./server-W42ENYFX.js");
4700
+ const { signalMcpReady } = await import("./server-OYE7GERR.js");
4634
4701
  signalMcpReady();
4635
4702
  });
4636
4703
  const app = express();
@@ -4791,7 +4858,7 @@ async function createServerHandle(config3) {
4791
4858
  const { getProject: getProject2 } = await import("./projects-7HSBZY2D.js");
4792
4859
  const project = getProject2(req.params.id);
4793
4860
  if (!project) return res.status(404).json({ error: "Project not found" });
4794
- const { listBranches } = await import("./worktree-EIF75WGF.js");
4861
+ const { listBranches } = await import("./worktree-6U45P63P.js");
4795
4862
  const branches = await listBranches(project.workdir);
4796
4863
  res.json({ branches });
4797
4864
  });
@@ -4801,7 +4868,7 @@ async function createServerHandle(config3) {
4801
4868
  if (!project) return res.status(404).json({ error: "Project not found" });
4802
4869
  const { branch } = req.body;
4803
4870
  if (!branch || typeof branch !== "string") return res.status(400).json({ error: "branch is required" });
4804
- const { checkoutBranch } = await import("./worktree-EIF75WGF.js");
4871
+ const { checkoutBranch } = await import("./worktree-6U45P63P.js");
4805
4872
  try {
4806
4873
  await checkoutBranch(project.workdir, branch);
4807
4874
  res.json({ branch });
@@ -4815,7 +4882,7 @@ async function createServerHandle(config3) {
4815
4882
  if (!project) return res.status(404).json({ error: "Project not found" });
4816
4883
  const { name } = req.body;
4817
4884
  if (!name || typeof name !== "string") return res.status(400).json({ error: "name is required" });
4818
- const { createBranch } = await import("./worktree-EIF75WGF.js");
4885
+ const { createBranch } = await import("./worktree-6U45P63P.js");
4819
4886
  try {
4820
4887
  await createBranch(project.workdir, name);
4821
4888
  res.json({ branch: name });
@@ -4827,7 +4894,7 @@ async function createServerHandle(config3) {
4827
4894
  const { getProject: getProject2 } = await import("./projects-7HSBZY2D.js");
4828
4895
  const project = getProject2(req.params.id);
4829
4896
  if (!project) return res.status(404).json({ error: "Project not found" });
4830
- const { listWorktrees } = await import("./worktree-EIF75WGF.js");
4897
+ const { listWorktrees } = await import("./worktree-6U45P63P.js");
4831
4898
  const all = await listWorktrees(project.workdir);
4832
4899
  const worktrees = all.filter((wt) => wt.path !== project.workdir);
4833
4900
  res.json({ worktrees });
@@ -4902,7 +4969,7 @@ async function createServerHandle(config3) {
4902
4969
  app.get("/api/sessions/:id", async (req, res) => {
4903
4970
  const { getEventStore: getEventStore2 } = await import("./events-CDQ4HASP.js");
4904
4971
  const { buildMessagesFromStoredEvents } = await import("./folding-V2K34EGN.js");
4905
- const { getPendingQuestionsForSession } = await import("./tools-2EB7C6H2.js");
4972
+ const { getPendingQuestionsForSession } = await import("./tools-INWP6FGV.js");
4906
4973
  const session = sessionManager.getSession(req.params.id);
4907
4974
  if (!session) {
4908
4975
  return res.status(404).json({ error: "Session not found" });
@@ -4921,8 +4988,8 @@ async function createServerHandle(config3) {
4921
4988
  if (!session) {
4922
4989
  return res.status(404).json({ error: "Session not found" });
4923
4990
  }
4924
- const { stopSessionExecution } = await import("./chat-handler-ZRDNSLOG.js");
4925
- const { cancelQuestionsForSession, cancelPathConfirmationsForSession } = await import("./tools-2EB7C6H2.js");
4991
+ const { stopSessionExecution } = await import("./chat-handler-72DFHK5K.js");
4992
+ const { cancelQuestionsForSession, cancelPathConfirmationsForSession } = await import("./tools-INWP6FGV.js");
4926
4993
  sessionManager.clearMessageQueue(sessionId);
4927
4994
  stopSessionExecution(sessionId, sessionManager);
4928
4995
  abortSession(sessionId);
@@ -5076,7 +5143,7 @@ async function createServerHandle(config3) {
5076
5143
  if (!callId || approved === void 0) {
5077
5144
  return res.status(400).json({ error: "callId and approved are required" });
5078
5145
  }
5079
- const { providePathConfirmation } = await import("./tools-2EB7C6H2.js");
5146
+ const { providePathConfirmation } = await import("./tools-INWP6FGV.js");
5080
5147
  const result = providePathConfirmation(callId, approved, alwaysAllow);
5081
5148
  if (!result.found) {
5082
5149
  return res.status(404).json({ error: "No pending path confirmation with that ID" });
@@ -5084,7 +5151,7 @@ async function createServerHandle(config3) {
5084
5151
  const { getEventStore: getEventStore2 } = await import("./events-CDQ4HASP.js");
5085
5152
  const { buildMessagesFromStoredEvents, foldPendingConfirmations } = await import("./folding-V2K34EGN.js");
5086
5153
  const { createSessionStateMessage } = await import("./protocol-CTNE3ANP.js");
5087
- const { getPendingQuestionsForSession } = await import("./tools-2EB7C6H2.js");
5154
+ const { getPendingQuestionsForSession } = await import("./tools-INWP6FGV.js");
5088
5155
  const eventStore = getEventStore2();
5089
5156
  const events = eventStore.getEvents(sessionId);
5090
5157
  const messages = buildMessagesFromStoredEvents(events);
@@ -5105,7 +5172,7 @@ async function createServerHandle(config3) {
5105
5172
  if (!skip && typeof answer !== "string") {
5106
5173
  return res.status(400).json({ error: "answer is required when not skipping" });
5107
5174
  }
5108
- const { provideAnswer } = await import("./tools-2EB7C6H2.js");
5175
+ const { provideAnswer } = await import("./tools-INWP6FGV.js");
5109
5176
  const found = provideAnswer(callId, answer ?? "", skip ?? false);
5110
5177
  if (!found) {
5111
5178
  return res.status(404).json({ error: "No pending question with that ID" });
@@ -5133,7 +5200,7 @@ async function createServerHandle(config3) {
5133
5200
  if (!session) {
5134
5201
  return res.status(404).json({ error: "Session not found" });
5135
5202
  }
5136
- const { getSetting: getSetting2, SETTINGS_KEYS } = await import("./settings-ZZ6AKFPD.js");
5203
+ const { getSetting: getSetting2, SETTINGS_KEYS } = await import("./settings-6ZPWOBWL.js");
5137
5204
  if (getSetting2(SETTINGS_KEYS.CACHE_WARMING) !== "true") {
5138
5205
  return res.json({ success: false, reason: "disabled" });
5139
5206
  }
@@ -5165,7 +5232,7 @@ async function createServerHandle(config3) {
5165
5232
  backend: activeProvider?.backend ?? llmClient.getBackend(),
5166
5233
  model: llmClient.getModel()
5167
5234
  };
5168
- const { runAgentTurn, TurnMetrics } = await import("./orchestrator-LZQTDOWM.js");
5235
+ const { runAgentTurn, TurnMetrics } = await import("./orchestrator-FEMPJOZD.js");
5169
5236
  runAgentTurn(
5170
5237
  {
5171
5238
  sessionManager,
@@ -5203,8 +5270,8 @@ async function createServerHandle(config3) {
5203
5270
  if (!session) {
5204
5271
  return res.status(404).json({ error: "Session not found" });
5205
5272
  }
5206
- const { stopSessionExecution } = await import("./chat-handler-ZRDNSLOG.js");
5207
- const { cancelQuestionsForSession, cancelPathConfirmationsForSession } = await import("./tools-2EB7C6H2.js");
5273
+ const { stopSessionExecution } = await import("./chat-handler-72DFHK5K.js");
5274
+ const { cancelQuestionsForSession, cancelPathConfirmationsForSession } = await import("./tools-INWP6FGV.js");
5208
5275
  const queuedMessages = sessionManager.getQueueState(sessionId);
5209
5276
  sessionManager.clearMessageQueue(sessionId);
5210
5277
  stopSessionExecution(sessionId, sessionManager);
@@ -5284,7 +5351,7 @@ async function createServerHandle(config3) {
5284
5351
  res.json({ accepted: true });
5285
5352
  });
5286
5353
  app.get("/api/settings", async (req, res) => {
5287
- const { getSetting: getSetting2, SETTINGS_DEFAULTS } = await import("./settings-ZZ6AKFPD.js");
5354
+ const { getSetting: getSetting2, SETTINGS_DEFAULTS } = await import("./settings-6ZPWOBWL.js");
5288
5355
  const keysParam = req.query["keys"];
5289
5356
  if (!keysParam) {
5290
5357
  return res.status(400).json({ error: "keys query parameter is required" });
@@ -5297,19 +5364,19 @@ async function createServerHandle(config3) {
5297
5364
  res.json(result);
5298
5365
  });
5299
5366
  app.get("/api/settings/:key", async (req, res) => {
5300
- const { getSetting: getSetting2, SETTINGS_DEFAULTS } = await import("./settings-ZZ6AKFPD.js");
5367
+ const { getSetting: getSetting2, SETTINGS_DEFAULTS } = await import("./settings-6ZPWOBWL.js");
5301
5368
  const key = req.params.key;
5302
5369
  const value = getSetting2(key) ?? SETTINGS_DEFAULTS[key] ?? null;
5303
5370
  res.json({ key, value });
5304
5371
  });
5305
5372
  app.get("/api/settings/:key", async (req, res) => {
5306
- const { getSetting: getSetting2, SETTINGS_DEFAULTS } = await import("./settings-ZZ6AKFPD.js");
5373
+ const { getSetting: getSetting2, SETTINGS_DEFAULTS } = await import("./settings-6ZPWOBWL.js");
5307
5374
  const key = req.params.key;
5308
5375
  const value = getSetting2(key) ?? SETTINGS_DEFAULTS[key] ?? null;
5309
5376
  res.json({ key, value });
5310
5377
  });
5311
5378
  app.put("/api/settings/:key", async (req, res) => {
5312
- const { setSetting: setSetting2 } = await import("./settings-ZZ6AKFPD.js");
5379
+ const { setSetting: setSetting2 } = await import("./settings-6ZPWOBWL.js");
5313
5380
  const key = req.params.key;
5314
5381
  const { value } = req.body;
5315
5382
  if (value === void 0) {
@@ -5321,20 +5388,24 @@ async function createServerHandle(config3) {
5321
5388
  app.get("/api/tools/rtk-check", async (_req, res) => {
5322
5389
  const { spawn: spawn3 } = await import("child_process");
5323
5390
  try {
5324
- const available = await new Promise((resolve6) => {
5391
+ const available = await new Promise((resolve7) => {
5325
5392
  const proc = spawn3("rtk", ["--version"], { stdio: ["ignore", "pipe", "pipe"] });
5326
5393
  let out = "";
5327
5394
  proc.stdout?.on("data", (d) => {
5328
5395
  out += d.toString();
5329
5396
  });
5330
- proc.on("error", () => resolve6(false));
5331
- proc.on("close", (code) => resolve6(code === 0 && out.startsWith("rtk ")));
5397
+ proc.on("error", () => resolve7(false));
5398
+ proc.on("close", (code) => resolve7(code === 0 && out.startsWith("rtk ")));
5332
5399
  });
5333
5400
  res.json({ available });
5334
5401
  } catch {
5335
5402
  res.json({ available: false });
5336
5403
  }
5337
5404
  });
5405
+ app.get("/api/tools/shells", async (_req, res) => {
5406
+ const { listAvailableShells } = await import("./platform-AB3GIEGO.js");
5407
+ res.json({ shells: listAvailableShells() });
5408
+ });
5338
5409
  app.get("/api/config", async (_req, res) => {
5339
5410
  const llmClient = getLLMClient();
5340
5411
  const activeProvider = providerManager.getActiveProvider();
@@ -5822,7 +5893,7 @@ async function createServerHandle(config3) {
5822
5893
  });
5823
5894
  async function rebuildMcpTools() {
5824
5895
  const { createMcpTools: createMcpTools2 } = await import("./tool-adapter-MOGEI6TP.js");
5825
- const { setMcpTools: setMcpTools2 } = await import("./tools-2EB7C6H2.js");
5896
+ const { setMcpTools: setMcpTools2 } = await import("./tools-INWP6FGV.js");
5826
5897
  const mcpTools = createMcpTools2(mcpManager);
5827
5898
  setMcpTools2(mcpTools);
5828
5899
  }
@@ -5977,6 +6048,7 @@ async function createServerHandle(config3) {
5977
6048
  app.use("/api/agents", createAgentRoutes(configDir, projectDir));
5978
6049
  app.use("/api/workflows", createWorkflowRoutes(configDir, config3, projectDir));
5979
6050
  app.use("/api/dev-server", createDevServerRoutes());
6051
+ app.use("/api/worktree", createWorktreeConfigRoutes());
5980
6052
  app.use("/api/terminals", createTerminalRoutes());
5981
6053
  app.use(
5982
6054
  "/api/auto-update",
@@ -5993,13 +6065,13 @@ async function createServerHandle(config3) {
5993
6065
  })
5994
6066
  );
5995
6067
  app.get("/api/sessions/:id/background-processes", async (req, res) => {
5996
- const { getSessionProcesses } = await import("./manager-344C5JLZ.js");
6068
+ const { getSessionProcesses } = await import("./manager-JXYRGR6B.js");
5997
6069
  const sessionId = req.params.id;
5998
6070
  const processes = getSessionProcesses(sessionId);
5999
6071
  res.json({ processes });
6000
6072
  });
6001
6073
  app.post("/api/sessions/:id/background-process/:processId/stop", async (req, res) => {
6002
- const { stopProcess } = await import("./manager-344C5JLZ.js");
6074
+ const { stopProcess } = await import("./manager-JXYRGR6B.js");
6003
6075
  const sessionId = req.params.id;
6004
6076
  const processId = req.params.processId;
6005
6077
  const session = sessionManager.getSession(sessionId);
@@ -6019,14 +6091,14 @@ async function createServerHandle(config3) {
6019
6091
  });
6020
6092
  app.use("/api/directories", createDirectoryRoutes());
6021
6093
  app.use("/api/files", createFileSearchRoutes());
6022
- const webDir = resolve5(__dirname3, "../../web");
6094
+ const webDir = resolve6(__dirname3, "../../web");
6023
6095
  const isDev = config3.mode === "development";
6024
6096
  let viteServer;
6025
6097
  if (isDev) {
6026
6098
  logger.info("Dev mode: using Vite middleware");
6027
6099
  viteServer = await createViteServer({
6028
6100
  root: webDir,
6029
- configFile: resolve5(__dirname3, "../../web/vite.config.ts"),
6101
+ configFile: resolve6(__dirname3, "../../web/vite.config.ts"),
6030
6102
  server: { middlewareMode: true },
6031
6103
  appType: "spa",
6032
6104
  logLevel: "warn"
@@ -6046,7 +6118,7 @@ async function createServerHandle(config3) {
6046
6118
  }
6047
6119
  });
6048
6120
  app.get("/fox.svg", (_req, res) => {
6049
- readFile3(join8(webDir, "fox.svg")).then((content) => {
6121
+ readFile4(join9(webDir, "fox.svg")).then((content) => {
6050
6122
  res.set("Content-Type", "image/svg+xml");
6051
6123
  res.send(content);
6052
6124
  }).catch(() => {
@@ -6055,7 +6127,7 @@ async function createServerHandle(config3) {
6055
6127
  });
6056
6128
  app.use(
6057
6129
  "/sounds",
6058
- express.static(join8(webDir, "public", "sounds"), {
6130
+ express.static(join9(webDir, "public", "sounds"), {
6059
6131
  setHeaders: (res) => {
6060
6132
  res.set("Content-Type", "audio/mpeg");
6061
6133
  }
@@ -6064,13 +6136,13 @@ async function createServerHandle(config3) {
6064
6136
  app.use("/__inspect__.js", (_req, res) => {
6065
6137
  res.set("Access-Control-Allow-Origin", "*");
6066
6138
  res.set("Content-Type", "application/javascript");
6067
- readFile3(join8(webDir, "public", "__inspect__.js")).then((content) => res.send(content)).catch(() => res.status(404).send("Not found"));
6139
+ readFile4(join9(webDir, "public", "__inspect__.js")).then((content) => res.send(content)).catch(() => res.status(404).send("Not found"));
6068
6140
  });
6069
6141
  app.get("/*path", (req, res) => {
6070
6142
  if (req.path.startsWith("/api/")) {
6071
6143
  return;
6072
6144
  }
6073
- readFile3(join8(webDir, "index.html"), "utf-8").then((indexHtml) => viteServer.transformIndexHtml(req.originalUrl, indexHtml)).then((transformed) => res.send(transformed)).catch((err) => {
6145
+ readFile4(join9(webDir, "index.html"), "utf-8").then((indexHtml) => viteServer.transformIndexHtml(req.originalUrl, indexHtml)).then((transformed) => res.send(transformed)).catch((err) => {
6074
6146
  logger.error("Error serving index.html", { error: err });
6075
6147
  res.status(500).send("Server error");
6076
6148
  });
@@ -6078,10 +6150,10 @@ async function createServerHandle(config3) {
6078
6150
  logger.info("Vite middleware ready", { port: config3.server.port });
6079
6151
  }
6080
6152
  if (!isDev) {
6081
- const distWebDir = resolve5(__dirname3, "web");
6153
+ const distWebDir = resolve6(__dirname3, "web");
6082
6154
  app.use(
6083
6155
  "/assets",
6084
- express.static(join8(distWebDir, "assets"), {
6156
+ express.static(join9(distWebDir, "assets"), {
6085
6157
  setHeaders: (res, filepath) => {
6086
6158
  if (filepath.endsWith(".css")) {
6087
6159
  res.set("Content-Type", "text/css");
@@ -6089,11 +6161,11 @@ async function createServerHandle(config3) {
6089
6161
  }
6090
6162
  })
6091
6163
  );
6092
- app.use("/manifest.webmanifest", express.static(join8(distWebDir, "manifest.webmanifest")));
6093
- app.use("/registerSW.js", express.static(join8(distWebDir, "registerSW.js")));
6094
- app.use("/sw.js", express.static(join8(distWebDir, "sw.js")));
6164
+ app.use("/manifest.webmanifest", express.static(join9(distWebDir, "manifest.webmanifest")));
6165
+ app.use("/registerSW.js", express.static(join9(distWebDir, "registerSW.js")));
6166
+ app.use("/sw.js", express.static(join9(distWebDir, "sw.js")));
6095
6167
  app.get("/fox.svg", (_req, res) => {
6096
- readFile3(join8(distWebDir, "fox.svg")).then((content) => {
6168
+ readFile4(join9(distWebDir, "fox.svg")).then((content) => {
6097
6169
  res.set("Content-Type", "image/svg+xml");
6098
6170
  res.send(content);
6099
6171
  }).catch(() => {
@@ -6102,7 +6174,7 @@ async function createServerHandle(config3) {
6102
6174
  });
6103
6175
  app.use(
6104
6176
  "/sounds",
6105
- express.static(join8(distWebDir, "sounds"), {
6177
+ express.static(join9(distWebDir, "sounds"), {
6106
6178
  setHeaders: (res) => {
6107
6179
  res.set("Content-Type", "audio/mpeg");
6108
6180
  }
@@ -6111,10 +6183,10 @@ async function createServerHandle(config3) {
6111
6183
  app.use("/__inspect__.js", (_req, res) => {
6112
6184
  res.set("Access-Control-Allow-Origin", "*");
6113
6185
  res.set("Content-Type", "application/javascript");
6114
- readFile3(join8(distWebDir, "__inspect__.js")).then((content) => res.send(content)).catch(() => res.status(404).send("Not found"));
6186
+ readFile4(join9(distWebDir, "__inspect__.js")).then((content) => res.send(content)).catch(() => res.status(404).send("Not found"));
6115
6187
  });
6116
6188
  app.get("/", (_req, res) => {
6117
- readFile3(join8(distWebDir, "index.html"), "utf-8").then((content) => res.send(content)).catch(() => {
6189
+ readFile4(join9(distWebDir, "index.html"), "utf-8").then((content) => res.send(content)).catch(() => {
6118
6190
  res.status(404).send("Web UI not built. Run `npm run build:web`");
6119
6191
  });
6120
6192
  });
@@ -6122,7 +6194,7 @@ async function createServerHandle(config3) {
6122
6194
  if (req.path.startsWith("/api/") || req.path.startsWith("/assets/") || req.path.startsWith("/sounds/") || req.path.startsWith("/manifest.webmanifest") || req.path.startsWith("/registerSW.js") || req.path.startsWith("/sw.js") || req.path === "/fox.svg") {
6123
6195
  return;
6124
6196
  }
6125
- readFile3(join8(distWebDir, "index.html"), "utf-8").then((content) => res.send(content)).catch(() => {
6197
+ readFile4(join9(distWebDir, "index.html"), "utf-8").then((content) => res.send(content)).catch(() => {
6126
6198
  res.status(404).send("Web UI not built");
6127
6199
  });
6128
6200
  });
@@ -6142,7 +6214,7 @@ async function createServerHandle(config3) {
6142
6214
  const state = sessionManager.getContextState(sessionId);
6143
6215
  wssExports.broadcastForSession(sessionId, createContextStateMessage(state));
6144
6216
  });
6145
- const { QueueProcessor } = await import("./processor-7KAXESY5.js");
6217
+ const { QueueProcessor } = await import("./processor-QB3NMRMO.js");
6146
6218
  const queueProcessor = new QueueProcessor({
6147
6219
  sessionManager,
6148
6220
  providerManager,
@@ -6165,7 +6237,7 @@ async function createServerHandle(config3) {
6165
6237
  return {
6166
6238
  httpServer,
6167
6239
  ctx: { config: config3, sessionManager, llmClient: getLLMClient(), toolRegistry, providerManager },
6168
- start: (port) => new Promise((resolve6, reject) => {
6240
+ start: (port) => new Promise((resolve7, reject) => {
6169
6241
  const listenPort = port ?? config3.server.port;
6170
6242
  const host = config3.server.host;
6171
6243
  httpServer.listen(listenPort, host, () => {
@@ -6175,16 +6247,16 @@ async function createServerHandle(config3) {
6175
6247
  logger.info(`OpenFox server running at http://${host}:${actualPort}`);
6176
6248
  logger.info(`WebSocket available at ws://${host}:${actualPort}/ws`);
6177
6249
  logger.info(`LLM backend: ${client.getBackend()}, model: ${client.getModel()}, url: ${config3.llm.baseUrl}`);
6178
- resolve6({ port: actualPort });
6250
+ resolve7({ port: actualPort });
6179
6251
  });
6180
6252
  httpServer.on("error", reject);
6181
6253
  }),
6182
- close: () => new Promise((resolve6) => {
6254
+ close: () => new Promise((resolve7) => {
6183
6255
  logger.info("Shutting down...");
6184
6256
  void (async () => {
6185
6257
  await devServerManager.stopAll();
6186
6258
  await mcpManager.disconnectAll();
6187
- const { stopAllInspectProxies } = await import("./inspect-proxy-PKMDR47R.js");
6259
+ const { stopAllInspectProxies } = await import("./inspect-proxy-OVEFBJ26.js");
6188
6260
  stopAllInspectProxies();
6189
6261
  const { cleanupAllProcesses } = await import("./store-FXTCHBI4.js");
6190
6262
  cleanupAllProcesses();
@@ -6198,7 +6270,7 @@ async function createServerHandle(config3) {
6198
6270
  client.terminate();
6199
6271
  }
6200
6272
  wss.close();
6201
- httpServer.close(() => resolve6());
6273
+ httpServer.close(() => resolve7());
6202
6274
  })();
6203
6275
  })
6204
6276
  };
@@ -6223,4 +6295,4 @@ export {
6223
6295
  createServerHandle,
6224
6296
  createServer
6225
6297
  };
6226
- //# sourceMappingURL=chunk-OE5B44P6.js.map
6298
+ //# sourceMappingURL=chunk-2GRUQN2B.js.map