openfox 2.0.70 → 2.0.72

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 (68) hide show
  1. package/dist/{chat-handler-K3DWIGHG.js → chat-handler-LK5RUAGO.js} +19 -19
  2. package/dist/{chunk-64GN6OPR.js → chunk-2DCJERYX.js} +8 -8
  3. package/dist/chunk-2M6JM7OR.js +7 -0
  4. package/dist/{chunk-XDWV5CYV.js → chunk-4LBSC4R3.js} +15 -20
  5. package/dist/{chunk-TFDK6VSG.js → chunk-6XKM25OT.js} +13 -13
  6. package/dist/{chunk-E4POUD2M.js → chunk-6XOA2WPU.js} +2 -2
  7. package/dist/{chunk-YQ3MEZJL.js → chunk-CHPRGEY5.js} +3 -3
  8. package/dist/{chunk-C3VLGVSQ.js → chunk-DJASQ2ZB.js} +11 -2
  9. package/dist/{chunk-4QBDV6LX.js → chunk-E5LLEO3C.js} +2 -2
  10. package/dist/{chunk-JHGKXQBO.js → chunk-EZK7CGJ7.js} +87 -30
  11. package/dist/{chunk-ZZ5JPVBT.js → chunk-FILRB5QX.js} +259 -300
  12. package/dist/{chunk-PVWAE43V.js → chunk-GMF36EZ3.js} +123 -106
  13. package/dist/{chunk-GMXKJGJ2.js → chunk-I4RWK2L2.js} +8 -4
  14. package/dist/{chunk-PK2RMVMB.js → chunk-I72ACQ6R.js} +19 -18
  15. package/dist/{chunk-F4PMNP7S.js → chunk-NOU2QIL5.js} +3 -2
  16. package/dist/{chunk-UTSSFPYA.js → chunk-O2BE7KVQ.js} +8 -8
  17. package/dist/{chunk-7OW6X764.js → chunk-OHGQILRF.js} +15 -4
  18. package/dist/{chunk-TFCHWMOJ.js → chunk-PYB2UEC3.js} +11 -5
  19. package/dist/{chunk-XUPKS5FL.js → chunk-QNKXZH3Z.js} +2 -2
  20. package/dist/{chunk-X5DOUA3Z.js → chunk-S7O77CVO.js} +2 -2
  21. package/dist/{chunk-46OR4W3L.js → chunk-TK4BZIXA.js} +45 -31
  22. package/dist/{chunk-KXVFHMSM.js → chunk-UV3EMWL4.js} +2 -2
  23. package/dist/chunk-X2Y3AJPP.js +216 -0
  24. package/dist/{chunk-QFSDJIUS.js → chunk-XWBNYU2L.js} +3 -3
  25. package/dist/cli/dev.js +1 -1
  26. package/dist/cli/index.js +1 -1
  27. package/dist/{client-63U5CTPE.js → client-SC6X65GY.js} +3 -3
  28. package/dist/{client-pure-XHH4RRLB.js → client-pure-NMLDKRDN.js} +6 -4
  29. package/dist/{compactor-IPMMFFHM.js → compactor-4UKYWC5F.js} +9 -9
  30. package/dist/{events-CDQ4HASP.js → events-AEQ6GQXI.js} +4 -4
  31. package/dist/{folding-V2K34EGN.js → folding-ONH3D4OK.js} +2 -2
  32. package/dist/{inspect-proxy-OVEFBJ26.js → inspect-proxy-PHVZBZUO.js} +4 -4
  33. package/dist/{manager-JXYRGR6B.js → manager-24C2AXVF.js} +6 -6
  34. package/dist/{orchestrator-PUV4WG77.js → orchestrator-RTZVMWQV.js} +18 -18
  35. package/dist/package.json +2 -2
  36. package/dist/{platform-AB3GIEGO.js → platform-XQ7BS3KQ.js} +4 -4
  37. package/dist/{processor-O2QW27BD.js → processor-3O26I7DO.js} +19 -19
  38. package/dist/{project-creator-EMGRSPYS.js → project-creator-FQRBN3RG.js} +3 -3
  39. package/dist/{projects-7HSBZY2D.js → projects-LHRNCUGW.js} +3 -3
  40. package/dist/{protocol-CTNE3ANP.js → protocol-4QFU7WAI.js} +2 -2
  41. package/dist/{protocol-DIhV-tAc.d.ts → protocol-DGQWVFcP.d.ts} +1 -1
  42. package/dist/provider/index.d.ts +4 -4
  43. package/dist/{provider-IBIWR4AI.js → provider-OJUCZ5RN.js} +4 -4
  44. package/dist/{provider-manager-7C3JVOLW.js → provider-manager-MAKXSL6L.js} +4 -4
  45. package/dist/{pwa-T6JRAYJB.js → pwa-SEWCVKZX.js} +7 -8
  46. package/dist/{serve-NOHD22CT.js → serve-6PSAQ2YH.js} +26 -24
  47. package/dist/server/index.d.ts +12 -22
  48. package/dist/server/index.js +23 -22
  49. package/dist/server-G2J4RAXL.js +38 -0
  50. package/dist/{service-6DL3MJZD.js → service-2PW2V25M.js} +6 -1
  51. package/dist/{settings-6ZPWOBWL.js → settings-PFXRYXZU.js} +3 -3
  52. package/dist/shared/index.d.ts +3 -3
  53. package/dist/{store-FXTCHBI4.js → store-SARB6V2N.js} +2 -2
  54. package/dist/{tools-CALGWIV2.js → tools-X52DFUS6.js} +17 -17
  55. package/dist/{types-BsfYpEai.d.ts → types-C4cG9CtC.d.ts} +3 -2
  56. package/dist/{types-CBC6lLqc.d.ts → types-DSZhFA8O.d.ts} +1 -1
  57. package/dist/update-I2M2RG4Q.js +40 -0
  58. package/dist/web/assets/index-C7SW16F7.js +305 -0
  59. package/dist/web/assets/{index-BVTG7SRG.css → index-CmechlaK.css} +1 -1
  60. package/dist/web/index.html +2 -2
  61. package/dist/web/sw.js +1 -1
  62. package/dist/workspace-ET3FHZYN.js +32 -0
  63. package/package.json +2 -2
  64. package/dist/chunk-VLV3XWZS.js +0 -191
  65. package/dist/cli/update.sh +0 -16
  66. package/dist/server-RLNPHLY2.js +0 -38
  67. package/dist/web/assets/index-CtWMMQ_X.js +0 -305
  68. package/dist/worktree-6U45P63P.js +0 -30
@@ -21,7 +21,7 @@ import {
21
21
  tokenFromPassword,
22
22
  verifyPassword,
23
23
  workflowExists
24
- } from "./chunk-46OR4W3L.js";
24
+ } from "./chunk-TK4BZIXA.js";
25
25
  import {
26
26
  agentExists,
27
27
  createToolRegistry,
@@ -66,22 +66,35 @@ import {
66
66
  setSkillEnabled,
67
67
  skillExists,
68
68
  updateOwnedSkill
69
- } from "./chunk-PVWAE43V.js";
69
+ } from "./chunk-GMF36EZ3.js";
70
+ import {
71
+ deleteWorkspace,
72
+ ensureWorkspace,
73
+ getCommitsBehind,
74
+ getGitBranch,
75
+ getWorkspacesDir,
76
+ loadWorkspaceConfig,
77
+ runGit,
78
+ saveWorkspaceConfig,
79
+ workspaceExists
80
+ } from "./chunk-X2Y3AJPP.js";
81
+ import {
82
+ EventEmitter
83
+ } from "./chunk-EU3WWTFH.js";
70
84
  import {
71
85
  ALWAYS_ALLOWED,
72
86
  ALWAYS_ALLOWED_FOR_SUBAGENTS,
73
87
  TOP_LEVEL_ONLY_TOOLS
74
- } from "./chunk-QFSDJIUS.js";
88
+ } from "./chunk-XWBNYU2L.js";
75
89
  import {
76
90
  getProject
77
- } from "./chunk-KXVFHMSM.js";
91
+ } from "./chunk-UV3EMWL4.js";
78
92
  import {
79
93
  createMcpTools
80
94
  } from "./chunk-NWO6GRYE.js";
81
95
  import {
82
- ensureWorktree,
83
- syncIgnoredAssets
84
- } from "./chunk-VLV3XWZS.js";
96
+ VERSION
97
+ } from "./chunk-2M6JM7OR.js";
85
98
  import {
86
99
  createSession,
87
100
  deleteSession,
@@ -109,31 +122,28 @@ import {
109
122
  updateSessionProvider,
110
123
  updateSessionRunning,
111
124
  updateSessionWorkdir
112
- } from "./chunk-TFDK6VSG.js";
125
+ } from "./chunk-6XKM25OT.js";
113
126
  import {
114
127
  createContextStateMessage
115
- } from "./chunk-F4PMNP7S.js";
128
+ } from "./chunk-NOU2QIL5.js";
116
129
  import {
117
130
  getPathSeparator,
118
131
  isAbsolutePath
119
- } from "./chunk-X5DOUA3Z.js";
132
+ } from "./chunk-S7O77CVO.js";
120
133
  import {
121
134
  deleteSetting,
122
135
  getSetting,
123
136
  setSetting
124
- } from "./chunk-XUPKS5FL.js";
137
+ } from "./chunk-QNKXZH3Z.js";
125
138
  import {
126
139
  initDatabase
127
- } from "./chunk-GMXKJGJ2.js";
128
- import {
129
- EventEmitter
130
- } from "./chunk-EU3WWTFH.js";
140
+ } from "./chunk-I4RWK2L2.js";
131
141
  import {
132
142
  createProviderManager,
133
143
  detectModel,
134
144
  getLlmStatus,
135
145
  parseDefaultModelSelection
136
- } from "./chunk-7OW6X764.js";
146
+ } from "./chunk-OHGQILRF.js";
137
147
  import {
138
148
  getModelProfile
139
149
  } from "./chunk-V4IE7HJY.js";
@@ -162,8 +172,8 @@ import express from "express";
162
172
  import cors from "cors";
163
173
  import { createServer as createHttpServer } from "http";
164
174
  import { fileURLToPath as fileURLToPath7 } from "url";
165
- import { dirname as dirname8, resolve as resolve7, join as join10 } from "path";
166
- import { readFile as readFile5 } from "fs/promises";
175
+ import { dirname as dirname8, resolve as resolve7, join as join9 } from "path";
176
+ import { readFile as readFile4 } from "fs/promises";
167
177
  import { createServer as createViteServer } from "vite";
168
178
 
169
179
  // src/server/llm/mock.ts
@@ -1604,34 +1614,8 @@ var McpManager = class {
1604
1614
  }
1605
1615
  };
