nolo-cli 0.185.0-alpha.3 → 0.186.0-alpha.1

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 (62) hide show
  1. package/{_executeModel-5SGPPCT6.js → _executeModel-35LFG5KF.js} +12 -12
  2. package/{agentDeleteCommand-RUBWHUMZ.js → agentDeleteCommand-TMFQR6QL.js} +11 -11
  3. package/{agentEmailCommands-RXCDWZDW.js → agentEmailCommands-JZ6GYJ4H.js} +13 -13
  4. package/{agentListCommands-PRG4ZBJC.js → agentListCommands-PFZRMIAI.js} +2 -2
  5. package/{agentMachineCommands-SPQ3CCYU.js → agentMachineCommands-BT643ADE.js} +3 -3
  6. package/{agentRecordCommands-AKAQ7BRK.js → agentRecordCommands-LJ5EWR67.js} +12 -12
  7. package/{agentRunCommand-S3VSGTS4.js → agentRunCommand-6CPXONR3.js} +14 -14
  8. package/{agentRuntimeLocal-CBDP2OYK.js → agentRuntimeLocal-3QBUFZEC.js} +2 -2
  9. package/{agentSlice-2PEJP3NV.js → agentSlice-RW25WUPR.js} +1 -1
  10. package/{appDeleteCommands-OP4GGXEJ.js → appDeleteCommands-WEBDQMVH.js} +2 -2
  11. package/{appDeployCommands-LHTVLNL5.js → appDeployCommands-HFZ3I7Z4.js} +2 -2
  12. package/{appDeployStatusCommands-BSDDQU7S.js → appDeployStatusCommands-TVBQOFIY.js} +2 -2
  13. package/{appGetCommands-LNHGUJKF.js → appGetCommands-Y5RKR25C.js} +2 -2
  14. package/{appListCommands-RGOFZV5M.js → appListCommands-4UZIZPB3.js} +2 -2
  15. package/{chunk-D4JCY67U.js → chunk-37ZDGCX6.js} +10 -9
  16. package/{chunk-IOQHM7ID.js → chunk-4ALQFIFF.js} +720 -92
  17. package/{chunk-VXCDYN6M.js → chunk-4GZ2LY5F.js} +12 -8
  18. package/{chunk-MIPGIRJJ.js → chunk-6HFMPUSN.js} +2 -2
  19. package/{chunk-AU7AXHUL.js → chunk-7KWPNGVJ.js} +57 -21
  20. package/{chunk-7DPEOMDL.js → chunk-BRBG72OP.js} +7 -7
  21. package/{chunk-DWTNJZ63.js → chunk-CDUK5BF6.js} +2 -2
  22. package/{chunk-YXTQJ2QR.js → chunk-DK7QNJVM.js} +2 -2
  23. package/{chunk-BJPALUYR.js → chunk-ECAGROXS.js} +2 -2
  24. package/{chunk-M4JDIVIS.js → chunk-IOB5RBBZ.js} +1 -1
  25. package/{chunk-JJU5FBYH.js → chunk-J5Y3BXJP.js} +124 -22
  26. package/{chunk-HRLKX6YP.js → chunk-PEOLOK72.js} +1 -1
  27. package/{chunk-WVIBJBDF.js → chunk-PL6YNOF7.js} +10 -10
  28. package/chunk-Q6RMLYSA.js +385 -0
  29. package/{chunk-CN6T5QKA.js → chunk-QBMO66MI.js} +3 -3
  30. package/{chunk-NCC2SYOD.js → chunk-SIX7N4AH.js} +2 -2
  31. package/{chunk-ZYI6K46I.js → chunk-TB7E6UEO.js} +1 -1
  32. package/{chunk-DBEIHUCJ.js → chunk-VMMS7L64.js} +3 -3
  33. package/{chunk-7YW5OUQE.js → chunk-XJECR5M3.js} +2 -2
  34. package/{chunk-ZU2BF6Q4.js → chunk-ZV6ESGA7.js} +2 -2
  35. package/{chunk-MROMTEHV.js → chunk-ZXUPGFJ5.js} +6 -6
  36. package/{commandRegistry-OTD2XOHY.js → commandRegistry-6EEZMM43.js} +40 -40
  37. package/{contentThunks-BSCTL5G3.js → contentThunks-EPHFLF62.js} +3 -3
  38. package/{createAgentAutomationAction-Y5W2FW3Y.js → createAgentAutomationAction-MFE4QIL4.js} +3 -3
  39. package/{createDialogAction-GIZ7QCRQ.js → createDialogAction-SGOXQ7BC.js} +4 -4
  40. package/{createPageAction-GFH4DXMX.js → createPageAction-OTNUT7WI.js} +3 -3
  41. package/{dialogCommands-6MR232CJ.js → dialogCommands-KNE72SUM.js} +2 -2
  42. package/{dialogSlice-U3X3CBR7.js → dialogSlice-PHPLFD5F.js} +2 -2
  43. package/{docCreateCommands-DAZJ2Y5E.js → docCreateCommands-MG67RHCR.js} +2 -2
  44. package/{docDeleteCommands-XO26LNIO.js → docDeleteCommands-2UAG5JVZ.js} +2 -2
  45. package/{docReadCommands-77XGRLD6.js → docReadCommands-JKJJ4FNU.js} +2 -2
  46. package/{docStore-H2XCYODR.js → docStore-HI7P3MVA.js} +1 -1
  47. package/{docUpdateCommands-QXN3MJAJ.js → docUpdateCommands-6D7ADVPS.js} +2 -2
  48. package/{handleSendMessageAction-MZKFIPYL.js → handleSendMessageAction-YAO4RDWU.js} +8 -8
  49. package/index.js +3 -3
  50. package/{localRuntimeAdapter-E2QDYFTW.js → localRuntimeAdapter-4J62I4YU.js} +11 -11
  51. package/{machineCommands-SQELO6HH.js → machineCommands-XW5I55QW.js} +12 -12
  52. package/{machineWsRunDispatch-E33LUXWG.js → machineWsRunDispatch-W5VEHHMI.js} +12 -12
  53. package/package.json +1 -1
  54. package/{readlineWorkspace-B2MGBCUY.js → readlineWorkspace-EE6JMRIW.js} +14 -14
  55. package/{runAgentClientLoop-JRW5EA5U.js → runAgentClientLoop-BU6GOWQI.js} +10 -10
  56. package/skillDiscovery-F3TMVQOJ.js +28 -0
  57. package/{spaceCommands-PHLKQ2AW.js → spaceCommands-GTQQ6GFS.js} +2 -2
  58. package/{streamAgentChatTurn-CBGAGRQL.js → streamAgentChatTurn-MHRXV7XZ.js} +13 -13
  59. package/{tools-RVVZ2Y6V.js → tools-YA5NIWI7.js} +7 -7
  60. package/{updateDialogTitleAction-2RKLYUPB.js → updateDialogTitleAction-M6U2VK5L.js} +3 -3
  61. package/chunk-VEA7H5FG.js +0 -173
  62. package/skillDiscovery-QC35EQY4.js +0 -18
@@ -185,7 +185,7 @@ import {
185
185
  } from "./chunk-ZWQUWF6W.js";
186
186
  import {
187
187
  buildDialogSummaryLayer
188
- } from "./chunk-VEA7H5FG.js";
188
+ } from "./chunk-Q6RMLYSA.js";
189
189
  import {
190
190
  buildUserResponseLanguageContext
191
191
  } from "./chunk-4VJAC32I.js";
@@ -5222,8 +5222,8 @@ var runPromiseExitWith = (context3) => {
5222
5222
  const runFork3 = runForkWith(context3);
5223
5223
  return (effect, options) => {
5224
5224
  const fiber3 = runFork3(effect, options);
5225
- return new Promise((resolve6) => {
5226
- fiber3.addObserver((exit3) => resolve6(exit3));
5225
+ return new Promise((resolve7) => {
5226
+ fiber3.addObserver((exit3) => resolve7(exit3));
5227
5227
  });
5228
5228
  };
5229
5229
  };
@@ -5340,8 +5340,8 @@ var Latch = class {
5340
5340
  return this._isOpen;
5341
5341
  }
5342
5342
  };
5343
- var makeLatchUnsafe = (open) => new Latch(open ?? false);
5344
- var makeLatch = (open) => sync(() => makeLatchUnsafe(open));
5343
+ var makeLatchUnsafe = (open2) => new Latch(open2 ?? false);
5344
+ var makeLatch = (open2) => sync(() => makeLatchUnsafe(open2));
5345
5345
  var tracer = /* @__PURE__ */ withFiber((fiber3) => succeed3(fiber3.getRef(Tracer)));
5346
5346
  var withTracer = /* @__PURE__ */ dual(2, (effect, tracer3) => provideService(effect, Tracer, tracer3));
5347
5347
  var withTracerEnabled = /* @__PURE__ */ provideService(TracerEnabled);
@@ -12209,8 +12209,8 @@ var toReadableStreamWith = /* @__PURE__ */ dual((args2) => isStream(args2[0]), (
12209
12209
  });
12210
12210
  },
