openfox 2.0.71 → 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 (56) hide show
  1. package/dist/{chat-handler-IKLQ3ZUN.js → chat-handler-LK5RUAGO.js} +15 -15
  2. package/dist/{chunk-NEL2REUM.js → chunk-2DCJERYX.js} +4 -4
  3. package/dist/chunk-2M6JM7OR.js +7 -0
  4. package/dist/{chunk-6V7DU7ID.js → chunk-4LBSC4R3.js} +3 -3
  5. package/dist/{chunk-TFDK6VSG.js → chunk-6XKM25OT.js} +13 -13
  6. package/dist/{chunk-TQGGMWS6.js → chunk-CHPRGEY5.js} +3 -3
  7. package/dist/{chunk-C3VLGVSQ.js → chunk-DJASQ2ZB.js} +11 -2
  8. package/dist/{chunk-4QBDV6LX.js → chunk-E5LLEO3C.js} +2 -2
  9. package/dist/{chunk-OLXHRPAD.js → chunk-FILRB5QX.js} +243 -285
  10. package/dist/{chunk-Y4YESMVA.js → chunk-GMF36EZ3.js} +81 -92
  11. package/dist/{chunk-GMXKJGJ2.js → chunk-I4RWK2L2.js} +8 -4
  12. package/dist/{chunk-F4PMNP7S.js → chunk-NOU2QIL5.js} +3 -2
  13. package/dist/{chunk-X7OCC37J.js → chunk-O2BE7KVQ.js} +8 -8
  14. package/dist/{chunk-PVUBCGAT.js → chunk-PYB2UEC3.js} +10 -4
  15. package/dist/{chunk-XUPKS5FL.js → chunk-QNKXZH3Z.js} +2 -2
  16. package/dist/{chunk-X5DOUA3Z.js → chunk-S7O77CVO.js} +2 -2
  17. package/dist/{chunk-Z42YTK3O.js → chunk-TK4BZIXA.js} +34 -23
  18. package/dist/{chunk-KXVFHMSM.js → chunk-UV3EMWL4.js} +2 -2
  19. package/dist/chunk-X2Y3AJPP.js +216 -0
  20. package/dist/{chunk-RKD2FML3.js → chunk-XWBNYU2L.js} +2 -2
  21. package/dist/cli/dev.js +1 -1
  22. package/dist/cli/index.js +1 -1
  23. package/dist/{compactor-MXXF5WQR.js → compactor-4UKYWC5F.js} +8 -8
  24. package/dist/{events-CDQ4HASP.js → events-AEQ6GQXI.js} +4 -4
  25. package/dist/{folding-V2K34EGN.js → folding-ONH3D4OK.js} +2 -2
  26. package/dist/{inspect-proxy-OVEFBJ26.js → inspect-proxy-PHVZBZUO.js} +4 -4
  27. package/dist/{manager-EHIQCIUP.js → manager-24C2AXVF.js} +5 -5
  28. package/dist/{orchestrator-YGCZZNNV.js → orchestrator-RTZVMWQV.js} +14 -14
  29. package/dist/package.json +1 -1
  30. package/dist/{platform-AB3GIEGO.js → platform-XQ7BS3KQ.js} +4 -4
  31. package/dist/{processor-K6UPVMIP.js → processor-3O26I7DO.js} +15 -15
  32. package/dist/{project-creator-EMGRSPYS.js → project-creator-FQRBN3RG.js} +3 -3
  33. package/dist/{projects-7HSBZY2D.js → projects-LHRNCUGW.js} +3 -3
  34. package/dist/{protocol-CTNE3ANP.js → protocol-4QFU7WAI.js} +2 -2
  35. package/dist/{protocol-DIhV-tAc.d.ts → protocol-DGQWVFcP.d.ts} +1 -1
  36. package/dist/provider/index.d.ts +4 -4
  37. package/dist/{serve-5IOKFKGL.js → serve-6PSAQ2YH.js} +18 -18
  38. package/dist/server/index.d.ts +12 -22
  39. package/dist/server/index.js +17 -17
  40. package/dist/{server-T5QDCUBN.js → server-G2J4RAXL.js} +16 -16
  41. package/dist/{settings-6ZPWOBWL.js → settings-PFXRYXZU.js} +3 -3
  42. package/dist/shared/index.d.ts +3 -3
  43. package/dist/{tools-K3SNGBI2.js → tools-X52DFUS6.js} +13 -13
  44. package/dist/{types-BsfYpEai.d.ts → types-C4cG9CtC.d.ts} +3 -2
  45. package/dist/{types-CBC6lLqc.d.ts → types-DSZhFA8O.d.ts} +1 -1
  46. package/dist/{update-734IDLKT.js → update-I2M2RG4Q.js} +2 -2
  47. package/dist/web/assets/index-C7SW16F7.js +305 -0
  48. package/dist/web/assets/{index-BVTG7SRG.css → index-CmechlaK.css} +1 -1
  49. package/dist/web/index.html +2 -2
  50. package/dist/web/sw.js +1 -1
  51. package/dist/workspace-ET3FHZYN.js +32 -0
  52. package/package.json +1 -1
  53. package/dist/chunk-7NMOWPNY.js +0 -7
  54. package/dist/chunk-VLV3XWZS.js +0 -191
  55. package/dist/web/assets/index-HTzupfR0.js +0 -305
  56. package/dist/worktree-6U45P63P.js +0 -30
