openfox 2.0.136 → 2.0.138

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 (51) hide show
  1. package/CHANGELOG.md +18 -0
  2. package/dist/CHANGELOG.md +18 -0
  3. package/dist/{chat-handler-SYU4HJMI.js → chat-handler-AUB5HDQD.js} +12 -11
  4. package/dist/{chunk-GP5BYQMF.js → chunk-2KCREKHC.js} +19 -13
  5. package/dist/{chunk-342BKOTE.js → chunk-2OO46UAW.js} +2 -2
  6. package/dist/{chunk-UL7776XB.js → chunk-2Q4THMD7.js} +7 -7
  7. package/dist/{chunk-CPVEONNS.js → chunk-5CZPHAHN.js} +6 -6
  8. package/dist/{chunk-U6FHHT2B.js → chunk-76C2PVOC.js} +4 -4
  9. package/dist/{chunk-YDPC4FLR.js → chunk-BENMBAU2.js} +4 -4
  10. package/dist/{chunk-PQKLOLGC.js → chunk-DBCWILV3.js} +21 -3
  11. package/dist/{chunk-QQQBNL7A.js → chunk-HI25RCRW.js} +233 -52
  12. package/dist/{chunk-XGG4XCKP.js → chunk-MMGHIPBU.js} +71 -53
  13. package/dist/{chunk-EXLCFEML.js → chunk-N3PANDLT.js} +14 -10
  14. package/dist/chunk-OU7WD35E.js +7 -0
  15. package/dist/{chunk-AATMPL7S.js → chunk-OVAHNEFG.js} +6 -2
  16. package/dist/{chunk-HF3NDXB4.js → chunk-PW5L4WBG.js} +1 -1
  17. package/dist/{chunk-MILEZY2J.js → chunk-RJ2GRUVF.js} +3 -3
  18. package/dist/{chunk-VA2TYWQR.js → chunk-U7XCK7WL.js} +2 -2
  19. package/dist/{chunk-5YPHN5NC.js → chunk-XS2QQERB.js} +4 -4
  20. package/dist/cli/dev.js +1 -1
  21. package/dist/cli/index.js +1 -1
  22. package/dist/{compactor-LBK53WAK.js → compactor-KDTY4ERE.js} +4 -4
  23. package/dist/{describe-image-4XDLSKAB.js → describe-image-AU6KBSWA.js} +7 -7
  24. package/dist/{dynamic-context-RDBNQPPA.js → dynamic-context-SKHOUP4T.js} +4 -4
  25. package/dist/{events-YTYYT3PR.js → events-ADE2KEHI.js} +4 -6
  26. package/dist/{export-import-GHRCOQHF.js → export-import-SC3UW22Z.js} +4 -4
  27. package/dist/{folding-3MMOPS4W.js → folding-CM63AVSB.js} +4 -4
  28. package/dist/{launch-YZ46OEFP.js → launch-PTMPNZEN.js} +11 -11
  29. package/dist/{orchestrator-6QGQ55NT.js → orchestrator-KRHMAVBN.js} +10 -10
  30. package/dist/package.json +1 -1
  31. package/dist/{path-security-EC4Z2ZZG.js → path-security-YP2MRJNS.js} +8 -6
  32. package/dist/{processor-B2RV7MVC.js → processor-QZOGF5ES.js} +11 -10
  33. package/dist/{protocol-Nr_H1_oC.d.ts → protocol-D6DZzkSH.d.ts} +6 -3
  34. package/dist/{protocol-XO4ZROAU.js → protocol-MRMOB3P4.js} +5 -3
  35. package/dist/provider/index.d.ts +4 -4
  36. package/dist/{serve-EWA5HXC7.js → serve-LVDF4XLG.js} +16 -16
  37. package/dist/server/index.d.ts +33 -3
  38. package/dist/server/index.js +15 -15
  39. package/dist/{server-ZAPAB3FS.js → server-AIRQGHHR.js} +14 -14
  40. package/dist/shared/index.d.ts +3 -3
  41. package/dist/shared/index.js +1 -1
  42. package/dist/{tools-EJOABHVO.js → tools-NIPKV4YY.js} +10 -8
  43. package/dist/{types-G10ho8PT.d.ts → types-CLcL33hJ.d.ts} +11 -1
  44. package/dist/{types-BlQjLBui.d.ts → types-CmiWoQ7p.d.ts} +1 -1
  45. package/dist/{update-IPHJMRQZ.js → update-Y5QXN3FK.js} +2 -2
  46. package/dist/web/assets/{index-ChJjYovg.css → index-C1oW6oq0.css} +1 -1
  47. package/dist/web/assets/{index-CfFwerN2.js → index-CTAslWsi.js} +66 -66
  48. package/dist/web/index.html +2 -2
  49. package/dist/web/sw.js +1 -1
  50. package/package.json +1 -1
  51. package/dist/chunk-VWBPQZLO.js +0 -7
@@ -9,7 +9,7 @@ import {
9
9
  terminalManager,
10
10
  tokenFromPassword,
11
11
  verifyPassword
12
- } from "./chunk-GP5BYQMF.js";
12
+ } from "./chunk-2KCREKHC.js";
13
13
  import {
14
14
  projectSessionStatus
15
15
  } from "./chunk-T3S5MTMD.js";