12211
12211
  pull() {
12212
- return new Promise((resolve6) => {
12213
- currentResolve = resolve6;
12212
+ return new Promise((resolve7) => {
12213
+ currentResolve = resolve7;
12214
12214
  latch.openUnsafe();
12215
12215
  });
12216
12216
  },
@@ -12357,16 +12357,79 @@ function runAbortableWithTimeout(args2) {
12357
12357
 
12358
12358
  // packages/agent-runtime/observationStream.ts
12359
12359
  var DEFAULT_OBSERVATION_QUEUE_CAPACITY = 1024;
12360
+ var DEFAULT_OBSERVATION_QUEUE_BYTE_CAPACITY = 2 * 1024 * 1024;
12361
+ var OBSERVATION_EVENT_BYTE_FALLBACK = 1024;
12362
+ var UTF8_ENCODER = typeof TextEncoder !== "undefined" ? new TextEncoder() : void 0;
12363
+ var observeByteLength = (text2) => {
12364
+ const nodeBuffer = globalThis.Buffer;
12365
+ if (typeof nodeBuffer?.byteLength === "function") {
12366
+ return nodeBuffer.byteLength(text2, "utf8");
12367
+ }
12368
+ if (UTF8_ENCODER) {
12369
+ return UTF8_ENCODER.encode(text2).byteLength;
12370
+ }
12371
+ return text2.length;
12372
+ };
12373
+ var measureObservationEventBytes = (event) => {
12374
+ try {
12375
+ const serialized = JSON.stringify(event);
12376
+ return typeof serialized === "string" ? observeByteLength(serialized) : OBSERVATION_EVENT_BYTE_FALLBACK;
12377
+ } catch {
12378
+ return OBSERVATION_EVENT_BYTE_FALLBACK;
12379
+ }
12380
+ };
12381
+ var resolveByteCapacity = (raw) => {
12382
+ if (raw === null) return null;
12383
+ if (raw === void 0) return DEFAULT_OBSERVATION_QUEUE_BYTE_CAPACITY;
12384
+ if (typeof raw !== "number" || !Number.isFinite(raw) || raw <= 0) {
12385
+ return DEFAULT_OBSERVATION_QUEUE_BYTE_CAPACITY;
12386
+ }
12387
+ return Math.floor(raw);
12388
+ };
12360
12389
  function createLocalLoopObservationBoundary(initialCallbacks, options) {
12361
12390
  const rawCapacity = options?.capacity;
12362
12391
  const capacity = typeof rawCapacity === "number" && Number.isFinite(rawCapacity) && rawCapacity >= 1 ? Math.floor(rawCapacity) : DEFAULT_OBSERVATION_QUEUE_CAPACITY;
12363
12392
  const strategy = options?.strategy ?? "sliding";
12393
+ const byteCapacity = strategy === "unbounded" ? null : resolveByteCapacity(options?.byteCapacity);
12394
+ const byteBudgetEnabled = byteCapacity !== null;
12364
12395
  let queue;
12365
12396
  let cachedStream;
12366
12397
  let closed = false;
12367
12398
  let totalEmitted = 0;
12368
12399
  let dropped = 0;
12369
12400
  let peakSize = 0;
12401
+ const shadowSizes = [];
12402
+ let shadowHead = 0;
12403
+ let bufferedBytes = 0;
12404
+ let peakBytes = 0;
12405
+ let droppedByBytesCount = 0;
12406
+ const shadowLength = () => shadowSizes.length - shadowHead;
12407
+ const compactShadow = () => {
12408
+ if (shadowHead > 0 && shadowHead * 2 >= shadowSizes.length) {
12409
+ shadowSizes.splice(0, shadowHead);
12410
+ shadowHead = 0;
12411
+ }
12412
+ };
12413
+ const syncShadow = (activeQueue) => {
12414
+ const liveSize = Queue_exports.sizeUnsafe(activeQueue);
12415
+ while (shadowLength() > liveSize) {
12416
+ bufferedBytes -= shadowSizes[shadowHead++] ?? 0;
12417
+ }
12418
+ if (bufferedBytes < 0) bufferedBytes = 0;
12419
+ compactShadow();
12420
+ return liveSize;
12421
+ };
12422
+ const evictOldestForBytes = (activeQueue, incomingBytes) => {
12423
+ if (byteCapacity === null) return;
12424
+ while (shadowLength() > 0 && bufferedBytes + incomingBytes > byteCapacity) {
12425
+ const taken = Queue_exports.takeUnsafe(activeQueue);
12426
+ if (taken === void 0 || !Exit_exports.isSuccess(taken)) break;
12427
+ bufferedBytes -= shadowSizes[shadowHead++] ?? 0;
12428
+ droppedByBytesCount++;
12429
+ }
12430
+ if (bufferedBytes < 0) bufferedBytes = 0;
12431
+ compactShadow();
12432
+ };
12370
12433
  const callbackList = [];
12371
12434
  if (initialCallbacks) {
12372
12435
  callbackList.push(initialCallbacks);
@@ -12395,13 +12458,27 @@ function createLocalLoopObservationBoundary(initialCallbacks, options) {
12395
12458
  const envelope = "event" in envelopeOrEvent && typeof envelopeOrEvent.event === "object" && envelopeOrEvent.event !== null && "kind" in envelopeOrEvent.event ? envelopeOrEvent : { event: envelopeOrEvent };
12396
12459
  const { event, bridge } = envelope;
12397
12460
  if (queue) {
12398
- const preSize = Queue_exports.sizeUnsafe(queue) ?? 0;
12399
- const offered = Queue_exports.offerUnsafe(queue, event);
12400
- if (strategy === "dropping" && !offered) {
12461
+ const eventBytes = byteBudgetEnabled ? measureObservationEventBytes(event) : 0;
12462
+ const liveSize = syncShadow(queue);
12463
+ const rejectedByBytes = strategy === "dropping" && liveSize > 0 && byteCapacity !== null ? bufferedBytes + eventBytes > byteCapacity : false;
12464
+ if (strategy === "sliding" && byteBudgetEnabled) {
12465
+ evictOldestForBytes(queue, eventBytes);
12466
+ }
12467
+ const preSize = Queue_exports.sizeUnsafe(queue);
12468
+ const offered = rejectedByBytes ? false : Queue_exports.offerUnsafe(queue, event);
12469
+ if (offered) {
12470
+ shadowSizes.push(eventBytes);
12471
+ bufferedBytes += eventBytes;
12472
+ if (bufferedBytes > peakBytes) peakBytes = bufferedBytes;
12473
+ }
12474
+ if (rejectedByBytes) {
12475
+ droppedByBytesCount++;
12476
+ } else if (strategy === "dropping" && !offered) {
12401
12477
  dropped++;
12402
12478
  } else if (strategy === "sliding" && preSize >= capacity && offered) {
12403
12479
  dropped++;
12404
12480
  }
12481
+ syncShadow(queue);
12405
12482
  const postSize = Queue_exports.sizeUnsafe(queue) ?? 0;
12406
12483
  if (postSize > peakSize) {
12407
12484
  peakSize = postSize;
@@ -12444,9 +12521,10 @@ function createLocalLoopObservationBoundary(initialCallbacks, options) {
12444
12521
  const close2 = () => {
12445
12522
  if (closed) return;
12446
12523
  closed = true;
12447
- if (dropped > 0) {
12524
+ const totalDropped = dropped + droppedByBytesCount;
12525
+ if (totalDropped > 0) {
12448
12526
  console.warn(
12449
- `[observationStream] stream buffer overflow: dropped ${dropped}/${totalEmitted} events (strategy=${strategy}, capacity=${capacity})`
12527
+ `[observationStream] stream buffer overflow: dropped ${totalDropped}/${totalEmitted} events (strategy=${strategy}, capacity=${capacity}, byteCapacity=${byteCapacity ?? "off"}, droppedByCount=${dropped}, droppedByBytes=${droppedByBytesCount}, peakBytes=${peakBytes})`
12450
12528
  );
12451
12529
  }
12452
12530
  if (queue) {
@@ -12463,14 +12541,26 @@ function createLocalLoopObservationBoundary(initialCallbacks, options) {
12463
12541
  if (!queue) return 0;
12464
12542
  return Queue_exports.sizeUnsafe(queue) ?? 0;
12465
12543
  };
12466
- const droppedCount = () => dropped;
12544
+ const droppedCount = () => dropped + droppedByBytesCount;
12545
+ const bufferedBytesOfQueue = () => {
12546
+ if (!queue) return 0;
12547
+ syncShadow(queue);
12548
+ return bufferedBytes;
12549
+ };
12550
+ const droppedByBytes = () => droppedByBytesCount;
12467
12551
  const getMetrics = () => ({
12468
12552
  totalEmitted,
12469
- droppedCount: dropped,
12553
+ droppedCount: dropped + droppedByBytesCount,
12470
12554
  peakSize,
12471
12555
  capacity,
12472
12556
  strategy
12473
12557
  });
12558
+ const getByteMetrics = () => ({
12559
+ byteCapacity,
12560
+ bufferedBytes: bufferedBytesOfQueue(),
12561
+ peakBytes,
12562
+ droppedByBytes: droppedByBytesCount
12563
+ });
12474
12564
  return {
12475
12565
  get queue() {
12476
12566
  return getOrCreateQueue();
@@ -12487,8 +12577,11 @@ function createLocalLoopObservationBoundary(initialCallbacks, options) {
12487
12577
  attachCallbacks,
12488
12578
  isQueueActive,
12489
12579
  queueSize,
12580
+ bufferedBytes: bufferedBytesOfQueue,
12490
12581
  droppedCount,
12491
- getMetrics
12582
+ droppedByBytes,
12583
+ getMetrics,
12584
+ getByteMetrics
12492
12585
  };
12493
12586
  }
12494
12587
 
@@ -12864,6 +12957,144 @@ function scrubObjectSecrets(val) {
12864
12957
  return val;
12865
12958
  }
12866
12959
 
12960
+ // packages/agent-runtime/toolOutputSanitizer.ts
12961
+ var SANITIZE_REPLACEMENT_CHAR = "\uFFFD";
12962
+ var MAX_CONTROL_SEQUENCE_CHARS = 256;
12963
+ var ESC = 27;
12964
+ var BEL = 7;
12965
+ var LINE_FEED = 10;
12966
+ var TAB = 9;
12967
+ var DEL = 127;
12968
+ var C1_DCS = 144;
12969
+ var C1_SOS = 152;
12970
+ var C1_CSI = 155;
12971
+ var C1_ST = 156;
12972
+ var C1_OSC = 157;
12973
+ var C1_PM = 158;
12974
+ var C1_APC = 159;
12975
+ var HIGH_SURROGATE_MIN = 55296;
12976
+ var HIGH_SURROGATE_MAX = 56319;
12977
+ var LOW_SURROGATE_MIN = 56320;
12978
+ var LOW_SURROGATE_MAX = 57343;
12979
+ var NEEDS_SANITIZE_RE = new RegExp("[\\u0000-\\u0008\\u000b-\\u001f\\u007f-\\u009f]|\\p{Cs}", "u");
12980
+ function isC1Introducer(code) {
12981
+ return code === C1_CSI || code === C1_OSC || code === C1_DCS || code === C1_SOS || code === C1_PM || code === C1_APC;
12982
+ }
12983
+ var UNTERMINATED_SEQUENCE = -1;
12984
+ function skipCsiBody(text2, start, limit) {
12985
+ let i = start;
12986
+ while (i < limit) {
12987
+ const code = text2.charCodeAt(i);
12988
+ if (code >= 64 && code <= 126) return i + 1;
12989
+ if (code >= 32 && code <= 63) {
12990
+ i += 1;
12991
+ continue;
12992
+ }
12993
+ return i;
12994
+ }
12995
+ return UNTERMINATED_SEQUENCE;
12996
+ }
12997
+ function skipControlStringBody(text2, start, limit) {
12998
+ const length = text2.length;
12999
+ let i = start;
13000
+ while (i < limit) {
13001
+ const code = text2.charCodeAt(i);
13002
+ if (code === BEL || code === C1_ST) return i + 1;
13003
+ if (code === ESC && i + 1 < length && text2.charCodeAt(i + 1) === 92) {
13004
+ return Math.min(i + 2, limit);
13005
+ }
13006
+ i += 1;
13007
+ }
13008
+ return UNTERMINATED_SEQUENCE;
13009
+ }
13010
+ function skipEscapeSequence(text2, escIndex) {
13011
+ const length = text2.length;
13012
+ const limit = Math.min(length, escIndex + MAX_CONTROL_SEQUENCE_CHARS);
13013
+ const leadIndex = escIndex + 1;
13014
+ if (leadIndex >= length) return leadIndex;
13015
+ const lead = text2.charCodeAt(leadIndex);
13016
+ if (lead === 91) {
13017
+ const csiEnd = skipCsiBody(text2, leadIndex + 1, limit);
13018
+ return csiEnd === UNTERMINATED_SEQUENCE ? escIndex + 1 : csiEnd;
13019
+ }
13020
+ if (lead === 93 || lead === 80 || lead === 88 || lead === 94 || lead === 95) {
13021
+ const stringEnd = skipControlStringBody(text2, leadIndex + 1, limit);
13022
+ return stringEnd === UNTERMINATED_SEQUENCE ? escIndex + 1 : stringEnd;
13023
+ }
13024
+ let j = leadIndex;
13025
+ while (j < limit && text2.charCodeAt(j) >= 32 && text2.charCodeAt(j) <= 47) {
13026
+ j += 1;
13027
+ }
13028
+ if (j < limit) {
13029
+ const final = text2.charCodeAt(j);
13030
+ if (final >= 48 && final <= 126) return j + 1;
13031
+ }
13032
+ return escIndex + 1;
13033
+ }
13034
+ function skipC1Sequence(text2, index) {
13035
+ const limit = Math.min(text2.length, index + MAX_CONTROL_SEQUENCE_CHARS);
13036
+ const code = text2.charCodeAt(index);
13037
+ const bodyEnd = code === C1_CSI ? skipCsiBody(text2, index + 1, limit) : skipControlStringBody(text2, index + 1, limit);
13038
+ return bodyEnd === UNTERMINATED_SEQUENCE ? index + 1 : bodyEnd;
13039
+ }
13040
+ function sanitizeToolOutputText(text2) {
13041
+ if (typeof text2 !== "string" || text2.length === 0) return text2;
13042
+ if (!NEEDS_SANITIZE_RE.test(text2)) return text2;
13043
+ const out = [];
13044
+ const length = text2.length;
13045
+ let plainStart = 0;
13046
+ let i = 0;
13047
+ const dropRange = (end3) => {
13048
+ if (plainStart < i) out.push(text2.slice(plainStart, i));
13049
+ i = end3;
13050
+ plainStart = end3;
13051
+ };
13052
+ while (i < length) {
13053
+ const code = text2.charCodeAt(i);
13054
+ if (code === LINE_FEED || code === TAB) {
13055
+ i += 1;
13056
+ continue;
13057
+ }
13058
+ if (code === ESC) {
13059
+ dropRange(skipEscapeSequence(text2, i));
13060
+ continue;
13061
+ }
13062
+ if (isC1Introducer(code)) {
13063
+ dropRange(skipC1Sequence(text2, i));
13064
+ continue;
13065
+ }
13066
+ if (code < 32 || code === DEL || code >= 128 && code <= 159) {
13067
+ dropRange(i + 1);
13068
+ continue;
13069
+ }
13070
+ if (code >= HIGH_SURROGATE_MIN && code <= HIGH_SURROGATE_MAX) {
13071
+ const low = text2.charCodeAt(i + 1);
13072
+ if (low >= LOW_SURROGATE_MIN && low <= LOW_SURROGATE_MAX) {
13073
+ i += 2;
13074
+ continue;
13075
+ }
13076
+ if (plainStart < i) out.push(text2.slice(plainStart, i));
13077
+ out.push(SANITIZE_REPLACEMENT_CHAR);
13078
+ i += 1;
13079
+ plainStart = i;
13080
+ continue;
13081
+ }
13082
+ if (code >= LOW_SURROGATE_MIN && code <= LOW_SURROGATE_MAX) {
13083
+ if (plainStart < i) out.push(text2.slice(plainStart, i));
13084
+ out.push(SANITIZE_REPLACEMENT_CHAR);
13085
+ i += 1;
13086
+ plainStart = i;
13087
+ continue;
13088
+ }
13089
+ i += 1;
13090
+ }
13091
+ if (plainStart < length) out.push(text2.slice(plainStart));
13092
+ return out.join("");
13093
+ }
13094
+ function sanitizeToolOutputContent(content) {
13095
+ return typeof content === "string" ? sanitizeToolOutputText(content) : content;
13096
+ }
13097
+
12867
13098
  // packages/agent-runtime/providerMessageProjection.ts
12868
13099
  var TOOL_DURATION_METADATA_KEY = "toolExecMs";
12869
13100
  var OBSERVATION_ONLY_METADATA_KEYS = /* @__PURE__ */ new Set([
@@ -12871,7 +13102,8 @@ var OBSERVATION_ONLY_METADATA_KEYS = /* @__PURE__ */ new Set([
12871
13102
  TOOL_HAD_IMAGES
12872
13103
  ]);
12873
13104
  function formatToolMessageContent(args2) {
12874
- const scrubbedContent = scrubSecrets(args2.content).cleaned;
13105
+ const sanitizedContent = sanitizeToolOutputText(args2.content ?? "");
13106
+ const scrubbedContent = scrubSecrets(sanitizedContent).cleaned;
12875
13107
  if (args2.toolName !== "globFiles" && args2.toolName !== "codeSearch" && args2.toolName !== "readFile" || !args2.metadata || Object.keys(args2.metadata).length === 0) {
12876
13108
  return scrubbedContent;
12877
13109
  }
@@ -13040,7 +13272,8 @@ function compactToolMetadata(metadata) {
13040
13272
  return Object.keys(selected).length > 0 ? clipCompactText(JSON.stringify(selected), 1200) : "";
13041
13273
  }
13042
13274
  function projectToolContentForProvider(args2) {
13043
- const content = args2.content;
13275
+ const rawContent = args2.content;
13276
+ const content = typeof rawContent === "string" ? sanitizeToolOutputText(rawContent) : rawContent;
13044
13277
  if (typeof content !== "string") return content;
13045
13278
  const metadataText = compactToolMetadata(args2.metadata);
13046
13279
  const embeddedMetadataIndex = metadataText ? content.indexOf("\n\n[tool metadata]\n") : -1;
@@ -13065,7 +13298,7 @@ ${metadataText}` : "";
13065
13298
  let clipped = clipToolText(contentForProjection, initialBudget, headRatio);
13066
13299
  const wasClipped = clipped.length < contentForProjection.trim().length;
13067
13300
  const needsProjection = wasClipped || Boolean(metadataSuffix) || embeddedMetadataIndex >= 0;
13068
- if (!needsProjection) return args2.content;
13301
+ if (!needsProjection) return content;
13069
13302
  let spillNote = "";
13070
13303
  if (wasClipped) {
13071
13304
  try {
@@ -14107,8 +14340,8 @@ function resolveExecutableOnPath(name) {
14107
14340
  return null;
14108
14341
  }
14109
14342
  const pathEnv = process.env.PATH ?? "";
14110
- const sep2 = pathEnv.includes(";") && IS_WINDOWS ? ";" : ":";
14111
- const pathDirs = pathEnv.split(sep2).filter(Boolean);
14343
+ const sep3 = pathEnv.includes(";") && IS_WINDOWS ? ";" : ":";
14344
+ const pathDirs = pathEnv.split(sep3).filter(Boolean);
14112
14345
  const fallbackDirs = IS_WINDOWS ? [] : [
14113
14346
  "/opt/homebrew/bin",
14114
14347
  "/usr/local/bin",
@@ -14237,9 +14470,9 @@ function spawnToWebStreams(options) {
14237
14470
  env: options.env,
14238
14471
  stdio: ["ignore", "pipe", "pipe"]
14239
14472
  });
14240
- const exited = new Promise((resolve6) => {
14241
- child.on("exit", (code) => resolve6(code ?? 1));
14242
- child.on("error", () => resolve6(127));
14473
+ const exited = new Promise((resolve7) => {
14474
+ child.on("exit", (code) => resolve7(code ?? 1));
14475
+ child.on("error", () => resolve7(127));
14243
14476
  });
14244
14477
  const toWeb = (stream) => {
14245
14478
  if (!stream) return null;
@@ -15733,8 +15966,8 @@ import { createHash as createHash4 } from "node:crypto";
15733
15966
  // packages/agent-runtime/visualRenderer.node.ts
15734
15967
  import { createRequire } from "node:module";
15735
15968
  import { existsSync as existsSync4 } from "node:fs";
15736
- import { mkdir, realpath, stat, readFile, writeFile } from "node:fs/promises";
15737
- import { dirname as dirname2, isAbsolute as isAbsolute2, relative as relative2, win32 } from "node:path";
15969
+ import { realpath, stat, readFile } from "node:fs/promises";
15970
+ import { isAbsolute as isAbsolute2, relative as relative2, win32 } from "node:path";
15738
15971
  import { fileURLToPath, pathToFileURL } from "node:url";
15739
15972
  import { lookup as lookup2 } from "node:dns/promises";
15740
15973
  import { isIP } from "node:net";
@@ -15785,7 +16018,7 @@ var VisualRenderSemaphore = class {
15785
16018
  active = 0;
15786
16019
  queue = [];
15787
16020
  async run(task) {
15788
- if (this.active >= this.limit) await new Promise((resolve6) => this.queue.push(resolve6));
16021
+ if (this.active >= this.limit) await new Promise((resolve7) => this.queue.push(resolve7));
15789
16022
  else this.active++;
15790
16023
  try {
15791
16024
  return await task();
@@ -15816,6 +16049,9 @@ async function renderVisualPage(args2) {
15816
16049
  throw new Error(`renderVisualPage: ${field} is required (expected a non-empty string)`);
15817
16050
  }
15818
16051
  }
16052
+ if (typeof args2.persistScreenshot !== "function") {
16053
+ throw new Error("renderVisualPage: persistScreenshot is required (expected a function that stores the PNG bytes)");
16054
+ }
15819
16055
  if (!isAbsolute2(args2.workspaceRoot)) {
15820
16056
  throw new Error("renderVisualPage: workspaceRoot must be an absolute path");
15821
16057
  }
@@ -15915,8 +16151,7 @@ async function renderVisualPage(args2) {
15915
16151
  const result4 = { ...metrics, pageUrl: localFile ? url.href : page.url(), title: await page.title(), viewport: page.viewportSize(), renderer: "platform-playwright", capturedAt: (/* @__PURE__ */ new Date()).toISOString() };
15916
16152
  if (Date.now() >= deadline) throw new Error("Renderer timed out before screenshot persistence.");
15917
16153
  if (timer) clearTimeout(timer);
15918
- await mkdir(dirname2(args2.screenshotPath), { recursive: true });
15919
- await writeFile(args2.screenshotPath, screenshot);
16154
+ await args2.persistScreenshot(screenshot);
15920
16155
  return result4;
15921
16156
  };
15922
16157
  return await Promise.race([routeFailure, work(), new Promise((_, reject) => {
@@ -15977,7 +16212,7 @@ finally:
15977
16212
  pass
15978
16213
  bus.signal_unsubscribe(subscription)
15979
16214
  `;
15980
- var capturePortalScreenshot = (signal) => new Promise((resolve6, reject) => {
16215
+ var capturePortalScreenshot = (signal) => new Promise((resolve7, reject) => {
15981
16216
  const child = spawn2("/usr/bin/python3", ["-c", PORTAL_SCRIPT], { stdio: ["ignore", "pipe", "pipe"] });
15982
16217
  let stdout = "";
15983
16218
  let stderr = "";
@@ -15998,7 +16233,7 @@ var capturePortalScreenshot = (signal) => new Promise((resolve6, reject) => {
15998
16233
  if (signal.aborted) return reject(new Error("portal capture timeout"));
15999
16234
  if (code !== 0) return reject(new Error(stderr.trim() || `portal helper exited ${code}`));
16000
16235
  try {
16001
- resolve6(JSON.parse(stdout));
16236
+ resolve7(JSON.parse(stdout));
16002
16237
  } catch {
16003
16238
  reject(new Error("invalid portal response"));
16004
16239
  }
@@ -16010,7 +16245,7 @@ function createHostWindowCapture(options = {}) {
16010
16245
  let active = 0;
16011
16246
  const waiters = [];
16012
16247
  function acquire(signal) {
16013
- return new Promise((resolve6, reject) => {
16248
+ return new Promise((resolve7, reject) => {
16014
16249
  const abort = () => {
16015
16250
  const index = waiters.indexOf(start);
16016
16251
  if (index >= 0) waiters.splice(index, 1);
@@ -16019,7 +16254,7 @@ function createHostWindowCapture(options = {}) {
16019
16254
  const start = () => {
16020
16255
  signal.removeEventListener("abort", abort);
16021
16256
  active++;
16022
- resolve6();
16257
+ resolve7();
16023
16258
  };
16024
16259
  if (signal.aborted) return abort();
16025
16260
  if (active < concurrency) start();
@@ -16075,9 +16310,9 @@ function createHostWindowCapture(options = {}) {
16075
16310
  var captureHostWindow = createHostWindowCapture();
16076
16311
 
16077
16312
  // packages/agent-runtime/localWorkspaceTools.ts
16078
- import { lstat, mkdir as mkdir2, readdir as readdir2, readFile as readFile4, realpath as realpath2, stat as stat4, writeFile as writeFile2 } from "node:fs/promises";
16313
+ import { lstat as lstat2, readdir as readdir2, readFile as readFile4, realpath as realpath3, stat as stat4 } from "node:fs/promises";
16079
16314
  import { homedir } from "node:os";
16080
- import { dirname as dirname3, isAbsolute as isAbsolute3, relative as relative4, resolve as resolve4, sep } from "node:path";
16315
+ import { dirname as dirname3, relative as relative5, resolve as resolve5, sep as sep2 } from "node:path";
16081
16316
  import { spawn as spawnChildProcess3 } from "node:child_process";
16082
16317
 
16083
16318
  // packages/core/readRangeLedger.ts
@@ -16102,14 +16337,14 @@ function mergeLineRanges(ranges) {
16102
16337
  }
16103
16338
  function isLineRangeCovered(request3, covered) {
16104
16339
  if (!isValidRange(request3)) return false;
16105
- let open = request3.startLine;
16340
+ let open2 = request3.startLine;
16106
16341
  for (const range3 of mergeLineRanges(covered)) {
16107
- if (range3.endLine < open) continue;
16108
- if (range3.startLine > open) return false;
16109
- open = range3.endLine + 1;
16110
- if (open > request3.endLine) return true;
16342
+ if (range3.endLine < open2) continue;
16343
+ if (range3.startLine > open2) return false;
16344
+ open2 = range3.endLine + 1;
16345
+ if (open2 > request3.endLine) return true;
16111
16346
  }
16112
- return open > request3.endLine;
16347
+ return open2 > request3.endLine;
16113
16348
  }
16114
16349
 
16115
16350
  // packages/agent-runtime/fileTextSearch.ts
@@ -16346,7 +16581,7 @@ function resolveCleanupReport(evidence, previousStatus) {
16346
16581
  }
16347
16582
  var TERMINAL_EVENT_TYPES = /* @__PURE__ */ new Set(["exited", "killed"]);
16348
16583
  function defaultSleep(ms) {
16349
- return new Promise((resolve6) => setTimeout(resolve6, ms));
16584
+ return new Promise((resolve7) => setTimeout(resolve7, ms));
16350
16585
  }
16351
16586
  function defaultSignalSender(pid, signal) {
16352
16587
  process.kill(pid, signal);
@@ -16953,6 +17188,308 @@ function filterDeclaredWorkspaceToolNames(args2) {
16953
17188
  );
16954
17189
  }
16955
17190
 
17191
+ // packages/agent-runtime/workspacePathGuard.ts
17192
+ import { constants as fsConstants } from "node:fs";
17193
+ import { lstat, mkdir, open, readlink, realpath as realpath2 } from "node:fs/promises";
17194
+ import { basename as basename2, dirname as dirname2, isAbsolute as isAbsolute3, join as join5, relative as relative4, resolve as resolve4, sep } from "node:path";
17195
+ function isPathInsideRoot(root, targetPath) {
17196
+ const rel = relative4(resolve4(root), resolve4(targetPath));
17197
+ return rel === "" || rel !== ".." && !rel.startsWith(`..${sep}`) && !isAbsolute3(rel);
17198
+ }
17199
+ function isNotFoundError(error) {
17200
+ const code = error?.code;
17201
+ return code === "ENOENT" || code === "ENOTDIR";
17202
+ }
17203
+ async function realpathAllowMissing(targetPath) {
17204
+ const tail = [];
17205
+ let current = resolve4(targetPath);
17206
+ for (; ; ) {
17207
+ try {
17208
+ const real = await realpath2(current);
17209
+ return {
17210
+ realPath: tail.length === 0 ? real : join5(real, ...tail.slice().reverse()),
17211
+ exists: tail.length === 0
17212
+ };
17213
+ } catch (error) {
17214
+ if (!isNotFoundError(error)) return null;
17215
+ const parent = dirname2(current);
17216
+ if (parent === current) return null;
17217
+ tail.push(basename2(current));
17218
+ current = parent;
17219
+ }
17220
+ }
17221
+ }
17222
+ async function resolveWorkspaceSafePath(args2) {
17223
+ const requested = args2.requestedPath ?? args2.targetPath;
17224
+ const lexicalRoot = resolve4(args2.workspaceRoot);
17225
+ const targetPath = resolve4(args2.targetPath);
17226
+ const lexicalInside = args2.lexicalInside ?? isPathInsideRoot(lexicalRoot, targetPath);
17227
+ const [physicalRoot, resolved] = await Promise.all([
17228
+ realpath2(lexicalRoot).catch(() => null),
17229
+ realpathAllowMissing(targetPath)
17230
+ ]);
17231
+ if (resolved === null) {
17232
+ return lexicalInside ? { ok: false, error: "path_unresolvable", target: requested } : {
17233
+ ok: true,
17234
+ requested,
17235
+ path: targetPath,
17236
+ realPath: targetPath,
17237
+ exists: false,
17238
+ lexicalInside,
17239
+ insideWorkspace: false,
17240
+ allowedRoots: [targetPath]
17241
+ };
17242
+ }
17243
+ if (physicalRoot === null) {
17244
+ return {
17245
+ ok: true,
17246
+ requested,
17247
+ path: targetPath,
17248
+ realPath: resolved.realPath,
17249
+ exists: resolved.exists,
17250
+ lexicalInside,
17251
+ insideWorkspace: lexicalInside,
17252
+ allowedRoots: [lexicalRoot]
17253
+ };
17254
+ }
17255
+ const insideWorkspace = isPathInsideRoot(physicalRoot, resolved.realPath);
17256
+ if (lexicalInside && !insideWorkspace) {
17257
+ return { ok: false, error: "path_outside_workspace", target: requested };
17258
+ }
17259
+ return {
17260
+ ok: true,
17261
+ requested,
17262
+ path: targetPath,
17263
+ realPath: resolved.realPath,
17264
+ exists: resolved.exists,
17265
+ lexicalInside,
17266
+ insideWorkspace,
17267
+ allowedRoots: insideWorkspace ? [physicalRoot] : [resolved.realPath]
17268
+ };
17269
+ }
17270
+ function workspacePathGuardError(failure, note) {
17271
+ const detail = failure.error === "path_outside_workspace" ? `${failure.error}: ${failure.target} (resolves outside the workspace boundary)` : `${failure.error}: ${failure.target} (cannot be resolved to a physical path)`;
17272
+ const error = new Error(note ? `${detail} \u2014 ${note}` : detail);
17273
+ error.code = failure.error;
17274
+ error.target = failure.target;
17275
+ return error;
17276
+ }
17277
+ var FD_LINK_ROOTS = ["/proc/self/fd", "/dev/fd"];
17278
+ var O_NOFOLLOW = fsConstants.O_NOFOLLOW ?? 0;
17279
+ var O_DIRECTORY = fsConstants.O_DIRECTORY ?? 0;
17280
+ async function resolveOpenedFilePath(handle) {
17281
+ for (const root of FD_LINK_ROOTS) {
17282
+ try {
17283
+ const linked = await readlink(`${root}/${handle.fd}`);
17284
+ if (isAbsolute3(linked)) return linked.replace(/ \(deleted\)$/, "");
17285
+ } catch {
17286
+ }
17287
+ }
17288
+ return null;
17289
+ }
17290
+ function assertPathInsideApproval(physicalPath, guard) {
17291
+ if (guard.allowedRoots.some((root) => isPathInsideRoot(root, physicalPath))) return;
17292
+ throw workspacePathGuardError({
17293
+ ok: false,
17294
+ error: "path_outside_workspace",
17295
+ target: guard.requested
17296
+ });
17297
+ }
17298
+ async function assertOpenedFileInsideApproval(handle, guard) {
17299
+ const openedPath = await resolveOpenedFilePath(handle);
17300
+ if (openedPath === null) return;
17301
+ assertPathInsideApproval(openedPath, guard);
17302
+ }
17303
+ async function readGuardApprovedFile(guard) {
17304
+ const handle = await open(guard.path, "r");
17305
+ try {
17306
+ await assertOpenedFileInsideApproval(handle, guard);
17307
+ return await handle.readFile({ encoding: "utf8" });
17308
+ } finally {
17309
+ await handle.close();
17310
+ }
17311
+ }
17312
+ async function ensureGuardApprovedDirectory(guard) {
17313
+ const before = await realpathAllowMissing(guard.path);
17314
+ if (before === null) {
17315
+ throw workspacePathGuardError({
17316
+ ok: false,
17317
+ error: "path_unresolvable",
17318
+ target: guard.requested
17319
+ });
17320
+ }
17321
+ assertPathInsideApproval(before.realPath, guard);
17322
+ let createdByPinnedWalk = false;
17323
+ if (!before.exists) {
17324
+ createdByPinnedWalk = await createMissingDirectoryChain(guard);
17325
+ }
17326
+ const after = await realpathAllowMissing(guard.path);
17327
+ if (after === null) {
17328
+ throw workspacePathGuardError({
17329
+ ok: false,
17330
+ error: "path_unresolvable",
17331
+ target: guard.requested
17332
+ });
17333
+ }
17334
+ if (!guard.allowedRoots.some((root) => isPathInsideRoot(root, after.realPath))) {
17335
+ throw workspacePathGuardError(
17336
+ { ok: false, error: "path_outside_workspace", target: guard.requested },
17337
+ createdByPinnedWalk ? "directory creation had already run; verify the filesystem for empty directories created outside the workspace" : "directory creation had already run for a path component swapped during the operation"
17338
+ );
17339
+ }
17340
+ let handle;
17341
+ try {
17342
+ handle = await open(guard.path, "r");
17343
+ } catch {
17344
+ return;
17345
+ }
17346
+ try {
17347
+ await assertOpenedFileInsideApproval(handle, guard);
17348
+ } finally {
17349
+ await handle.close();
17350
+ }
17351
+ }
17352
+ async function openPinnedDirectory(dirPath, guard) {
17353
+ let handle;
17354
+ try {
17355
+ handle = await open(dirPath, fsConstants.O_RDONLY | O_DIRECTORY);
17356
+ } catch (error) {
17357
+ if (isNotFoundError(error)) return null;
17358
+ throw error;
17359
+ }
17360
+ try {
17361
+ await assertOpenedFileInsideApproval(handle, guard);
17362
+ } catch (error) {
17363
+ await handle.close();
17364
+ throw error;
17365
+ }
17366
+ for (const root of FD_LINK_ROOTS) {
17367
+ let probe;
17368
+ try {
17369
+ probe = await open(`${root}/${handle.fd}`, fsConstants.O_RDONLY);
17370
+ return { handle, fdRoot: root };
17371
+ } catch {
17372
+ } finally {
17373
+ await probe?.close();
17374
+ }
17375
+ }
17376
+ await handle.close();
17377
+ return null;
17378
+ }
17379
+ async function createMissingDirectoryChain(guard) {
17380
+ const missing = [];
17381
+ let existing = resolve4(guard.path);
17382
+ for (; ; ) {
17383
+ try {
17384
+ await lstat(existing);
17385
+ break;
17386
+ } catch (error) {
17387
+ if (!isNotFoundError(error)) throw error;
17388
+ const parent = dirname2(existing);
17389
+ if (parent === existing) {
17390
+ throw workspacePathGuardError({
17391
+ ok: false,
17392
+ error: "path_unresolvable",
17393
+ target: guard.requested
17394
+ });
17395
+ }
17396
+ missing.push(existing);
17397
+ existing = parent;
17398
+ }
17399
+ }
17400
+ if (!guard.insideWorkspace) {
17401
+ await mkdir(guard.path, { recursive: true });
17402
+ return false;
17403
+ }
17404
+ let pinned = await openPinnedDirectory(existing, guard);
17405
+ if (pinned === null) {
17406
+ await mkdir(guard.path, { recursive: true });
17407
+ return false;
17408
+ }
17409
+ try {
17410
+ for (const target of missing.slice().reverse()) {
17411
+ const name = basename2(target);
17412
+ if (!name || name === "." || name === "..") {
17413
+ throw workspacePathGuardError({
17414
+ ok: false,
17415
+ error: "path_unresolvable",
17416
+ target: guard.requested
17417
+ });
17418
+ }
17419
+ const childPath = `${pinned.fdRoot}/${pinned.handle.fd}/${name}`;
17420
+ try {
17421
+ await mkdir(childPath);
17422
+ } catch (error) {
17423
+ if (error?.code !== "EEXIST") throw error;
17424
+ }
17425
+ const child = await open(childPath, fsConstants.O_RDONLY | O_DIRECTORY | O_NOFOLLOW);
17426
+ try {
17427
+ await assertOpenedFileInsideApproval(child, guard);
17428
+ } catch (error) {
17429
+ await child.close();
17430
+ throw error;
17431
+ }
17432
+ await pinned.handle.close();
17433
+ pinned = { handle: child, fdRoot: pinned.fdRoot };
17434
+ }
17435
+ } finally {
17436
+ await pinned.handle.close();
17437
+ }
17438
+ return true;
17439
+ }
17440
+ async function openGuardApprovedWriteHandle(guard) {
17441
+ let info;
17442
+ try {
17443
+ info = await lstat(guard.path);
17444
+ } catch (error) {
17445
+ if (!isNotFoundError(error)) throw error;
17446
+ info = null;
17447
+ }
17448
+ if (info?.isSymbolicLink()) {
17449
+ throw workspacePathGuardError({
17450
+ ok: false,
17451
+ error: "path_outside_workspace",
17452
+ target: guard.requested
17453
+ });
17454
+ }
17455
+ try {
17456
+ return await open(
17457
+ guard.path,
17458
+ fsConstants.O_WRONLY | fsConstants.O_CREAT | O_NOFOLLOW,
17459
+ 438
17460
+ );
17461
+ } catch (error) {
17462
+ if (error?.code === "ELOOP") {
17463
+ throw workspacePathGuardError({
17464
+ ok: false,
17465
+ error: "path_outside_workspace",
17466
+ target: guard.requested
17467
+ });
17468
+ }
17469
+ throw error;
17470
+ }
17471
+ }
17472
+ async function writeGuardApprovedBytes(guard, content) {
17473
+ const handle = await openGuardApprovedWriteHandle(guard);
17474
+ try {
17475
+ await assertOpenedFileInsideApproval(handle, guard);
17476
+ await handle.truncate(0);
17477
+ if (typeof content === "string") {
17478
+ await handle.writeFile(content, { encoding: "utf8" });
17479
+ } else {
17480
+ await handle.writeFile(content);
17481
+ }
17482
+ } finally {
17483
+ await handle.close();
17484
+ }
17485
+ }
17486
+ async function writeGuardApprovedFile(guard, content) {
17487
+ await writeGuardApprovedBytes(guard, content);
17488
+ }
17489
+ async function writeGuardApprovedBinaryFile(guard, content) {
17490
+ await writeGuardApprovedBytes(guard, content);
17491
+ }
17492
+
16956
17493
  // packages/agent-runtime/localWorkspaceTools.ts
16957
17494
  async function hasRootGitignore2(workspaceRoot) {
16958
17495
  return hasRootGitignore(workspaceRoot);
@@ -17053,12 +17590,12 @@ function parseWorkspaceToolArguments(raw) {
17053
17590
  }
17054
17591
  }
17055
17592
  function normalizeWorkspaceRelativePath(args2) {
17056
- const relativePath = relative4(args2.workspaceRoot, args2.targetPath);
17593
+ const relativePath = relative5(args2.workspaceRoot, args2.targetPath);
17057
17594
  return relativePath || ".";
17058
17595
  }
17059
17596
  function isPathInsideWorkspace(args2) {
17060
- const relativePath = relative4(args2.workspaceRoot, args2.targetPath);
17061
- return relativePath === "" || !relativePath.startsWith("..") && !relativePath.includes(`..${sep}`);
17597
+ const relativePath = relative5(args2.workspaceRoot, args2.targetPath);
17598
+ return relativePath === "" || !relativePath.startsWith("..") && !relativePath.includes(`..${sep2}`);
17062
17599
  }
17063
17600
  var PATH_FIELD_ALIASES = ["path", "file_path", "filePath", "filename", "file", "target_file", "targetFile", "file_to_read", "fileToRead", "target_path", "read_path", "path_to_read", "pathToRead"];
17064
17601
  var OLD_TEXT_FIELD_ALIASES = ["oldText", "old_string", "oldString", "search", "search_string", "find", "match"];
@@ -17332,17 +17869,13 @@ function resolveRipgrepBinary(env = process.env) {
17332
17869
  return resolveExecutableOnPath("rg");
17333
17870
  }
17334
17871
  var SEARCH_OUTPUT_CHAR_LIMIT = 2e4;
17335
- function isPathInsideRoot(root, targetPath) {
17336
- const rel = relative4(resolve4(root), resolve4(targetPath));
17337
- return rel === "" || rel !== ".." && !rel.startsWith(`..${sep}`) && !isAbsolute3(rel);
17338
- }
17339
17872
  async function resolveRuntimeOwnedSpillPath(targetPath) {
17340
17873
  const spillRoot = resolveNoloStateDir("spills");
17341
17874
  if (!isPathInsideRoot(spillRoot, targetPath)) return null;
17342
- const rootStat = await lstat(spillRoot).catch(() => void 0);
17875
+ const rootStat = await lstat2(spillRoot).catch(() => void 0);
17343
17876
  if (rootStat?.isDirectory() !== true) return null;
17344
17877
  try {
17345
- const [realRoot, realTarget] = await Promise.all([realpath2(spillRoot), realpath2(targetPath)]);
17878
+ const [realRoot, realTarget] = await Promise.all([realpath3(spillRoot), realpath3(targetPath)]);
17346
17879
  return isPathInsideRoot(realRoot, realTarget) ? realTarget : null;
17347
17880
  } catch {
17348
17881
  return null;
@@ -17350,16 +17883,23 @@ async function resolveRuntimeOwnedSpillPath(targetPath) {
17350
17883
  }
17351
17884
  function expandHomePath(requestedPath) {
17352
17885
  if (requestedPath === "~") return homedir();
17353
- if (requestedPath.startsWith("~/")) return resolve4(homedir(), requestedPath.slice(2));
17886
+ if (requestedPath.startsWith("~/")) return resolve5(homedir(), requestedPath.slice(2));
17354
17887
  return requestedPath;
17355
17888
  }
17356
17889
  function resolveRequestedWorkspacePath(workspaceRoot, requestedPath) {
17357
- return resolve4(resolve4(workspaceRoot), expandHomePath(requestedPath));
17890
+ return resolve5(resolve5(workspaceRoot), expandHomePath(requestedPath));
17358
17891
  }
17359
- async function resolveLocalWorkspaceToolPath(args2) {
17360
- const workspaceRoot = resolve4(args2.workspaceRoot);
17892
+ async function resolveLocalWorkspaceToolApproval(args2) {
17893
+ const workspaceRoot = resolve5(args2.workspaceRoot);
17361
17894
  const targetPath = resolveRequestedWorkspacePath(workspaceRoot, args2.requestedPath);
17362
17895
  const insideWorkspace = isPathInsideWorkspace({ workspaceRoot, targetPath });
17896
+ const guard = await resolveWorkspaceSafePath({
17897
+ workspaceRoot,
17898
+ targetPath,
17899
+ requestedPath: args2.requestedPath,
17900
+ lexicalInside: insideWorkspace
17901
+ });
17902
+ if (!guard.ok) throw workspacePathGuardError(guard);
17363
17903
  const trustedSpillPath = !insideWorkspace && args2.allowRuntimeOwnedSpill === true ? await resolveRuntimeOwnedSpillPath(targetPath) : null;
17364
17904
  if (!insideWorkspace && trustedSpillPath === null) {
17365
17905
  if (args2.confirmExternalFileAccess) {
@@ -17386,7 +17926,20 @@ async function resolveLocalWorkspaceToolPath(args2) {
17386
17926
  }
17387
17927
  }
17388
17928
  }
17389
- return trustedSpillPath ?? targetPath;
17929
+ if (trustedSpillPath !== null) {
17930
+ return {
17931
+ ...guard,
17932
+ path: trustedSpillPath,
17933
+ realPath: trustedSpillPath,
17934
+ insideWorkspace: false,
17935
+ allowedRoots: [trustedSpillPath]
17936
+ };
17937
+ }
17938
+ return guard;
17939
+ }
17940
+ async function resolveLocalWorkspaceToolPath(args2) {
17941
+ const approval = await resolveLocalWorkspaceToolApproval(args2);
17942
+ return approval.path;
17390
17943
  }
17391
17944
  var READ_FILE_MAX_CHAR_LIMIT = 32e3;
17392
17945
  function defensivelyTruncateReadFile(args2) {
@@ -17436,13 +17989,14 @@ async function readFileTool(args2) {
17436
17989
  const parsed = parseWorkspaceToolArguments(args2.call.arguments);
17437
17990
  const requestedPath = requireWorkspaceToolPath(parsed);
17438
17991
  const { warnings, ...sliceArgs } = readFileSliceArgs(parsed);
17439
- const absolutePath = await resolveLocalWorkspaceToolPath({
17992
+ const approval = await resolveLocalWorkspaceToolApproval({
17440
17993
  workspaceRoot: args2.workspaceRoot,
17441
17994
  requestedPath,
17442
17995
  allowRuntimeOwnedSpill: true,
17443
17996
  ...args2.confirmExternalFileAccess ? { confirmExternalFileAccess: args2.confirmExternalFileAccess } : {}
17444
17997
  });
17445
- const content = await readFile4(absolutePath, "utf8");
17998
+ const absolutePath = approval.path;
17999
+ const content = await readGuardApprovedFile(approval);
17446
18000
  const activity = extractActivity(parsed);
17447
18001
  const sliced = sliceReadFileContent({
17448
18002
  content,
@@ -17454,7 +18008,7 @@ async function readFileTool(args2) {
17454
18008
  });
17455
18009
  const isTruncated = sliced.truncated || truncatedRead.truncatedByCharLimit;
17456
18010
  const relativePath = normalizeWorkspaceRelativePath({
17457
- workspaceRoot: resolve4(args2.workspaceRoot),
18011
+ workspaceRoot: resolve5(args2.workspaceRoot),
17458
18012
  targetPath: absolutePath
17459
18013
  });
17460
18014
  const force = parsed.force === true;
@@ -17517,19 +18071,29 @@ async function readFileTool(args2) {
17517
18071
  }
17518
18072
  return { content: truncatedRead.content, metadata };
17519
18073
  }
18074
+ async function ensureGuardedParentDirectory(args2) {
18075
+ const directoryGuard = await resolveWorkspaceSafePath({
18076
+ workspaceRoot: args2.workspaceRoot,
18077
+ targetPath: dirname3(args2.fileApproval.path),
18078
+ requestedPath: args2.fileApproval.requested
18079
+ });
18080
+ if (!directoryGuard.ok) throw workspacePathGuardError(directoryGuard);
18081
+ await ensureGuardApprovedDirectory(directoryGuard);
18082
+ }
17520
18083
  async function writeFileTool(args2) {
17521
18084
  const parsed = parseWorkspaceToolArguments(args2.call.arguments);
17522
18085
  const requestedPath = requireWorkspaceToolPath(parsed);
17523
18086
  const content = requireWorkspaceFileContent(parsed);
17524
- const absolutePath = await resolveLocalWorkspaceToolPath({
18087
+ const approval = await resolveLocalWorkspaceToolApproval({
17525
18088
  workspaceRoot: args2.workspaceRoot,
17526
18089
  requestedPath,
17527
18090
  ...args2.confirmExternalFileAccess ? { confirmExternalFileAccess: args2.confirmExternalFileAccess } : {}
17528
18091
  });
17529
- await mkdir2(dirname3(absolutePath), { recursive: true });
17530
- await writeFile2(absolutePath, content, "utf8");
18092
+ const absolutePath = approval.path;
18093
+ await ensureGuardedParentDirectory({ workspaceRoot: args2.workspaceRoot, fileApproval: approval });
18094
+ await writeGuardApprovedFile(approval, content);
17531
18095
  const relativePath = normalizeWorkspaceRelativePath({
17532
- workspaceRoot: resolve4(args2.workspaceRoot),
18096
+ workspaceRoot: resolve5(args2.workspaceRoot),
17533
18097
  targetPath: absolutePath
17534
18098
  });
17535
18099
  const activity = extractActivity(parsed);
@@ -17630,12 +18194,13 @@ async function editFileTool(args2) {
17630
18194
  const oldText = requireWorkspaceOldText(parsed);
17631
18195
  const newText = requireWorkspaceNewText(parsed);
17632
18196
  const expectedReplacements = readExpectedReplacementCount(parsed);
17633
- const absolutePath = await resolveLocalWorkspaceToolPath({
18197
+ const approval = await resolveLocalWorkspaceToolApproval({
17634
18198
  workspaceRoot: args2.workspaceRoot,
17635
18199
  requestedPath,
17636
18200
  ...args2.confirmExternalFileAccess ? { confirmExternalFileAccess: args2.confirmExternalFileAccess } : {}
17637
18201
  });
17638
- const content = await readFile4(absolutePath, "utf8");
18202
+ const absolutePath = approval.path;
18203
+ const content = await readGuardApprovedFile(approval);
17639
18204
  const { count: replacementCount, result: nextContent } = countAndReplaceEolTolerant({
17640
18205
  content,
17641
18206
  oldText,
@@ -17649,9 +18214,9 @@ async function editFileTool(args2) {
17649
18214
  ${hint}` : "")
17650
18215
  );
17651
18216
  }
17652
- await writeFile2(absolutePath, nextContent, "utf8");
18217
+ await writeGuardApprovedFile(approval, nextContent);
17653
18218
  const relativePath = normalizeWorkspaceRelativePath({
17654
- workspaceRoot: resolve4(args2.workspaceRoot),
18219
+ workspaceRoot: resolve5(args2.workspaceRoot),
17655
18220
  targetPath: absolutePath
17656
18221
  });
17657
18222
  const activity = extractActivity(parsed);
@@ -17691,9 +18256,9 @@ async function listWorkspaceEntries(args2) {
17691
18256
  const names = (await readdir2(dirPath)).sort((left, right) => left.localeCompare(right));
17692
18257
  for (const name of names) {
17693
18258
  if (truncated) break;
17694
- const absolutePath = resolve4(dirPath, name);
18259
+ const absolutePath = resolve5(dirPath, name);
17695
18260
  const info = await stat4(absolutePath);
17696
- const relativePath = relative4(args2.dirPath, absolutePath) || ".";
18261
+ const relativePath = relative5(args2.dirPath, absolutePath) || ".";
17697
18262
  const isDirectory = info.isDirectory();
17698
18263
  entries.push(isDirectory ? `${relativePath}/` : relativePath);
17699
18264
  if (args2.maxResults && entries.length >= args2.maxResults) {
@@ -17720,7 +18285,7 @@ async function internalSearchWorkspace(args2) {
17720
18285
  allowRuntimeOwnedSpill: true,
17721
18286
  ...args2.confirmExternalFileAccess ? { confirmExternalFileAccess: args2.confirmExternalFileAccess } : {}
17722
18287
  });
17723
- const workspaceRoot = resolve4(args2.workspaceRoot);
18288
+ const workspaceRoot = resolve5(args2.workspaceRoot);
17724
18289
  const inside = isPathInsideWorkspace({ workspaceRoot, targetPath: searchPath });
17725
18290
  const result4 = await searchFileTextMatches({
17726
18291
  root: inside ? workspaceRoot : searchPath,
@@ -17800,7 +18365,7 @@ async function globFilesTool(args2) {
17800
18365
  ...args2.confirmExternalFileAccess ? { confirmExternalFileAccess: args2.confirmExternalFileAccess } : {}
17801
18366
  });
17802
18367
  const relativeSearchPath = normalizeWorkspaceRelativePath({
17803
- workspaceRoot: resolve4(args2.workspaceRoot),
18368
+ workspaceRoot: resolve5(args2.workspaceRoot),
17804
18369
  targetPath: searchPath
17805
18370
  });
17806
18371
  const pathPrefix = relativeSearchPath === "." ? "" : `${relativeSearchPath.replace(/\/+$/, "")}/`;
@@ -17904,6 +18469,26 @@ async function resolveVisualStateBaseUrl(args2) {
17904
18469
  if (args2.explicitBaseUrl) return args2.explicitBaseUrl;
17905
18470
  return DEFAULT_LOCAL_API_ORIGIN;
17906
18471
  }
18472
+ async function persistApprovedScreenshot(args2) {
18473
+ const fresh = await resolveWorkspaceSafePath({
18474
+ workspaceRoot: args2.workspaceRoot,
18475
+ targetPath: args2.approval.path,
18476
+ requestedPath: args2.approval.requested
18477
+ });
18478
+ if (!fresh.ok) throw workspacePathGuardError(fresh);
18479
+ if (!fresh.insideWorkspace) {
18480
+ throw workspacePathGuardError({
18481
+ ok: false,
18482
+ error: "path_outside_workspace",
18483
+ target: args2.approval.requested
18484
+ });
18485
+ }
18486
+ await ensureGuardedParentDirectory({
18487
+ workspaceRoot: args2.workspaceRoot,
18488
+ fileApproval: fresh
18489
+ });
18490
+ await writeGuardApprovedBinaryFile(fresh, args2.bytes);
18491
+ }
17907
18492
  async function captureVisualStateTool(args2) {
17908
18493
  try {
17909
18494
  const parsed = parseWorkspaceToolArguments(args2.call.arguments);
@@ -17912,9 +18497,40 @@ async function captureVisualStateTool(args2) {
17912
18497
  if (!capability.available) return { content: `captureVisualState unavailable: ${capability.reason}`, metadata: { ok: false, rendererAvailable: false } };
17913
18498
  const baseUrl = await resolveVisualStateBaseUrl({ explicitBaseUrl: captureArgs.baseUrl });
17914
18499
  const pageUrl = new URL(captureArgs.path, baseUrl.endsWith("/") ? baseUrl : `${baseUrl}/`).href;
17915
- const screenshotPath = resolveRequestedWorkspacePath(args2.workspaceRoot, captureArgs.screenshotPath);
17916
- const metricsPath = resolveRequestedWorkspacePath(args2.workspaceRoot, captureArgs.metricsPath);
17917
- const rendered = await renderVisualPage({ ...captureArgs, workspaceRoot: args2.workspaceRoot, url: pageUrl, screenshotPath, timeoutMs: args2.commandTimeoutMs });
18500
+ const fileApprovalArgs = args2.confirmExternalFileAccess ? { confirmExternalFileAccess: args2.confirmExternalFileAccess } : {};
18501
+ const screenshotApproval = await resolveLocalWorkspaceToolApproval({
18502
+ workspaceRoot: args2.workspaceRoot,
18503
+ requestedPath: captureArgs.screenshotPath,
18504
+ ...fileApprovalArgs
18505
+ });
18506
+ if (!screenshotApproval.insideWorkspace) {
18507
+ throw new Error(
18508
+ `captureVisualState screenshotPath must stay inside the workspace: ${captureArgs.screenshotPath}`
18509
+ );
18510
+ }
18511
+ const metricsApproval = await resolveLocalWorkspaceToolApproval({
18512
+ workspaceRoot: args2.workspaceRoot,
18513
+ requestedPath: captureArgs.metricsPath,
18514
+ ...fileApprovalArgs
18515
+ });
18516
+ await ensureGuardedParentDirectory({
18517
+ workspaceRoot: args2.workspaceRoot,
18518
+ fileApproval: screenshotApproval
18519
+ });
18520
+ await ensureGuardedParentDirectory({
18521
+ workspaceRoot: args2.workspaceRoot,
18522
+ fileApproval: metricsApproval
18523
+ });
18524
+ const screenshotPath = screenshotApproval.path;
18525
+ const metricsPath = metricsApproval.path;
18526
+ const rendered = await renderVisualPage({
18527
+ ...captureArgs,
18528
+ workspaceRoot: args2.workspaceRoot,
18529
+ url: pageUrl,
18530
+ screenshotPath,
18531
+ timeoutMs: args2.commandTimeoutMs,
18532
+ persistScreenshot: (bytes) => persistApprovedScreenshot({ workspaceRoot: args2.workspaceRoot, approval: screenshotApproval, bytes })
18533
+ });
17918
18534
  const metrics = {
17919
18535
  ...captureArgs,
17920
18536
  ...rendered,
@@ -17922,8 +18538,7 @@ async function captureVisualStateTool(args2) {
17922
18538
  focusSelector: captureArgs.focusSelector ?? null,
17923
18539
  expectText: captureArgs.expectText ?? null
17924
18540
  };
17925
- await mkdir2(dirname3(metricsPath), { recursive: true });
17926
- await writeFile2(metricsPath, JSON.stringify(metrics, null, 2));
18541
+ await writeGuardApprovedFile(metricsApproval, JSON.stringify(metrics, null, 2));
17927
18542
  const image = await readLocalImage(screenshotPath);
17928
18543
  return {
17929
18544
  content: [
@@ -18047,7 +18662,7 @@ async function launchProcessTool(args2) {
18047
18662
  ];
18048
18663
  const detached = process.platform !== "win32";
18049
18664
  const proc = spawnChildProcess3(cmdArgs[0] ?? "", cmdArgs.slice(1), {
18050
- cwd: resolve4(args2.workspaceRoot),
18665
+ cwd: resolve5(args2.workspaceRoot),
18051
18666
  stdio: ["ignore", "pipe", "pipe"],
18052
18667
  detached
18053
18668
  });
@@ -18383,14 +18998,18 @@ function createLocalWorkspaceToolExecutors(args2) {
18383
18998
  captureVisualState: (call) => captureVisualStateTool({
18384
18999
  call,
18385
19000
  workspaceRoot: args2.workspaceRoot,
18386
- commandTimeoutMs: args2.commandTimeoutMs
19001
+ commandTimeoutMs: args2.commandTimeoutMs,
19002
+ ...fileAccess
18387
19003
  }),
18388
19004
  execShell: (call, opts) => execShellTool({
18389
19005
  call,
18390
19006
  workspaceRoot: args2.workspaceRoot,
18391
19007
  commandTimeoutMs: args2.commandTimeoutMs,
18392
19008
  commandOutputLimit: args2.commandOutputLimit,
18393
- commandPrefix: args2.commandPrefix,
19009
+ commandPrefix: [
19010
+ ...args2.execShellCommandPrefix ?? [],
19011
+ ...args2.commandPrefix ?? []
19012
+ ],
18394
19013
  restrictToWorkspace: args2.restrictShellToWorkspace,
18395
19014
  abortSignal: opts?.abortSignal ?? args2.abortSignal,
18396
19015
  detachMs: opts?.detachMs ?? args2.detachMs,
@@ -18812,6 +19431,10 @@ function projectSafeToolObservationMetadata(metadata) {
18812
19431
  if (typeof metadata.lineCount === "number") safe.lineCount = metadata.lineCount;
18813
19432
  return Object.keys(safe).length > 0 ? safe : void 0;
18814
19433
  }
19434
+ function sanitizeToolResultContent(result4) {
19435
+ const content = sanitizeToolOutputContent(result4.content);
19436
+ return content === result4.content ? result4 : { ...result4, content };
19437
+ }
18815
19438
  function summarizeToolResult(content, metadata) {
18816
19439
  const parts2 = [];
18817
19440
  const exitCode = metadata?.exitCode;
@@ -19038,6 +19661,7 @@ ${toolResult.content}` : toolResult.content,
19038
19661
  toolResult = replacement;
19039
19662
  }
19040
19663
  }
19664
+ toolResult = sanitizeToolResultContent(toolResult);
19041
19665
  const finishedAt = Date.now();
19042
19666
  const summary = summarizeToolResult(toolResult.content, toolResult.metadata);
19043
19667
  const safeMetadata = projectSafeToolObservationMetadata(toolResult.metadata);
@@ -19103,7 +19727,7 @@ ${toolResult.content}` : toolResult.content,
19103
19727
  }
19104
19728
  };
19105
19729
  }
19106
- return { toolResult, toolExecMs };
19730
+ return { toolResult: sanitizeToolResultContent(toolResult), toolExecMs };
19107
19731
  }
19108
19732
 
19109
19733
  // packages/agent-runtime/turnTranscript.ts
@@ -19564,16 +20188,16 @@ async function maybeAutoCompactLocalHistory(args2) {
19564
20188
  (error) => ({ kind: "provider-error", error })
19565
20189
  );
19566
20190
  const guards = [];
19567
- if (timeoutMs) guards.push(new Promise((resolve6) => {
20191
+ if (timeoutMs) guards.push(new Promise((resolve7) => {
19568
20192
  timeoutHandle = setTimeout(() => {
19569
20193
  requestController.abort();
19570
- resolve6({ kind: "timeout" });
20194
+ resolve7({ kind: "timeout" });
19571
20195
  }, timeoutMs);
19572
20196
  }));
19573
- if (args2.abortSignal) guards.push(new Promise((resolve6) => {
20197
+ if (args2.abortSignal) guards.push(new Promise((resolve7) => {
19574
20198
  abortListener = () => {
19575
20199
  requestController.abort(args2.abortSignal?.reason);
19576
- resolve6({ kind: "aborted" });
20200
+ resolve7({ kind: "aborted" });
19577
20201
  };
19578
20202
  args2.abortSignal?.addEventListener("abort", abortListener, { once: true });
19579
20203
  if (args2.abortSignal?.aborted) abortListener();
@@ -22218,6 +22842,10 @@ function createHybridRecordStore(deps) {
22218
22842
  };
22219
22843
  }
22220
22844
 
22845
+ // packages/agent-runtime/sandboxCommandPrefix.ts
22846
+ var DEFAULT_SANDBOX_TMPFS_SIZE_BYTES = 128 * 1024 * 1024;
22847
+ var BWRAP_PROBE_TTL_MS = 5 * 6e4;
22848
+
22221
22849
  // packages/cli/client/localDialogRecords.ts
22222
22850
  var localDialogMessageRecordToRuntimeMessage = dialogMessageRecordToAgentRuntimeMessage;
22223
22851
  function buildLocalDialogWritePlan(args2) {
@@ -22354,7 +22982,7 @@ function buildLoadSkillExecutor(args2) {
22354
22982
  metadata: { loadSkill: true, resolved: false }
22355
22983
  };
22356
22984
  }
22357
- const { resolveSkillByName } = await import("./skillDiscovery-QC35EQY4.js");
22985
+ const { resolveSkillByName } = await import("./skillDiscovery-F3TMVQOJ.js");
22358
22986
  const resolved = resolveSkillByName(args2.cwd, name);
22359
22987
  if (!resolved) {
22360
22988
  const { resolveBuiltinSkillByName } = await import("./builtinSkillRegistry-RR35BY57.js");
@@ -22400,7 +23028,7 @@ ${body}`,
22400
23028
  };
22401
23029
  }
22402
23030
  async function formatUnknownSkillMessage(cwd, requestedName) {
22403
- const { discoverSkills } = await import("./skillDiscovery-QC35EQY4.js");
23031
+ const { discoverSkills } = await import("./skillDiscovery-F3TMVQOJ.js");
22404
23032
  let available = [];
22405
23033
  try {
22406
23034
  available = discoverSkills(cwd).map((s) => s.name);
@@ -22972,17 +23600,17 @@ function createDevinProvider(options) {
22972
23600
  }
22973
23601
 
22974
23602
  // packages/agent-runtime/executionLeaseValidation.ts
22975
- import { isAbsolute as isAbsolute4, relative as relative5, resolve as resolve5 } from "node:path";
23603
+ import { isAbsolute as isAbsolute5, relative as relative6, resolve as resolve6 } from "node:path";
22976
23604
  function withinRoot(root, child) {
22977
- if (!isAbsolute4(root) || !isAbsolute4(child)) return false;
22978
- const canonicalRoot = resolve5(root);
22979
- const canonicalChild = resolve5(child);
22980
- const suffix = relative5(canonicalRoot, canonicalChild);
22981
- return suffix === "" || suffix !== ".." && !suffix.startsWith("../") && !suffix.startsWith("..\\") && !isAbsolute4(suffix);
23605
+ if (!isAbsolute5(root) || !isAbsolute5(child)) return false;
23606
+ const canonicalRoot = resolve6(root);
23607
+ const canonicalChild = resolve6(child);
23608
+ const suffix = relative6(canonicalRoot, canonicalChild);
23609
+ return suffix === "" || suffix !== ".." && !suffix.startsWith("../") && !suffix.startsWith("..\\") && !isAbsolute5(suffix);
22982
23610
  }
22983
23611
  function subsetOf(allowed, actual) {
22984
23612
  return actual.every(
22985
- (root) => isAbsolute4(root) && allowed.some((parent) => withinRoot(parent, root))
23613
+ (root) => isAbsolute5(root) && allowed.some((parent) => withinRoot(parent, root))
22986
23614
  );
22987
23615
  }
22988
23616
  function validateConfiguredRootExecutionLease(ticket, lease) {