nolo-cli 0.186.0 → 0.187.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.
- package/{_executeModel-WTNQE227.js → _executeModel-35LFG5KF.js} +12 -12
- package/{agentDeleteCommand-KJFY6C7J.js → agentDeleteCommand-TMFQR6QL.js} +11 -11
- package/{agentEmailCommands-CGXK25TI.js → agentEmailCommands-JZ6GYJ4H.js} +13 -13
- package/{agentListCommands-PRG4ZBJC.js → agentListCommands-PFZRMIAI.js} +2 -2
- package/{agentMachineCommands-OVFR25AO.js → agentMachineCommands-BT643ADE.js} +3 -3
- package/{agentRecordCommands-V233UFDQ.js → agentRecordCommands-LJ5EWR67.js} +12 -12
- package/{agentRunCommand-CNBQZ4PZ.js → agentRunCommand-6CPXONR3.js} +14 -14
- package/{agentRuntimeLocal-CBDP2OYK.js → agentRuntimeLocal-3QBUFZEC.js} +2 -2
- package/{agentSlice-XC35R4QW.js → agentSlice-RW25WUPR.js} +1 -1
- package/{appDeleteCommands-OP4GGXEJ.js → appDeleteCommands-WEBDQMVH.js} +2 -2
- package/{appDeployCommands-LHTVLNL5.js → appDeployCommands-HFZ3I7Z4.js} +2 -2
- package/{appDeployStatusCommands-BSDDQU7S.js → appDeployStatusCommands-TVBQOFIY.js} +2 -2
- package/{appGetCommands-LNHGUJKF.js → appGetCommands-Y5RKR25C.js} +2 -2
- package/{appListCommands-RGOFZV5M.js → appListCommands-4UZIZPB3.js} +2 -2
- package/{chunk-5BSIT4IP.js → chunk-37ZDGCX6.js} +8 -8
- package/{chunk-IOQHM7ID.js → chunk-4ALQFIFF.js} +720 -92
- package/{chunk-Z4AZSU7X.js → chunk-4GZ2LY5F.js} +12 -8
- package/{chunk-KQFC7IPI.js → chunk-6HFMPUSN.js} +2 -2
- package/{chunk-AU7AXHUL.js → chunk-7KWPNGVJ.js} +57 -21
- package/{chunk-5STT2WW5.js → chunk-BRBG72OP.js} +7 -7
- package/{chunk-3SMSREBB.js → chunk-CDUK5BF6.js} +2 -2
- package/{chunk-ZN2PUXZ2.js → chunk-DK7QNJVM.js} +2 -2
- package/{chunk-TGH6MIC7.js → chunk-ECAGROXS.js} +2 -2
- package/{chunk-TIHN5AXV.js → chunk-IOB5RBBZ.js} +1 -1
- package/{chunk-7XY4VVIL.js → chunk-J5Y3BXJP.js} +124 -22
- package/{chunk-PHD5UL5B.js → chunk-PEOLOK72.js} +1 -1
- package/{chunk-MKAWH3AL.js → chunk-PL6YNOF7.js} +10 -10
- package/chunk-Q6RMLYSA.js +385 -0
- package/{chunk-DKYQN6DO.js → chunk-QBMO66MI.js} +3 -3
- package/{chunk-DIP5EVZD.js → chunk-SIX7N4AH.js} +2 -2
- package/{chunk-TURPPK3Y.js → chunk-TB7E6UEO.js} +1 -1
- package/{chunk-KBW2QSGY.js → chunk-VMMS7L64.js} +3 -3
- package/{chunk-ZPRV4GQD.js → chunk-XJECR5M3.js} +2 -2
- package/{chunk-CH3QKJ2T.js → chunk-ZV6ESGA7.js} +2 -2
- package/{chunk-SL2TDPXF.js → chunk-ZXUPGFJ5.js} +6 -6
- package/{commandRegistry-2J53NSBR.js → commandRegistry-6EEZMM43.js} +40 -40
- package/{contentThunks-TFYSYUDO.js → contentThunks-EPHFLF62.js} +3 -3
- package/{createAgentAutomationAction-KCODNBWN.js → createAgentAutomationAction-MFE4QIL4.js} +3 -3
- package/{createDialogAction-RGDFOBVN.js → createDialogAction-SGOXQ7BC.js} +4 -4
- package/{createPageAction-XXI7D2CN.js → createPageAction-OTNUT7WI.js} +3 -3
- package/{dialogCommands-6MR232CJ.js → dialogCommands-KNE72SUM.js} +2 -2
- package/{dialogSlice-IZAIMZXJ.js → dialogSlice-PHPLFD5F.js} +2 -2
- package/{docCreateCommands-DAZJ2Y5E.js → docCreateCommands-MG67RHCR.js} +2 -2
- package/{docDeleteCommands-XO26LNIO.js → docDeleteCommands-2UAG5JVZ.js} +2 -2
- package/{docReadCommands-77XGRLD6.js → docReadCommands-JKJJ4FNU.js} +2 -2
- package/{docStore-IRZWBI3X.js → docStore-HI7P3MVA.js} +1 -1
- package/{docUpdateCommands-QXN3MJAJ.js → docUpdateCommands-6D7ADVPS.js} +2 -2
- package/{handleSendMessageAction-E6PA6K6X.js → handleSendMessageAction-YAO4RDWU.js} +8 -8
- package/index.js +3 -3
- package/{localRuntimeAdapter-ATJCBXFO.js → localRuntimeAdapter-4J62I4YU.js} +11 -11
- package/{machineCommands-T4XT4J4G.js → machineCommands-XW5I55QW.js} +12 -12
- package/{machineWsRunDispatch-VZZHV4G7.js → machineWsRunDispatch-W5VEHHMI.js} +12 -12
- package/package.json +1 -1
- package/{readlineWorkspace-4RIJTRPN.js → readlineWorkspace-EE6JMRIW.js} +14 -14
- package/{runAgentClientLoop-7DKG2KL2.js → runAgentClientLoop-BU6GOWQI.js} +10 -10
- package/skillDiscovery-F3TMVQOJ.js +28 -0
- package/{spaceCommands-PHLKQ2AW.js → spaceCommands-GTQQ6GFS.js} +2 -2
- package/{streamAgentChatTurn-2764VROY.js → streamAgentChatTurn-MHRXV7XZ.js} +13 -13
- package/{tools-UJELIY4A.js → tools-YA5NIWI7.js} +7 -7
- package/{updateDialogTitleAction-HUFWSVYC.js → updateDialogTitleAction-M6U2VK5L.js} +3 -3
- package/chunk-VEA7H5FG.js +0 -173
- 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-
|
|
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((
|
|
5226
|
-
fiber3.addObserver((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 = (
|
|
5344
|
-
var makeLatch = (
|
|
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((
|
|
12213
|
-
currentResolve =
|
|
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
|
|
12399
|
-
const
|
|
12400
|
-
|
|
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
|
-
|
|
12524
|
+
const totalDropped = dropped + droppedByBytesCount;
|
|
12525
|
+
if (totalDropped > 0) {
|
|
12448
12526
|
console.warn(
|
|
12449
|
-
`[observationStream] stream buffer overflow: dropped ${
|
|
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
|
-
|
|
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
|
|
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
|
|
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
|
|
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
|
|
14111
|
-
const pathDirs = pathEnv.split(
|
|
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((
|
|
14241
|
-
child.on("exit", (code) =>
|
|
14242
|
-
child.on("error", () =>
|
|
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 {
|
|
15737
|
-
import {
|
|
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((
|
|
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
|
|
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((
|
|
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
|
-
|
|
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((
|
|
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
|
-
|
|
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
|
|
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,
|
|
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
|
|
16340
|
+
let open2 = request3.startLine;
|
|
16106
16341
|
for (const range3 of mergeLineRanges(covered)) {
|
|
16107
|
-
if (range3.endLine <
|
|
16108
|
-
if (range3.startLine >
|
|
16109
|
-
|
|
16110
|
-
if (
|
|
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
|
|
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((
|
|
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 =
|
|
17593
|
+
const relativePath = relative5(args2.workspaceRoot, args2.targetPath);
|
|
17057
17594
|
return relativePath || ".";
|
|
17058
17595
|
}
|
|
17059
17596
|
function isPathInsideWorkspace(args2) {
|
|
17060
|
-
const relativePath =
|
|
17061
|
-
return relativePath === "" || !relativePath.startsWith("..") && !relativePath.includes(`..${
|
|
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
|
|
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([
|
|
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
|
|
17886
|
+
if (requestedPath.startsWith("~/")) return resolve5(homedir(), requestedPath.slice(2));
|
|
17354
17887
|
return requestedPath;
|
|
17355
17888
|
}
|
|
17356
17889
|
function resolveRequestedWorkspacePath(workspaceRoot, requestedPath) {
|
|
17357
|
-
return
|
|
17890
|
+
return resolve5(resolve5(workspaceRoot), expandHomePath(requestedPath));
|
|
17358
17891
|
}
|
|
17359
|
-
async function
|
|
17360
|
-
const 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
|
-
|
|
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
|
|
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
|
|
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:
|
|
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
|
|
18087
|
+
const approval = await resolveLocalWorkspaceToolApproval({
|
|
17525
18088
|
workspaceRoot: args2.workspaceRoot,
|
|
17526
18089
|
requestedPath,
|
|
17527
18090
|
...args2.confirmExternalFileAccess ? { confirmExternalFileAccess: args2.confirmExternalFileAccess } : {}
|
|
17528
18091
|
});
|
|
17529
|
-
|
|
17530
|
-
await
|
|
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:
|
|
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
|
|
18197
|
+
const approval = await resolveLocalWorkspaceToolApproval({
|
|
17634
18198
|
workspaceRoot: args2.workspaceRoot,
|
|
17635
18199
|
requestedPath,
|
|
17636
18200
|
...args2.confirmExternalFileAccess ? { confirmExternalFileAccess: args2.confirmExternalFileAccess } : {}
|
|
17637
18201
|
});
|
|
17638
|
-
const
|
|
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
|
|
18217
|
+
await writeGuardApprovedFile(approval, nextContent);
|
|
17653
18218
|
const relativePath = normalizeWorkspaceRelativePath({
|
|
17654
|
-
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 =
|
|
18259
|
+
const absolutePath = resolve5(dirPath, name);
|
|
17695
18260
|
const info = await stat4(absolutePath);
|
|
17696
|
-
const relativePath =
|
|
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 =
|
|
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:
|
|
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
|
|
17916
|
-
const
|
|
17917
|
-
|
|
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
|
|
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:
|
|
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:
|
|
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((
|
|
20191
|
+
if (timeoutMs) guards.push(new Promise((resolve7) => {
|
|
19568
20192
|
timeoutHandle = setTimeout(() => {
|
|
19569
20193
|
requestController.abort();
|
|
19570
|
-
|
|
20194
|
+
resolve7({ kind: "timeout" });
|
|
19571
20195
|
}, timeoutMs);
|
|
19572
20196
|
}));
|
|
19573
|
-
if (args2.abortSignal) guards.push(new Promise((
|
|
20197
|
+
if (args2.abortSignal) guards.push(new Promise((resolve7) => {
|
|
19574
20198
|
abortListener = () => {
|
|
19575
20199
|
requestController.abort(args2.abortSignal?.reason);
|
|
19576
|
-
|
|
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-
|
|
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-
|
|
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
|
|
23603
|
+
import { isAbsolute as isAbsolute5, relative as relative6, resolve as resolve6 } from "node:path";
|
|
22976
23604
|
function withinRoot(root, child) {
|
|
22977
|
-
if (!
|
|
22978
|
-
const canonicalRoot =
|
|
22979
|
-
const canonicalChild =
|
|
22980
|
-
const suffix =
|
|
22981
|
-
return suffix === "" || suffix !== ".." && !suffix.startsWith("../") && !suffix.startsWith("..\\") && !
|
|
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) =>
|
|
23613
|
+
(root) => isAbsolute5(root) && allowed.some((parent) => withinRoot(parent, root))
|
|
22986
23614
|
);
|
|
22987
23615
|
}
|
|
22988
23616
|
function validateConfiguredRootExecutionLease(ticket, lease) {
|