@@ -1,6 +1,7 @@
1
1
  import {
2
- listBranches
3
- } from "./chunk-VLV3XWZS.js";
2
+ getGitBranch,
3
+ listWorkspaces
4
+ } from "./chunk-X2Y3AJPP.js";
4
5
  import {
5
6
  AskUserInterrupt,
6
7
  askUserTool
@@ -17,13 +18,13 @@ import {
17
18
  createToolCallEvent,
18
19
  createToolResultEvent,
19
20
  streamLLMPure
20
- } from "./chunk-RKD2FML3.js";
21
+ } from "./chunk-XWBNYU2L.js";
21
22
  import {
22
23
  startInspectProxy
23
- } from "./chunk-4QBDV6LX.js";
24
+ } from "./chunk-E5LLEO3C.js";
24
25
  import {
25
26
  getProject
26
- } from "./chunk-KXVFHMSM.js";
27
+ } from "./chunk-UV3EMWL4.js";
27
28
  import {
28
29
  checkAborted,
29
30
  createProcess,
@@ -34,7 +35,7 @@ import {
34
35
  spawnShellProcess,
35
36
  startProcessCommand,
36
37
  stopProcess
37
- } from "./chunk-PVUBCGAT.js";
38
+ } from "./chunk-PYB2UEC3.js";
38
39
  import {
39
40
  getMaxPerSession,
40
41
  getSessionProcessCount,
@@ -51,7 +52,7 @@ import {
51
52
  getCurrentWindowMessageOptions,
52
53
  getEventStore,
53
54
  getRuntimeConfig
54
- } from "./chunk-TFDK6VSG.js";
55
+ } from "./chunk-6XKM25OT.js";
55
56
  import {
56
57
  buildContextMessagesFromEventHistory,
57
58
  foldContextState,
@@ -61,20 +62,20 @@ import {
61
62
  handleToolResult,
62
63
  reorderToolMessages,
63
64
  stripOrphanedToolCalls
64
- } from "./chunk-C3VLGVSQ.js";
65
+ } from "./chunk-DJASQ2ZB.js";
65
66
  import {
66
67
  createChatDoneMessage,
67
68
  createChatMessageMessage,
68
69
  createChatMessageUpdatedMessage,
69
70
  createChatPathConfirmationMessage,
70
71
  createQueueStateMessage
71
- } from "./chunk-F4PMNP7S.js";
72
+ } from "./chunk-NOU2QIL5.js";
72
73
  import {
73
74
  SETTINGS_KEYS,
74
75
  deleteSetting,
75
76
  getSetting,
76
77
  setSetting
77
- } from "./chunk-XUPKS5FL.js";
78
+ } from "./chunk-QNKXZH3Z.js";
78
79
  import {
79
80
  modelSupportsVision
80
81
  } from "./chunk-V4IE7HJY.js";
@@ -105,7 +106,7 @@ import { resolve as resolve2, isAbsolute } from "path";
105
106
 
106
107
  // src/server/tools/path-security.ts
107
108
  import { realpath } from "fs/promises";
108
- import { resolve, normalize, join, basename, sep } from "path";
109
+ import { resolve, normalize, join, basename, sep, posix, win32 } from "path";
109
110
  import { homedir, tmpdir } from "os";