1606
1616
 
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
- }
1617
+ // src/server/session/manager.ts
1618
+ import { resolve as resolve2 } from "path";
1635
1619
 
1636
1620
  // src/server/lsp/server.ts
1637
1621
  import { spawn } from "child_process";
@@ -2190,14 +2174,14 @@ import { readFileSync as readFileSync2 } from "fs";
2190
2174
 
2191
2175
  // src/server/utils/which.ts
2192
2176
  import { access, constants } from "fs/promises";
2193
- import { join as join2, dirname } from "path";
2177
+ import { join, dirname } from "path";
2194
2178
  import { fileURLToPath as fileURLToPath2 } from "url";
2195
2179
  var __dirname = dirname(fileURLToPath2(import.meta.url));
2196
2180
  function getBundledBinPaths() {
2197
2181
  const paths = [];
2198
- paths.push(join2(process.cwd(), "node_modules", ".bin"));
2199
- paths.push(join2(__dirname, "..", "..", "..", "node_modules", ".bin"));
2200
- paths.push(join2(__dirname, "..", "..", "..", "..", "node_modules", ".bin"));
2182
+ paths.push(join(process.cwd(), "node_modules", ".bin"));
2183
+ paths.push(join(__dirname, "..", "..", "..", "node_modules", ".bin"));
2184
+ paths.push(join(__dirname, "..", "..", "..", "..", "node_modules", ".bin"));
2201
2185
  return paths;
2202
2186
  }
