openfox 2.0.114 → 2.0.116

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 (120) hide show
  1. package/CHANGELOG.md +43 -0
  2. package/dist/CHANGELOG.md +43 -0
  3. package/dist/{ask-ZYPCJKZD.js → ask-UBIRH3SO.js} +2 -2
  4. package/dist/{auth-YY5PJYSC.js → auth-GTGIGX5X.js} +2 -2
  5. package/dist/{auto-config-T5GR2N6X.js → auto-config-AAUO4PKW.js} +2 -2
  6. package/dist/{backend-LVYHLGQJ.js → backend-67OLCS5O.js} +2 -2
  7. package/dist/{branch.api-XVTYACSH.js → branch.api-UMKSQMSA.js} +2 -2
  8. package/dist/changelog-FZUE6OSG.js +63 -0
  9. package/dist/{chat-handler-KWXRSWXZ.js → chat-handler-Z6BEY66U.js} +31 -31
  10. package/dist/{chunk-2XD65L7M.js → chunk-27NABDXB.js} +2 -2
  11. package/dist/{chunk-YGJIK3CG.js → chunk-2FCLCUVR.js} +5 -5
  12. package/dist/{chunk-UTIQ7OO5.js → chunk-3KBRMBTP.js} +2 -2
  13. package/dist/{chunk-SFZGMB2G.js → chunk-3PG65AXG.js} +18 -3
  14. package/dist/{chunk-QD7MRMCH.js → chunk-4E52GUXJ.js} +231 -173
  15. package/dist/{chunk-I7FY2LTR.js → chunk-4GHLULHB.js} +18 -2
  16. package/dist/{chunk-K733B5T2.js → chunk-4HV3PDEK.js} +135 -134
  17. package/dist/{chunk-PBW3YC3G.js → chunk-5PT4UMRR.js} +5 -1
  18. package/dist/{chunk-NWJLWLKF.js → chunk-6XHDNSA3.js} +11 -11
  19. package/dist/{chunk-SA34STZ6.js → chunk-AESOGRFK.js} +2 -2
  20. package/dist/{chunk-4H427UBV.js → chunk-AGXJ5O63.js} +2 -2
  21. package/dist/{chunk-7GWARYQC.js → chunk-BH3BBUGB.js} +24 -22
  22. package/dist/{chunk-L63Q4JQJ.js → chunk-EQ5CGNOT.js} +3 -3
  23. package/dist/{chunk-NLO64UE3.js → chunk-EQ7DK2TG.js} +10 -6
  24. package/dist/{chunk-MUSPWEBB.js → chunk-GZTMCTUS.js} +4 -4
  25. package/dist/{chunk-HP5CIB66.js → chunk-HD6Y77RO.js} +2 -2
  26. package/dist/chunk-HNHSUQCN.js +7 -0
  27. package/dist/{chunk-W77NBJAZ.js → chunk-HYPXL7K5.js} +178 -33
  28. package/dist/{chunk-OTYAEEX3.js → chunk-HZSKKJHQ.js} +9 -8
  29. package/dist/{chunk-JP7NM545.js → chunk-JLAR2CMV.js} +2 -2
  30. package/dist/{chunk-3O77NT4T.js → chunk-KLQEL2DZ.js} +10 -4
  31. package/dist/{chunk-UPBWEHIL.js → chunk-LNNBLB6G.js} +20 -5
  32. package/dist/{chunk-OXSTNSCF.js → chunk-LTYL6ZGH.js} +2 -2
  33. package/dist/{chunk-P5UANBBX.js → chunk-M6X6AIEG.js} +2 -2
  34. package/dist/{chunk-LXYPMFTH.js → chunk-MKWS7TQH.js} +4 -4
  35. package/dist/{chunk-SBSUDHL4.js → chunk-O6DU226D.js} +2 -2
  36. package/dist/{chunk-HV6IALXF.js → chunk-QJWTBVJO.js} +14 -14
  37. package/dist/{chunk-BZVW77PI.js → chunk-QQVPUZQB.js} +157 -21
  38. package/dist/{chunk-GUHHUDNL.js → chunk-SQLJRO3J.js} +10 -10
  39. package/dist/{chunk-JXLRL5JR.js → chunk-TGVDUK4N.js} +7 -7
  40. package/dist/{chunk-L737Y63F.js → chunk-TOKQ2UVG.js} +2 -2
  41. package/dist/{chunk-FW4NDUBL.js → chunk-U4HMAYAD.js} +15 -14
  42. package/dist/{chunk-V4IE7HJY.js → chunk-W7VIYHPQ.js} +2 -2
  43. package/dist/{chunk-VPVLO436.js → chunk-X3XKYGUN.js} +4 -4
  44. package/dist/{chunk-5WRI5ZAA.js → chunk-YLJ4XMA6.js} +6 -2
  45. package/dist/{chunk-X25Q6RAV.js → chunk-ZKLE2Q3I.js} +1 -1
  46. package/dist/{chunk-TKKP56QK.js → chunk-ZTOG6LJD.js} +3 -3
  47. package/dist/cli/dev.js +3 -3
  48. package/dist/cli/index.js +3 -3
  49. package/dist/client-KCNTDTIR.js +16 -0
  50. package/dist/{client-pure-VFZIIK4S.js → client-pure-B5DHEKQJ.js} +3 -3
  51. package/dist/command-defaults/mark-done.command.md +14 -0
  52. package/dist/compactor-LAXZLPPA.js +32 -0
  53. package/dist/{config-EAB3V4QK.js → config-TUCHLIWD.js} +2 -2
  54. package/dist/{dynamic-context-MVGOF5V2.js → dynamic-context-YHWFFP53.js} +10 -10
  55. package/dist/{events-PI7IMPHT.js → events-IVPAMMR5.js} +9 -8
  56. package/dist/{folding-FO57K4JM.js → folding-RTGU63BW.js} +7 -6
  57. package/dist/http-client-IPUW2MSW.js +11 -0
  58. package/dist/inspect-proxy-WPEDMCG7.js +13 -0
  59. package/dist/{install-CPOPMCSE.js → install-VA2F6X6Z.js} +2 -2
  60. package/dist/launch-PAVQAWGP.js +52 -0
  61. package/dist/{manager-66YAEO7K.js → manager-EMLSLMMT.js} +6 -6
  62. package/dist/{model-overrides-L53PZNZA.js → model-overrides-7F2EOA4U.js} +5 -5
  63. package/dist/{oauth-provider-52YILVUJ.js → oauth-provider-DGBC2YM6.js} +2 -2
  64. package/dist/{oauth-store-XCFXV2VM.js → oauth-store-KECHUT54.js} +2 -2
  65. package/dist/{openFolder-HX7X356L.js → openFolder-XCMSU3OI.js} +2 -2
  66. package/dist/orchestrator-CS3KXLZE.js +63 -0
  67. package/dist/package.json +5 -2
  68. package/dist/{path-security-RSEI3YKB.js → path-security-JTCHWYG3.js} +13 -12
  69. package/dist/{paths-F27V3S4I.js → paths-BHR7CZ7I.js} +2 -2
  70. package/dist/{permissions-K6YEA2ZZ.js → permissions-UKR524ZB.js} +2 -2
  71. package/dist/{platform-WA4GK5BO.js → platform-ECDDYMAR.js} +5 -5
  72. package/dist/{processor-WDZSFBVO.js → processor-RZD4JRDX.js} +30 -30
  73. package/dist/profiles-GYHXBWPV.js +10 -0
  74. package/dist/{project-creator-676WQXVI.js → project-creator-PMQ65NKN.js} +4 -4
  75. package/dist/{projects-SSBWIYL4.js → projects-NDPNOV6D.js} +6 -4
  76. package/dist/{protocol-BzHs024-.d.ts → protocol-CfUkCYxF.d.ts} +12 -3
  77. package/dist/{protocol-RKSWKNXI.js → protocol-HYA5BYVN.js} +8 -4
  78. package/dist/provider/index.d.ts +4 -4
  79. package/dist/{provider-PLIWRBCF.js → provider-Q7J4UFTS.js} +11 -11
  80. package/dist/{provider-manager-2QSJTPWS.js → provider-manager-TMBO4DFG.js} +9 -9
  81. package/dist/{pwa-XPHP3PY2.js → pwa-2GRFSXD7.js} +3 -3
  82. package/dist/{registry-ZP4TN2IN.js → registry-5QL3BOWN.js} +6 -5
  83. package/dist/{serve-MZ3BCCWC.js → serve-KR22J37W.js} +36 -36
  84. package/dist/server/index.d.ts +26 -6
  85. package/dist/server/index.js +35 -35
  86. package/dist/server-ESKTIZL5.js +55 -0
  87. package/dist/service-M7XJHAK4.js +25 -0
  88. package/dist/{service-CXWJQFOZ.js → service-WKABQHKL.js} +2 -2
  89. package/dist/{session-overrides-LXN6W7SA.js → session-overrides-CWBKPHMF.js} +8 -7
  90. package/dist/{sessions-CHPVUG6H.js → sessions-I7ELDIIP.js} +9 -6
  91. package/dist/{settings-NEBM3GQX.js → settings-FGXQHKUH.js} +4 -4
  92. package/dist/shared/index.d.ts +3 -3
  93. package/dist/shared/index.js +2 -2
  94. package/dist/{store-SARB6V2N.js → store-JYPZ2RXB.js} +2 -2
  95. package/dist/{tasks-TJXG2V3U.js → tasks-X5H5HM4J.js} +12 -12
  96. package/dist/{tool-adapter-FEAHWU5C.js → tool-adapter-FJAFLDZA.js} +2 -2
  97. package/dist/{tools-CIM26IFB.js → tools-KBS6X3EN.js} +28 -28
  98. package/dist/{types-CbggXFvR.d.ts → types-CIVhQMvD.d.ts} +1 -1
  99. package/dist/{types-CMtHpDWT.d.ts → types-Df7NM9b5.d.ts} +2 -0
  100. package/dist/{update-UZBBO42X.js → update-TDS6LP5N.js} +4 -4
  101. package/dist/{update-server-LOOXIXDW.js → update-server-SVPV6ZJZ.js} +2 -2
  102. package/dist/{url-utils-SAJP7AEX.js → url-utils-C5BM7NF7.js} +2 -2
  103. package/dist/web/assets/index-ChtRS33s.js +324 -0
  104. package/dist/web/assets/{index-BmILAZrT.css → index-c43YT-4A.css} +1 -1
  105. package/dist/web/index.html +2 -2
  106. package/dist/web/sw.js +1 -1
  107. package/dist/workflow-defaults/default.workflow.json +2 -2
  108. package/dist/{workspace-2XODU4YJ.js → workspace-IQLLHMYR.js} +5 -5
  109. package/package.json +5 -2
  110. package/dist/chunk-NCZRWCJN.js +0 -7
  111. package/dist/client-EM7ISGUP.js +0 -16
  112. package/dist/compactor-V3LR7APW.js +0 -31
  113. package/dist/http-client-33EZ3BLR.js +0 -11
  114. package/dist/inspect-proxy-NHKQQ2CD.js +0 -13
  115. package/dist/launch-L5ROVNI3.js +0 -52
  116. package/dist/orchestrator-XK5K3RPL.js +0 -63
  117. package/dist/profiles-5J7F4BML.js +0 -10
  118. package/dist/server-EPXODFMB.js +0 -55
  119. package/dist/service-54PGIPDQ.js +0 -25
  120. package/dist/web/assets/index-rZHXkfMq.js +0 -324