@@ -27,7 +27,7 @@ import {
27
27
  } from "./chunk-IJ53Y77N.js";
28
28
  import {
29
29
  TEMPLATE_VARIABLES
30
- } from "./chunk-CPVEONNS.js";
30
+ } from "./chunk-5CZPHAHN.js";
31
31
  import {
32
32
  createToolRegistry,
33
33
  devServerManager,
@@ -42,7 +42,7 @@ import {
42
42
  setMcpManagerForTools,
43
43
  setMcpTools,
44
44
  setNotifyMcpServersChanged
45
- } from "./chunk-EXLCFEML.js";
45
+ } from "./chunk-N3PANDLT.js";
46
46
  import {
47
47
  deleteOwnedSkill,
48
48
  deleteProjectSkill,
@@ -133,7 +133,7 @@ import {
133
133
  import {
134
134
  getPendingConfirmationsBySession,
135
135
  providePathConfirmation
136
- } from "./chunk-PQKLOLGC.js";
136
+ } from "./chunk-DBCWILV3.js";
137
137
  import {
138
138
  combineEventsWithSnapshot,
139
139
  emitAssistantMessageStart,
@@ -151,10 +151,10 @@ import {
151
151
  getEventStore,
152
152
  getSessionState,
153
153
  initEventStore
154
- } from "./chunk-342BKOTE.js";
154
+ } from "./chunk-2OO46UAW.js";
155
155
  import {
156
156
  buildMessagesFromStoredEvents
157
- } from "./chunk-XGG4XCKP.js";
157
+ } from "./chunk-MMGHIPBU.js";
158
158
  import {
159
159
  clearWorkflowExecution,
160
160
  createSession,
@@ -206,7 +206,7 @@ import {
206
206
  import {
207
207
  createContextStateMessage,
208
208
  toClientSession
209
- } from "./chunk-AATMPL7S.js";
209
+ } from "./chunk-OVAHNEFG.js";
210
210
  import {
211
211
  getPathSeparator,
212
212
  isAbsolutePath
@@ -222,7 +222,7 @@ import {
222
222
  } from "./chunk-YNMP647F.js";
223
223
  import {
224
224
  VERSION
225
- } from "./chunk-VWBPQZLO.js";
225
+ } from "./chunk-OU7WD35E.js";
226
226
  import {
227
227
  deleteProject,
228
228
  getProject,
@@ -264,7 +264,7 @@ import {
264
264
  } from "./chunk-K44MW7JJ.js";
265
265
  import {
266
266
  createServerMessage
267
- } from "./chunk-HF3NDXB4.js";
267
+ } from "./chunk-PW5L4WBG.js";
268
268
  import {
269
269
  getGlobalConfigDir
270
270
  } from "./chunk-CQGTEGKL.js";
@@ -540,6 +540,15 @@ var RULES = [
540
540
  tools: [{ name: "write_file", arguments: { path: "/home/test/approved.txt", content: "approved" } }],
541
541
  response: "Wrote to the approved path."
542
542
  },
543
+ {
544
+ match: /write.*(?:three|3).*outside|three.*files.*outside/i,
545
+ tools: [
546
+ { name: "write_file", arguments: { path: "/home/test/alpha.txt", content: "alpha" } },
547
+ { name: "write_file", arguments: { path: "/home/test/beta.txt", content: "beta" } },
548
+ { name: "write_file", arguments: { path: "/home/test/gamma.txt", content: "gamma" } }
549
+ ],
550
+ response: "Wrote three files outside the project."
551
+ },
543
552
  {
544
553
  match: /write.*\/home\/test\/denied/i,
545
554
  tools: [{ name: "write_file", arguments: { path: "/home/test/denied.txt", content: "denied" } }],
@@ -2840,6 +2849,10 @@ var SessionManager = class {
2840
2849
  unknownProviderWarned = /* @__PURE__ */ new Set();
2841
2850
  switchLocks = /* @__PURE__ */ new Map();
2842
2851
  workspaceCreationLocks = /* @__PURE__ */ new Map();
2852
+ // Cooperative pause: in-memory only (a pause is only meaningful for a live,
2853
+ // running turn — it never survives a process restart).
2854
+ pauseStates = /* @__PURE__ */ new Map();
2855
+ pauseWaiters = /* @__PURE__ */ new Map();
2843
2856
  constructor(providerManager) {
2844
2857
  this.providerManager = providerManager;
2845
2858
  }
@@ -3132,8 +3145,8 @@ var SessionManager = class {
3132
3145
  * @throws Error for invalid payloads or unknown project
3133
3146
  */
3134
3147
  async importSession(projectId, rawPayload) {
3135
- const { parseSessionExport, IMPORTED_SESSION_REMINDER, SESSION_EXPORT_VERSION } = await import("./export-import-GHRCOQHF.js");
3136
- const { injectContextDriftReminders, getToolSetFingerprint } = await import("./dynamic-context-RDBNQPPA.js");
3148
+ const { parseSessionExport, IMPORTED_SESSION_REMINDER, SESSION_EXPORT_VERSION } = await import("./export-import-SC3UW22Z.js");
3149
+ const { injectContextDriftReminders, getToolSetFingerprint } = await import("./dynamic-context-SKHOUP4T.js");
3137
3150
  const { loadAllAgentsDefault: loadAllAgentsDefault2, resolveDefaultAgentId } = await import("./registry-FMDMGIUB.js");
3138
3151
  const payload = parseSessionExport(rawPayload);
3139
3152
  if (payload.version !== SESSION_EXPORT_VERSION) {
@@ -3268,6 +3281,7 @@ var SessionManager = class {
3268
3281
  const eventStore = getEventStore();
3269
3282
  eventStore.deleteSession(id);
3270
3283
  this.messageQueues.delete(id);
3284
+ this.clearPauseState(id);
3271
3285
  this.warmedUpSessions.delete(id);
3272
3286
  this.announcedPromptHashStore.delete(id);
3273
3287
  this.announcedToolFingerprintStore.delete(id);
@@ -3371,11 +3385,137 @@ var SessionManager = class {
3371
3385
  logger.debug("Setting session running state", { sessionId, isRunning });
3372
3386
  updateSessionRunning(sessionId, isRunning);
3373
3387
  emitRunningChanged(sessionId, isRunning);
3388
+ if (!isRunning) {
3389
+ this.clearPauseState(sessionId);
3390
+ }
3374
3391
  const updatedSession = this.requireSession(sessionId);
3375
3392
  this.emit({ type: "session_updated", session: updatedSession });
3376
3393
  this.emit({ type: "running_changed", sessionId, isRunning });
3377
3394
  return updatedSession;
3378
3395
  }
3396
+ // ============================================================================
3397
+ // Cooperative pause
3398
+ //
3399
+ // A pause never aborts the in-flight LLM request: it only gates the NEXT one.
3400
+ // The agent loop calls enterPauseGate() before every top-level LLM request;
3401
+ // the gate blocks until the user resumes (or the session aborts).
3402
+ //
3403
+ // none --requestPause--> pending --gate reached--> paused
3404
+ // pending --requestResume--> none (cancel, no interruption)
3405
+ // paused --requestResume--> resuming --gate released--> none
3406
+ // ============================================================================
3407
+ /** Current pause state ('none' when the session has no pause in flight). */
3408
+ getPauseState(sessionId) {
3409
+ return this.pauseStates.get(sessionId) ?? "none";
3410
+ }
3411
+ /** Request a pause. Succeeds only from 'none'. Returns false otherwise. */
3412
+ requestPause(sessionId) {
3413
+ if (this.getPauseState(sessionId) !== "none") {
3414
+ return false;
3415
+ }
3416
+ this.transitionPauseState(sessionId, "pending");
3417
+ return true;
3418
+ }
3419
+ /**
3420
+ * Request resume. From 'pending' this cancels the pause (the running turn is
3421
+ * left alone); from 'paused' it releases the blocked gate. Returns false
3422
+ * when there is nothing to resume.
3423
+ */
3424
+ requestResume(sessionId) {
3425
+ const state = this.getPauseState(sessionId);
3426
+ if (state === "pending") {
3427
+ this.transitionPauseState(sessionId, "none");
3428
+ return true;
3429
+ }
3430
+ if (state === "paused") {
3431
+ this.transitionPauseState(sessionId, "resuming");
3432
+ this.wakePauseWaiters(sessionId, "released");
3433
+ return true;
3434
+ }
3435
+ return false;
3436
+ }
3437
+ /**
3438
+ * Pause gate — call before each top-level LLM request. Resolves 'released'
3439
+ * when the request may proceed (no pause, or the user resumed) and 'aborted'
3440
+ * when the session was aborted while paused. Concurrent gates (parent +
3441
+ * sub-agent loops) all block on a single pause and all release on resume.
3442
+ */
3443
+ async enterPauseGate(sessionId, signal) {
3444
+ const state = this.getPauseState(sessionId);
3445
+ if (state === "none") {
3446
+ return "released";
3447
+ }
3448
+ if (state === "resuming") {
3449
+ this.transitionPauseState(sessionId, "none");
3450
+ return "released";
3451
+ }
3452
+ if (state === "pending") {
3453
+ this.transitionPauseState(sessionId, "paused");
3454
+ }
3455
+ const outcome = await new Promise((resolve9) => {
3456
+ let waiters = this.pauseWaiters.get(sessionId);
3457
+ if (!waiters) {
3458
+ waiters = /* @__PURE__ */ new Set();
3459
+ this.pauseWaiters.set(sessionId, waiters);
3460
+ }
3461
+ const onWake = (o) => {
3462
+ cleanup();
3463
+ resolve9(o);
3464
+ };
3465
+ const onAbort = () => {
3466
+ cleanup();
3467
+ resolve9("aborted");
3468
+ };
3469
+ const cleanup = () => {
3470
+ waiters.delete(onWake);
3471
+ signal?.removeEventListener("abort", onAbort);
3472
+ if (waiters.size === 0) {
3473
+ this.pauseWaiters.delete(sessionId);
3474
+ }
3475
+ };
3476
+ waiters.add(onWake);
3477
+ if (signal?.aborted) {
3478
+ cleanup();
3479
+ resolve9("aborted");
3480
+ return;
3481
+ }
3482
+ signal?.addEventListener("abort", onAbort, { once: true });
3483
+ });
3484
+ this.transitionPauseState(sessionId, "none");
3485
+ return outcome;
3486
+ }
3487
+ /**
3488
+ * Clear any pause state and wake blocked gates with 'aborted'. Used by the
3489
+ * stop/abort paths and session deletion so a paused gate never hangs.
3490
+ */
3491
+ clearPauseState(sessionId) {
3492
+ if (this.getPauseState(sessionId) !== "none") {
3493
+ this.transitionPauseState(sessionId, "none");
3494
+ }
3495
+ this.wakePauseWaiters(sessionId, "aborted");
3496
+ }
3497
+ transitionPauseState(sessionId, next) {
3498
+ if (this.getPauseState(sessionId) === next) {
3499
+ return;
3500
+ }
3501
+ logger.debug("Changing session pause state", { sessionId, from: this.getPauseState(sessionId), to: next });
3502
+ this.pauseStates.set(sessionId, next);
3503
+ this.emit({ type: "pause_changed", sessionId, pauseState: next });
3504
+ }
3505
+ wakePauseWaiters(sessionId, outcome) {
3506
+ const waiters = this.pauseWaiters.get(sessionId);
3507
+ if (!waiters) {
3508
+ return;
3509
+ }
3510
+ this.pauseWaiters.delete(sessionId);
3511
+ for (const wake of waiters) {
3512
+ try {
3513
+ wake(outcome);
3514
+ } catch (error) {
3515
+ logger.error("Pause waiter wake error", { sessionId, error });
3516
+ }
3517
+ }
3518
+ }
3379
3519
  /**
3380
3520
  * Set session provider/model. Updates DB directly.
3381
3521
  */
@@ -4371,6 +4511,7 @@ All file and git operations should use this directory.${commitHint}
4371
4511
  mode: dbSession.mode,
4372
4512
  phase: "plan",
4373
4513
  isRunning: dbSession.isRunning,
4514
+ pauseState: this.getPauseState(dbSession.id),
4374
4515
  messages: [],
4375
4516
  criteria: [],
4376
4517
  contextWindows: [],
@@ -4405,6 +4546,7 @@ All file and git operations should use this directory.${commitHint}
4405
4546
  mode: eventState.mode,
4406
4547
  phase: eventState.phase,
4407
4548
  isRunning,
4549
+ pauseState: this.getPauseState(dbSession.id),
4408
4550
  messages,
4409
4551
  criteria: eventState.criteria,
4410
4552
  metadataEntries: eventState.metadataEntries,
@@ -5139,6 +5281,7 @@ function buildSessionStatusPayload(sessionId, deps) {
5139
5281
  return {
5140
5282
  ...status,
5141
5283
  isRunning: session.isRunning,
5284
+ pauseState: session.pauseState ?? "none",
5142
5285
  pending: { questions: pendingQuestions, confirmations: pendingConfirmations },
5143
5286
  workflow: workflowPayload(activeExecution)
5144
5287
  };
@@ -7103,7 +7246,7 @@ function detectWsl() {
7103
7246
  // src/server/index.ts
7104
7247
  var __dirname3 = dirname7(fileURLToPath6(import.meta.url));
7105
7248
  async function announceContextDrift(sessionManager, sessionIds) {
7106
- const { injectContextDriftRemindersForSessions } = await import("./dynamic-context-RDBNQPPA.js");
7249
+ const { injectContextDriftRemindersForSessions } = await import("./dynamic-context-SKHOUP4T.js");
7107
7250
  await injectContextDriftRemindersForSessions(sessionManager, sessionIds);
7108
7251
  }
7109
7252
  async function createServerHandle(config3) {
@@ -7218,7 +7361,7 @@ async function createServerHandle(config3) {
7218
7361
  toolRegistry = createToolRegistry();
7219
7362
  logger.info("MCP tools registered", { count: mcpTools.length });
7220
7363
  }
7221
- const { signalMcpReady } = await import("./server-ZAPAB3FS.js");
7364
+ const { signalMcpReady } = await import("./server-AIRQGHHR.js");
7222
7365
  signalMcpReady();
7223
7366
  });
7224
7367
  const app = express();
@@ -7435,7 +7578,7 @@ async function createServerHandle(config3) {
7435
7578
  app.use("/api", sessionFavoriteRouter);
7436
7579
  const { createTasksService } = await import("./service-NKLQH647.js");
7437
7580
  const { registerTaskRoutes } = await import("./tasks-GPM3JAE6.js");
7438
- const { setTasksService } = await import("./tools-EJOABHVO.js");
7581
+ const { setTasksService } = await import("./tools-NIPKV4YY.js");
7439
7582
  const tasksService = createTasksService({
7440
7583
  sessionManager,
7441
7584
  config: config3,
@@ -7633,8 +7776,8 @@ All file and git operations should use this branch.
7633
7776
  res.json({ workspaces: workspacesList });
7634
7777
  });
7635
7778
  app.get("/api/sessions", async (req, res) => {
7636
- const { getRecentUserPromptsForSession } = await import("./events-YTYYT3PR.js");
7637
- const { getPendingConfirmationsBySession: getPendingConfirmationsBySession2 } = await import("./path-security-EC4Z2ZZG.js");
7779
+ const { getRecentUserPromptsForSession } = await import("./events-ADE2KEHI.js");
7780
+ const { getPendingConfirmationsBySession: getPendingConfirmationsBySession2 } = await import("./path-security-YP2MRJNS.js");
7638
7781
  const projectId = req.query["projectId"];
7639
7782
  const rawLimit = req.query["limit"];
7640
7783
  const offset = parseInt(req.query["offset"]) || 0;
@@ -7752,9 +7895,9 @@ All file and git operations should use this branch.
7752
7895
  }
7753
7896
  });
7754
7897
  app.get("/api/sessions/:id", async (req, res) => {
7755
- const { getEventStore: getEventStore2, combineEventsWithSnapshot: combineEventsWithSnapshot2 } = await import("./events-YTYYT3PR.js");
7756
- const { buildMessagesFromStoredEvents: buildMessagesFromStoredEvents2, foldPendingConfirmations } = await import("./folding-3MMOPS4W.js");
7757
- const { getPendingQuestionsForSession: getPendingQuestionsForSession2 } = await import("./tools-EJOABHVO.js");
7898
+ const { getEventStore: getEventStore2, combineEventsWithSnapshot: combineEventsWithSnapshot2 } = await import("./events-ADE2KEHI.js");
7899
+ const { buildMessagesFromStoredEvents: buildMessagesFromStoredEvents2, foldPendingConfirmations } = await import("./folding-CM63AVSB.js");
7900
+ const { getPendingQuestionsForSession: getPendingQuestionsForSession2 } = await import("./tools-NIPKV4YY.js");
7758
7901
  const { getMaxVisibleItems } = await import("./settings-WH6BVQCP.js");
7759
7902
  const session = sessionManager.getSession(req.params.id);
7760
7903
  if (!session) {
@@ -7783,9 +7926,9 @@ All file and git operations should use this branch.
7783
7926
  });
7784
7927
  app.get("/api/sessions/:id/status", async (req, res) => {
7785
7928
  const { projectSessionStatus: projectSessionStatus2 } = await import("./session-status-UFO5IFI7.js");
7786
- const { getPendingQuestionsForSession: getPendingQuestionsForSession2 } = await import("./tools-EJOABHVO.js");
7787
- const { getEventStore: getEventStore2, combineEventsWithSnapshot: combineEventsWithSnapshot2 } = await import("./events-YTYYT3PR.js");
7788
- const { foldPendingConfirmations } = await import("./folding-3MMOPS4W.js");
7929
+ const { getPendingQuestionsForSession: getPendingQuestionsForSession2 } = await import("./tools-NIPKV4YY.js");
7930
+ const { getEventStore: getEventStore2, combineEventsWithSnapshot: combineEventsWithSnapshot2 } = await import("./events-ADE2KEHI.js");
7931
+ const { foldPendingConfirmations } = await import("./folding-CM63AVSB.js");
7789
7932
  const sessionId = req.params["id"];
7790
7933
  if (!sessionId) {
7791
7934
  return res.status(400).json({ error: "Session id is required" });
@@ -7815,8 +7958,8 @@ All file and git operations should use this branch.
7815
7958
  if (!session) {
7816
7959
  return res.status(404).json({ error: "Session not found" });
7817
7960
  }
7818
- const { stopSessionExecution } = await import("./chat-handler-SYU4HJMI.js");
7819
- const { cancelQuestionsForSession, cancelPathConfirmationsForSession } = await import("./tools-EJOABHVO.js");
7961
+ const { stopSessionExecution } = await import("./chat-handler-AUB5HDQD.js");
7962
+ const { cancelQuestionsForSession, cancelPathConfirmationsForSession } = await import("./tools-NIPKV4YY.js");
7820
7963
  sessionManager.clearMessageQueue(sessionId);
7821
7964
  stopSessionExecution(sessionId, sessionManager);
7822
7965
  abortSession(sessionId);
@@ -7845,8 +7988,8 @@ All file and git operations should use this branch.
7845
7988
  res.json({ success: true });
7846
7989
  });
7847
7990
  app.post("/api/sessions/:id/provider", async (req, res) => {
7848
- const { getEventStore: getEventStore2, combineEventsWithSnapshot: combineEv } = await import("./events-YTYYT3PR.js");
7849
- const { buildMessagesFromStoredEvents: buildMessagesFromStoredEvents2 } = await import("./folding-3MMOPS4W.js");
7991
+ const { getEventStore: getEventStore2, combineEventsWithSnapshot: combineEv } = await import("./events-ADE2KEHI.js");
7992
+ const { buildMessagesFromStoredEvents: buildMessagesFromStoredEvents2 } = await import("./folding-CM63AVSB.js");
7850
7993
  const { getMaxVisibleItems } = await import("./settings-WH6BVQCP.js");
7851
7994
  const sessionId = req.params.id;
7852
7995
  const session = sessionManager.getSession(sessionId);
@@ -7876,8 +8019,8 @@ All file and git operations should use this branch.
7876
8019
  res.json({ session: toClientSession(updatedSession), messages, hiddenCount, contextState });
7877
8020
  });
7878
8021
  app.delete("/api/sessions/:id/provider", async (req, res) => {
7879
- const { getEventStore: getEventStore2, combineEventsWithSnapshot: combineEv } = await import("./events-YTYYT3PR.js");
7880
- const { buildMessagesFromStoredEvents: buildMessagesFromStoredEvents2 } = await import("./folding-3MMOPS4W.js");
8022
+ const { getEventStore: getEventStore2, combineEventsWithSnapshot: combineEv } = await import("./events-ADE2KEHI.js");
8023
+ const { buildMessagesFromStoredEvents: buildMessagesFromStoredEvents2 } = await import("./folding-CM63AVSB.js");
7881
8024
  const { getMaxVisibleItems } = await import("./settings-WH6BVQCP.js");
7882
8025
  const sessionId = req.params.id;
7883
8026
  const session = sessionManager.getSession(sessionId);
@@ -8010,8 +8153,8 @@ All file and git operations should use this branch.
8010
8153
  res.json({ success: true });
8011
8154
  });
8012
8155
  app.put("/api/sessions/:id/mode", async (req, res) => {
8013
- const { getEventStore: getEventStore2, combineEventsWithSnapshot: combineEv } = await import("./events-YTYYT3PR.js");
8014
- const { buildMessagesFromStoredEvents: buildMessagesFromStoredEvents2 } = await import("./folding-3MMOPS4W.js");
8156
+ const { getEventStore: getEventStore2, combineEventsWithSnapshot: combineEv } = await import("./events-ADE2KEHI.js");
8157
+ const { buildMessagesFromStoredEvents: buildMessagesFromStoredEvents2 } = await import("./folding-CM63AVSB.js");
8015
8158
  const { getMaxVisibleItems } = await import("./settings-WH6BVQCP.js");
8016
8159
  const sessionId = req.params.id;
8017
8160
  const session = sessionManager.getSession(sessionId);
@@ -8047,6 +8190,17 @@ All file and git operations should use this branch.
8047
8190
  return res.status(400).json({ error: 'dangerLevel is required and must be "normal" or "dangerous"' });
8048
8191
  }
8049
8192
  sessionManager.setDangerLevel(sessionId, dangerLevel);
8193
+ if (dangerLevel === "dangerous") {
8194
+ const { autoApprovePendingConfirmationsForSession } = await import("./tools-NIPKV4YY.js");
8195
+ const approvedCallIds = autoApprovePendingConfirmationsForSession(sessionId);
8196
+ for (const callId of approvedCallIds) {
8197
+ wssExports.broadcastForSession(sessionId, {
8198
+ type: "session.confirmation_resolved",
8199
+ sessionId,
8200
+ payload: { sessionId, callId }
8201
+ });
8202
+ }
8203
+ }
8050
8204
  const updatedSession = sessionManager.getSession(sessionId);
8051
8205
  res.json({ session: toClientSession(updatedSession) });
8052
8206
  });
@@ -8072,7 +8226,7 @@ All file and git operations should use this branch.
8072
8226
  setSessionDisabledServers(sessionId, disabledServers);
8073
8227
  const messages = session.messages ?? [];
8074
8228
  if (messages.length === 0) {
8075
- const { applyDynamicContext } = await import("./dynamic-context-RDBNQPPA.js");
8229
+ const { applyDynamicContext } = await import("./dynamic-context-SKHOUP4T.js");
8076
8230
  const modelName = session.providerModel ?? providerManager.getCurrentModel();
8077
8231
  await applyDynamicContext(sessionManager, sessionId, modelName);
8078
8232
  } else {
@@ -8106,7 +8260,7 @@ All file and git operations should use this branch.
8106
8260
  if (alwaysAllow !== void 0 && typeof alwaysAllow !== "boolean") {
8107
8261
  return res.status(400).json({ error: "alwaysAllow must be a boolean if provided" });
8108
8262
  }
8109
- const { providePathConfirmation: providePathConfirmation2, getConfirmationSessionId } = await import("./tools-EJOABHVO.js");
8263
+ const { providePathConfirmation: providePathConfirmation2, getConfirmationSessionId } = await import("./tools-NIPKV4YY.js");
8110
8264
  const pendingSessionId = getConfirmationSessionId(callId);
8111
8265
  if (!pendingSessionId) {
8112
8266
  return res.status(404).json({ error: "No pending path confirmation with that ID" });
@@ -8118,10 +8272,10 @@ All file and git operations should use this branch.
8118
8272
  if (!result.found) {
8119
8273
  return res.status(404).json({ error: "No pending path confirmation with that ID" });
8120
8274
  }
8121
- const { getEventStore: getEventStore2, combineEventsWithSnapshot: combineEvents } = await import("./events-YTYYT3PR.js");
8122
- const { buildMessagesFromStoredEvents: buildMessagesFromStoredEvents2, foldPendingConfirmations } = await import("./folding-3MMOPS4W.js");
8123
- const { createSessionStateMessage } = await import("./protocol-XO4ZROAU.js");
8124
- const { getPendingQuestionsForSession: getPendingQuestionsForSession2 } = await import("./tools-EJOABHVO.js");
8275
+ const { getEventStore: getEventStore2, combineEventsWithSnapshot: combineEvents } = await import("./events-ADE2KEHI.js");
8276
+ const { buildMessagesFromStoredEvents: buildMessagesFromStoredEvents2, foldPendingConfirmations } = await import("./folding-CM63AVSB.js");
8277
+ const { createSessionStateMessage } = await import("./protocol-MRMOB3P4.js");
8278
+ const { getPendingQuestionsForSession: getPendingQuestionsForSession2 } = await import("./tools-NIPKV4YY.js");
8125
8279
  const { getMaxVisibleItems } = await import("./settings-WH6BVQCP.js");
8126
8280
  const eventStore = getEventStore2();
8127
8281
  const { snapshot, events: eventsSinceSnapshot } = eventStore.getEventsSinceSnapshot(sessionId);
@@ -8159,7 +8313,7 @@ All file and git operations should use this branch.
8159
8313
  if (!skip && typeof answer !== "string") {
8160
8314
  return res.status(400).json({ error: "answer is required when not skipping" });
8161
8315
  }
8162
- const { provideAnswer: provideAnswer2 } = await import("./tools-EJOABHVO.js");
8316
+ const { provideAnswer: provideAnswer2 } = await import("./tools-NIPKV4YY.js");
8163
8317
  const found = provideAnswer2(callId, answer ?? "", skip ?? false);
8164
8318
  if (!found) {
8165
8319
  return res.status(404).json({ error: "No pending question with that ID" });
@@ -8225,7 +8379,7 @@ All file and git operations should use this branch.
8225
8379
  backend: activeProvider?.backend ?? llmClient.getBackend(),
8226
8380
  model: llmClient.getModel()
8227
8381
  };
8228
- const { runAgentTurn, TurnMetrics } = await import("./orchestrator-6QGQ55NT.js");
8382
+ const { runAgentTurn, TurnMetrics } = await import("./orchestrator-KRHMAVBN.js");
8229
8383
  runAgentTurn(
8230
8384
  {
8231
8385
  sessionManager,
@@ -8263,18 +8417,45 @@ All file and git operations should use this branch.
8263
8417
  if (!session) {
8264
8418
  return res.status(404).json({ error: "Session not found" });
8265
8419
  }
8266
- const { stopSessionExecution } = await import("./chat-handler-SYU4HJMI.js");
8267
- const { cancelQuestionsForSession, cancelPathConfirmationsForSession } = await import("./tools-EJOABHVO.js");
8420
+ const { stopSessionExecution } = await import("./chat-handler-AUB5HDQD.js");
8421
+ const { cancelQuestionsForSession, cancelPathConfirmationsForSession } = await import("./tools-NIPKV4YY.js");
8268
8422
  const queuedMessages = sessionManager.getQueueState(sessionId);
8269
8423
  sessionManager.clearMessageQueue(sessionId);
8270
8424
  stopSessionExecution(sessionId, sessionManager);
8271
8425
  abortSession(sessionId);
8272
8426
  cancelQuestionsForSession(sessionId, "Session stopped by user");
8273
8427
  cancelPathConfirmationsForSession(sessionId, "Session stopped by user");
8274
- const eventStore = (await import("./events-YTYYT3PR.js")).getEventStore();
8428
+ const eventStore = (await import("./events-ADE2KEHI.js")).getEventStore();
8275
8429
  eventStore.append(sessionId, { type: "running.changed", data: { isRunning: false } });
8276
8430
  res.json({ success: true, queuedMessages });
8277
8431
  });
8432
+ app.post("/api/sessions/:id/pause", async (req, res) => {
8433
+ const sessionId = req.params.id;
8434
+ const session = sessionManager.getSession(sessionId);
8435
+ if (!session) {
8436
+ return res.status(404).json({ error: "Session not found" });
8437
+ }
8438
+ if (!session.isRunning) {
8439
+ return res.status(409).json({ error: "Session is not running" });
8440
+ }
8441
+ const ok2 = sessionManager.requestPause(sessionId);
8442
+ if (!ok2) {
8443
+ return res.status(409).json({ error: "A pause is already in progress" });
8444
+ }
8445
+ res.json({ success: true, pauseState: sessionManager.getPauseState(sessionId) });
8446
+ });
8447
+ app.post("/api/sessions/:id/resume", async (req, res) => {
8448
+ const sessionId = req.params.id;
8449
+ const session = sessionManager.getSession(sessionId);
8450
+ if (!session) {
8451
+ return res.status(404).json({ error: "Session not found" });
8452
+ }
8453
+ const ok2 = sessionManager.requestResume(sessionId);
8454
+ if (!ok2) {
8455
+ return res.status(409).json({ error: "Nothing to resume" });
8456
+ }
8457
+ res.json({ success: true, pauseState: sessionManager.getPauseState(sessionId) });
8458
+ });
8278
8459
  app.post("/api/sessions/:id/truncate", async (req, res) => {
8279
8460
  const sessionId = req.params.id;
8280
8461
  const session = sessionManager.getSession(sessionId);
@@ -8285,7 +8466,7 @@ All file and git operations should use this branch.
8285
8466
  if (typeof messageIndex !== "number" || messageIndex < 0) {
8286
8467
  return res.status(400).json({ error: "messageIndex must be a non-negative number" });
8287
8468
  }
8288
- const { truncateSessionMessages } = await import("./events-YTYYT3PR.js");
8469
+ const { truncateSessionMessages } = await import("./events-ADE2KEHI.js");
8289
8470
  truncateSessionMessages(sessionId, messageIndex);
8290
8471
  res.json({ success: true });
8291
8472
  });
@@ -8305,8 +8486,8 @@ All file and git operations should use this branch.
8305
8486
  if (attachments !== void 0 && !Array.isArray(attachments)) {
8306
8487
  return res.status(400).json({ error: "attachments must be an array if provided" });
8307
8488
  }
8308
- const { getEventStore: getEventStore2 } = await import("./events-YTYYT3PR.js");
8309
- const { buildMessagesFromStoredEvents: buildMessagesFromStoredEvents2 } = await import("./folding-3MMOPS4W.js");
8489
+ const { getEventStore: getEventStore2 } = await import("./events-ADE2KEHI.js");
8490
+ const { buildMessagesFromStoredEvents: buildMessagesFromStoredEvents2 } = await import("./folding-CM63AVSB.js");
8310
8491
  const eventStore = getEventStore2();
8311
8492
  const events = eventStore.getEvents(sessionId);
8312
8493
  const { messages } = buildMessagesFromStoredEvents2(events);
@@ -8318,7 +8499,7 @@ All file and git operations should use this branch.
8318
8499
  if (msg.role !== "user" || msg.isSystemGenerated) {
8319
8500
  return res.status(400).json({ error: "Can only replay user messages" });
8320
8501
  }
8321
- const { truncateSessionMessages } = await import("./events-YTYYT3PR.js");
8502
+ const { truncateSessionMessages } = await import("./events-ADE2KEHI.js");
8322
8503
  truncateSessionMessages(sessionId, msgIndex - 1);
8323
8504
  sessionManager.queueMessage(
8324
8505
  sessionId,
@@ -8360,7 +8541,7 @@ All file and git operations should use this branch.
8360
8541
  return res.status(404).json({ error: "Session not found" });
8361
8542
  }
8362
8543
  try {
8363
- const { buildSessionExport } = await import("./export-import-GHRCOQHF.js");
8544
+ const { buildSessionExport } = await import("./export-import-SC3UW22Z.js");
8364
8545
  const payload = buildSessionExport(sessionManager, sessionId);
8365
8546
  const filename = `${(payload.session.title ?? "session").replace(/[^a-zA-Z0-9-_]/g, "_")}.openfox-session.json`;
8366
8547
  res.setHeader("Content-Disposition", `attachment; filename="${filename}"`);
@@ -9183,7 +9364,7 @@ All file and git operations should use this branch.
9183
9364
  });
9184
9365
  async function rebuildMcpTools() {
9185
9366
  const { createMcpTools: createMcpTools2 } = await import("./tool-adapter-ZY4FC4C4.js");
9186
- const { setMcpTools: setMcpTools2 } = await import("./tools-EJOABHVO.js");
9367
+ const { setMcpTools: setMcpTools2 } = await import("./tools-NIPKV4YY.js");
9187
9368
  const mcpTools = createMcpTools2(mcpManager);
9188
9369
  setMcpTools2(mcpTools);
9189
9370
  toolRegistry = createToolRegistry();
@@ -9759,7 +9940,7 @@ All file and git operations should use this branch.
9759
9940
  );
9760
9941
  const wss = wssExports.wss;
9761
9942
  deferTasksBroadcast = (projectId, payload) => wssExports.broadcastForProject(projectId, "", { type: "tasks.update", payload });
9762
- const { launchWorkflowRun, abortRunnerRun } = await import("./launch-YZ46OEFP.js");
9943
+ const { launchWorkflowRun, abortRunnerRun } = await import("./launch-PTMPNZEN.js");
9763
9944
  deferTasksLaunchWorkflow = (sessionId, launch) => {
9764
9945
  const effective = sessionManager.resolveEffectiveProviderModel(sessionId);
9765
9946
  let llmClient = getLLMClient();
@@ -9804,7 +9985,7 @@ All file and git operations should use this branch.
9804
9985
  const state = sessionManager.getContextState(sessionId);
9805
9986
  wssExports.broadcastForSession(sessionId, createContextStateMessage(state));
9806
9987
  });
9807
- const { QueueProcessor } = await import("./processor-B2RV7MVC.js");
9988
+ const { QueueProcessor } = await import("./processor-QZOGF5ES.js");
9808
9989
  const queueProcessor = new QueueProcessor({
9809
9990
  sessionManager,
9810
9991
  providerManager,
@@ -9846,8 +10027,8 @@ All file and git operations should use this branch.
9846
10027
  launchWorkflow: (sessionId, launch) => deferTasksLaunchWorkflow(sessionId, launch),
9847
10028
  stopSession: (sessionId) => {
9848
10029
  void (async () => {
9849
- const { stopSessionExecution } = await import("./chat-handler-SYU4HJMI.js");
9850
- const { cancelQuestionsForSession, cancelPathConfirmationsForSession } = await import("./tools-EJOABHVO.js");
10030
+ const { stopSessionExecution } = await import("./chat-handler-AUB5HDQD.js");
10031
+ const { cancelQuestionsForSession, cancelPathConfirmationsForSession } = await import("./tools-NIPKV4YY.js");
9851
10032
  sessionManager.clearMessageQueue(sessionId);
9852
10033
  stopSessionExecution(sessionId, sessionManager);
9853
10034
  abortSession(sessionId);
@@ -9968,4 +10149,4 @@ export {
9968
10149
  createServerHandle,
9969
10150
  createServer
9970
10151
  };
9971
- //# sourceMappingURL=chunk-QQQBNL7A.js.map
10152
+ //# sourceMappingURL=chunk-HI25RCRW.js.map