110
111
  var SAFE_PATHS = /* @__PURE__ */ new Set([
111
112
  "/dev/null",
@@ -218,6 +219,9 @@ var isWindows = () => process.platform === "win32";
218
219
  function isWindowsAbsolutePath(str) {
219
220
  return /^[A-Za-z]:[\\/]/.test(str);
220
221
  }
222
+ function normalizeExtracted(path) {
223
+ return isWindowsAbsolutePath(path) ? win32.normalize(path) : posix.normalize(path);
224
+ }
221
225
  function isPlaceholderToken(str) {
222
226
  return str.includes("__URL__") || str.includes("__FILEURL__") || str.includes("__SED__") || str.includes("__COMMIT_MSG__");
223
227
  }
@@ -239,7 +243,7 @@ function extractAbsolutePathsFromCommand(command) {
239
243
  for (const match2 of fileUrlMatches) {
240
244
  const filePath = match2[1];
241
245
  if (filePath && !isSafePath(filePath)) {
242
- paths.push(normalize(filePath));
246
+ paths.push(normalizeExtracted(filePath));
243
247
  }
244
248
  }
245
249
  sanitized = sanitized.replace(/file:\/\/[^\s'"]+/g, " __FILEURL__ ");
@@ -263,12 +267,12 @@ function extractAbsolutePathsFromCommand(command) {
263
267
  continue;
264
268
  }
265
269
  if (isWindowsAbsolutePath(content)) {
266
- const resolved = normalize(content);
270
+ const resolved = normalizeExtracted(content);
267
271
  if (!isSafePath(resolved)) {
268
272
  paths.push(resolved);
269
273
  }
270
274
  } else if (!isWindows() && content.startsWith("/")) {
271
- const resolved = normalize(content);
275
+ const resolved = normalizeExtracted(content);
272
276
  if (!isSafePath(resolved)) {
273
277
  paths.push(resolved);
274
278
  }
@@ -286,7 +290,7 @@ function extractAbsolutePathsFromCommand(command) {
286
290
  while ((match = winAbsolutePattern.exec(sanitized)) !== null) {
287
291
  const candidate = match[1];
288
292
  if (isPlaceholderToken(candidate)) continue;
289
- const resolved = normalize(candidate);
293
+ const resolved = normalizeExtracted(candidate);
290
294
  if (!isSafePath(resolved)) {
291
295
  paths.push(resolved);
292
296
  }
@@ -297,7 +301,7 @@ function extractAbsolutePathsFromCommand(command) {
297
301
  const candidate = match[1];
298
302
  if (isPlaceholderToken(candidate)) continue;
299
303
  if (looksLikeRegex(candidate)) continue;
300
- const resolved = normalize(candidate);
304
+ const resolved = normalizeExtracted(candidate);
301
305
  if (resolved === "/" || resolved === "") continue;
302
306
  if (!isSafePath(resolved)) {
303
307
  paths.push(resolved);
@@ -331,7 +335,7 @@ function extractSensitivePathsFromCommand(command) {
331
335
  return [...new Set(paths)];
332
336
  }
333
337
  function isSafePath(path) {
334
- const normalized = normalize(path);
338
+ const normalized = posix.normalize(path);
335
339
  return SAFE_PATHS.has(normalized);
336
340
  }
337
341
  async function checkPathsAccess(paths, workdir, sessionId) {
@@ -2902,10 +2906,10 @@ ${CONTINUE_PROMPT}` : CONTINUE_PROMPT;
2902
2906
  previousContextTokens,
2903
2907
  result.modelParams
2904
2908
  );
2905
- sessionManager.setCurrentContextSize(sessionId, result.usage.promptTokens);
2909
+ sessionManager.setCurrentContextSize(sessionId, result.usage.promptTokens, config.subAgentMetadata?.subAgentId);
2906
2910
  if (!compacting) {
2907
2911
  const contextState2 = sessionManager.getContextState(sessionId);
2908
- const { shouldCompact, appendCompactionPrompt } = await import("./compactor-MXXF5WQR.js");
2912
+ const { shouldCompact, appendCompactionPrompt } = await import("./compactor-4UKYWC5F.js");
2909
2913
  if (shouldCompact(contextState2.currentTokens, contextState2.maxTokens, runtimeConfig.context.compactionThreshold)) {
2910
2914
  appendCompactionPrompt(sessionId, append);
2911
2915
  compacting = true;
@@ -2986,7 +2990,7 @@ ${COMPACTION_PROMPT}`,
2986
2990
  toolRegistry,
2987
2991
  sessionManager,
2988
2992
  sessionId,
2989
- workdir: session.worktree ?? session.workdir,
2993
+ workdir: session.workspace ?? session.workdir,
2990
2994
  turnMetrics,
2991
2995
  signal,
2992
2996
  onMessage,
@@ -3695,7 +3699,7 @@ async function executeSubAgent(options) {
3695
3699
  })
3696
3700
  );
3697
3701
  }
3698
- const effectiveWorkdir = session.worktree ?? session.workdir;
3702
+ const effectiveWorkdir = session.workspace ?? session.workdir;
3699
3703
  const { content: instructionContent } = await getAllInstructions(effectiveWorkdir, session.projectId);
3700
3704
  const config = getRuntimeConfig();
3701
3705
  const configDir = getGlobalConfigDir(config.mode ?? "production");
@@ -3810,7 +3814,7 @@ var callSubAgentTool = {
3810
3814
  };
3811
3815
  }
3812
3816
  try {
3813
- const { getToolRegistryForAgent: getToolRegistryForAgent2 } = await import("./tools-K3SNGBI2.js");
3817
+ const { getToolRegistryForAgent: getToolRegistryForAgent2 } = await import("./tools-X52DFUS6.js");
3814
3818
  const toolRegistry = getToolRegistryForAgent2(agentDef);
3815
3819
  const turnMetrics = new TurnMetrics();
3816
3820
  const result = await executeSubAgent({
@@ -4218,7 +4222,7 @@ var DevServerManager = class {
4218
4222
  }
4219
4223
  /**
4220
4224
  * Load dev server config from workdir.
4221
- * If not found and the path looks like a git worktree (contains /worktrees/),
4225
+ * If not found and the path looks like a workspace (contains /workspaces/),
4222
4226
  * falls back to the parent project root.
4223
4227
  */
4224
4228
  async loadConfig(workdir) {
@@ -4240,9 +4244,9 @@ var DevServerManager = class {
4240
4244
  };
4241
4245
  const config = await tryLoad(workdir);
4242
4246
  if (config) return config;
4243
- const wtIdx = workdir.indexOf("/worktrees/");
4244
- if (wtIdx !== -1) {
4245
- const projectRoot = workdir.slice(0, wtIdx);
4247
+ const wsIdx = workdir.indexOf("/workspaces/");
4248
+ if (wsIdx !== -1) {
4249
+ const projectRoot = workdir.slice(0, wsIdx);
4246
4250
  if (projectRoot !== workdir) {
4247
4251
  return tryLoad(projectRoot);
4248
4252
  }
@@ -4418,7 +4422,7 @@ var devServerTool = createTool(
4418
4422
  type: "function",
4419
4423
  function: {
4420
4424
  name: "dev_server",
4421
- description: "Control the project dev server. Start, stop, restart, check status, or fetch logs with optional pagination. Each workdir (project root or git worktree) gets its own independent dev server instance with auto-assigned ports. The dev server is configured via .openfox/dev.json \u2014 searched in the current workdir first, falling back to the project root. Fields: command (string, required), url (string, required), hotReload (boolean, optional, default false), disableInspect (boolean, optional, default false). You can use ${PORT} in command and url \u2014 it will be replaced with an available port at runtime (auto-assigned if the configured port is taken).",
4425
+ description: "Control the project dev server. Start, stop, restart, check status, or fetch logs with optional pagination. Each workdir (project root or workspace) gets its own independent dev server instance with auto-assigned ports. The dev server is configured via .openfox/dev.json \u2014 searched in the current workdir first, falling back to the project root. Fields: command (string, required), url (string, required), hotReload (boolean, optional, default false), disableInspect (boolean, optional, default false). You can use ${PORT} in command and url \u2014 it will be replaced with an available port at runtime (auto-assigned if the configured port is taken).",
4422
4426
  parameters: {
4423
4427
  type: "object",
4424
4428
  properties: {
@@ -4809,7 +4813,7 @@ var mcpConfigTool = createTool(
4809
4813
  mcpNotifyChanged?.(sessionId);
4810
4814
  }
4811
4815
  async function rebuildTools() {
4812
- const { setMcpTools: setMcpTools2 } = await import("./tools-K3SNGBI2.js");
4816
+ const { setMcpTools: setMcpTools2 } = await import("./tools-X52DFUS6.js");
4813
4817
  const mcpTools = createMcpTools(mcpManagerForTools);
4814
4818
  setMcpTools2(mcpTools);
4815
4819
  }
@@ -5074,29 +5078,29 @@ var webSearchTool = createTool(
5074
5078
  }
5075
5079
  );
5076
5080
 
5077
- // src/server/tools/worktree.ts
5078
- var worktreeTool = createTool(
5079
- "worktree",
5081
+ // src/server/tools/workspace.ts
5082
+ var workspaceTool = createTool(
5083
+ "workspace",
5080
5084
  {
5081
5085
  type: "function",
5082
5086
  function: {
5083
- name: "worktree",
5084
- description: 'Manage git worktrees for the current session. Use this to work on isolated branches without affecting the main working tree.\n\nAsset strategy for .gitignored files (e.g. node_modules) is configured via .openfox/worktree.json in the project root with fields: ignoredAssets ("symlink"|"copy"|"skip", default "skip"), overrides (optional, per-path exceptions). The server reads this file automatically on create. You can manage it via read_file/write_file, or the user can configure it in Project Settings \u2192 Worktree Asset Strategy.\n\nActions:\n- list_branches: List local git branches for the current project\n- create: Create a new branch + git worktree and attach this session to it (provide: name)\n- attach: Attach this session to an existing git worktree by path (provide: path)\n- close: Close the current worktree and return the session to the project root\n- status: Show current worktree state (active branch, worktree path)',
5087
+ name: "workspace",
5088
+ description: 'Manage workspaces for the current session. A workspace is a cloned copy of the project.\n\nUse "switch" to move between workspaces. Target "original" for the project root, or a workspace name.\nIf the workspace does not exist yet, it is created automatically.\n\nSetup commands (e.g. npm install) are configured via .openfox/workspace.json.\n\nActions:\n- switch: Switch to a workspace (target: "original" or a name, optional branch for new workspaces)\n- list: List all workspaces with their current branch and active status\n- delete: Delete a workspace by name (cannot delete "original")',
5085
5089
  parameters: {
5086
5090
  type: "object",
5087
5091
  properties: {
5088
5092
  action: {
5089
5093
  type: "string",
5090
- enum: ["list_branches", "create", "attach", "close", "status"],
5094
+ enum: ["switch", "list", "delete"],
5091
5095
  description: "The action to perform"
5092
5096
  },
5093
- name: {
5097
+ target: {
5094
5098
  type: "string",
5095
- description: "Branch name for creating a new worktree (required for action=create)"
5099
+ description: 'For switch: "original" or a workspace name. For delete: the workspace name to delete.'
5096
5100
  },
5097
- path: {
5101
+ branch: {
5098
5102
  type: "string",
5099
- description: "Path to an existing worktree directory (required for action=attach)"
5103
+ description: "Optional git branch to check out when creating a new workspace"
5100
5104
  }
5101
5105
  },
5102
5106
  required: ["action"]
@@ -5105,77 +5109,62 @@ var worktreeTool = createTool(
5105
5109
  },
5106
5110
  async (args, context, helpers) => {
5107
5111
  const { sessionId, sessionManager } = context;
5108
- const validActions = ["list_branches", "create", "attach", "close", "status"];
5112
+ const validActions = ["switch", "list", "delete"];
5109
5113
  if (!validActions.includes(args.action)) {
5110
5114
  return helpers.error(`Invalid action: ${args.action}. Must be one of: ${validActions.join(", ")}`);
5111
5115
  }
5112
5116
  switch (args.action) {
5113
- case "list_branches": {
5114
- const session = sessionManager.getSession(sessionId);
5115
- if (!session) return helpers.error("Session not found");
5116
- const project = sessionManager.getProject(session.projectId);
5117
- if (!project) return helpers.error("Project not found");
5118
- const branches = await listBranches(project.workdir);
5119
- return helpers.success(JSON.stringify({ branches }, null, 2));
5120
- }
5121
- case "create": {
5122
- if (!args.name || typeof args.name !== "string") {
5123
- return helpers.error('Parameter "name" is required for action=create (the branch name)');
5124
- }
5125
- const updated = await sessionManager.createSessionWorktree(sessionId, args.name);
5126
- return helpers.success(
5127
- JSON.stringify(
5128
- {
5129
- worktree: updated.worktree,
5130
- branch: args.name,
5131
- message: `Worktree created and session attached to branch "${args.name}"`
5132
- },
5133
- null,
5134
- 2
5135
- )
5136
- );
5137
- }
5138
- case "attach": {
5139
- if (!args.path || typeof args.path !== "string") {
5140
- return helpers.error('Parameter "path" is required for action=attach (path to existing worktree)');
5117
+ case "switch": {
5118
+ if (!args.target || typeof args.target !== "string") {
5119
+ return helpers.error('Parameter "target" is required for action=switch ("original" or a workspace name)');
5141
5120
  }
5142
- const updated = await sessionManager.attachSessionWorktree(sessionId, args.path);
5121
+ const updated = await sessionManager.switchWorkspace(sessionId, args.target, args.branch);
5122
+ const wsName = args.target === "original" ? "original" : updated.workspace?.split("/").pop() ?? args.target;
5123
+ const branch = await getGitBranch(updated.workspace ?? updated.workdir);
5143
5124
  return helpers.success(
5144
5125
  JSON.stringify(
5145
5126
  {
5146
- worktree: updated.worktree,
5147
- message: `Session attached to existing worktree at ${args.path}`
5127
+ workspace: wsName,
5128
+ path: updated.workspace ?? updated.workdir,
5129
+ branch,
5130
+ message: args.target === "original" ? "Switched to original project" : `Switched to workspace "${wsName}" on branch "${branch ?? "unknown"}"`
5148
5131
  },
5149
5132
  null,
5150
5133
  2
5151
5134
  )
5152
5135
  );
5153
5136
  }
5154
- case "close": {
5155
- const updated = await sessionManager.closeSessionWorktree(sessionId);
5156
- return helpers.success(
5157
- JSON.stringify(
5158
- {
5159
- worktree: updated.worktree,
5160
- workdir: updated.workdir,
5161
- message: "Worktree closed. Session returned to project root."
5162
- },
5163
- null,
5164
- 2
5165
- )
5166
- );
5167
- }
5168
- case "status": {
5137
+ case "list": {
5169
5138
  const session = sessionManager.getSession(sessionId);
5170
5139
  if (!session) return helpers.error("Session not found");
5171
- const active = !!session.worktree;
5140
+ const project = sessionManager.getProject(session.projectId);
5141
+ if (!project) return helpers.error("Project not found");
5142
+ const currentBranch = await getGitBranch(session.workspace ?? session.workdir);
5143
+ const named = await listWorkspaces(project.name);
5144
+ const activeWsName = session.workspace?.split("/").pop() ?? null;
5145
+ const workspaces = [
5146
+ { name: "original", branch: currentBranch, active: !session.workspace },
5147
+ ...named.map((ws) => ({
5148
+ name: ws.name,
5149
+ branch: ws.branch,
5150
+ active: ws.name === activeWsName
5151
+ }))
5152
+ ];
5153
+ return helpers.success(JSON.stringify({ workspaces }, null, 2));
5154
+ }
5155
+ case "delete": {
5156
+ if (!args.target || typeof args.target !== "string") {
5157
+ return helpers.error('Parameter "target" is required for action=delete (the workspace name)');
5158
+ }
5159
+ if (args.target === "original") {
5160
+ return helpers.error("Cannot delete the original workspace");
5161
+ }
5162
+ await sessionManager.deleteWorkspace(sessionId, args.target);
5172
5163
  return helpers.success(
5173
5164
  JSON.stringify(
5174
5165
  {
5175
- active,
5176
- worktree: session.worktree ?? null,
5177
- workdir: session.workdir,
5178
- ...active ? { branch: session.worktree?.split("/worktrees/")[1] ?? session.worktree } : {}
5166
+ workspace: args.target,
5167
+ message: `Workspace "${args.target}" has been deleted`
5179
5168
  },
5180
5169
  null,
5181
5170
  2
@@ -5208,7 +5197,7 @@ function getBuiltInTools() {
5208
5197
  stepDoneTool,
5209
5198
  backgroundProcessTool,
5210
5199
  mcpConfigTool,
5211
- worktreeTool
5200
+ workspaceTool
5212
5201
  ];
5213
5202
  }
5214
5203
  return _builtInTools;
@@ -5504,4 +5493,4 @@ export {
5504
5493
  getToolRegistryForAgent,
5505
5494
  createToolRegistry
5506
5495
  };
5507
- //# sourceMappingURL=chunk-Y4YESMVA.js.map
5496
+ //# sourceMappingURL=chunk-GMF36EZ3.js.map
@@ -173,9 +173,13 @@ function runMigrations(db2) {
173
173
  logger.info("Migrating sessions table: adding cached_hash column");
174
174
  db2.exec(`ALTER TABLE sessions ADD COLUMN cached_hash TEXT`);
175
175
  }
176
- if (!columnNames.includes("worktree")) {
177
- logger.info("Migrating sessions table: adding worktree column");
178
- db2.exec(`ALTER TABLE sessions ADD COLUMN worktree TEXT`);
176
+ if (!columnNames.includes("workspace") && columnNames.includes("worktree")) {
177
+ logger.info("Migrating sessions table: renaming worktree to workspace");
178
+ db2.exec(`ALTER TABLE sessions RENAME COLUMN worktree TO workspace`);
179
+ }
180
+ if (!columnNames.includes("workspace")) {
181
+ logger.info("Migrating sessions table: adding workspace column");
182
+ db2.exec(`ALTER TABLE sessions ADD COLUMN workspace TEXT`);
179
183
  }
180
184
  logger.info("Database migrations completed");
181
185
  }
@@ -184,4 +188,4 @@ export {
184
188
  initDatabase,
185
189
  getDatabase
186
190
  };
187
- //# sourceMappingURL=chunk-GMXKJGJ2.js.map
191
+ //# sourceMappingURL=chunk-I4RWK2L2.js.map
@@ -263,7 +263,8 @@ function storedEventToServerMessage(event) {
263
263
  }
264
264
  case "context.state": {
265
265
  const data = event.data;
266
- return createContextStateMessage(data);
266
+ const { subAgentId, ...context } = data;
267
+ return createContextStateMessage(context, subAgentId);
267
268
  }
268
269
  case "session.name_generated": {
269
270
  const data = event.data;
@@ -339,4 +340,4 @@ export {
339
340
  createQueueStateMessage,
340
341
  storedEventToServerMessage
341
342
  };
342
- //# sourceMappingURL=chunk-F4PMNP7S.js.map
343
+ //# sourceMappingURL=chunk-NOU2QIL5.js.map
@@ -10,7 +10,7 @@ import {
10
10
  loadAllAgentsDefault,
11
11
  processEventsForConversation,
12
12
  runTopLevelAgentLoop
13
- } from "./chunk-Y4YESMVA.js";
13
+ } from "./chunk-GMF36EZ3.js";
14
14
  import {
15
15
  TurnMetrics,
16
16
  buildAgentReminder,
@@ -18,16 +18,16 @@ import {
18
18
  buildTopLevelSystemPrompt,
19
19
  createChatDoneEvent,
20
20
  createMessageStartEvent
21
- } from "./chunk-RKD2FML3.js";
21
+ } from "./chunk-XWBNYU2L.js";
22
22
  import {
23
23
  getCurrentContextWindowId,
24
24
  getCurrentWindowMessageOptions,
25
25
  getEventStore,
26
26
  getRuntimeConfig
27
- } from "./chunk-TFDK6VSG.js";
27
+ } from "./chunk-6XKM25OT.js";
28
28
  import {
29
29
  buildSnapshotFromSessionState
30
- } from "./chunk-C3VLGVSQ.js";
30
+ } from "./chunk-DJASQ2ZB.js";
31
31
  import {
32
32
  logger
33
33
  } from "./chunk-K44MW7JJ.js";
@@ -64,7 +64,7 @@ function resolveAgentDef(sessionManager, sessionId) {
64
64
  }
65
65
  async function buildCachedPrompt(sessionManager, sessionId, agentDef) {
66
66
  const { instructionContent, skills } = await loadSessionContext(sessionManager, sessionId);
67
- const { getToolRegistryForAgent: getToolRegistryForAgent2 } = await import("./tools-K3SNGBI2.js");
67
+ const { getToolRegistryForAgent: getToolRegistryForAgent2 } = await import("./tools-X52DFUS6.js");
68
68
  const tools = getToolRegistryForAgent2(agentDef).definitions;
69
69
  const toolFingerprint = getToolFingerprint(tools);
70
70
  const allAgents = await loadAllAgentsDefault();
@@ -77,7 +77,7 @@ async function buildCachedPrompt(sessionManager, sessionId, agentDef) {
77
77
  async function computeSessionHash(sessionManager, sessionId) {
78
78
  const { instructionContent, skills } = await loadSessionContext(sessionManager, sessionId);
79
79
  const agentDef = await resolveAgentDef(sessionManager, sessionId);
80
- const { getToolRegistryForAgent: getToolRegistryForAgent2 } = await import("./tools-K3SNGBI2.js");
80
+ const { getToolRegistryForAgent: getToolRegistryForAgent2 } = await import("./tools-X52DFUS6.js");
81
81
  const tools = getToolRegistryForAgent2(agentDef).definitions;
82
82
  const toolFingerprint = getToolFingerprint(tools);
83
83
  return computeDynamicContextHash(instructionContent, skills, toolFingerprint);
@@ -95,7 +95,7 @@ async function applyDynamicContext(sessionManager, sessionId) {
95
95
 
96
96
  // src/server/chat/orchestrator.ts
97
97
  async function buildRetryPatterns() {
98
- const { getSetting, SETTINGS_KEYS } = await import("./settings-6ZPWOBWL.js");
98
+ const { getSetting, SETTINGS_KEYS } = await import("./settings-PFXRYXZU.js");
99
99
  const raw = getSetting(SETTINGS_KEYS.RETRY_PATTERNS);
100
100
  if (!raw) {
101
101
  const oldXmlProtection = getSetting("llm.disableXmlProtection");
@@ -357,4 +357,4 @@ export {
357
357
  runChatTurn,
358
358
  runAgentTurn
359
359
  };
360
- //# sourceMappingURL=chunk-X7OCC37J.js.map
360
+ //# sourceMappingURL=chunk-O2BE7KVQ.js.map
@@ -11,7 +11,7 @@ import {
11
11
  } from "./chunk-I72ACQ6R.js";
12
12
  import {
13
13
  getPlatformShell
14
- } from "./chunk-X5DOUA3Z.js";
14
+ } from "./chunk-S7O77CVO.js";
15
15
 
16
16
  // src/server/utils/shell.ts
17
17
  import { spawn } from "child_process";
@@ -20,12 +20,18 @@ function checkAborted(signal) {
20
20
  }
21
21
  function spawnShell(command, options) {
22
22
  const shell = getPlatformShell();
23
- return spawn(shell.command, [...shell.args, command], {
23
+ const isCmd = shell.command === "cmd.exe";
24
+ const args = isCmd ? ["/d", "/s", "/c", `"${command}"`] : [...shell.args, command];
25
+ return spawn(shell.command, args, {
26
+ ...isCmd ? { windowsVerbatimArguments: true } : {},
24
27
  cwd: options.cwd,
25
28
  env: { ...process.env },
26
29
  stdio: options.stdio ?? ["ignore", "pipe", "pipe"],
27
30
  windowsHide: true,
28
- ...options.detached ? { detached: true } : {}
31
+ // detached is only useful for Unix process-group semantics; on win32 it
32
+ // spawns a visible console window and makes MSYS binaries (tail, sleep)
33
+ // hang on pipes. Tree-kill uses taskkill on win32, so detached is unneeded.
34
+ ...options.detached && process.platform !== "win32" ? { detached: true } : {}
29
35
  });
30
36
  }
31
37
  function spawnShellProcess(command, cwd, _signal, detached = false) {
@@ -147,4 +153,4 @@ export {
147
153
  getSessionProcesses2 as getSessionProcesses,
148
154
  getProcessLogs
149
155
  };
150
- //# sourceMappingURL=chunk-PVUBCGAT.js.map
156
+ //# sourceMappingURL=chunk-PYB2UEC3.js.map
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  getDatabase
3
- } from "./chunk-GMXKJGJ2.js";
3
+ } from "./chunk-I4RWK2L2.js";
4
4
 
5
5
  // src/server/db/settings.ts
6
6
  var SETTINGS_KEYS = {
@@ -101,4 +101,4 @@ export {
101
101
  deleteSetting,
102
102
  getAllSettings
103
103
  };
104
- //# sourceMappingURL=chunk-XUPKS5FL.js.map
104
+ //# sourceMappingURL=chunk-QNKXZH3Z.js.map
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  SETTINGS_KEYS,
3
3
  getSetting
4
- } from "./chunk-XUPKS5FL.js";
4
+ } from "./chunk-QNKXZH3Z.js";
5
5
 
6
6
  // src/server/utils/platform.ts
7
7
  import os from "os";
@@ -63,4 +63,4 @@ export {
63
63
  isWindowsPath,
64
64
  isAbsolutePath
65
65
  };
66
- //# sourceMappingURL=chunk-X5DOUA3Z.js.map
66
+ //# sourceMappingURL=chunk-S7O77CVO.js.map