@@ -4,7 +4,7 @@ import {
4
4
  import {
5
5
  createServerMessage,
6
6
  isClientMessage
7
- } from "./chunk-X25Q6RAV.js";
7
+ } from "./chunk-ZKLE2Q3I.js";
8
8
 
9
9
  // src/server/session/client-session.ts
10
10
  function toClientSession(session) {
@@ -140,6 +140,12 @@ function createChatDoneMessage(messageId, reason, stats, agentType) {
140
140
  function createChatErrorMessage(error, recoverable) {
141
141
  return createServerMessage("chat.error", { error, recoverable });
142
142
  }
143
+ function createChatMessageRemovedMessage(messageIds) {
144
+ return createServerMessage("chat.message_removed", { messageIds });
145
+ }
146
+ function createChatStepRetryMessage(stepName, attempt, retryInMs) {
147
+ return createServerMessage("chat.step_retry", { stepName, attempt, retryInMs });
148
+ }
143
149
  function createChatPathConfirmationMessage(callId, tool, paths, workdir, reason) {
144
150
  return createServerMessage("chat.path_confirmation", { callId, tool, paths, workdir, reason });
145
151
  }
@@ -316,6 +322,14 @@ function storedEventToServerMessage(event) {
316
322
  const data = event.data;
317
323
  return createChatFormatRetryMessage(data.attempt, data.maxAttempts, data.pattern, data.field, data.matchedContent);
318
324
  }
325
+ case "message.removed": {
326
+ const data = event.data;
327
+ return createChatMessageRemovedMessage(data.messageIds);
328
+ }
329
+ case "workflow.step_retry": {
330
+ const data = event.data;
331
+ return createChatStepRetryMessage(data.stepName, data.attempt, data.retryInMs);
332
+ }
319
333
  case "path.confirmation_pending":
320
334
  case "path.confirmation_responded":
321
335
  return null;
@@ -351,6 +365,8 @@ export {
351
365
  createChatMessageUpdatedMessage,
352
366
  createChatDoneMessage,
353
367
  createChatErrorMessage,
368
+ createChatMessageRemovedMessage,
369
+ createChatStepRetryMessage,
354
370
  createChatPathConfirmationMessage,
355
371
  createChatAskUserMessage,
356
372
  createModeChangedMessage,
@@ -366,4 +382,4 @@ export {
366
382
  createQueueStateMessage,
367
383
  storedEventToServerMessage
368
384
  };
369
- //# sourceMappingURL=chunk-I7FY2LTR.js.map
385
+ //# sourceMappingURL=chunk-4GHLULHB.js.map
@@ -4,7 +4,7 @@ import {
4
4
  getEnabledSkillMetadata,
5
5
  isSkillEnabled,
6
6
  loadAllSkills
7
- } from "./chunk-YGJIK3CG.js";
7
+ } from "./chunk-2FCLCUVR.js";
8
8
  import {
9
9
  TurnMetrics,
10
10
  consumeStreamGenerator,
@@ -14,15 +14,15 @@ import {
14
14
  createToolCallEvent,
15
15
  createToolResultEvent,
16
16
  streamLLMPure
17
- } from "./chunk-NLO64UE3.js";
17
+ } from "./chunk-EQ7DK2TG.js";
18
18
  import {
19
19
  COMPACTION_PROMPT,
20
20
  buildBasePrompt,
21
21
  computeEffectiveTools
22
- } from "./chunk-2XD65L7M.js";
22
+ } from "./chunk-27NABDXB.js";
23
23
  import {
24
24
  startInspectProxy
25
- } from "./chunk-P5UANBBX.js";
25
+ } from "./chunk-M6X6AIEG.js";
26
26
  import {
27
27
  checkAborted,
28
28
  createProcess,
@@ -36,7 +36,7 @@ import {
36
36
  spawnShellProcess,
37
37
  startProcessCommand,
38
38
  stopProcess
39
- } from "./chunk-TKKP56QK.js";
39
+ } from "./chunk-ZTOG6LJD.js";
40
40
  import {
41
41
  getMaxPerSession,
42
42
  getSessionProcessCount,
@@ -52,41 +52,41 @@ import {
52
52
  getGitBranch,
53
53
  isGitRepository,
54
54
  listWorkspaces
55
- } from "./chunk-SBSUDHL4.js";
55
+ } from "./chunk-O6DU226D.js";
56
56
  import {
57
57
  getGateConfig,
58
58
  isTaskConflictError,
59
59
  isTaskGateError
60
- } from "./chunk-OTYAEEX3.js";
60
+ } from "./chunk-HZSKKJHQ.js";
61
61
  import {
62
62
  getSessionDisabledServers
63
- } from "./chunk-L63Q4JQJ.js";
63
+ } from "./chunk-EQ5CGNOT.js";
64
64
  import {
65
65
  PathAccessDeniedError,
66
66
  extractAbsolutePathsFromCommand,
67
67
  extractSensitivePathsFromCommand,
68
68
  registerPathConfirmation,
69
69
  requestPathAccess
70
- } from "./chunk-BZVW77PI.js";
70
+ } from "./chunk-QQVPUZQB.js";
71
71
  import {
72
72
  getCurrentContextWindowId,
73
73
  getCurrentWindowMessageOptions,
74
74
  getEventStore
75
- } from "./chunk-JXLRL5JR.js";
75
+ } from "./chunk-TGVDUK4N.js";
76
76
  import {
77
77
  createChatDoneMessage,
78
78
  createChatMessageMessage,
79
79
  createChatMessageUpdatedMessage,
80
80
  createChatPathConfirmationMessage,
81
81
  createQueueStateMessage
82
- } from "./chunk-I7FY2LTR.js";
82
+ } from "./chunk-4GHLULHB.js";
83
83
  import {
84
84
  AskUserInterrupt,
85
85
  askUserTool
86
86
  } from "./chunk-JURM3RPZ.js";