2203
2187
  async function existsExecutable(path) {
@@ -2216,7 +2200,7 @@ function candidateNames(command) {
2216
2200
  }
2217
2201
  async function findInDir(dir, command) {
2218
2202
  for (const name of candidateNames(command)) {
2219
- const fullPath = join2(dir, name);
2203
+ const fullPath = join(dir, name);
2220
2204
  if (await existsExecutable(fullPath)) {
2221
2205
  return fullPath;
2222
2206
  }
@@ -2237,7 +2221,7 @@ async function which(command, workdir) {
2237
2221
  }
2238
2222
  }
2239
2223
  if (workdir) {
2240
- const found = await findInDir(join2(workdir, "node_modules", ".bin"), command);
2224
+ const found = await findInDir(join(workdir, "node_modules", ".bin"), command);
2241
2225
  if (found) {
2242
2226
  return found;
2243
2227
  }
@@ -2258,9 +2242,9 @@ async function which(command, workdir) {
2258
2242
  import { extname as extname2, basename } from "path";
2259
2243
  import { readFileSync } from "fs";
2260
2244
  import { fileURLToPath as fileURLToPath3 } from "url";
2261
- import { dirname as dirname2, resolve as resolve2 } from "path";
2245
+ import { dirname as dirname2, resolve } from "path";
2262
2246
  var __dirname2 = dirname2(fileURLToPath3(import.meta.url));
2263
- var languagesJson = JSON.parse(readFileSync(resolve2(__dirname2, "languages.json"), "utf-8"));
2247
+ var languagesJson = JSON.parse(readFileSync(resolve(__dirname2, "languages.json"), "utf-8"));
2264
2248
  var LANGUAGES = languagesJson;
2265
2249
  var extensionToLanguage = /* @__PURE__ */ new Map();
2266
2250
  for (const lang of LANGUAGES) {
@@ -2603,7 +2587,7 @@ var SessionManager = class {
2603
2587
  * Create a new session. Emits session.initialized event.
2604
2588
  * Note: maxTokens is no longer stored in the session - it comes from the current model config
2605
2589
  */
2606
- createSession(projectId, title, providerId, providerModel, worktree) {
2590
+ createSession(projectId, title, providerId, providerModel, workspace) {
2607
2591
  const project = getProject(projectId);
2608
2592
  if (!project) {
2609
2593
  throw new Error(`Project not found: ${projectId}`);
@@ -2613,9 +2597,9 @@ var SessionManager = class {
2613
2597
  const existingSessions = listSessionsByProject(projectId, 1e3, 0);
2614
2598
  sessionTitle = `Session ${existingSessions.sessions.length + 1}`;
2615
2599
  }
2616
- const effectiveWorkdir = worktree ?? project.workdir;
2600
+ const effectiveWorkdir = workspace ?? project.workdir;
2617
2601
  logger.debug("Creating session", { projectId, workdir: effectiveWorkdir, title: sessionTitle });
2618
- const dbSession = createSession(projectId, effectiveWorkdir, sessionTitle, providerId, providerModel, worktree);
2602
+ const dbSession = createSession(projectId, effectiveWorkdir, sessionTitle, providerId, providerModel, workspace);
2619
2603
  const contextWindowId = crypto.randomUUID();
2620
2604
  emitSessionInitialized(dbSession.id, projectId, effectiveWorkdir, contextWindowId, sessionTitle);
2621
2605
  const session = this.buildSessionFromDb(dbSession);
@@ -3215,71 +3199,70 @@ var SessionManager = class {
3215
3199
  // ============================================================================
3216
3200
  /**
3217
3201
  * Get the LSP manager for a session.
3218
- * Uses worktree path when active, otherwise the project workdir.
3202
+ * Uses workspace path when active, otherwise the project workdir.
3219
3203
  */
3220
3204
  getLspManager(sessionId) {
3221
3205
  const session = this.requireSession(sessionId);
3222
- const effectiveWorkdir = session.worktree ?? session.workdir;
3206
+ const effectiveWorkdir = session.workspace ?? session.workdir;
3223
3207
  return getLspManager(sessionId, effectiveWorkdir);
3224
3208
  }
3225
3209
  // ============================================================================
3226
- // Worktree Lifecycle
3210
+ // Workspace Lifecycle
3227
3211
  // ============================================================================
3228
3212
  /**
3229
- * Create a git worktree for an existing session and move the session into it.
3230
- * Keeps session.workdir as the project root (stable system prompt).
3231
- * Sets session.worktree to the worktree path for tool execution.
3232
- * Restarts LSP to pick up the new workdir.
3233
- * Injects a system reminder to inform the agent about the worktree.
3213
+ * Switch to a workspace. Target can be "original" (project root) or a workspace name.
3214
+ * If the workspace doesn't exist yet, it's created first.
3215
+ * Emits a single type of event switching is always "opening" a workspace.
3234
3216
  */
3235
- async createSessionWorktree(sessionId, name) {
3217
+ async switchWorkspace(sessionId, target, branch) {
3236
3218
  const session = this.requireSession(sessionId);
3237
3219
  const project = getProject(session.projectId);
3238
3220
  if (!project) throw new Error(`Project not found: ${session.projectId}`);
3239
- if (session.worktree) throw new Error("Session already has a worktree");
3240
- const result = await ensureWorktree(project.workdir, name);
3241
- const wtConfig = await loadWorktreeConfig(project.workdir);
3242
- if (wtConfig) {
3243
- await syncIgnoredAssets(project.workdir, result.path, wtConfig);
3221
+ if (target === "original" && !session.workspace) return session;
3222
+ if (target !== "original" && session.workspace?.endsWith(`/${target}`)) return session;
3223
+ const previousPath = session.workspace;
3224
+ if (previousPath) {
3225
+ try {
3226
+ await devServerManager.stop(previousPath);
3227
+ } catch (err) {
3228
+ logger.error("Error stopping dev server for workspace switch", {
3229
+ sessionId,
3230
+ workspace: previousPath,
3231
+ error: err
3232
+ });
3233
+ }
3244
3234
  }
3245
- updateSessionWorkdir(sessionId, project.workdir, result.path);
3246
- try {
3247
- await shutdownLspManager(sessionId);
3248
- } catch (err) {
3249
- logger.error("Error shutting down LSP for worktree switch", { sessionId, error: err });
3235
+ if (target === "original") {
3236
+ updateSessionWorkdir(sessionId, project.workdir, null);
3237
+ } else {
3238
+ const exists = await workspaceExists(project.name, target);
3239
+ if (!exists) {
3240
+ await ensureWorkspace(project.workdir, target, project.name, branch);
3241
+ }
3242
+ const wsPath = resolve2(getWorkspacesDir(project.name), target);
3243
+ updateSessionWorkdir(sessionId, project.workdir, wsPath);
3250
3244
  }
3251
- const reminderContent = `<system-reminder>
3252
- This session is now operating in a git worktree at ${result.path}.
3253
- All file and git operations should use this directory.
3254
- </system-reminder>`;
3255
- this.addMessage(sessionId, {
3256
- role: "user",
3257
- content: reminderContent,
3258
- isSystemGenerated: true,
3259
- messageKind: "auto-prompt",
3260
- metadata: { type: "worktree", name: "Worktree", color: "#22c55e", kind: "definition", branchName: name }
3261
- });
3262
- const updated = this.requireSession(sessionId);
3263
- this.emit({ type: "session_updated", session: updated });
3264
- return updated;
3265
- }
3266
- /**
3267
- * Attach session to an existing worktree by path.
3268
- * Sets session.worktree to the given path without creating a new worktree.
3269
- * Restarts LSP to pick up the new workdir.
3270
- */
3271
- async attachSessionWorktree(sessionId, wtPath) {
3272
- const session = this.requireSession(sessionId);
3273
- if (session.worktree) throw new Error("Session already has a worktree");
3274
- updateSessionWorkdir(sessionId, session.workdir, wtPath);
3275
3245
  try {
3276
3246
  await shutdownLspManager(sessionId);
3277
3247
  } catch (err) {
3278
- logger.error("Error shutting down LSP for worktree attach", { sessionId, error: err });
3248
+ logger.error("Error shutting down LSP for workspace switch", { sessionId, error: err });
3249
+ }
3250
+ const effectiveWorkdir = target === "original" ? project.workdir : resolve2(getWorkspacesDir(project.name), target);
3251
+ const actualBranch = await getGitBranch(effectiveWorkdir);
3252
+ let stalenessHint = "";
3253
+ if (target !== "original" && actualBranch) {
3254
+ await runGit(effectiveWorkdir, ["fetch", "origin", "--no-tags", "--quiet"]).catch(() => {
3255
+ });
3256
+ const behind = await getCommitsBehind(effectiveWorkdir, actualBranch);
3257
+ if (behind !== null && behind > 0) {
3258
+ const plural = behind === 1 ? "" : "s";
3259
+ stalenessHint = `
3260
+ (${behind} commit${plural} behind ${actualBranch} on main workspace \u2014 run \`git pull\` to sync)`;
3261
+ }
3279
3262
  }
3280
- const branchName = wtPath.includes("/worktrees/") ? wtPath.split("/worktrees/")[1] ?? wtPath : wtPath;
3263
+ const wsLabel = target === "original" ? "original" : target;
3281
3264
  const reminderContent = `<system-reminder>
3282
- This session is now operating in a git worktree at ${wtPath}.
3265
+ This session is now operating in workspace "${wsLabel}" on branch "${actualBranch ?? "unknown"}" at ${effectiveWorkdir}.${stalenessHint}
3283
3266
  All file and git operations should use this directory.
3284
3267
  </system-reminder>`;
3285
3268
  this.addMessage(sessionId, {
@@ -3287,47 +3270,33 @@ All file and git operations should use this directory.
3287
3270
  content: reminderContent,
3288
3271
  isSystemGenerated: true,
3289
3272
  messageKind: "auto-prompt",
3290
- metadata: { type: "worktree", name: "Worktree", color: "#22c55e", kind: "definition", branchName }
3273
+ metadata: {
3274
+ type: "workspace",
3275
+ name: "Workspace",
3276
+ color: "#22c55e",
3277
+ kind: "definition",
3278
+ workspaceName: wsLabel,
3279
+ ...actualBranch ? { branchName: actualBranch } : {}
3280
+ }
3291
3281
  });
3292
3282
  const updated = this.requireSession(sessionId);
3293
3283
  this.emit({ type: "session_updated", session: updated });
3294
3284
  return updated;
3295
3285
  }
3296
3286
  /**
3297
- * Close the worktree for a session and move it back to the project root.
3298
- * Clears session.worktree session.workdir stays as project root.
3299
- * Restarts LSP to pick up the original workdir.
3300
- * Injects a system reminder to inform the agent the worktree is closed.
3287
+ * Delete a workspace by name. If the session is currently in that workspace,
3288
+ * switches to original first. Throws if target is "original".
3301
3289
  */
3302
- async closeSessionWorktree(sessionId) {
3290
+ async deleteWorkspace(sessionId, target) {
3291
+ if (target === "original") throw new Error("Cannot delete the original workspace");
3303
3292
  const session = this.requireSession(sessionId);
3304
- if (!session.worktree) throw new Error("Session does not have a worktree");
3305
3293
  const project = getProject(session.projectId);
3306
3294
  if (!project) throw new Error(`Project not found: ${session.projectId}`);
3307
- const closedPath = session.worktree;
3308
- const branchName = closedPath.includes("/worktrees/") ? closedPath.split("/worktrees/")[1] ?? closedPath : closedPath;
3309
- try {
3310
- await devServerManager.stop(closedPath);
3311
- } catch (err) {
3312
- logger.error("Error stopping dev server for worktree close", { sessionId, worktree: closedPath, error: err });
3295
+ const currentWsName = session.workspace?.split("/").pop();
3296
+ if (currentWsName === target) {
3297
+ await this.switchWorkspace(sessionId, "original");
3313
3298
  }
3314
- updateSessionWorkdir(sessionId, project.workdir, null);
3315
- try {
3316
- await shutdownLspManager(sessionId);
3317
- } catch (err) {
3318
- logger.error("Error shutting down LSP for worktree close", { sessionId, error: err });
3319
- }
3320
- const reminderContent = `<system-reminder>
3321
- The worktree at ${closedPath} has been closed.
3322
- Operating in the original project directory at ${project.workdir}.
3323
- </system-reminder>`;
3324
- this.addMessage(sessionId, {
3325
- role: "user",
3326
- content: reminderContent,
3327
- isSystemGenerated: true,
3328
- messageKind: "auto-prompt",
3329
- metadata: { type: "worktree", name: "Worktree", color: "#ef4444", kind: "reminder", branchName }
3330
- });
3299
+ await deleteWorkspace(project.name, target);
3331
3300
  const updated = this.requireSession(sessionId);
3332
3301
  this.emit({ type: "session_updated", session: updated });
3333
3302
  return updated;
@@ -3433,15 +3402,15 @@ Operating in the original project directory at ${project.workdir}.
3433
3402
  // src/server/routes/skills.ts
3434
3403
  import { Router as Router2 } from "express";
3435
3404
  import multer from "multer";
3436
- import { access as access2, mkdir as mkdir3, realpath, stat } from "fs/promises";
3405
+ import { access as access2, mkdir as mkdir2, realpath, stat } from "fs/promises";
3437
3406
  import { constants as constants2 } from "fs";
3438
3407
  import { homedir } from "os";
3439
- import { isAbsolute as isAbsolute2, join as join5, resolve as resolve3 } from "path";
3408
+ import { isAbsolute as isAbsolute2, join as join4, resolve as resolve3 } from "path";
3440
3409
 
3441
3410
  // src/server/skills/installer.ts
3442
3411
  import { randomUUID } from "crypto";
3443
- import { mkdir as mkdir2, readFile as readFile2, rename, rm, writeFile as writeFile2 } from "fs/promises";
3444
- import { dirname as dirname3, isAbsolute, join as join3 } from "path";
3412
+ import { mkdir, readFile, rename, rm, writeFile } from "fs/promises";
3413
+ import { dirname as dirname3, isAbsolute, join as join2 } from "path";
3445
3414
  import matter from "gray-matter";
3446
3415
  var SkillInstallError = class extends Error {
3447
3416
  constructor(message, status) {
@@ -3473,17 +3442,17 @@ async function installSkillPackage(libraryDir, packageName, files) {
3473
3442
  totalBytes += file.content.byteLength;
3474
3443
  }
3475
3444
  if (totalBytes > 50 * 1024 * 1024) throw new SkillInstallError("Package exceeds 50 MiB", 413);
3476
- const destination = join3(libraryDir, packageName);
3445
+ const destination = join2(libraryDir, packageName);
3477
3446
  if (await pathExists(destination)) throw new SkillInstallError("A package with this name already exists", 409);
3478
- const staging = join3(libraryDir, `.${packageName}.openfox-upload-${randomUUID()}`);
3447
+ const staging = join2(libraryDir, `.${packageName}.openfox-upload-${randomUUID()}`);
3479
3448
  try {
3480
- await mkdir2(staging, { recursive: false });
3449
+ await mkdir(staging, { recursive: false });
3481
3450
  for (const file of files) {
3482
- const target = join3(staging, file.path);
3483
- await mkdir2(dirname3(target), { recursive: true });
3484
- await writeFile2(target, file.content);
3451
+ const target = join2(staging, file.path);
3452
+ await mkdir(dirname3(target), { recursive: true });
3453
+ await writeFile(target, file.content);
3485
3454
  }
3486
- const parsed = matter(await readFile2(join3(staging, "SKILL.md"), "utf-8"));
3455
+ const parsed = matter(await readFile(join2(staging, "SKILL.md"), "utf-8"));
3487
3456
  const name = typeof parsed.data["name"] === "string" ? parsed.data["name"].trim() : "";
3488
3457
  const description = typeof parsed.data["description"] === "string" ? parsed.data["description"].trim() : "";
3489
3458
  if (!name || !description || !parsed.content.trim()) {
@@ -3500,7 +3469,7 @@ async function installSkillPackage(libraryDir, packageName, files) {
3500
3469
 
3501
3470
  // src/server/routes/crud-helpers.ts
3502
3471
  import { Router } from "express";
3503
- import { join as join4 } from "path";
3472
+ import { join as join3 } from "path";
3504
3473
  function computeOverrideIds(defaults, userItems) {
3505
3474
  return userItems.filter((u) => defaults.some((d) => d.metadata.id === u.metadata.id)).map((u) => u.metadata.id);
3506
3475
  }
@@ -3512,7 +3481,7 @@ function validateNameIdPrompt(body) {
3512
3481
  return null;
3513
3482
  }
3514
3483
  function getProjectItemPath(projectDir, dirName, id, ext) {
3515
- return join4(projectDir, ".openfox", dirName, `${id}${ext}`);
3484
+ return join3(projectDir, ".openfox", dirName, `${id}${ext}`);
3516
3485
  }
3517
3486
  async function isProjectItem(projectDir, dirName, id, ext) {
3518
3487
  if (!projectDir) return false;
@@ -3657,7 +3626,7 @@ var upload = multer({
3657
3626
  });
3658
3627
  function expandHome(path) {
3659
3628
  if (path === "~") return homedir();
3660
- return path.startsWith("~/") ? join5(homedir(), path.slice(2)) : path;
3629
+ return path.startsWith("~/") ? join4(homedir(), path.slice(2)) : path;
3661
3630
  }
3662
3631
  function configuredDirectory() {
3663
3632
  const raw = getSetting(SKILL_DIRECTORIES_SETTING);
@@ -3765,7 +3734,7 @@ function createSkillRoutes(configDir, projectDir) {
3765
3734
  try {
3766
3735
  const configured = configuredDirectory();
3767
3736
  const library = configured ? await resolveLibrary(configured) : defaultLibrary(configDir);
3768
- await mkdir3(library.resolvedPath, { recursive: true });
3737
+ await mkdir2(library.resolvedPath, { recursive: true });
3769
3738
  const packageName = String(req.body["packageName"] ?? "");
3770
3739
  const paths = JSON.parse(String(req.body["paths"] ?? "[]"));
3771
3740
  const files = req.files;
@@ -3815,19 +3784,19 @@ function createSkillRoutes(configDir, projectDir) {
3815
3784
  }
3816
3785
 
3817
3786
  // src/server/commands/registry.ts
3818
- import { writeFile as writeFile3, mkdir as mkdir4, unlink } from "fs/promises";
3819
- import { join as join6, dirname as dirname4 } from "path";
3787
+ import { writeFile as writeFile2, mkdir as mkdir3, unlink } from "fs/promises";
3788
+ import { join as join5, dirname as dirname4 } from "path";
3820
3789
  import { fileURLToPath as fileURLToPath4 } from "url";
3821
3790
  import matter2 from "gray-matter";
3822
3791
  var __bundleDir = dirname4(fileURLToPath4(import.meta.url));
3823
- var DEFAULTS_DIR = join6(__bundleDir, "defaults");
3824
- var DEFAULTS_DIR_ALT = join6(__bundleDir, "command-defaults");
3792
+ var DEFAULTS_DIR = join5(__bundleDir, "defaults");
3793
+ var DEFAULTS_DIR_ALT = join5(__bundleDir, "command-defaults");
3825
3794
  var COMMAND_EXTENSION = ".command.md";
3826
3795
  function getCommandsDir(configDir) {
3827
- return join6(configDir, "commands");
3796
+ return join5(configDir, "commands");
3828
3797
  }
3829
3798
  function getProjectCommandsDir(projectDir) {
3830
- return join6(projectDir, ".openfox", "commands");
3799
+ return join5(projectDir, ".openfox", "commands");
3831
3800
  }
3832
3801
  async function loadDefaultCommands() {
3833
3802
  let defaults = await loadItemsFromDir(DEFAULTS_DIR, {
@@ -3884,19 +3853,19 @@ function findCommandById(commandId, commands) {
3884
3853
  return commands.find((c) => c.metadata.id === commandId);
3885
3854
  }
3886
3855
  async function commandExists(configDir, commandId, projectDir) {
3887
- if (await pathExists(join6(getCommandsDir(configDir), `${commandId}${COMMAND_EXTENSION}`))) return true;
3888
- if (projectDir && await pathExists(join6(getProjectCommandsDir(projectDir), `${commandId}${COMMAND_EXTENSION}`)))
3856
+ if (await pathExists(join5(getCommandsDir(configDir), `${commandId}${COMMAND_EXTENSION}`))) return true;
3857
+ if (projectDir && await pathExists(join5(getProjectCommandsDir(projectDir), `${commandId}${COMMAND_EXTENSION}`)))
3889
3858
  return true;
3890
3859
  return false;
3891
3860
  }
3892
3861
  async function saveCommand(configDir, command) {
3893
3862
  const commandsDir = getCommandsDir(configDir);
3894
3863
  if (!await pathExists(commandsDir)) {
3895
- await mkdir4(commandsDir, { recursive: true });
3864
+ await mkdir3(commandsDir, { recursive: true });
3896
3865
  }
3897
- const filePath = join6(commandsDir, `${command.metadata.id}${COMMAND_EXTENSION}`);
3866
+ const filePath = join5(commandsDir, `${command.metadata.id}${COMMAND_EXTENSION}`);
3898
3867
  const content = matter2.stringify(command.prompt, command.metadata);
3899
- await writeFile3(filePath, content, "utf-8");
3868
+ await writeFile2(filePath, content, "utf-8");
3900
3869
  }
3901
3870
  async function saveCommandToProject(projectDir, command) {
3902
3871
  await saveItemToDir(
@@ -3914,7 +3883,7 @@ async function deleteCommand(configDir, commandId) {
3914
3883
  if (isDefault) {
3915
3884
  return { success: false, reason: "Cannot delete built-in defaults" };
3916
3885
  }
3917
- const filePath = join6(getCommandsDir(configDir), `${commandId}${COMMAND_EXTENSION}`);
3886
+ const filePath = join5(getCommandsDir(configDir), `${commandId}${COMMAND_EXTENSION}`);
3918
3887
  try {
3919
3888
  await unlink(filePath);
3920
3889
  return { success: true };
@@ -4094,26 +4063,26 @@ function createDevServerRoutes() {
4094
4063
  return router;
4095
4064
  }
4096
4065
 
4097
- // src/server/routes/worktree-config.ts
4066
+ // src/server/routes/workspace-config.ts
4098
4067
  import { Router as Router5 } from "express";
4099
- function createWorktreeConfigRoutes() {
4068
+ function createWorkspaceConfigRoutes() {
4100
4069
  const router = Router5();
4101
4070
  router.get("/config", async (req, res) => {
4102
4071
  const workdir = req.query["workdir"];
4103
4072
  if (!workdir) return res.status(400).json({ error: "workdir required" });
4104
- const config3 = await loadWorktreeConfig(workdir);
4073
+ const config3 = await loadWorkspaceConfig(workdir);
4105
4074
  res.json({ config: config3 });
4106
4075
  });
4107
4076
  router.post("/config", async (req, res) => {
4108
4077
  const workdir = req.query["workdir"];
4109
4078
  if (!workdir) return res.status(400).json({ error: "workdir required" });
4110
- const { ignoredAssets, overrides } = req.body;
4111
- if (!ignoredAssets || !["symlink", "copy", "skip"].includes(ignoredAssets)) {
4112
- return res.status(400).json({ error: "ignoredAssets must be one of: symlink, copy, skip" });
4079
+ const { setup } = req.body;
4080
+ if (!Array.isArray(setup)) {
4081
+ return res.status(400).json({ error: "setup must be an array of strings" });
4113
4082
  }
4114
4083
  try {
4115
- const config3 = { ignoredAssets, overrides: overrides ?? void 0 };
4116
- await saveWorktreeConfig(workdir, config3);
4084
+ const config3 = { setup };
4085
+ await saveWorkspaceConfig(workdir, config3);
4117
4086
  res.json({ config: config3 });
4118
4087
  } catch (err) {
4119
4088
  res.status(500).json({ error: err instanceof Error ? err.message : "Failed to save config" });
@@ -4166,7 +4135,7 @@ function createTerminalRoutes() {
4166
4135
  // src/server/routes/directories.ts
4167
4136
  import { Router as Router7 } from "express";
4168
4137
  import { readdir } from "fs/promises";
4169
- import { resolve as resolve4, join as join7, dirname as dirname5, basename as basename2 } from "path";
4138
+ import { resolve as resolve4, join as join6, dirname as dirname5, basename as basename2 } from "path";
4170
4139
  function createDirectoryRoutes() {
4171
4140
  const router = Router7();
4172
4141
  const DEFAULT_BASE_PATH = process.cwd();
@@ -4177,7 +4146,7 @@ function createDirectoryRoutes() {
4177
4146
  const entries = await readdir(resolvedPath, { withFileTypes: true });
4178
4147
  const directories = entries.filter((entry) => entry.isDirectory()).map((entry) => ({
4179
4148
  name: entry.name,
4180
- path: join7(resolvedPath, entry.name)
4149
+ path: join6(resolvedPath, entry.name)
4181
4150
  })).sort((a, b) => a.name.localeCompare(b.name));
4182
4151
  const parent = dirname5(resolvedPath);
4183
4152
  const hasParent = parent !== resolvedPath;
@@ -4282,11 +4251,6 @@ function fuzzyScore(filePath, query) {
4282
4251
  // src/server/routes/auto-update.ts
4283
4252
  import { Router as Router9 } from "express";
4284
4253
  import { spawn as spawn2 } from "child_process";
4285
-
4286
- // src/constants.ts
4287
- var VERSION = "2.0.70";
4288
-
4289
- // src/server/routes/auto-update.ts
4290
4254
  var updateInProgress = false;
4291
4255
  function isRunningAsService() {
4292
4256
  return process.env["OPENFOX_SERVICE"] === "true";
@@ -4308,8 +4272,10 @@ function createAutoUpdateRoutes(options = {}) {
4308
4272
  const current = VERSION;
4309
4273
  try {
4310
4274
  const latest = await new Promise((resolve8, reject) => {
4311
- const child = spawn2("npm", ["view", "openfox", "version"], {
4275
+ const win = process.platform === "win32";
4276
+ const child = spawn2(win ? "npm view openfox version" : "npm", win ? [] : ["view", "openfox", "version"], {
4312
4277
  stdio: ["ignore", "pipe", "pipe"],
4278
+ shell: win,
4313
4279
  windowsHide: true
4314
4280
  });
4315
4281
  let stdout = "";
@@ -4347,8 +4313,9 @@ function createAutoUpdateRoutes(options = {}) {
4347
4313
  updateInProgress = true;
4348
4314
  try {
4349
4315
  const isService = isRunningAsService();
4350
- const child = spawn2("bash", ["-c", "openfox update"], {
4316
+ const child = spawn2("openfox update", {
4351
4317
  stdio: ["ignore", "pipe", "pipe"],
4318
+ shell: true,
4352
4319
  windowsHide: true
4353
4320
  });
4354
4321
  let stdout = "";
@@ -4387,9 +4354,10 @@ function createAutoUpdateRoutes(options = {}) {
4387
4354
  return;
4388
4355
  }
4389
4356
  try {
4390
- const child = spawn2("bash", ["-c", "openfox service restart"], {
4357
+ const child = spawn2("openfox service restart", {
4391
4358
  detached: true,
4392
4359
  stdio: "ignore",
4360
+ shell: true,
4393
4361
  windowsHide: true
4394
4362
  });
4395
4363
  child.unref();
@@ -4535,8 +4503,8 @@ var ProviderRegistry = class {
4535
4503
  };
4536
4504
 
4537
4505
  // src/server/providers/plugins/loader.ts
4538
- import { readdir as readdir2, readFile as readFile3, stat as stat2 } from "fs/promises";
4539
- import { dirname as dirname6, join as join8, resolve as resolve5 } from "path";
4506
+ import { readdir as readdir2, readFile as readFile2, stat as stat2 } from "fs/promises";
4507
+ import { dirname as dirname6, join as join7, resolve as resolve5 } from "path";
4540
4508
  import { fileURLToPath as fileURLToPath5, pathToFileURL } from "url";
4541
4509
  async function packageDirectories(root) {
4542
4510
  let entries;
@@ -4547,13 +4515,13 @@ async function packageDirectories(root) {
4547
4515
  }
4548
4516
  const directories = [];
4549
4517
  for (const entry of entries) {
4550
- const entryPath = join8(root, entry.name);
4518
+ const entryPath = join7(root, entry.name);
4551
4519
  const isDirectory = entry.isDirectory() || entry.isSymbolicLink() && (await stat2(entryPath).catch(() => void 0))?.isDirectory();
4552
4520
  if (!isDirectory) continue;
4553
4521
  if (entry.name.startsWith("@")) {
4554
4522
  const scoped = await readdir2(entryPath, { withFileTypes: true }).catch(() => []);
4555
4523
  for (const child of scoped) {
4556
- const childPath = join8(entryPath, child.name);
4524
+ const childPath = join7(entryPath, child.name);
4557
4525
  const childIsDirectory = child.isDirectory() || child.isSymbolicLink() && (await stat2(childPath).catch(() => void 0))?.isDirectory();
4558
4526
  if (childIsDirectory) directories.push(childPath);
4559
4527
  }
@@ -4566,8 +4534,8 @@ async function packageDirectories(root) {
4566
4534
  async function loadProviderPlugins(options) {
4567
4535
  const moduleDirectory = dirname6(fileURLToPath5(import.meta.url));
4568
4536
  const roots = [
4569
- join8(options.configDirectory, "plugins"),
4570
- join8(options.cwd ?? process.cwd(), "node_modules"),
4537
+ join7(options.configDirectory, "plugins"),
4538
+ join7(options.cwd ?? process.cwd(), "node_modules"),
4571
4539
  resolve5(moduleDirectory, "node_modules"),
4572
4540
  resolve5(moduleDirectory, "../../../../node_modules")
4573
4541
  ];
@@ -4575,10 +4543,10 @@ async function loadProviderPlugins(options) {
4575
4543
  const diagnostics = [];
4576
4544
  for (const root of roots) {
4577
4545
  for (const packageDir of await packageDirectories(root)) {
4578
- const manifestPath = join8(packageDir, "package.json");
4546
+ const manifestPath = join7(packageDir, "package.json");
4579
4547
  let manifest;
4580
4548
  try {
4581
- manifest = JSON.parse(await readFile3(manifestPath, "utf8"));
4549
+ manifest = JSON.parse(await readFile2(manifestPath, "utf8"));
4582
4550
  } catch {
4583
4551
  continue;
4584
4552
  }
@@ -4616,7 +4584,7 @@ async function loadProviderPlugins(options) {
4616
4584
  }
4617
4585
  };
4618
4586
  try {
4619
- const module = await import(pathToFileURL(join8(packageDir, plugin)).href);
4587
+ const module = await import(pathToFileURL(join7(packageDir, plugin)).href);
4620
4588
  if (typeof module.register !== "function") throw new Error("Plugin does not export register(registry)");
4621
4589
  await module.register(trackingRegistry);
4622
4590
  diagnostic.loaded = true;
@@ -4631,9 +4599,9 @@ async function loadProviderPlugins(options) {
4631
4599
  // src/server/routes/plugins.ts
4632
4600
  import { Router as Router11 } from "express";
4633
4601
  import { fileURLToPath as fileURLToPath6, pathToFileURL as pathToFileURL2 } from "url";
4634
- import { dirname as dirname7, resolve as resolve6, join as join9 } from "path";
4602
+ import { dirname as dirname7, resolve as resolve6, join as join8 } from "path";
4635
4603
  import { existsSync } from "fs";
4636
- import { readFile as readFile4, readdir as readdir3, rm as rm2, rename as rename2 } from "fs/promises";
4604
+ import { readFile as readFile3, readdir as readdir3, rm as rm2, rename as rename2 } from "fs/promises";
4637
4605
  import { platform } from "os";
4638
4606
  import { execFile } from "child_process";
4639
4607
  import { promisify } from "util";
@@ -4663,7 +4631,7 @@ function createPluginRoutes(options) {
4663
4631
  if (!existsSync(registryPath)) {
4664
4632
  registryPath = resolve6(moduleDir, "../../../plugins-registry.json");
4665
4633
  }
4666
- const data = JSON.parse(await readFile4(registryPath, "utf8"));
4634
+ const data = JSON.parse(await readFile3(registryPath, "utf8"));
4667
4635
  registryCache = { data, ts: now };
4668
4636
  res.json({ plugins: data });
4669
4637
  } catch (err) {
@@ -4684,9 +4652,9 @@ function createPluginRoutes(options) {
4684
4652
  if (!/^[a-zA-Z0-9_-]+$/.test(repoName)) {
4685
4653
  return res.status(400).json({ error: "Invalid repository name" });
4686
4654
  }
4687
- const pluginsDir = join9(getGlobalConfigDir(config3.mode ?? "production"), "plugins");
4688
- const targetDir = join9(pluginsDir, repoName);
4689
- const tmpDir = join9(pluginsDir, `.${repoName}-tmp-${Date.now()}`);
4655
+ const pluginsDir = join8(getGlobalConfigDir(config3.mode ?? "production"), "plugins");
4656
+ const targetDir = join8(pluginsDir, repoName);
4657
+ const tmpDir = join8(pluginsDir, `.${repoName}-tmp-${Date.now()}`);
4690
4658
  try {
4691
4659
  await execFileP("mkdir", ["-p", pluginsDir], { timeout: 5e3 });
4692
4660
  } catch {
@@ -4717,7 +4685,7 @@ function createPluginRoutes(options) {
4717
4685
  }
4718
4686
  if (!loadError) {
4719
4687
  try {
4720
- const manifest = JSON.parse(await readFile4(join9(targetDir, "package.json"), "utf8"));
4688
+ const manifest = JSON.parse(await readFile3(join8(targetDir, "package.json"), "utf8"));
4721
4689
  const pluginEntry = manifest.openfox?.plugin;
4722
4690
  const apiVersion = manifest.openfox?.apiVersion;
4723
4691
  if (!pluginEntry || !manifest.name) {
@@ -4725,7 +4693,7 @@ function createPluginRoutes(options) {
4725
4693
  } else if (apiVersion !== 1) {
4726
4694
  loadError = `Unsupported plugin API version: ${String(apiVersion)}`;
4727
4695
  } else {
4728
- const mod = await import(pathToFileURL2(join9(targetDir, pluginEntry)).href);
4696
+ const mod = await import(pathToFileURL2(join8(targetDir, pluginEntry)).href);
4729
4697
  if (typeof mod.register !== "function") {
4730
4698
  loadError = "Plugin does not export register(registry)";
4731
4699
  } else {
@@ -4774,16 +4742,16 @@ function createPluginRoutes(options) {
4774
4742
  }
4775
4743
  });
4776
4744
  router.get("/installed", async (_req, res) => {
4777
- const pluginsDir = join9(getGlobalConfigDir(config3.mode ?? "production"), "plugins");
4745
+ const pluginsDir = join8(getGlobalConfigDir(config3.mode ?? "production"), "plugins");
4778
4746
  try {
4779
4747
  const entries = await readdir3(pluginsDir, { withFileTypes: true });
4780
4748
  const installed = [];
4781
4749
  for (const entry of entries) {
4782
4750
  if (!entry.isDirectory()) continue;
4783
- const pkgPath = join9(pluginsDir, entry.name, "package.json");
4751
+ const pkgPath = join8(pluginsDir, entry.name, "package.json");
4784
4752
  let version = null;
4785
4753
  try {
4786
- const pkg = JSON.parse(await readFile4(pkgPath, "utf8"));
4754
+ const pkg = JSON.parse(await readFile3(pkgPath, "utf8"));
4787
4755
  version = pkg.version ?? null;
4788
4756
  } catch {
4789
4757
  }
@@ -4795,13 +4763,13 @@ function createPluginRoutes(options) {
4795
4763
  }
4796
4764
  });
4797
4765
  router.get("/open-folder", async (_req, res) => {
4798
- const pluginsDir = join9(getGlobalConfigDir(config3.mode ?? "production"), "plugins");
4766
+ const pluginsDir = join8(getGlobalConfigDir(config3.mode ?? "production"), "plugins");
4799
4767
  await openFolder(pluginsDir, res);
4800
4768
  });
4801
4769
  router.get("/:name/open-folder", async (req, res) => {
4802
4770
  const name = req.params.name;
4803
4771
  if (!/^[a-zA-Z0-9_-]+$/.test(name)) return res.status(400).json({ error: "Invalid plugin name" });
4804
- const targetDir = join9(getGlobalConfigDir(config3.mode ?? "production"), "plugins", name);
4772
+ const targetDir = join8(getGlobalConfigDir(config3.mode ?? "production"), "plugins", name);
4805
4773
  await openFolder(targetDir, res);
4806
4774
  });
4807
4775
  router.delete("/:name", async (req, res) => {
@@ -4809,7 +4777,7 @@ function createPluginRoutes(options) {
4809
4777
  if (!/^[a-zA-Z0-9_-]+$/.test(name)) {
4810
4778
  return res.status(400).json({ error: "Invalid plugin name" });
4811
4779
  }
4812
- const targetDir = join9(getGlobalConfigDir(config3.mode ?? "production"), "plugins", name);
4780
+ const targetDir = join8(getGlobalConfigDir(config3.mode ?? "production"), "plugins", name);
4813
4781
  try {
4814
4782
  await rm2(targetDir, { recursive: true, force: true });
4815
4783
  for (let i = pluginDiagnostics.length - 1; i >= 0; i--) {
@@ -4921,7 +4889,7 @@ async function createServerHandle(config3) {
4921
4889
  setMcpTools(mcpTools);
4922
4890
  logger.info("MCP tools registered", { count: mcpTools.length });
4923
4891
  }
4924
- const { signalMcpReady } = await import("./server-RLNPHLY2.js");
4892
+ const { signalMcpReady } = await import("./server-G2J4RAXL.js");
4925
4893
  signalMcpReady();
4926
4894
  });
4927
4895
  const app = express();
@@ -4983,7 +4951,7 @@ async function createServerHandle(config3) {
4983
4951
  res.json({ tools });
4984
4952
  });
4985
4953
  app.get("/api/projects", async (_req, res) => {
4986
- const { listProjects } = await import("./projects-7HSBZY2D.js");
4954
+ const { listProjects } = await import("./projects-LHRNCUGW.js");
4987
4955
  const projects = listProjects();
4988
4956
  res.json({ projects });
4989
4957
  });
@@ -4992,7 +4960,7 @@ async function createServerHandle(config3) {
4992
4960
  if (!name || !workdir) {
4993
4961
  return res.status(400).json({ error: "name and workdir are required" });
4994
4962
  }
4995
- const { createDirectoryWithGit } = await import("./project-creator-EMGRSPYS.js");
4963
+ const { createDirectoryWithGit } = await import("./project-creator-FQRBN3RG.js");
4996
4964
  try {
4997
4965
  const project = await createDirectoryWithGit(name, workdir);
4998
4966
  res.status(201).json({ project });
@@ -5037,7 +5005,7 @@ async function createServerHandle(config3) {
5037
5005
  }
5038
5006
  });
5039
5007
  app.get("/api/projects/:id", async (req, res) => {
5040
- const { getProject: getProject2 } = await import("./projects-7HSBZY2D.js");
5008
+ const { getProject: getProject2 } = await import("./projects-LHRNCUGW.js");
5041
5009
  const project = getProject2(req.params.id);
5042
5010
  if (!project) {
5043
5011
  return res.status(404).json({ error: "Project not found" });
@@ -5045,7 +5013,7 @@ async function createServerHandle(config3) {
5045
5013
  res.json({ project });
5046
5014
  });
5047
5015
  app.put("/api/projects/:id", async (req, res) => {
5048
- const { updateProject } = await import("./projects-7HSBZY2D.js");
5016
+ const { updateProject } = await import("./projects-LHRNCUGW.js");
5049
5017
  const { name, customInstructions, dangerLevel } = req.body;
5050
5018
  const updates = {};
5051
5019
  if (name !== void 0) updates.name = name;
@@ -5058,7 +5026,7 @@ async function createServerHandle(config3) {
5058
5026
  res.json({ project: updated });
5059
5027
  });
5060
5028
  app.delete("/api/projects/:id", async (req, res) => {
5061
- const { getProject: getProject2, deleteProject } = await import("./projects-7HSBZY2D.js");
5029
+ const { getProject: getProject2, deleteProject } = await import("./projects-LHRNCUGW.js");
5062
5030
  const project = getProject2(req.params.id);
5063
5031
  if (!project) {
5064
5032
  return res.status(404).json({ error: "Project not found" });
@@ -5067,7 +5035,7 @@ async function createServerHandle(config3) {
5067
5035
  res.json({ success: true });
5068
5036
  });
5069
5037
  app.put("/api/projects/:id/star", async (req, res) => {
5070
- const { toggleStar } = await import("./projects-7HSBZY2D.js");
5038
+ const { toggleStar } = await import("./projects-LHRNCUGW.js");
5071
5039
  const { isStarred } = req.body;
5072
5040
  if (typeof isStarred !== "boolean") {
5073
5041
  return res.status(400).json({ error: "isStarred is required and must be a boolean" });
@@ -5079,20 +5047,20 @@ async function createServerHandle(config3) {
5079
5047
  res.json({ project });
5080
5048
  });
5081
5049
  app.get("/api/projects/:id/branches", async (req, res) => {
5082
- const { getProject: getProject2 } = await import("./projects-7HSBZY2D.js");
5050
+ const { getProject: getProject2 } = await import("./projects-LHRNCUGW.js");
5083
5051
  const project = getProject2(req.params.id);
5084
5052
  if (!project) return res.status(404).json({ error: "Project not found" });
5085
- const { listBranches } = await import("./worktree-6U45P63P.js");
5053
+ const { listBranches } = await import("./workspace-ET3FHZYN.js");
5086
5054
  const branches = await listBranches(project.workdir);
5087
5055
  res.json({ branches });
5088
5056
  });
5089
5057
  app.post("/api/projects/:id/checkout", async (req, res) => {
5090
- const { getProject: getProject2 } = await import("./projects-7HSBZY2D.js");
5058
+ const { getProject: getProject2 } = await import("./projects-LHRNCUGW.js");
5091
5059
  const project = getProject2(req.params.id);
5092
5060
  if (!project) return res.status(404).json({ error: "Project not found" });
5093
5061
  const { branch } = req.body;
5094
5062
  if (!branch || typeof branch !== "string") return res.status(400).json({ error: "branch is required" });
5095
- const { checkoutBranch } = await import("./worktree-6U45P63P.js");
5063
+ const { checkoutBranch } = await import("./workspace-ET3FHZYN.js");
5096
5064
  try {
5097
5065
  await checkoutBranch(project.workdir, branch);
5098
5066
  res.json({ branch });
@@ -5101,12 +5069,12 @@ async function createServerHandle(config3) {
5101
5069
  }
5102
5070
  });
5103
5071
  app.post("/api/projects/:id/checkout-new", async (req, res) => {
5104
- const { getProject: getProject2 } = await import("./projects-7HSBZY2D.js");
5072
+ const { getProject: getProject2 } = await import("./projects-LHRNCUGW.js");
5105
5073
  const project = getProject2(req.params.id);
5106
5074
  if (!project) return res.status(404).json({ error: "Project not found" });
5107
5075
  const { name } = req.body;
5108
5076
  if (!name || typeof name !== "string") return res.status(400).json({ error: "name is required" });
5109
- const { createBranch } = await import("./worktree-6U45P63P.js");
5077
+ const { createBranch } = await import("./workspace-ET3FHZYN.js");
5110
5078
  try {
5111
5079
  await createBranch(project.workdir, name);
5112
5080
  res.json({ branch: name });
@@ -5114,17 +5082,17 @@ async function createServerHandle(config3) {
5114
5082
  res.status(400).json({ error: err instanceof Error ? err.message : "Failed to create branch" });
5115
5083
  }
5116
5084
  });
5117
- app.get("/api/projects/:id/worktrees", async (req, res) => {
5118
- const { getProject: getProject2 } = await import("./projects-7HSBZY2D.js");
5085
+ app.get("/api/projects/:id/workspaces", async (req, res) => {
5086
+ const { getProject: getProject2 } = await import("./projects-LHRNCUGW.js");
5119
5087
  const project = getProject2(req.params.id);
5120
5088
  if (!project) return res.status(404).json({ error: "Project not found" });
5121
- const { listWorktrees } = await import("./worktree-6U45P63P.js");
5122
- const all = await listWorktrees(project.workdir);
5123
- const worktrees = all.filter((wt) => wt.path !== project.workdir);
5124
- res.json({ worktrees });
5089
+ const { listWorkspaces } = await import("./workspace-ET3FHZYN.js");
5090
+ const all = await listWorkspaces(project.name);
5091
+ const workspacesList = all.filter((ws) => ws.path !== project.workdir);
5092
+ res.json({ workspaces: workspacesList });
5125
5093
  });
5126
5094
  app.get("/api/sessions", async (req, res) => {
5127
- const { getRecentUserPromptsForSession } = await import("./events-CDQ4HASP.js");
5095
+ const { getRecentUserPromptsForSession } = await import("./events-AEQ6GQXI.js");
5128
5096
  const projectId = req.query["projectId"];
5129
5097
  const limit = Math.min(parseInt(req.query["limit"]) || 20, 100);
5130
5098
  const offset = parseInt(req.query["offset"]) || 0;
@@ -5156,44 +5124,34 @@ async function createServerHandle(config3) {
5156
5124
  const session = sessionManager.createSession(projectId, title, providerId ?? null, model ?? null);
5157
5125
  res.status(201).json({ session });
5158
5126
  });
5159
- app.post("/api/sessions/:id/worktree", async (req, res) => {
5127
+ app.post("/api/sessions/:id/switch-workspace", async (req, res) => {
5160
5128
  const session = sessionManager.getSession(req.params.id);
5161
5129
  if (!session) return res.status(404).json({ error: "Session not found" });
5162
- const { name } = req.body;
5163
- if (!name || typeof name !== "string") return res.status(400).json({ error: "name is required" });
5130
+ const { target, branch } = req.body;
5131
+ if (!target || typeof target !== "string") return res.status(400).json({ error: "target is required" });
5164
5132
  try {
5165
- const updated = await sessionManager.createSessionWorktree(req.params.id, name);
5133
+ const updated = await sessionManager.switchWorkspace(req.params.id, target, branch);
5166
5134
  res.json({ session: updated });
5167
5135
  } catch (err) {
5168
- res.status(400).json({ error: err instanceof Error ? err.message : "Failed to create worktree" });
5136
+ res.status(400).json({ error: err instanceof Error ? err.message : "Failed to switch workspace" });
5169
5137
  }
5170
5138
  });
5171
- app.post("/api/sessions/:id/close-worktree", async (req, res) => {
5139
+ app.post("/api/sessions/:id/delete-workspace", async (req, res) => {
5172
5140
  const session = sessionManager.getSession(req.params.id);
5173
5141
  if (!session) return res.status(404).json({ error: "Session not found" });
5142
+ const { target } = req.body;
5143
+ if (!target || typeof target !== "string") return res.status(400).json({ error: "target is required" });
5174
5144
  try {
5175
- const updated = await sessionManager.closeSessionWorktree(req.params.id);
5145
+ const updated = await sessionManager.deleteWorkspace(req.params.id, target);
5176
5146
  res.json({ session: updated });
5177
5147
  } catch (err) {
5178
- res.status(400).json({ error: err instanceof Error ? err.message : "Failed to close worktree" });
5179
- }
5180
- });
5181
- app.post("/api/sessions/:id/attach-worktree", async (req, res) => {
5182
- const session = sessionManager.getSession(req.params.id);
5183
- if (!session) return res.status(404).json({ error: "Session not found" });
5184
- const { path } = req.body;
5185
- if (!path || typeof path !== "string") return res.status(400).json({ error: "path is required" });
5186
- try {
5187
- const updated = await sessionManager.attachSessionWorktree(req.params.id, path);
5188
- res.json({ session: updated });
5189
- } catch (err) {
5190
- res.status(400).json({ error: err instanceof Error ? err.message : "Failed to attach worktree" });
5148
+ res.status(400).json({ error: err instanceof Error ? err.message : "Failed to delete workspace" });
5191
5149
  }
5192
5150
  });
5193
5151
  app.get("/api/sessions/:id", async (req, res) => {
5194
- const { getEventStore: getEventStore2 } = await import("./events-CDQ4HASP.js");
5195
- const { buildMessagesFromStoredEvents } = await import("./folding-V2K34EGN.js");
5196
- const { getPendingQuestionsForSession } = await import("./tools-CALGWIV2.js");
5152
+ const { getEventStore: getEventStore2 } = await import("./events-AEQ6GQXI.js");
5153
+ const { buildMessagesFromStoredEvents } = await import("./folding-ONH3D4OK.js");
5154
+ const { getPendingQuestionsForSession } = await import("./tools-X52DFUS6.js");
5197
5155
  const session = sessionManager.getSession(req.params.id);
5198
5156
  if (!session) {
5199
5157
  return res.status(404).json({ error: "Session not found" });
@@ -5212,8 +5170,8 @@ async function createServerHandle(config3) {
5212
5170
  if (!session) {
5213
5171
  return res.status(404).json({ error: "Session not found" });
5214
5172
  }
5215
- const { stopSessionExecution } = await import("./chat-handler-K3DWIGHG.js");
5216
- const { cancelQuestionsForSession, cancelPathConfirmationsForSession } = await import("./tools-CALGWIV2.js");
5173
+ const { stopSessionExecution } = await import("./chat-handler-LK5RUAGO.js");
5174
+ const { cancelQuestionsForSession, cancelPathConfirmationsForSession } = await import("./tools-X52DFUS6.js");
5217
5175
  sessionManager.clearMessageQueue(sessionId);
5218
5176
  stopSessionExecution(sessionId, sessionManager);
5219
5177
  abortSession(sessionId);
@@ -5232,8 +5190,8 @@ async function createServerHandle(config3) {
5232
5190
  res.json({ success: true });
5233
5191
  });
5234
5192
  app.post("/api/sessions/:id/provider", async (req, res) => {
5235
- const { getEventStore: getEventStore2 } = await import("./events-CDQ4HASP.js");
5236
- const { buildMessagesFromStoredEvents } = await import("./folding-V2K34EGN.js");
5193
+ const { getEventStore: getEventStore2 } = await import("./events-AEQ6GQXI.js");
5194
+ const { buildMessagesFromStoredEvents } = await import("./folding-ONH3D4OK.js");
5237
5195
  const sessionId = req.params.id;
5238
5196
  const session = sessionManager.getSession(sessionId);
5239
5197
  if (!session) {
@@ -5332,18 +5290,20 @@ async function createServerHandle(config3) {
5332
5290
  return res.status(400).json({ error: `entries[${i}].status must be a string` });
5333
5291
  }
5334
5292
  }
5335
- const mapped = entries.map((c, i) => ({
5336
- ...c,
5337
- id: c.id != null ? String(c.id) : String(i),
5338
- description: c.description ?? "",
5339
- status: c.status ?? "open"
5340
- }));
5293
+ const mapped = entries.map(
5294
+ (c, i) => ({
5295
+ ...c,
5296
+ id: c.id != null ? String(c.id) : String(i),
5297
+ description: c.description ?? "",
5298
+ status: c.status ?? "open"
5299
+ })
5300
+ );
5341
5301
  sessionManager.setMetadataEntries(sessionId, key, mapped);
5342
5302
  res.json({ success: true });
5343
5303
  });
5344
5304
  app.put("/api/sessions/:id/mode", async (req, res) => {
5345
- const { getEventStore: getEventStore2 } = await import("./events-CDQ4HASP.js");
5346
- const { buildMessagesFromStoredEvents } = await import("./folding-V2K34EGN.js");
5305
+ const { getEventStore: getEventStore2 } = await import("./events-AEQ6GQXI.js");
5306
+ const { buildMessagesFromStoredEvents } = await import("./folding-ONH3D4OK.js");
5347
5307
  const sessionId = req.params.id;
5348
5308
  const session = sessionManager.getSession(sessionId);
5349
5309
  if (!session) {
@@ -5399,15 +5359,15 @@ async function createServerHandle(config3) {
5399
5359
  if (!callId || approved === void 0) {
5400
5360
  return res.status(400).json({ error: "callId and approved are required" });
5401
5361
  }
5402
- const { providePathConfirmation } = await import("./tools-CALGWIV2.js");
5362
+ const { providePathConfirmation } = await import("./tools-X52DFUS6.js");
5403
5363
  const result = providePathConfirmation(callId, approved, alwaysAllow);
5404
5364
  if (!result.found) {
5405
5365
  return res.status(404).json({ error: "No pending path confirmation with that ID" });
5406
5366
  }
5407
- const { getEventStore: getEventStore2 } = await import("./events-CDQ4HASP.js");
5408
- const { buildMessagesFromStoredEvents, foldPendingConfirmations } = await import("./folding-V2K34EGN.js");
5409
- const { createSessionStateMessage } = await import("./protocol-CTNE3ANP.js");
5410
- const { getPendingQuestionsForSession } = await import("./tools-CALGWIV2.js");
5367
+ const { getEventStore: getEventStore2 } = await import("./events-AEQ6GQXI.js");
5368
+ const { buildMessagesFromStoredEvents, foldPendingConfirmations } = await import("./folding-ONH3D4OK.js");
5369
+ const { createSessionStateMessage } = await import("./protocol-4QFU7WAI.js");
5370
+ const { getPendingQuestionsForSession } = await import("./tools-X52DFUS6.js");
5411
5371
  const eventStore = getEventStore2();
5412
5372
  const events = eventStore.getEvents(sessionId);
5413
5373
  const messages = buildMessagesFromStoredEvents(events);
@@ -5428,7 +5388,7 @@ async function createServerHandle(config3) {
5428
5388
  if (!skip && typeof answer !== "string") {
5429
5389
  return res.status(400).json({ error: "answer is required when not skipping" });
5430
5390
  }
5431
- const { provideAnswer } = await import("./tools-CALGWIV2.js");
5391
+ const { provideAnswer } = await import("./tools-X52DFUS6.js");
5432
5392
  const found = provideAnswer(callId, answer ?? "", skip ?? false);
5433
5393
  if (!found) {
5434
5394
  return res.status(404).json({ error: "No pending question with that ID" });
@@ -5456,7 +5416,7 @@ async function createServerHandle(config3) {
5456
5416
  if (!session) {
5457
5417
  return res.status(404).json({ error: "Session not found" });
5458
5418
  }
5459
- const { getSetting: getSetting2, SETTINGS_KEYS } = await import("./settings-6ZPWOBWL.js");
5419
+ const { getSetting: getSetting2, SETTINGS_KEYS } = await import("./settings-PFXRYXZU.js");
5460
5420
  if (getSetting2(SETTINGS_KEYS.CACHE_WARMING) !== "true") {
5461
5421
  return res.json({ success: false, reason: "disabled" });
5462
5422
  }
@@ -5488,7 +5448,7 @@ async function createServerHandle(config3) {
5488
5448
  backend: activeProvider?.backend ?? llmClient.getBackend(),
5489
5449
  model: llmClient.getModel()
5490
5450
  };
5491
- const { runAgentTurn, TurnMetrics } = await import("./orchestrator-PUV4WG77.js");
5451
+ const { runAgentTurn, TurnMetrics } = await import("./orchestrator-RTZVMWQV.js");
5492
5452
  runAgentTurn(
5493
5453
  {
5494
5454
  sessionManager,
@@ -5526,15 +5486,15 @@ async function createServerHandle(config3) {
5526
5486
  if (!session) {
5527
5487
  return res.status(404).json({ error: "Session not found" });
5528
5488
  }
5529
- const { stopSessionExecution } = await import("./chat-handler-K3DWIGHG.js");
5530
- const { cancelQuestionsForSession, cancelPathConfirmationsForSession } = await import("./tools-CALGWIV2.js");
5489
+ const { stopSessionExecution } = await import("./chat-handler-LK5RUAGO.js");
5490
+ const { cancelQuestionsForSession, cancelPathConfirmationsForSession } = await import("./tools-X52DFUS6.js");
5531
5491
  const queuedMessages = sessionManager.getQueueState(sessionId);
5532
5492
  sessionManager.clearMessageQueue(sessionId);
5533
5493
  stopSessionExecution(sessionId, sessionManager);
5534
5494
  abortSession(sessionId);
5535
5495
  cancelQuestionsForSession(sessionId, "Session stopped by user");
5536
5496
  cancelPathConfirmationsForSession(sessionId, "Session stopped by user");
5537
- const eventStore = (await import("./events-CDQ4HASP.js")).getEventStore();
5497
+ const eventStore = (await import("./events-AEQ6GQXI.js")).getEventStore();
5538
5498
  eventStore.append(sessionId, { type: "running.changed", data: { isRunning: false } });
5539
5499
  res.json({ success: true, queuedMessages });
5540
5500
  });
@@ -5548,7 +5508,7 @@ async function createServerHandle(config3) {
5548
5508
  if (typeof messageIndex !== "number" || messageIndex < 0) {
5549
5509
  return res.status(400).json({ error: "messageIndex must be a non-negative number" });
5550
5510
  }
5551
- const { truncateSessionMessages } = await import("./events-CDQ4HASP.js");
5511
+ const { truncateSessionMessages } = await import("./events-AEQ6GQXI.js");
5552
5512
  truncateSessionMessages(sessionId, messageIndex);
5553
5513
  res.json({ success: true });
5554
5514
  });
@@ -5562,8 +5522,8 @@ async function createServerHandle(config3) {
5562
5522
  if (typeof messageId !== "string" || !messageId) {
5563
5523
  return res.status(400).json({ error: "messageId is required" });
5564
5524
  }
5565
- const { getEventStore: getEventStore2 } = await import("./events-CDQ4HASP.js");
5566
- const { buildMessagesFromStoredEvents } = await import("./folding-V2K34EGN.js");
5525
+ const { getEventStore: getEventStore2 } = await import("./events-AEQ6GQXI.js");
5526
+ const { buildMessagesFromStoredEvents } = await import("./folding-ONH3D4OK.js");
5567
5527
  const eventStore = getEventStore2();
5568
5528
  const events = eventStore.getEvents(sessionId);
5569
5529
  const messages = buildMessagesFromStoredEvents(events);
@@ -5575,7 +5535,7 @@ async function createServerHandle(config3) {
5575
5535
  if (msg.role !== "user" || msg.isSystemGenerated) {
5576
5536
  return res.status(400).json({ error: "Can only replay user messages" });
5577
5537
  }
5578
- const { truncateSessionMessages } = await import("./events-CDQ4HASP.js");
5538
+ const { truncateSessionMessages } = await import("./events-AEQ6GQXI.js");
5579
5539
  truncateSessionMessages(sessionId, msgIndex - 1);
5580
5540
  sessionManager.queueMessage(sessionId, "asap", msg.content, msg.attachments, msg.messageKind);
5581
5541
  res.json({ success: true });
@@ -5607,7 +5567,7 @@ async function createServerHandle(config3) {
5607
5567
  res.json({ accepted: true });
5608
5568
  });
5609
5569
  app.get("/api/settings", async (req, res) => {
5610
- const { getSetting: getSetting2, SETTINGS_DEFAULTS } = await import("./settings-6ZPWOBWL.js");
5570
+ const { getSetting: getSetting2, SETTINGS_DEFAULTS } = await import("./settings-PFXRYXZU.js");
5611
5571
  const keysParam = req.query["keys"];
5612
5572
  if (!keysParam) {
5613
5573
  return res.status(400).json({ error: "keys query parameter is required" });
@@ -5620,19 +5580,19 @@ async function createServerHandle(config3) {
5620
5580
  res.json(result);
5621
5581
  });
5622
5582
  app.get("/api/settings/:key", async (req, res) => {
5623
- const { getSetting: getSetting2, SETTINGS_DEFAULTS } = await import("./settings-6ZPWOBWL.js");
5583
+ const { getSetting: getSetting2, SETTINGS_DEFAULTS } = await import("./settings-PFXRYXZU.js");
5624
5584
  const key = req.params.key;
5625
5585
  const value = getSetting2(key) ?? SETTINGS_DEFAULTS[key] ?? null;
5626
5586
  res.json({ key, value });
5627
5587
  });
5628
5588
  app.get("/api/settings/:key", async (req, res) => {
5629
- const { getSetting: getSetting2, SETTINGS_DEFAULTS } = await import("./settings-6ZPWOBWL.js");
5589
+ const { getSetting: getSetting2, SETTINGS_DEFAULTS } = await import("./settings-PFXRYXZU.js");
5630
5590
  const key = req.params.key;
5631
5591
  const value = getSetting2(key) ?? SETTINGS_DEFAULTS[key] ?? null;
5632
5592
  res.json({ key, value });
5633
5593
  });
5634
5594
  app.put("/api/settings/:key", async (req, res) => {
5635
- const { setSetting: setSetting2 } = await import("./settings-6ZPWOBWL.js");
5595
+ const { setSetting: setSetting2 } = await import("./settings-PFXRYXZU.js");
5636
5596
  const key = req.params.key;
5637
5597
  const { value } = req.body;
5638
5598
  if (value === void 0) {
@@ -5659,7 +5619,7 @@ async function createServerHandle(config3) {
5659
5619
  }
5660
5620
  });
5661
5621
  app.get("/api/tools/shells", async (_req, res) => {
5662
- const { listAvailableShells } = await import("./platform-AB3GIEGO.js");
5622
+ const { listAvailableShells } = await import("./platform-XQ7BS3KQ.js");
5663
5623
  res.json({ shells: listAvailableShells() });
5664
5624
  });
5665
5625
  app.get("/api/config", async (_req, res) => {
@@ -5821,7 +5781,7 @@ async function createServerHandle(config3) {
5821
5781
  const backend = req.query["backend"];
5822
5782
  if (!url) return res.status(400).json({ error: "url is required" });
5823
5783
  try {
5824
- const { fetchModelsWithContext } = await import("./provider-manager-7C3JVOLW.js");
5784
+ const { fetchModelsWithContext } = await import("./provider-manager-MAKXSL6L.js");
5825
5785
  const { getModelProfile: getModelProfile2 } = await import("./profiles-5J7F4BML.js");
5826
5786
  const models = await fetchModelsWithContext(
5827
5787
  url,
@@ -5891,7 +5851,7 @@ async function createServerHandle(config3) {
5891
5851
  }
5892
5852
  const { getModelProfile: getModelProfile2 } = await import("./profiles-5J7F4BML.js");
5893
5853
  const { getBackendCapabilities } = await import("./backend-P3GHHLHJ.js");
5894
- const { buildNonStreamingCreateParams } = await import("./client-pure-XHH4RRLB.js");
5854
+ const { buildNonStreamingCreateParams } = await import("./client-pure-NMLDKRDN.js");
5895
5855
  const { OpenAIHttpClient } = await import("./http-client-PIWB7BXK.js");
5896
5856
  const { ensureVersionPrefix } = await import("./url-utils-SAJP7AEX.js");
5897
5857
  const profile = getModelProfile2(model);
@@ -6150,7 +6110,7 @@ async function createServerHandle(config3) {
6150
6110
  });
6151
6111
  async function rebuildMcpTools() {
6152
6112
  const { createMcpTools: createMcpTools2 } = await import("./tool-adapter-MOGEI6TP.js");
6153
- const { setMcpTools: setMcpTools2 } = await import("./tools-CALGWIV2.js");
6113
+ const { setMcpTools: setMcpTools2 } = await import("./tools-X52DFUS6.js");
6154
6114
  const mcpTools = createMcpTools2(mcpManager);
6155
6115
  setMcpTools2(mcpTools);
6156
6116
  }
@@ -6368,7 +6328,7 @@ async function createServerHandle(config3) {
6368
6328
  app.use("/api/agents", createAgentRoutes(configDir, projectDir));
6369
6329
  app.use("/api/workflows", createWorkflowRoutes(configDir, config3, projectDir));
6370
6330
  app.use("/api/dev-server", createDevServerRoutes());
6371
- app.use("/api/worktree", createWorktreeConfigRoutes());
6331
+ app.use("/api/workspace", createWorkspaceConfigRoutes());
6372
6332
  app.use("/api/terminals", createTerminalRoutes());
6373
6333
  app.use(
6374
6334
  "/api/auto-update",
@@ -6385,13 +6345,13 @@ async function createServerHandle(config3) {
6385
6345
  })
6386
6346
  );
6387
6347
  app.get("/api/sessions/:id/background-processes", async (req, res) => {
6388
- const { getSessionProcesses } = await import("./manager-JXYRGR6B.js");
6348
+ const { getSessionProcesses } = await import("./manager-24C2AXVF.js");
6389
6349
  const sessionId = req.params.id;
6390
6350
  const processes = getSessionProcesses(sessionId);
6391
6351
  res.json({ processes });
6392
6352
  });
6393
6353
  app.post("/api/sessions/:id/background-process/:processId/stop", async (req, res) => {
6394
- const { stopProcess } = await import("./manager-JXYRGR6B.js");
6354
+ const { stopProcess } = await import("./manager-24C2AXVF.js");
6395
6355
  const sessionId = req.params.id;
6396
6356
  const processId = req.params.processId;
6397
6357
  const session = sessionManager.getSession(sessionId);
@@ -6438,7 +6398,7 @@ async function createServerHandle(config3) {
6438
6398
  }
6439
6399
  });
6440
6400
  app.get("/fox.svg", (_req, res) => {
6441
- readFile5(join10(webDir, "fox.svg")).then((content) => {
6401
+ readFile4(join9(webDir, "fox.svg")).then((content) => {
6442
6402
  res.set("Content-Type", "image/svg+xml");
6443
6403
  res.send(content);
6444
6404
  }).catch(() => {
@@ -6447,7 +6407,7 @@ async function createServerHandle(config3) {
6447
6407
  });
6448
6408
  app.use(
6449
6409
  "/sounds",
6450
- express.static(join10(webDir, "public", "sounds"), {
6410
+ express.static(join9(webDir, "public", "sounds"), {
6451
6411
  setHeaders: (res) => {
6452
6412
  res.set("Content-Type", "audio/mpeg");
6453
6413
  }
@@ -6456,13 +6416,13 @@ async function createServerHandle(config3) {
6456
6416
  app.use("/__inspect__.js", (_req, res) => {
6457
6417
  res.set("Access-Control-Allow-Origin", "*");
6458
6418
  res.set("Content-Type", "application/javascript");
6459
- readFile5(join10(webDir, "public", "__inspect__.js")).then((content) => res.send(content)).catch(() => res.status(404).send("Not found"));
6419
+ readFile4(join9(webDir, "public", "__inspect__.js")).then((content) => res.send(content)).catch(() => res.status(404).send("Not found"));
6460
6420
  });
6461
6421
  app.get("/*path", (req, res) => {
6462
6422
  if (req.path.startsWith("/api/")) {
6463
6423
  return;
6464
6424
  }
6465
- readFile5(join10(webDir, "index.html"), "utf-8").then((indexHtml) => viteServer.transformIndexHtml(req.originalUrl, indexHtml)).then((transformed) => res.send(transformed)).catch((err) => {
6425
+ readFile4(join9(webDir, "index.html"), "utf-8").then((indexHtml) => viteServer.transformIndexHtml(req.originalUrl, indexHtml)).then((transformed) => res.send(transformed)).catch((err) => {
6466
6426
  logger.error("Error serving index.html", { error: err });
6467
6427
  res.status(500).send("Server error");
6468
6428
  });
@@ -6473,7 +6433,7 @@ async function createServerHandle(config3) {
6473
6433
  const distWebDir = resolve7(__dirname3, "web");
6474
6434
  app.use(
6475
6435
  "/assets",
6476
- express.static(join10(distWebDir, "assets"), {
6436
+ express.static(join9(distWebDir, "assets"), {
6477
6437
  setHeaders: (res, filepath) => {
6478
6438
  if (filepath.endsWith(".css")) {
6479
6439
  res.set("Content-Type", "text/css");
@@ -6481,11 +6441,11 @@ async function createServerHandle(config3) {
6481
6441
  }
6482
6442
  })
6483
6443
  );
6484
- app.use("/manifest.webmanifest", express.static(join10(distWebDir, "manifest.webmanifest")));
6485
- app.use("/registerSW.js", express.static(join10(distWebDir, "registerSW.js")));
6486
- app.use("/sw.js", express.static(join10(distWebDir, "sw.js")));
6444
+ app.use("/manifest.webmanifest", express.static(join9(distWebDir, "manifest.webmanifest")));
6445
+ app.use("/registerSW.js", express.static(join9(distWebDir, "registerSW.js")));
6446
+ app.use("/sw.js", express.static(join9(distWebDir, "sw.js")));
6487
6447
  app.get("/fox.svg", (_req, res) => {
6488
- readFile5(join10(distWebDir, "fox.svg")).then((content) => {
6448
+ readFile4(join9(distWebDir, "fox.svg")).then((content) => {
6489
6449
  res.set("Content-Type", "image/svg+xml");
6490
6450
  res.send(content);
6491
6451
  }).catch(() => {
@@ -6494,7 +6454,7 @@ async function createServerHandle(config3) {
6494
6454
  });
6495
6455
  app.use(
6496
6456
  "/sounds",
6497
- express.static(join10(distWebDir, "sounds"), {
6457
+ express.static(join9(distWebDir, "sounds"), {
6498
6458
  setHeaders: (res) => {
6499
6459
  res.set("Content-Type", "audio/mpeg");
6500
6460
  }
@@ -6503,10 +6463,10 @@ async function createServerHandle(config3) {
6503
6463
  app.use("/__inspect__.js", (_req, res) => {
6504
6464
  res.set("Access-Control-Allow-Origin", "*");
6505
6465
  res.set("Content-Type", "application/javascript");
6506
- readFile5(join10(distWebDir, "__inspect__.js")).then((content) => res.send(content)).catch(() => res.status(404).send("Not found"));
6466
+ readFile4(join9(distWebDir, "__inspect__.js")).then((content) => res.send(content)).catch(() => res.status(404).send("Not found"));
6507
6467
  });
6508
6468
  app.get("/", (_req, res) => {
6509
- readFile5(join10(distWebDir, "index.html"), "utf-8").then((content) => res.send(content)).catch(() => {
6469
+ readFile4(join9(distWebDir, "index.html"), "utf-8").then((content) => res.send(content)).catch(() => {
6510
6470
  res.status(404).send("Web UI not built. Run `npm run build:web`");
6511
6471
  });
6512
6472
  });
@@ -6514,7 +6474,7 @@ async function createServerHandle(config3) {
6514
6474
  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") {
6515
6475
  return;
6516
6476
  }
6517
- readFile5(join10(distWebDir, "index.html"), "utf-8").then((content) => res.send(content)).catch(() => {
6477
+ readFile4(join9(distWebDir, "index.html"), "utf-8").then((content) => res.send(content)).catch(() => {
6518
6478
  res.status(404).send("Web UI not built");
6519
6479
  });
6520
6480
  });
@@ -6534,7 +6494,7 @@ async function createServerHandle(config3) {
6534
6494
  const state = sessionManager.getContextState(sessionId);
6535
6495
  wssExports.broadcastForSession(sessionId, createContextStateMessage(state));
6536
6496
  });
6537
- const { QueueProcessor } = await import("./processor-O2QW27BD.js");
6497
+ const { QueueProcessor } = await import("./processor-3O26I7DO.js");
6538
6498
  const queueProcessor = new QueueProcessor({
6539
6499
  sessionManager,
6540
6500
  providerManager,
@@ -6576,9 +6536,9 @@ async function createServerHandle(config3) {
6576
6536
  void (async () => {
6577
6537
  await devServerManager.stopAll();
6578
6538
  await mcpManager.disconnectAll();
6579
- const { stopAllInspectProxies } = await import("./inspect-proxy-OVEFBJ26.js");
6539
+ const { stopAllInspectProxies } = await import("./inspect-proxy-PHVZBZUO.js");
6580
6540
  stopAllInspectProxies();
6581
- const { cleanupAllProcesses } = await import("./store-FXTCHBI4.js");
6541
+ const { cleanupAllProcesses } = await import("./store-SARB6V2N.js");
6582
6542
  cleanupAllProcesses();
6583
6543
  viteServer?.close();
6584
6544
  if (config3.globalConfigPath) {
@@ -6611,8 +6571,7 @@ async function createServer(config3) {
6611
6571
  }
6612
6572
 
6613
6573
  export {
6614
- VERSION,
6615
6574
  createServerHandle,
6616
6575
  createServer
6617
6576
  };
6618
- //# sourceMappingURL=chunk-ZZ5JPVBT.js.map
6577
+ //# sourceMappingURL=chunk-FILRB5QX.js.map