87
87
  import {
88
88
  resolveLLMClientForAgent
89
- } from "./chunk-JP7NM545.js";
89
+ } from "./chunk-JLAR2CMV.js";
90
90
  import {
91
91
  buildContextMessagesFromEventHistory,
92
92
  foldContextState,
@@ -96,16 +96,16 @@ import {
96
96
  handleToolResult,
97
97
  reorderToolMessages,
98
98
  stripOrphanedToolCalls
99
- } from "./chunk-UTIQ7OO5.js";
99
+ } from "./chunk-3KBRMBTP.js";
100
100
  import {
101
101
  findAgentById,
102
102
  getRuntimeConfig,
103
103
  getSubAgents,
104
104
  loadAllAgentsDefault
105
- } from "./chunk-UPBWEHIL.js";
105
+ } from "./chunk-LNNBLB6G.js";
106
106
  import {
107
107
  modelSupportsVision
108
- } from "./chunk-V4IE7HJY.js";
108
+ } from "./chunk-W7VIYHPQ.js";
109
109
  import {
110
110
  OUTPUT_LIMITS,
111
111
  cacheSet,
@@ -116,11 +116,11 @@ import {
116
116
  formatPdfErrorMessage,
117
117
  isPdfBuffer,
118
118
  processPdfContent
119
- } from "./chunk-L737Y63F.js";
119
+ } from "./chunk-TOKQ2UVG.js";
120
120
  import {
121
121
  SETTINGS_KEYS,
122
122
  getSetting
123
- } from "./chunk-HP5CIB66.js";
123
+ } from "./chunk-HD6Y77RO.js";
124
124
  import {
125
125
  logger
126
126
  } from "./chunk-K44MW7JJ.js";
@@ -134,7 +134,7 @@ import {
134
134
 
135
135
  // src/server/tools/read.ts
136
136
  import { readFile as readFile2, stat, readdir } from "fs/promises";
137
- import { extname, join } from "path";
137
+ import { extname, join, relative as relative2 } from "path";
138
138
 
139
139
  // src/server/tools/tool-helpers.ts
140
140
  import { randomUUID } from "crypto";
@@ -144,7 +144,7 @@ async function requestUserConfirmation(context, toolLabel, desc) {
144
144
  if (context.dangerLevel === "dangerous") return Promise.resolve(true);
145
145
  if (toolLabel === "workspace" || toolLabel === "command") {
146
146
  try {
147
- const { getSetting: getSetting2, SETTINGS_KEYS: SETTINGS_KEYS2 } = await import("./settings-NEBM3GQX.js");
147
+ const { getSetting: getSetting2, SETTINGS_KEYS: SETTINGS_KEYS2 } = await import("./settings-FGXQHKUH.js");
148
148
  if (getSetting2(SETTINGS_KEYS2.CONFIRM_ON_WORKSPACE_ACTIONS) !== "true") {
149
149
  return Promise.resolve(true);
150
150
  }
@@ -273,7 +273,7 @@ function createTool(name, definition, handler2) {
273
273
  // src/server/tools/file-tracker.ts
274
274
  import { createHash } from "crypto";
275
275
  import { readFile } from "fs/promises";
276
- import { resolve as resolve2 } from "path";
276
+ import { relative, resolve as resolve2 } from "path";
277
277
  var FileNotReadError = class extends Error {
278
278
  constructor(path) {
279
279
  super(`File "${path}" must be read before writing. Use read_file first.`);
@@ -301,26 +301,35 @@ async function computeFileHash(filePath) {
301
301
  throw error;
302
302
  }
303
303
  }
304
- async function validateFileForWrite(filePath, readFiles) {
304
+ async function validateFileForWrite(filePath, readFiles, baseDir) {
305
305
  const normalizedPath = resolve2(filePath);
306
306
  const currentHash = await computeFileHash(normalizedPath);
307
307
  if (currentHash === null) {
308
308
  return { valid: true };
309
309
  }
310
310
  const readEntry = readFiles[normalizedPath];
311
- if (!readEntry) {
312
- return {
313
- valid: false,
314
- error: new FileNotReadError(filePath)
315
- };
311
+ if (readEntry) {
312
+ if (readEntry.hash !== currentHash) {
313
+ return {
314
+ valid: false,
315
+ error: new FileChangedExternallyError(filePath)
316
+ };
317
+ }
318
+ return { valid: true };
316
319
  }
317
- if (readEntry.hash !== currentHash) {
318
- return {
319
- valid: false,
320
- error: new FileChangedExternallyError(filePath)
321
- };
320
+ if (baseDir) {
321
+ const relPath = relative(baseDir, normalizedPath);
322
+ if (!relPath.startsWith("..")) {
323
+ const relMatches = Object.values(readFiles).filter((entry) => entry.relPath === relPath);
324
+ if (relMatches.some((entry) => entry.hash === currentHash)) {
325
+ return { valid: true };
326
+ }
327
+ }
322
328
  }
323
- return { valid: true };
329
+ return {
330
+ valid: false,
331
+ error: new FileNotReadError(filePath)
332
+ };
324
333
  }
325
334
  function isNodeError(error) {
326
335
  return error instanceof Error && "code" in error;
@@ -609,7 +618,12 @@ var readFileTool = createTool(
609
618
  const dataUrl = `data:${mimeType};base64,${base64Data}`;
610
619
  const contentHash3 = await computeFileHash(fullPath);
611
620
  if (contentHash3) {
612
- context.sessionManager.recordFileRead(context.sessionId, fullPath, contentHash3);
621
+ context.sessionManager.recordFileRead(
622
+ context.sessionId,
623
+ fullPath,
624
+ contentHash3,
625
+ relative2(context.workdir, fullPath)
626
+ );
613
627
  }
614
628
  return helpers.success(`[Image: ${args.path} (${mimeType}, ${rawBuffer.length} bytes)]`, false, {
615
629
  metadata: {
@@ -627,7 +641,12 @@ var readFileTool = createTool(
627
641
  const { output: output2, truncated: truncated2, isScanned } = processPdfContent(text, OUTPUT_LIMITS.read_file.maxBytes);
628
642
  const contentHash3 = await computeFileHash(fullPath);
629
643
  if (contentHash3) {
630
- context.sessionManager.recordFileRead(context.sessionId, fullPath, contentHash3);
644
+ context.sessionManager.recordFileRead(
645
+ context.sessionId,
646
+ fullPath,
647
+ contentHash3,
648
+ relative2(context.workdir, fullPath)
649
+ );
631
650
  }
632
651
  if (isScanned) {
633
652
  return helpers.success(
@@ -678,7 +697,12 @@ var readFileTool = createTool(
678
697
  }
679
698
  const contentHash2 = await computeFileHash(fullPath);
680
699
  if (contentHash2) {
681
- context.sessionManager.recordFileRead(context.sessionId, fullPath, contentHash2);
700
+ context.sessionManager.recordFileRead(
701
+ context.sessionId,
702
+ fullPath,
703
+ contentHash2,
704
+ relative2(context.workdir, fullPath)
705
+ );
682
706
  }
683
707
  return helpers.success(output, truncated, {
684
708
  metadata: {
@@ -695,7 +719,7 @@ var readFileTool = createTool(
695
719
 
696
720
  // src/server/tools/write.ts
697
721
  import { writeFile, mkdir } from "fs/promises";
698
- import { dirname } from "path";
722
+ import { dirname, relative as relative3 } from "path";
699
723
 
700
724
  // src/server/tools/diagnostics.ts
701
725
  function formatDiagnosticsForLLM(diagnostics) {
@@ -762,7 +786,7 @@ var writeFileTool = createTool(
762
786
  const fullPath = helpers.resolvePath(args.path);
763
787
  await helpers.checkPathAccess([fullPath]);
764
788
  const readFiles = context.sessionManager.getReadFiles(context.sessionId);
765
- const validation = await validateFileForWrite(fullPath, readFiles);
789
+ const validation = await validateFileForWrite(fullPath, readFiles, context.workdir);
766
790
  if (!validation.valid) {
767
791
  return helpers.error(validation.error?.message ?? "File validation failed");
768
792
  }
@@ -782,7 +806,7 @@ var writeFileTool = createTool(
782
806
  }
783
807
  const newHash = await computeFileHash(fullPath);
784
808
  if (newHash) {
785
- context.sessionManager.updateFileHash(context.sessionId, fullPath, newHash);
809
+ context.sessionManager.updateFileHash(context.sessionId, fullPath, newHash, relative3(context.workdir, fullPath));
786
810
  }
787
811
  return helpers.success(output, false, {
788
812
  ...diagnostics.length > 0 && { diagnostics },
@@ -793,6 +817,7 @@ var writeFileTool = createTool(
793
817
 
794
818
  // src/server/tools/edit.ts
795
819
  import { readFile as readFile3, writeFile as writeFile2 } from "fs/promises";
820
+ import { relative as relative4 } from "path";
796
821
 
797
822
  // src/server/tools/edit-context.ts
798
823
  var CONTEXT_LINES = 4;
@@ -958,7 +983,7 @@ var editFileTool = createTool(
958
983
  return withFileLock(fullPath, async () => {
959
984
  const replaceAll = args.replace_all ?? false;
960
985
  const readFiles = context.sessionManager.getReadFiles(context.sessionId);
961
- const validation = await validateFileForWrite(fullPath, readFiles);
986
+ const validation = await validateFileForWrite(fullPath, readFiles, context.workdir);
962
987
  if (!validation.valid) {
963
988
  return helpers.error(validation.error?.message ?? "File validation failed");
964
989
  }
@@ -1042,7 +1067,7 @@ Make sure whitespace and indentation match exactly.`
1042
1067
  }
1043
1068
  const newHash = await computeFileHash(fullPath);
1044
1069
  if (newHash) {
1045
- context.sessionManager.updateFileHash(context.sessionId, fullPath, newHash);
1070
+ context.sessionManager.updateFileHash(context.sessionId, fullPath, newHash, relative4(context.workdir, fullPath));
1046
1071
  }
1047
1072
  return helpers.success(output, false, {
1048
1073
  ...diagnostics.length > 0 && { diagnostics },
@@ -1522,10 +1547,10 @@ var INTERRUPTED_ERROR = "Tool execution was interrupted by user";
1522
1547
  function extractSubAgentPrompt(args) {
1523
1548
  return args["prompt"] || args["query"] || args["task"] || "";
1524
1549
  }
1525
- async function transformSubAgentAliases(toolCalls, toolRegistry) {
1550
+ async function transformSubAgentAliases(toolCalls, toolRegistry, projectDir) {
1526
1551
  const hasCallSubAgent = toolRegistry.tools.some((t) => t.name === "call_sub_agent");
1527
1552
  if (!hasCallSubAgent) return;
1528
- const agents = await loadAllAgentsDefault();
1553
+ const agents = await loadAllAgentsDefault(projectDir);
1529
1554
  for (const tc of toolCalls) {
1530
1555
  const agentDef = findAgentById(tc.name, agents);
1531
1556
  if (!agentDef?.metadata.subagent) continue;
@@ -1550,7 +1575,7 @@ async function executeTools(assistantMsgId, toolCalls, ctx, append) {
1550
1575
  if (ctx.signal?.aborted) {
1551
1576
  throw new Error("Aborted");
1552
1577
  }
1553
- await transformSubAgentAliases(toolCalls, ctx.toolRegistry);
1578
+ await transformSubAgentAliases(toolCalls, ctx.toolRegistry, ctx.sessionManager.getProjectWorkdir(ctx.sessionId));
1554
1579
  for (const toolCall of toolCalls) {
1555
1580
  append(createToolCallEvent(assistantMsgId, toolCall));
1556
1581
  }
@@ -1568,7 +1593,7 @@ async function executeTools(assistantMsgId, toolCalls, ctx, append) {
1568
1593
  data: { callId: error.callId, question: error.question, type: error.type, options: error.options }
1569
1594
  });
1570
1595
  append(createChatDoneEvent(assistantMsgId, "waiting_for_user"));
1571
- const { awaitAnswer } = await import("./ask-ZYPCJKZD.js");
1596
+ const { awaitAnswer } = await import("./ask-UBIRH3SO.js");
1572
1597
  const answerPromise = awaitAnswer(error.callId);
1573
1598
  if (!answerPromise) {
1574
1599
  throw new Error(`No pending question found for callId: ${error.callId}`);
@@ -1784,7 +1809,7 @@ async function runTopLevelAgentLoop(config, turnMetrics) {
1784
1809
  const session2 = sessionManager.requireSession(sessionId);
1785
1810
  const runtimeConfig2 = getRuntimeConfig();
1786
1811
  const configDir2 = getGlobalConfigDir(runtimeConfig2.mode ?? "production");
1787
- const skills2 = await getEnabledSkillMetadata(configDir2, sessionManager.getEffectiveWorkdir(sessionId));
1812
+ const skills2 = await getEnabledSkillMetadata(configDir2, sessionManager.getProjectWorkdir(sessionId));
1788
1813
  const { content: instructionContent2 } = await getAllInstructions(session2.workdir, session2.projectId);
1789
1814
  const toolRegistry2 = config.getToolRegistry();
1790
1815
  const assembledRequest2 = await config.assembleRequest({
@@ -1839,7 +1864,7 @@ ${CONTINUE_PROMPT}` : CONTINUE_PROMPT;
1839
1864
  }
1840
1865
  const runtimeConfig = getRuntimeConfig();
1841
1866
  const configDir = getGlobalConfigDir(runtimeConfig.mode ?? "production");
1842
- const skills = await getEnabledSkillMetadata(configDir, sessionManager.getEffectiveWorkdir(sessionId));
1867
+ const skills = await getEnabledSkillMetadata(configDir, sessionManager.getProjectWorkdir(sessionId));
1843
1868
  if (signal?.aborted) throw new Error("Aborted");
1844
1869
  const assembledRequest = await config.assembleRequest({
1845
1870
  workdir: session.workdir,
@@ -1866,7 +1891,7 @@ ${CONTINUE_PROMPT}` : CONTINUE_PROMPT;
1866
1891
  const requestedMaxTokens = modelSettings.maxTokens ?? 16384;
1867
1892
  modelSettings = { ...modelSettings, maxTokens: Math.min(requestedMaxTokens, availableForOutput) };
1868
1893
  }
1869
- const allAgents = await loadAllAgentsDefault();
1894
+ const allAgents = await loadAllAgentsDefault(sessionManager.getProjectWorkdir(sessionId));
1870
1895
  const subAgentAliases = new Set(getSubAgents(allAgents).map((a) => a.metadata.id));
1871
1896
  const streamGen = streamLLMPure({
1872
1897
  messageId: assistantMsgId,
@@ -1878,6 +1903,7 @@ ${CONTINUE_PROMPT}` : CONTINUE_PROMPT;
1878
1903
  signal,
1879
1904
  subAgentAliases,
1880
1905
  ...config.retryPatterns ? { retryPatterns: config.retryPatterns } : {},
1906
+ ...config.suppressChatError ? { suppressChatError: true } : {},
1881
1907
  ...modelSettings && { modelSettings }
1882
1908
  });
1883
1909
  const result = await consumeStreamGenerator(streamGen, (event) => {
@@ -1925,22 +1951,35 @@ ${CONTINUE_PROMPT}` : CONTINUE_PROMPT;
1925
1951
  emitPartialDoneEvents(sessionId, assistantMsgId, statsIdentity, mode, turnMetrics, append, agentType);
1926
1952
  throw new Error("Aborted");
1927
1953
  }
1928
- turnMetrics.addLLMCall(
1929
- result.timing,
1930
- result.usage.promptTokens,
1931
- result.usage.completionTokens,
1932
- previousContextTokens,
1933
- result.modelParams
1934
- );
1935
- sessionManager.setCurrentContextSize(
1936
- sessionId,
1937
- result.usage.promptTokens,
1938
- result.usage.completionTokens,
1939
- config.subAgentMetadata?.subAgentId
1940
- );
1954
+ if (result.error) {
1955
+ const stats2 = turnMetrics.buildStats(statsIdentity, mode);
1956
+ append(
1957
+ createMessageDoneEvent(assistantMsgId, {
1958
+ segments: result.segments,
1959
+ stats: stats2
1960
+ })
1961
+ );
1962
+ append(createChatDoneEvent(assistantMsgId, "error", stats2, agentType));
1963
+ return { failed: { error: result.error } };
1964
+ }
1965
+ if (!result.error) {
1966
+ turnMetrics.addLLMCall(
1967
+ result.timing,
1968
+ result.usage.promptTokens,
1969
+ result.usage.completionTokens,
1970
+ previousContextTokens,
1971
+ result.modelParams
1972
+ );
1973
+ sessionManager.setCurrentContextSize(
1974
+ sessionId,
1975
+ result.usage.promptTokens,
1976
+ result.usage.completionTokens,
1977
+ config.subAgentMetadata?.subAgentId
1978
+ );
1979
+ }
1941
1980
  if (!compacting) {
1942
1981
  const contextState2 = sessionManager.getContextState(sessionId);
1943
- const { shouldCompact, appendCompactionPrompt } = await import("./compactor-V3LR7APW.js");
1982
+ const { shouldCompact, appendCompactionPrompt } = await import("./compactor-LAXZLPPA.js");
1944
1983
  if (shouldCompact(
1945
1984
  contextState2.currentTokens,
1946
1985
  contextState2.maxTokens,
@@ -2310,7 +2349,7 @@ async function describeImageFromDataUrl(dataUrl, visionModel, options) {
2310
2349
  // src/server/context/image-processor.ts
2311
2350
  async function loadVisionModelFromGlobalConfig() {
2312
2351
  try {
2313
- const { loadGlobalConfig: loadGlobalConfig2, resolveVisionFallback } = await import("./config-EAB3V4QK.js");
2352
+ const { loadGlobalConfig: loadGlobalConfig2, resolveVisionFallback } = await import("./config-TUCHLIWD.js");
2314
2353
  const runtimeConfig = getRuntimeConfig();
2315
2354
  const mode = runtimeConfig.mode ?? "production";
2316
2355
  const globalConfig = await loadGlobalConfig2(mode);
@@ -2658,8 +2697,8 @@ function buildSubAgentResult(returnValueContent, returnValueResult) {
2658
2697
  ...returnValueResult !== null && returnValueResult !== void 0 ? { result: returnValueResult } : {}
2659
2698
  };
2660
2699
  }
2661
- async function resolveAgentDef(agentId) {
2662
- const allAgents = await loadAllAgentsDefault();
2700
+ async function resolveAgentDef(agentId, projectDir) {
2701
+ const allAgents = await loadAllAgentsDefault(projectDir);
2663
2702
  const def = findAgentById(agentId, allAgents);
2664
2703
  if (!def) throw new Error(`Unknown sub-agent type: ${agentId}`);
2665
2704
  if (!def.metadata.subagent) throw new Error(`Agent '${agentId}' is not a sub-agent`);
@@ -2710,7 +2749,7 @@ async function executeSubAgent(options) {
2710
2749
  signal,
2711
2750
  onMessage
2712
2751
  } = options;
2713
- const agentDef = await resolveAgentDef(subAgentType);
2752
+ const agentDef = await resolveAgentDef(subAgentType, sessionManager.getProjectWorkdir(sessionId));
2714
2753
  const eventStore = getEventStore();
2715
2754
  const subAgentId = crypto.randomUUID();
2716
2755
  const session = sessionManager.requireSession(sessionId);
@@ -2814,7 +2853,7 @@ async function executeSubAgent(options) {
2814
2853
  const { content: instructionContent } = await getAllInstructions(effectiveWorkdir, session.projectId);
2815
2854
  const config = getRuntimeConfig();
2816
2855
  const configDir = getGlobalConfigDir(config.mode ?? "production");
2817
- const skills = await getEnabledSkillMetadata(configDir, effectiveWorkdir);
2856
+ const skills = await getEnabledSkillMetadata(configDir, session.workdir);
2818
2857
  const hasRunCommand = agentDef.metadata.allowedTools?.includes("run_command") ?? false;
2819
2858
  const gitignoreSection = hasRunCommand ? await loadGitIgnoreRules(effectiveWorkdir) : "";
2820
2859
  const systemPrompt = buildBasePrompt(effectiveWorkdir, void 0, skills.length > 0 ? skills : void 0, llmClient.getModel()) + "\n\n" + agentDef.prompt + (gitignoreSection ? "\n\n" + gitignoreSection : "") + RETURN_VALUE_INSTRUCTION;
@@ -2928,7 +2967,7 @@ var callSubAgentTool = {
2928
2967
  };
2929
2968
  }
2930
2969
  try {
2931
- const { getToolRegistryForAgent: getToolRegistryForAgent2 } = await import("./tools-CIM26IFB.js");
2970
+ const { getToolRegistryForAgent: getToolRegistryForAgent2 } = await import("./tools-KBS6X3EN.js");
2932
2971
  const toolRegistry = getToolRegistryForAgent2(agentDef);
2933
2972
  const turnMetrics = new TurnMetrics();
2934
2973
  const result = await executeSubAgent({
@@ -2984,7 +3023,7 @@ var handler = async (args, context, helpers) => {
2984
3023
  }
2985
3024
  const config = getRuntimeConfig();
2986
3025
  const configDir = getGlobalConfigDir(config.mode ?? "production");
2987
- const allSkills = await loadAllSkills(configDir, context.workdir);
3026
+ const allSkills = await loadAllSkills(configDir, context.sessionManager.getProjectWorkdir(context.sessionId));
2988
3027
  const skill = findSkillById(skillId, allSkills);
2989
3028
  if (!skill) {
2990
3029
  const available = allSkills.map((s) => s.metadata.id).join(", ");
@@ -3950,7 +3989,7 @@ var mcpConfigTool = createTool(
3950
3989
  mcpNotifyChanged?.(sessionId);
3951
3990
  }
3952
3991
  async function rebuildTools() {
3953
- const { setMcpTools: setMcpTools2 } = await import("./tools-CIM26IFB.js");
3992
+ const { setMcpTools: setMcpTools2 } = await import("./tools-KBS6X3EN.js");
3954
3993
  const mcpTools = createMcpTools(mcpManagerForTools);
3955
3994
  setMcpTools2(mcpTools);
3956
3995
  }
@@ -4375,33 +4414,20 @@ function getTasksService() {
4375
4414
  }
4376
4415
  return tasksService;
4377
4416
  }
4378
- var VALID_ACTIONS = [
4379
- "list",
4380
- "get",
4381
- "create",
4382
- "edit",
4383
- "move",
4384
- "set_gate_value",
4385
- "set_gates",
4386
- "duplicate",
4387
- "delete",
4388
- "reorder"
4389
- ];
4417
+ var VALID_ACTIONS = ["list", "create", "edit", "move", "set_gate_value", "delete"];
4418
+ var LIST_STATUSES = ["todo", "in_progress", "done", "all"];
4390
4419
  var projectTasksTool = createTool(
4391
4420
  "project_tasks",
4392
4421
  {
4393
4422
  type: "function",
4394
4423
  function: {
4395
4424
  name: "project_tasks",
4396
- description: "Work with the project task board \u2014 the kanban of tasks owned by this project. Provides full parity with the human UI: list, get, create, edit, move, fill gate values, set gate configuration, duplicate, delete, and reorder.\n\nRules:\n- Moving a task to in_progress binds it to YOUR current session (you never create a new session for it).\n- Entering 'done' is blocked by unmet column gates (definition of done). When blocked, the error lists the missing fields; set them with action=set_gate_value (filling proof/evidence as part of your work), then retry the move.\n- All transitions are serialized server-side. If another actor changed the task, you get a CONFLICT error: re-list and retry.\n\nActions:\n- list: list all tasks (with gate values, status, queue position, bound session, audit trail)\n- get: fetch a single task (taskId)\n- create: create a task in To Do (prompt must contain text or an attachment)\n- edit: update prompt/attachments/agent/model (taskId + any fields)\n- move: change state \u2014 to: 'todo' | 'in_progress' | 'done' (optional reason for reverts)\n- set_gate_value: fill a gate field (taskId, gateId, value)\n- set_gates: replace the project gate configuration (gates: array of {id, name, description, required, variant})\n- duplicate: copy a task into To Do (taskId)\n- delete: permanently delete a task (taskId). Sessions stay untouched.\n- reorder: move a task to an index within its column (taskId, status, index)",
4425
+ description: "Kanban task board for this project. Core loop: list \u2192 move \u2192 set_gate_value.\n\nRules:\n- Moving to in_progress binds the task to YOUR current session.\n- Moving to done is blocked by unmet gates: the error names the missing fields \u2014 fill them via set_gate_value (that's part of the work), then retry the move.\n- Stale writes fail with CONFLICT \u2014 re-list and retry.\n\nActions:\n- list: tasks (status, gate values, queue position, bound session, audit trail); defaults to open tasks, filter via status (todo | in_progress | done | all)\n- create: add a task to To Do (prompt required)\n- edit: update prompt/attachments/agent/model (taskId + fields)\n- move: change column (to: todo | in_progress | done; optional reason)\n- set_gate_value: fill a gate field (taskId, gateId, value)\n- delete: remove a task (taskId)",
4397
4426
  parameters: {
4398
4427
  type: "object",
4399
4428
  properties: {
4400
4429
  action: { type: "string", enum: VALID_ACTIONS, description: "The action to perform" },
4401
- taskId: {
4402
- type: "string",
4403
- description: "Target task id (get, edit, move, set_gate_value, duplicate, delete, reorder)"
4404
- },
4430
+ taskId: { type: "string", description: "Target task id (edit, move, set_gate_value, delete)" },
4405
4431
  prompt: { type: "string", description: "The prompt/instruction executed when the task launches" },
4406
4432
  attachments: { type: "array", description: "Optional attachments (same shape as chat attachments)" },
4407
4433
  agentId: { type: "string", description: "Selected agent id" },
@@ -4411,15 +4437,14 @@ var projectTasksTool = createTool(
4411
4437
  reason: { type: "string", description: "Optional short reason (recorded in the audit trail) for reverts" },
4412
4438
  gateId: { type: "string", description: "Gate field id for set_gate_value" },
4413
4439
  value: { type: "string", description: "Proof/evidence value for set_gate_value" },
4414
- gates: {
4415
- type: "array",
4416
- description: "Full replacement gate config: [{id, name, description, required, variant}]"
4440
+ status: {
4441
+ type: "string",
4442
+ enum: ["todo", "in_progress", "done", "all"],
4443
+ description: "Column filter for action=list (default: open tasks)"
4417
4444
  },
4418
- status: { type: "string", enum: ["todo", "in_progress", "done"], description: "Column for reorder" },
4419
- index: { type: "number", description: "Zero-based target index within the column (reorder)" },
4420
4445
  expectedVersion: {
4421
4446
  type: "number",
4422
- description: "Optimistic concurrency guard \u2014 pass the task version you saw; stale writes fail with CONFLICT"
4447
+ description: "Task version from your last read; stale writes fail with CONFLICT"
4423
4448
  }
4424
4449
  },
4425
4450
  required: ["action"]
@@ -4438,15 +4463,16 @@ var projectTasksTool = createTool(
4438
4463
  try {
4439
4464
  switch (action) {
4440
4465
  case "list": {
4466
+ const status = args.status;
4467
+ if (status !== void 0 && !LIST_STATUSES.includes(status)) {
4468
+ return helpers.error(
4469
+ `Invalid "status" filter for action=list: "${String(status)}". Expected one of: todo, in_progress, done, all.`
4470
+ );
4471
+ }
4441
4472
  const tasks = svc.list(projectId);
4473
+ const filtered = status === "all" ? tasks : tasks.filter((t) => status === void 0 ? t.status !== "done" : t.status === status);
4442
4474
  const gates = getGateConfig(projectId);
4443
- return helpers.success(JSON.stringify({ gates, tasks: tasks.map((t) => taskForAgent(t)) }, null, 2));
4444
- }
4445
- case "get": {
4446
- if (!args.taskId) return helpers.error('Parameter "taskId" is required for action=get');
4447
- const task = svc.get(projectId, args.taskId);
4448
- if (!task) return helpers.error(`Task not found: ${args.taskId}`);
4449
- return helpers.success(JSON.stringify(taskForAgent(task), null, 2));
4475
+ return helpers.success(JSON.stringify({ gates, tasks: filtered.map((t) => taskForAgent(t)) }, null, 2));
4450
4476
  }
4451
4477
  case "create": {
4452
4478
  const task = svc.create(
@@ -4507,31 +4533,18 @@ var projectTasksTool = createTool(
4507
4533
  );
4508
4534
  return helpers.success(JSON.stringify(taskForAgent(result.task), null, 2));
4509
4535
  }
4510
- case "set_gates": {
4511
- if (!Array.isArray(args.gates)) {
4512
- return helpers.error('Parameter "gates" (array) is required for action=set_gates');
4513
- }
4514
- const gates = sanitizeGates(args.gates);
4515
- svc.setGateConfig(projectId, gates, actor);
4516
- return helpers.success(JSON.stringify({ gates }, null, 2));
4517
- }
4518
- case "duplicate": {
4519
- if (!args.taskId) return helpers.error('Parameter "taskId" is required for action=duplicate');
4520
- const task = svc.duplicate(projectId, args.taskId, actor);
4521
- return helpers.success(JSON.stringify(taskForAgent(task), null, 2));
4522
- }
4523
4536
  case "delete": {
4524
4537
  if (!args.taskId) return helpers.error('Parameter "taskId" is required for action=delete');
4538
+ const task = svc.get(projectId, args.taskId);
4539
+ if (!task) return helpers.error(`Task not found: ${args.taskId}`);
4525
4540
  await svc.remove(projectId, args.taskId, actor);
4526
- return helpers.success(`Task ${args.taskId} deleted (linked sessions untouched)`);
4527
- }
4528
- case "reorder": {
4529
- if (!args.taskId) return helpers.error('Parameter "taskId" is required for action=reorder');
4530
- if (!args.status || args.index === void 0) {
4531
- return helpers.error('Parameters "status" and "index" are required for action=reorder');
4532
- }
4533
- const task = svc.reorder(projectId, args.taskId, args.status, args.index);
4534
- return helpers.success(JSON.stringify(taskForAgent(task), null, 2));
4541
+ return helpers.success(
4542
+ JSON.stringify(
4543
+ { message: `Deleted: ${task.prompt.split("\n")[0]}`, taskId: task.id, prompt: task.prompt },
4544
+ null,
4545
+ 2
4546
+ )
4547
+ );
4535
4548
  }
4536
4549
  default:
4537
4550
  return helpers.error(`Unknown action: ${String(action)}`);
@@ -4578,18 +4591,6 @@ function sanitizeAttachments(raw) {
4578
4591
  (a) => typeof a === "object" && a !== null && typeof a.id === "string" && typeof a.filename === "string"
4579
4592
  );
4580
4593
  }
4581
- function sanitizeGates(raw) {
4582
- return raw.map((g, i) => {
4583
- const gate = g;
4584
- return {
4585
- id: typeof gate.id === "string" && gate.id ? gate.id : `gate_${i}`,
4586
- name: typeof gate.name === "string" && gate.name ? gate.name : `Gate ${i + 1}`,
4587
- description: typeof gate.description === "string" ? gate.description : "",
4588
- required: gate.required !== false,
4589
- variant: gate.variant === "ready" ? "ready" : "done"
4590
- };
4591
- });
4592
- }
4593
4594
 
4594
4595
  // src/server/tools/index.ts
4595
4596
  var _builtInTools;
@@ -4872,4 +4873,4 @@ export {
4872
4873
  getToolRegistryForAgent,
4873
4874
  createToolRegistry
4874
4875
  };
4875
- //# sourceMappingURL=chunk-K733B5T2.js.map
4876
+ //# sourceMappingURL=chunk-4HV3PDEK.js.map