perchai-cli 2.4.11 → 2.4.12
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/dist/perch.mjs +1735 -386
- package/package.json +1 -1
package/dist/perch.mjs
CHANGED
|
@@ -5198,8 +5198,8 @@ var require_xlsx = __commonJS({
|
|
|
5198
5198
|
}
|
|
5199
5199
|
return L.length - R.length;
|
|
5200
5200
|
}
|
|
5201
|
-
function
|
|
5202
|
-
if (p.charAt(p.length - 1) == "/") return p.slice(0, -1).indexOf("/") === -1 ? p :
|
|
5201
|
+
function dirname2(p) {
|
|
5202
|
+
if (p.charAt(p.length - 1) == "/") return p.slice(0, -1).indexOf("/") === -1 ? p : dirname2(p.slice(0, -1));
|
|
5203
5203
|
var c = p.lastIndexOf("/");
|
|
5204
5204
|
return c === -1 ? p : p.slice(0, c + 1);
|
|
5205
5205
|
}
|
|
@@ -5620,7 +5620,7 @@ var require_xlsx = __commonJS({
|
|
|
5620
5620
|
data.push([cfb.FullPaths[i2], cfb.FileIndex[i2]]);
|
|
5621
5621
|
}
|
|
5622
5622
|
for (i2 = 0; i2 < data.length; ++i2) {
|
|
5623
|
-
var dad =
|
|
5623
|
+
var dad = dirname2(data[i2][0]);
|
|
5624
5624
|
s = fullPaths[dad];
|
|
5625
5625
|
if (!s) {
|
|
5626
5626
|
data.push([dad, {
|
|
@@ -5656,13 +5656,13 @@ var require_xlsx = __commonJS({
|
|
|
5656
5656
|
elt.size = 0;
|
|
5657
5657
|
elt.type = 5;
|
|
5658
5658
|
} else if (nm.slice(-1) == "/") {
|
|
5659
|
-
for (j = i2 + 1; j < data.length; ++j) if (
|
|
5659
|
+
for (j = i2 + 1; j < data.length; ++j) if (dirname2(cfb.FullPaths[j]) == nm) break;
|
|
5660
5660
|
elt.C = j >= data.length ? -1 : j;
|
|
5661
|
-
for (j = i2 + 1; j < data.length; ++j) if (
|
|
5661
|
+
for (j = i2 + 1; j < data.length; ++j) if (dirname2(cfb.FullPaths[j]) == dirname2(nm)) break;
|
|
5662
5662
|
elt.R = j >= data.length ? -1 : j;
|
|
5663
5663
|
elt.type = 1;
|
|
5664
5664
|
} else {
|
|
5665
|
-
if (
|
|
5665
|
+
if (dirname2(cfb.FullPaths[i2 + 1] || "") == dirname2(nm)) elt.R = i2 + 1;
|
|
5666
5666
|
elt.type = 2;
|
|
5667
5667
|
}
|
|
5668
5668
|
}
|
|
@@ -41950,11 +41950,11 @@ var require_html2canvas = __commonJS({
|
|
|
41950
41950
|
};
|
|
41951
41951
|
function __awaiter3(thisArg, _arguments, P, generator) {
|
|
41952
41952
|
function adopt(value) {
|
|
41953
|
-
return value instanceof P ? value : new P(function(
|
|
41954
|
-
|
|
41953
|
+
return value instanceof P ? value : new P(function(resolve5) {
|
|
41954
|
+
resolve5(value);
|
|
41955
41955
|
});
|
|
41956
41956
|
}
|
|
41957
|
-
return new (P || (P = Promise))(function(
|
|
41957
|
+
return new (P || (P = Promise))(function(resolve5, reject2) {
|
|
41958
41958
|
function fulfilled(value) {
|
|
41959
41959
|
try {
|
|
41960
41960
|
step(generator.next(value));
|
|
@@ -41970,7 +41970,7 @@ var require_html2canvas = __commonJS({
|
|
|
41970
41970
|
}
|
|
41971
41971
|
}
|
|
41972
41972
|
function step(result2) {
|
|
41973
|
-
result2.done ?
|
|
41973
|
+
result2.done ? resolve5(result2.value) : adopt(result2.value).then(fulfilled, rejected);
|
|
41974
41974
|
}
|
|
41975
41975
|
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
41976
41976
|
});
|
|
@@ -43962,16 +43962,16 @@ var require_html2canvas = __commonJS({
|
|
|
43962
43962
|
[width, 0],
|
|
43963
43963
|
[width, height]
|
|
43964
43964
|
];
|
|
43965
|
-
return corners.reduce(function(
|
|
43965
|
+
return corners.reduce(function(stat2, corner) {
|
|
43966
43966
|
var cx = corner[0], cy = corner[1];
|
|
43967
43967
|
var d = distance(x - cx, y - cy);
|
|
43968
|
-
if (closest ? d <
|
|
43968
|
+
if (closest ? d < stat2.optimumDistance : d > stat2.optimumDistance) {
|
|
43969
43969
|
return {
|
|
43970
43970
|
optimumCorner: corner,
|
|
43971
43971
|
optimumDistance: d
|
|
43972
43972
|
};
|
|
43973
43973
|
}
|
|
43974
|
-
return
|
|
43974
|
+
return stat2;
|
|
43975
43975
|
}, {
|
|
43976
43976
|
optimumDistance: closest ? Infinity : -Infinity,
|
|
43977
43977
|
optimumCorner: null
|
|
@@ -46099,10 +46099,10 @@ var require_html2canvas = __commonJS({
|
|
|
46099
46099
|
return svg;
|
|
46100
46100
|
};
|
|
46101
46101
|
var loadSerializedSVG$1 = function(svg) {
|
|
46102
|
-
return new Promise(function(
|
|
46102
|
+
return new Promise(function(resolve5, reject2) {
|
|
46103
46103
|
var img = new Image();
|
|
46104
46104
|
img.onload = function() {
|
|
46105
|
-
return
|
|
46105
|
+
return resolve5(img);
|
|
46106
46106
|
};
|
|
46107
46107
|
img.onerror = reject2;
|
|
46108
46108
|
img.src = "data:image/svg+xml;charset=utf-8," + encodeURIComponent(new XMLSerializer().serializeToString(svg));
|
|
@@ -47464,24 +47464,24 @@ var require_html2canvas = __commonJS({
|
|
|
47464
47464
|
return cloneIframeContainer;
|
|
47465
47465
|
};
|
|
47466
47466
|
var imageReady = function(img) {
|
|
47467
|
-
return new Promise(function(
|
|
47467
|
+
return new Promise(function(resolve5) {
|
|
47468
47468
|
if (img.complete) {
|
|
47469
|
-
|
|
47469
|
+
resolve5();
|
|
47470
47470
|
return;
|
|
47471
47471
|
}
|
|
47472
47472
|
if (!img.src) {
|
|
47473
|
-
|
|
47473
|
+
resolve5();
|
|
47474
47474
|
return;
|
|
47475
47475
|
}
|
|
47476
|
-
img.onload =
|
|
47477
|
-
img.onerror =
|
|
47476
|
+
img.onload = resolve5;
|
|
47477
|
+
img.onerror = resolve5;
|
|
47478
47478
|
});
|
|
47479
47479
|
};
|
|
47480
47480
|
var imagesReady = function(document2) {
|
|
47481
47481
|
return Promise.all([].slice.call(document2.images, 0).map(imageReady));
|
|
47482
47482
|
};
|
|
47483
47483
|
var iframeLoader = function(iframe) {
|
|
47484
|
-
return new Promise(function(
|
|
47484
|
+
return new Promise(function(resolve5, reject2) {
|
|
47485
47485
|
var cloneWindow = iframe.contentWindow;
|
|
47486
47486
|
if (!cloneWindow) {
|
|
47487
47487
|
return reject2("No window assigned for iframe");
|
|
@@ -47492,7 +47492,7 @@ var require_html2canvas = __commonJS({
|
|
|
47492
47492
|
var interval = setInterval(function() {
|
|
47493
47493
|
if (documentClone.body.childNodes.length > 0 && documentClone.readyState === "complete") {
|
|
47494
47494
|
clearInterval(interval);
|
|
47495
|
-
|
|
47495
|
+
resolve5(iframe);
|
|
47496
47496
|
}
|
|
47497
47497
|
}, 50);
|
|
47498
47498
|
};
|
|
@@ -47631,10 +47631,10 @@ var require_html2canvas = __commonJS({
|
|
|
47631
47631
|
_a.label = 2;
|
|
47632
47632
|
case 2:
|
|
47633
47633
|
this.context.logger.debug("Added image " + key.substring(0, 256));
|
|
47634
|
-
return [4, new Promise(function(
|
|
47634
|
+
return [4, new Promise(function(resolve5, reject2) {
|
|
47635
47635
|
var img = new Image();
|
|
47636
47636
|
img.onload = function() {
|
|
47637
|
-
return
|
|
47637
|
+
return resolve5(img);
|
|
47638
47638
|
};
|
|
47639
47639
|
img.onerror = reject2;
|
|
47640
47640
|
if (isInlineBase64Image(src) || useCORS) {
|
|
@@ -47643,7 +47643,7 @@ var require_html2canvas = __commonJS({
|
|
|
47643
47643
|
img.src = src;
|
|
47644
47644
|
if (img.complete === true) {
|
|
47645
47645
|
setTimeout(function() {
|
|
47646
|
-
return
|
|
47646
|
+
return resolve5(img);
|
|
47647
47647
|
}, 500);
|
|
47648
47648
|
}
|
|
47649
47649
|
if (_this._options.imageTimeout > 0) {
|
|
@@ -47671,17 +47671,17 @@ var require_html2canvas = __commonJS({
|
|
|
47671
47671
|
throw new Error("No proxy defined");
|
|
47672
47672
|
}
|
|
47673
47673
|
var key = src.substring(0, 256);
|
|
47674
|
-
return new Promise(function(
|
|
47674
|
+
return new Promise(function(resolve5, reject2) {
|
|
47675
47675
|
var responseType = FEATURES.SUPPORT_RESPONSE_TYPE ? "blob" : "text";
|
|
47676
47676
|
var xhr = new XMLHttpRequest();
|
|
47677
47677
|
xhr.onload = function() {
|
|
47678
47678
|
if (xhr.status === 200) {
|
|
47679
47679
|
if (responseType === "text") {
|
|
47680
|
-
|
|
47680
|
+
resolve5(xhr.response);
|
|
47681
47681
|
} else {
|
|
47682
47682
|
var reader_1 = new FileReader();
|
|
47683
47683
|
reader_1.addEventListener("load", function() {
|
|
47684
|
-
return
|
|
47684
|
+
return resolve5(reader_1.result);
|
|
47685
47685
|
}, false);
|
|
47686
47686
|
reader_1.addEventListener("error", function(e2) {
|
|
47687
47687
|
return reject2(e2);
|
|
@@ -49496,10 +49496,10 @@ var require_html2canvas = __commonJS({
|
|
|
49496
49496
|
})(Renderer)
|
|
49497
49497
|
);
|
|
49498
49498
|
var loadSerializedSVG = function(svg) {
|
|
49499
|
-
return new Promise(function(
|
|
49499
|
+
return new Promise(function(resolve5, reject2) {
|
|
49500
49500
|
var img = new Image();
|
|
49501
49501
|
img.onload = function() {
|
|
49502
|
-
|
|
49502
|
+
resolve5(img);
|
|
49503
49503
|
};
|
|
49504
49504
|
img.onerror = reject2;
|
|
49505
49505
|
img.src = "data:image/svg+xml;charset=utf-8," + encodeURIComponent(new XMLSerializer().serializeToString(svg));
|
|
@@ -51584,7 +51584,7 @@ var require_make_built_in = __commonJS({
|
|
|
51584
51584
|
var defineProperty = Object.defineProperty;
|
|
51585
51585
|
var stringSlice = uncurryThis("".slice);
|
|
51586
51586
|
var replace = uncurryThis("".replace);
|
|
51587
|
-
var
|
|
51587
|
+
var join2 = uncurryThis([].join);
|
|
51588
51588
|
var CONFIGURABLE_LENGTH = DESCRIPTORS && !fails(function() {
|
|
51589
51589
|
return defineProperty(function() {
|
|
51590
51590
|
}, "length", { value: 8 }).length !== 8;
|
|
@@ -51611,7 +51611,7 @@ var require_make_built_in = __commonJS({
|
|
|
51611
51611
|
}
|
|
51612
51612
|
var state = enforceInternalState(value);
|
|
51613
51613
|
if (!hasOwn(state, "source")) {
|
|
51614
|
-
state.source =
|
|
51614
|
+
state.source = join2(TEMPLATE, typeof name == "string" ? name : "");
|
|
51615
51615
|
}
|
|
51616
51616
|
return value;
|
|
51617
51617
|
};
|
|
@@ -52685,8 +52685,8 @@ var require_promise_constructor_detection = __commonJS({
|
|
|
52685
52685
|
if (!GLOBAL_CORE_JS_PROMISE && V8_VERSION === 66) return true;
|
|
52686
52686
|
if (IS_PURE && !(NativePromisePrototype["catch"] && NativePromisePrototype["finally"])) return true;
|
|
52687
52687
|
if (!V8_VERSION || V8_VERSION < 51 || !/native code/.test(PROMISE_CONSTRUCTOR_SOURCE)) {
|
|
52688
|
-
var promise = new NativePromiseConstructor(function(
|
|
52689
|
-
|
|
52688
|
+
var promise = new NativePromiseConstructor(function(resolve5) {
|
|
52689
|
+
resolve5(1);
|
|
52690
52690
|
});
|
|
52691
52691
|
var FakePromise = function(exec3) {
|
|
52692
52692
|
exec3(function() {
|
|
@@ -52716,13 +52716,13 @@ var require_new_promise_capability = __commonJS({
|
|
|
52716
52716
|
var aCallable = require_a_callable();
|
|
52717
52717
|
var $TypeError = TypeError;
|
|
52718
52718
|
var PromiseCapability = function(C) {
|
|
52719
|
-
var
|
|
52719
|
+
var resolve5, reject2;
|
|
52720
52720
|
this.promise = new C(function($$resolve, $$reject) {
|
|
52721
|
-
if (
|
|
52722
|
-
|
|
52721
|
+
if (resolve5 !== void 0 || reject2 !== void 0) throw new $TypeError("Bad Promise constructor");
|
|
52722
|
+
resolve5 = $$resolve;
|
|
52723
52723
|
reject2 = $$reject;
|
|
52724
52724
|
});
|
|
52725
|
-
this.resolve = aCallable(
|
|
52725
|
+
this.resolve = aCallable(resolve5);
|
|
52726
52726
|
this.reject = aCallable(reject2);
|
|
52727
52727
|
};
|
|
52728
52728
|
module2.exports.f = function(C) {
|
|
@@ -52793,7 +52793,7 @@ var require_es_promise_constructor = __commonJS({
|
|
|
52793
52793
|
var value = state.value;
|
|
52794
52794
|
var ok = state.state === FULFILLED;
|
|
52795
52795
|
var handler = ok ? reaction.ok : reaction.fail;
|
|
52796
|
-
var
|
|
52796
|
+
var resolve5 = reaction.resolve;
|
|
52797
52797
|
var reject2 = reaction.reject;
|
|
52798
52798
|
var domain = reaction.domain;
|
|
52799
52799
|
var result2, then, exited;
|
|
@@ -52815,8 +52815,8 @@ var require_es_promise_constructor = __commonJS({
|
|
|
52815
52815
|
if (result2 === reaction.promise) {
|
|
52816
52816
|
reject2(new TypeError2("Promise-chain cycle"));
|
|
52817
52817
|
} else if (then = isThenable(result2)) {
|
|
52818
|
-
call(then, result2,
|
|
52819
|
-
} else
|
|
52818
|
+
call(then, result2, resolve5, reject2);
|
|
52819
|
+
} else resolve5(result2);
|
|
52820
52820
|
} else reject2(value);
|
|
52821
52821
|
} catch (error) {
|
|
52822
52822
|
if (domain && !exited) domain.exit();
|
|
@@ -52972,8 +52972,8 @@ var require_es_promise_constructor = __commonJS({
|
|
|
52972
52972
|
if (!NATIVE_PROMISE_SUBCLASSING) {
|
|
52973
52973
|
defineBuiltIn(NativePromisePrototype, "then", function then(onFulfilled, onRejected) {
|
|
52974
52974
|
var that = this;
|
|
52975
|
-
return new PromiseConstructor(function(
|
|
52976
|
-
call(nativeThen, that,
|
|
52975
|
+
return new PromiseConstructor(function(resolve5, reject2) {
|
|
52976
|
+
call(nativeThen, that, resolve5, reject2);
|
|
52977
52977
|
}).then(onFulfilled, onRejected);
|
|
52978
52978
|
}, { unsafe: true });
|
|
52979
52979
|
}
|
|
@@ -53233,7 +53233,7 @@ var require_es_promise_all = __commonJS({
|
|
|
53233
53233
|
all: function all(iterable) {
|
|
53234
53234
|
var C = this;
|
|
53235
53235
|
var capability = newPromiseCapabilityModule.f(C);
|
|
53236
|
-
var
|
|
53236
|
+
var resolve5 = capability.resolve;
|
|
53237
53237
|
var reject2 = capability.reject;
|
|
53238
53238
|
var result2 = perform(function() {
|
|
53239
53239
|
var $promiseResolve = aCallable(C.resolve);
|
|
@@ -53248,10 +53248,10 @@ var require_es_promise_all = __commonJS({
|
|
|
53248
53248
|
if (alreadyCalled) return;
|
|
53249
53249
|
alreadyCalled = true;
|
|
53250
53250
|
values2[index] = value;
|
|
53251
|
-
--remaining ||
|
|
53251
|
+
--remaining || resolve5(values2);
|
|
53252
53252
|
}, reject2);
|
|
53253
53253
|
});
|
|
53254
|
-
--remaining ||
|
|
53254
|
+
--remaining || resolve5(values2);
|
|
53255
53255
|
});
|
|
53256
53256
|
if (result2.error) reject2(result2.value);
|
|
53257
53257
|
return capability.promise;
|
|
@@ -53345,8 +53345,8 @@ var require_promise_resolve = __commonJS({
|
|
|
53345
53345
|
anObject(C);
|
|
53346
53346
|
if (isObject4(x) && x.constructor === C) return x;
|
|
53347
53347
|
var promiseCapability = newPromiseCapability.f(C);
|
|
53348
|
-
var
|
|
53349
|
-
|
|
53348
|
+
var resolve5 = promiseCapability.resolve;
|
|
53349
|
+
resolve5(x);
|
|
53350
53350
|
return promiseCapability.promise;
|
|
53351
53351
|
};
|
|
53352
53352
|
}
|
|
@@ -53365,7 +53365,7 @@ var require_es_promise_resolve = __commonJS({
|
|
|
53365
53365
|
var PromiseConstructorWrapper = getBuiltIn("Promise");
|
|
53366
53366
|
var CHECK_WRAPPER = IS_PURE && !FORCED_PROMISE_CONSTRUCTOR;
|
|
53367
53367
|
$2({ target: "Promise", stat: true, forced: IS_PURE || FORCED_PROMISE_CONSTRUCTOR }, {
|
|
53368
|
-
resolve: function
|
|
53368
|
+
resolve: function resolve5(x) {
|
|
53369
53369
|
return promiseResolve(CHECK_WRAPPER && this === PromiseConstructorWrapper ? NativePromiseConstructor : this, x);
|
|
53370
53370
|
}
|
|
53371
53371
|
});
|
|
@@ -54854,7 +54854,7 @@ var require_es_array_join = __commonJS({
|
|
|
54854
54854
|
var ES3_STRINGS = IndexedObject !== Object;
|
|
54855
54855
|
var FORCED = ES3_STRINGS || !arrayMethodIsStrict("join", ",");
|
|
54856
54856
|
$2({ target: "Array", proto: true, forced: FORCED }, {
|
|
54857
|
-
join: function
|
|
54857
|
+
join: function join2(separator) {
|
|
54858
54858
|
return nativeJoin(toIndexedObject(this), separator === void 0 ? "," : separator);
|
|
54859
54859
|
}
|
|
54860
54860
|
});
|
|
@@ -58983,8 +58983,8 @@ var require_lib2 = __commonJS({
|
|
|
58983
58983
|
var FRAMERATE = this.FRAMERATE, mouse = this.mouse;
|
|
58984
58984
|
var frameDuration = 1e3 / FRAMERATE;
|
|
58985
58985
|
this.frameDuration = frameDuration;
|
|
58986
|
-
this.readyPromise = new Promise(function(
|
|
58987
|
-
_this.resolveReady =
|
|
58986
|
+
this.readyPromise = new Promise(function(resolve5) {
|
|
58987
|
+
_this.resolveReady = resolve5;
|
|
58988
58988
|
});
|
|
58989
58989
|
if (this.isReady()) {
|
|
58990
58990
|
this.render(element, ignoreDimensions, ignoreClear, scaleWidth, scaleHeight, offsetX, offsetY);
|
|
@@ -65022,9 +65022,9 @@ var require_lib2 = __commonJS({
|
|
|
65022
65022
|
if (anonymousCrossOrigin) {
|
|
65023
65023
|
image2.crossOrigin = "Anonymous";
|
|
65024
65024
|
}
|
|
65025
|
-
return _context.abrupt("return", new Promise(function(
|
|
65025
|
+
return _context.abrupt("return", new Promise(function(resolve5, reject2) {
|
|
65026
65026
|
image2.onload = function() {
|
|
65027
|
-
|
|
65027
|
+
resolve5(image2);
|
|
65028
65028
|
};
|
|
65029
65029
|
image2.onerror = function(_event, _source, _lineno, _colno, error) {
|
|
65030
65030
|
reject2(error);
|
|
@@ -73320,7 +73320,7 @@ async function walk(rootPath, currentPath, files) {
|
|
|
73320
73320
|
continue;
|
|
73321
73321
|
}
|
|
73322
73322
|
if (!entry.isFile()) continue;
|
|
73323
|
-
const
|
|
73323
|
+
const stat2 = await fs3.promises.stat(fullPath);
|
|
73324
73324
|
const extension2 = path3.extname(entry.name).toLowerCase();
|
|
73325
73325
|
const role = sensitivity.sensitive ? "secret_sensitive" : classifyFileRole(entry.name, relativePath);
|
|
73326
73326
|
const ignored = sensitivity.sensitive;
|
|
@@ -73329,11 +73329,11 @@ async function walk(rootPath, currentPath, files) {
|
|
|
73329
73329
|
relativePath,
|
|
73330
73330
|
fileName: entry.name,
|
|
73331
73331
|
extension: extension2,
|
|
73332
|
-
sizeBytes:
|
|
73332
|
+
sizeBytes: stat2.size,
|
|
73333
73333
|
role,
|
|
73334
73334
|
ignored,
|
|
73335
73335
|
ignoreReason: sensitivity.reason,
|
|
73336
|
-
textSnippet: ignored ? void 0 : await safeTextSnippet(fullPath, extension2,
|
|
73336
|
+
textSnippet: ignored ? void 0 : await safeTextSnippet(fullPath, extension2, stat2.size)
|
|
73337
73337
|
});
|
|
73338
73338
|
}
|
|
73339
73339
|
}
|
|
@@ -75408,8 +75408,8 @@ async function listDirs(root2) {
|
|
|
75408
75408
|
}
|
|
75409
75409
|
async function fileExists(filePath) {
|
|
75410
75410
|
try {
|
|
75411
|
-
const
|
|
75412
|
-
return
|
|
75411
|
+
const stat2 = await fs7.promises.stat(filePath);
|
|
75412
|
+
return stat2.isFile();
|
|
75413
75413
|
} catch {
|
|
75414
75414
|
return false;
|
|
75415
75415
|
}
|
|
@@ -81720,7 +81720,7 @@ function buildThreadLedgerItemsFromTurn(input) {
|
|
|
81720
81720
|
kind: "context_boundary",
|
|
81721
81721
|
ts: event.ts,
|
|
81722
81722
|
runId: input.runId,
|
|
81723
|
-
summary: `Context compacted from ${event.tokensBefore} to ${event.tokensAfter} tokens
|
|
81723
|
+
summary: `Context compacted from ${event.tokensBefore} to ${event.tokensAfter} tokens` + (event.targetTokens ? ` (target ${event.targetTokens}).` : "."),
|
|
81724
81724
|
resultPreview: truncate3(event.summary, MAX_TEXT)
|
|
81725
81725
|
});
|
|
81726
81726
|
} else if (event.type === "live_card_end" && event.receipt) {
|
|
@@ -82300,6 +82300,8 @@ function sanitizePendingActionPayload(value) {
|
|
|
82300
82300
|
}
|
|
82301
82301
|
function parseContextCompaction(value) {
|
|
82302
82302
|
if (!isRecord4(value)) return null;
|
|
82303
|
+
const compactBoundary = parseCompactBoundary(value.compactBoundary);
|
|
82304
|
+
const compactionReport = parseCompactionReport(value.compactionReport);
|
|
82303
82305
|
return {
|
|
82304
82306
|
compactConversation: value.compactConversation === true,
|
|
82305
82307
|
dropNotFoundRows: value.dropNotFoundRows === true,
|
|
@@ -82310,9 +82312,38 @@ function parseContextCompaction(value) {
|
|
|
82310
82312
|
autoCompactedAtIso: typeof value.autoCompactedAtIso === "string" ? value.autoCompactedAtIso : void 0,
|
|
82311
82313
|
autoCompactedMessageCount: asFiniteNonNegativeInt(value.autoCompactedMessageCount) ?? void 0,
|
|
82312
82314
|
compactedSummary: typeof value.compactedSummary === "string" ? value.compactedSummary : void 0,
|
|
82313
|
-
effectiveContextLimitTokens: asFiniteNonNegativeInt(value.effectiveContextLimitTokens) ?? void 0
|
|
82315
|
+
effectiveContextLimitTokens: asFiniteNonNegativeInt(value.effectiveContextLimitTokens) ?? void 0,
|
|
82316
|
+
...compactBoundary ? { compactBoundary } : {},
|
|
82317
|
+
...compactionReport ? { compactionReport } : {}
|
|
82314
82318
|
};
|
|
82315
82319
|
}
|
|
82320
|
+
function parseCompactBoundary(value) {
|
|
82321
|
+
if (!isRecord4(value)) return void 0;
|
|
82322
|
+
const kind = value.kind === "manual" ? "manual" : value.kind === "auto" ? "auto" : null;
|
|
82323
|
+
const compactedAtIso = typeof value.compactedAtIso === "string" ? value.compactedAtIso : null;
|
|
82324
|
+
if (!kind || !compactedAtIso) return void 0;
|
|
82325
|
+
return {
|
|
82326
|
+
kind,
|
|
82327
|
+
compactedAtIso,
|
|
82328
|
+
compactedThroughMessageId: typeof value.compactedThroughMessageId === "string" ? value.compactedThroughMessageId : null,
|
|
82329
|
+
compactedThroughMessageCreatedAt: typeof value.compactedThroughMessageCreatedAt === "string" ? value.compactedThroughMessageCreatedAt : null,
|
|
82330
|
+
compactedThroughWireIndex: asFiniteNonNegativeInt(value.compactedThroughWireIndex)
|
|
82331
|
+
};
|
|
82332
|
+
}
|
|
82333
|
+
function parseCompactionReport(value) {
|
|
82334
|
+
if (!isRecord4(value)) return void 0;
|
|
82335
|
+
const parsed = {
|
|
82336
|
+
tokensBefore: asFiniteNonNegativeInt(value.tokensBefore) ?? void 0,
|
|
82337
|
+
tokensAfter: asFiniteNonNegativeInt(value.tokensAfter) ?? void 0,
|
|
82338
|
+
targetTokens: asFiniteNonNegativeInt(value.targetTokens) ?? void 0,
|
|
82339
|
+
summaryTokens: asFiniteNonNegativeInt(value.summaryTokens) ?? void 0,
|
|
82340
|
+
recentTailTokens: asFiniteNonNegativeInt(value.recentTailTokens) ?? void 0,
|
|
82341
|
+
recentTailMessages: asFiniteNonNegativeInt(value.recentTailMessages) ?? void 0,
|
|
82342
|
+
summarizedMessages: asFiniteNonNegativeInt(value.summarizedMessages) ?? void 0,
|
|
82343
|
+
restoredToolsOrFiles: asFiniteNonNegativeInt(value.restoredToolsOrFiles) ?? void 0
|
|
82344
|
+
};
|
|
82345
|
+
return Object.values(parsed).some((entry) => typeof entry === "number") ? parsed : void 0;
|
|
82346
|
+
}
|
|
82316
82347
|
function parseWorkerRuns(value) {
|
|
82317
82348
|
if (!Array.isArray(value)) return void 0;
|
|
82318
82349
|
const parsed = [];
|
|
@@ -82425,6 +82456,7 @@ function parseContextMetrics(value) {
|
|
|
82425
82456
|
const consecutiveAutoCompactFailures = asFiniteNonNegativeInt(value.consecutiveAutoCompactFailures);
|
|
82426
82457
|
const lastApiUsage = parseModelUsage(value.lastApiUsage);
|
|
82427
82458
|
const turnApiUsage = parseModelUsage(value.turnApiUsage);
|
|
82459
|
+
const compactionReport = parseCompactionReport(value.compactionReport);
|
|
82428
82460
|
return {
|
|
82429
82461
|
threadContextTokens,
|
|
82430
82462
|
latestSendTokens,
|
|
@@ -82448,6 +82480,7 @@ function parseContextMetrics(value) {
|
|
|
82448
82480
|
...consecutiveAutoCompactFailures !== null ? { consecutiveAutoCompactFailures } : {},
|
|
82449
82481
|
...typeof value.autoCompactedAtIso === "string" ? { autoCompactedAtIso: value.autoCompactedAtIso } : {},
|
|
82450
82482
|
...asFiniteNonNegativeInt(value.autoCompactedMessageCount) !== null ? { autoCompactedMessageCount: asFiniteNonNegativeInt(value.autoCompactedMessageCount) } : {},
|
|
82483
|
+
...compactionReport ? { compactionReport } : {},
|
|
82451
82484
|
resetAtIso: typeof value.resetAtIso === "string" ? value.resetAtIso : null,
|
|
82452
82485
|
updatedAtIso: typeof value.updatedAtIso === "string" ? value.updatedAtIso : (/* @__PURE__ */ new Date()).toISOString()
|
|
82453
82486
|
};
|
|
@@ -82906,7 +82939,17 @@ function buildMessageHistory(recentMessages, currentInput, options) {
|
|
|
82906
82939
|
const hasCompactedSummary = compactedSummary.length > 0;
|
|
82907
82940
|
const shouldUseCompactedHistory = options?.compactConversation === true && hasCompactedSummary;
|
|
82908
82941
|
const keepCount = options?.keepCount ?? (shouldUseCompactedHistory ? 12 : recentMessages.length);
|
|
82909
|
-
const sourceMessages = shouldUseCompactedHistory ?
|
|
82942
|
+
const sourceMessages = shouldUseCompactedHistory ? selectRecentHistoryTail(
|
|
82943
|
+
filterMessagesAfterCompactBoundary(recentMessages, {
|
|
82944
|
+
compactedThroughMessageId: options?.compactedThroughMessageId,
|
|
82945
|
+
compactedThroughMessageCreatedAt: options?.compactedThroughMessageCreatedAt
|
|
82946
|
+
}),
|
|
82947
|
+
{
|
|
82948
|
+
tokenTarget: options?.recentTailTokenTarget,
|
|
82949
|
+
fallbackKeepCount: keepCount,
|
|
82950
|
+
minMessages: Math.min(DEFAULT_COMPACTED_MIN_RECENT_MESSAGES, keepCount)
|
|
82951
|
+
}
|
|
82952
|
+
) : recentMessages;
|
|
82910
82953
|
if (hasCompactedSummary) {
|
|
82911
82954
|
history.push({
|
|
82912
82955
|
role: "user",
|
|
@@ -82955,6 +82998,47 @@ ${compactedSummary}`
|
|
|
82955
82998
|
history.push({ role: "user", content: currentInput });
|
|
82956
82999
|
return history;
|
|
82957
83000
|
}
|
|
83001
|
+
function filterMessagesAfterCompactBoundary(messages, boundary) {
|
|
83002
|
+
const boundaryId = boundary.compactedThroughMessageId?.trim();
|
|
83003
|
+
if (boundaryId) {
|
|
83004
|
+
const idx = messages.findIndex((message) => message.id === boundaryId);
|
|
83005
|
+
if (idx >= 0) return messages.slice(idx + 1);
|
|
83006
|
+
}
|
|
83007
|
+
const boundaryAt = boundary.compactedThroughMessageCreatedAt?.trim();
|
|
83008
|
+
if (boundaryAt) {
|
|
83009
|
+
const boundaryMs = Date.parse(boundaryAt);
|
|
83010
|
+
if (Number.isFinite(boundaryMs)) {
|
|
83011
|
+
return messages.filter((message) => {
|
|
83012
|
+
const createdMs = Date.parse(message.createdAt);
|
|
83013
|
+
return !Number.isFinite(createdMs) || createdMs > boundaryMs;
|
|
83014
|
+
});
|
|
83015
|
+
}
|
|
83016
|
+
}
|
|
83017
|
+
return messages;
|
|
83018
|
+
}
|
|
83019
|
+
function selectRecentHistoryTail(messages, input) {
|
|
83020
|
+
const tokenTarget = typeof input.tokenTarget === "number" && Number.isFinite(input.tokenTarget) && input.tokenTarget > 0 ? Math.floor(input.tokenTarget) : null;
|
|
83021
|
+
if (!tokenTarget) {
|
|
83022
|
+
return messages.slice(-Math.max(1, input.fallbackKeepCount));
|
|
83023
|
+
}
|
|
83024
|
+
const minMessages = Math.max(1, input.minMessages ?? DEFAULT_COMPACTED_MIN_RECENT_MESSAGES);
|
|
83025
|
+
let startIndex = messages.length;
|
|
83026
|
+
let tokens = 0;
|
|
83027
|
+
for (let i = messages.length - 1; i >= 0; i -= 1) {
|
|
83028
|
+
const msgTokens = estimateHistoryMessageTokens(messages[i]);
|
|
83029
|
+
const selectedCount = messages.length - startIndex;
|
|
83030
|
+
const mustKeep = selectedCount === 0;
|
|
83031
|
+
if (!mustKeep && tokens + msgTokens > tokenTarget) break;
|
|
83032
|
+
tokens += msgTokens;
|
|
83033
|
+
startIndex = i;
|
|
83034
|
+
if (selectedCount + 1 >= minMessages && tokens >= tokenTarget) break;
|
|
83035
|
+
}
|
|
83036
|
+
return messages.slice(startIndex);
|
|
83037
|
+
}
|
|
83038
|
+
function estimateHistoryMessageTokens(message) {
|
|
83039
|
+
const text = message.kind === "text" ? messageContentForModelHistory(message) : `[Plan: ${message.plan.title}] ${message.plan.goal}`;
|
|
83040
|
+
return Math.max(1, Math.ceil(`${message.kind}:${text}`.length / 4));
|
|
83041
|
+
}
|
|
82958
83042
|
function messageContentForModelHistory(msg) {
|
|
82959
83043
|
if (msg.role !== "assistant" || !msg.operatorState?.events?.length) {
|
|
82960
83044
|
return msg.text;
|
|
@@ -82966,11 +83050,14 @@ function messageContentForModelHistory(msg) {
|
|
|
82966
83050
|
turnSummary: msg.turnSummary
|
|
82967
83051
|
});
|
|
82968
83052
|
}
|
|
83053
|
+
var DEFAULT_COMPACTED_RECENT_TAIL_TOKENS, DEFAULT_COMPACTED_MIN_RECENT_MESSAGES;
|
|
82969
83054
|
var init_messageHistory = __esm({
|
|
82970
83055
|
"features/perchTerminal/runtime/messageContext/messageHistory.ts"() {
|
|
82971
83056
|
"use strict";
|
|
82972
83057
|
init_operatorTruth();
|
|
82973
83058
|
init_wireTranscript();
|
|
83059
|
+
DEFAULT_COMPACTED_RECENT_TAIL_TOKENS = 24e3;
|
|
83060
|
+
DEFAULT_COMPACTED_MIN_RECENT_MESSAGES = 4;
|
|
82974
83061
|
}
|
|
82975
83062
|
});
|
|
82976
83063
|
|
|
@@ -91612,6 +91699,9 @@ function assembleContext(input) {
|
|
|
91612
91699
|
{
|
|
91613
91700
|
compactConversation: contextCompaction?.compactConversation === true,
|
|
91614
91701
|
compactedSummary: contextCompaction?.compactedSummary ?? null,
|
|
91702
|
+
compactedThroughMessageId: contextCompaction?.compactBoundary?.compactedThroughMessageId ?? null,
|
|
91703
|
+
compactedThroughMessageCreatedAt: contextCompaction?.compactBoundary?.compactedThroughMessageCreatedAt ?? null,
|
|
91704
|
+
recentTailTokenTarget: contextCompaction?.compactionReport?.recentTailTokens ?? DEFAULT_COMPACTED_RECENT_TAIL_TOKENS,
|
|
91615
91705
|
wireReplayMessages: threadSession?.threadWireMessages ?? null,
|
|
91616
91706
|
wireReplayContextLimitTokens: input.contextLimitTokens ?? threadSession?.contextMetrics?.effectiveLimitTokens ?? null,
|
|
91617
91707
|
// Coordinator sessions reference planIds and worker completions from earlier
|
|
@@ -93571,11 +93661,11 @@ function __metadata(metadataKey, metadataValue) {
|
|
|
93571
93661
|
}
|
|
93572
93662
|
function __awaiter(thisArg, _arguments, P, generator) {
|
|
93573
93663
|
function adopt(value) {
|
|
93574
|
-
return value instanceof P ? value : new P(function(
|
|
93575
|
-
|
|
93664
|
+
return value instanceof P ? value : new P(function(resolve5) {
|
|
93665
|
+
resolve5(value);
|
|
93576
93666
|
});
|
|
93577
93667
|
}
|
|
93578
|
-
return new (P || (P = Promise))(function(
|
|
93668
|
+
return new (P || (P = Promise))(function(resolve5, reject2) {
|
|
93579
93669
|
function fulfilled(value) {
|
|
93580
93670
|
try {
|
|
93581
93671
|
step(generator.next(value));
|
|
@@ -93591,7 +93681,7 @@ function __awaiter(thisArg, _arguments, P, generator) {
|
|
|
93591
93681
|
}
|
|
93592
93682
|
}
|
|
93593
93683
|
function step(result2) {
|
|
93594
|
-
result2.done ?
|
|
93684
|
+
result2.done ? resolve5(result2.value) : adopt(result2.value).then(fulfilled, rejected);
|
|
93595
93685
|
}
|
|
93596
93686
|
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
93597
93687
|
});
|
|
@@ -93782,14 +93872,14 @@ function __asyncValues(o) {
|
|
|
93782
93872
|
}, i);
|
|
93783
93873
|
function verb(n) {
|
|
93784
93874
|
i[n] = o[n] && function(v) {
|
|
93785
|
-
return new Promise(function(
|
|
93786
|
-
v = o[n](v), settle(
|
|
93875
|
+
return new Promise(function(resolve5, reject2) {
|
|
93876
|
+
v = o[n](v), settle(resolve5, reject2, v.done, v.value);
|
|
93787
93877
|
});
|
|
93788
93878
|
};
|
|
93789
93879
|
}
|
|
93790
|
-
function settle(
|
|
93880
|
+
function settle(resolve5, reject2, d, v) {
|
|
93791
93881
|
Promise.resolve(v).then(function(v2) {
|
|
93792
|
-
|
|
93882
|
+
resolve5({ value: v2, done: d });
|
|
93793
93883
|
}, reject2);
|
|
93794
93884
|
}
|
|
93795
93885
|
}
|
|
@@ -94404,18 +94494,18 @@ var require_dist = __commonJS({
|
|
|
94404
94494
|
}
|
|
94405
94495
|
};
|
|
94406
94496
|
function sleep2(ms, signal) {
|
|
94407
|
-
return new Promise((
|
|
94497
|
+
return new Promise((resolve5) => {
|
|
94408
94498
|
if (signal === null || signal === void 0 ? void 0 : signal.aborted) {
|
|
94409
|
-
|
|
94499
|
+
resolve5();
|
|
94410
94500
|
return;
|
|
94411
94501
|
}
|
|
94412
94502
|
const id = setTimeout(() => {
|
|
94413
94503
|
signal === null || signal === void 0 || signal.removeEventListener("abort", onAbort);
|
|
94414
|
-
|
|
94504
|
+
resolve5();
|
|
94415
94505
|
}, ms);
|
|
94416
94506
|
function onAbort() {
|
|
94417
94507
|
clearTimeout(id);
|
|
94418
|
-
|
|
94508
|
+
resolve5();
|
|
94419
94509
|
}
|
|
94420
94510
|
signal === null || signal === void 0 || signal.addEventListener("abort", onAbort);
|
|
94421
94511
|
});
|
|
@@ -102425,15 +102515,15 @@ var require_RealtimeChannel = __commonJS({
|
|
|
102425
102515
|
}
|
|
102426
102516
|
}
|
|
102427
102517
|
} else {
|
|
102428
|
-
return new Promise((
|
|
102518
|
+
return new Promise((resolve5) => {
|
|
102429
102519
|
var _a2, _b2, _c;
|
|
102430
102520
|
const push2 = this.channelAdapter.push(args.type, args, opts.timeout || this.timeout);
|
|
102431
102521
|
if (args.type === "broadcast" && !((_c = (_b2 = (_a2 = this.params) === null || _a2 === void 0 ? void 0 : _a2.config) === null || _b2 === void 0 ? void 0 : _b2.broadcast) === null || _c === void 0 ? void 0 : _c.ack)) {
|
|
102432
|
-
|
|
102522
|
+
resolve5("ok");
|
|
102433
102523
|
}
|
|
102434
|
-
push2.receive("ok", () =>
|
|
102435
|
-
push2.receive("error", () =>
|
|
102436
|
-
push2.receive("timeout", () =>
|
|
102524
|
+
push2.receive("ok", () => resolve5("ok"));
|
|
102525
|
+
push2.receive("error", () => resolve5("error"));
|
|
102526
|
+
push2.receive("timeout", () => resolve5("timed out"));
|
|
102437
102527
|
});
|
|
102438
102528
|
}
|
|
102439
102529
|
}
|
|
@@ -102458,8 +102548,8 @@ var require_RealtimeChannel = __commonJS({
|
|
|
102458
102548
|
* @category Realtime
|
|
102459
102549
|
*/
|
|
102460
102550
|
async unsubscribe(timeout = this.timeout) {
|
|
102461
|
-
return new Promise((
|
|
102462
|
-
this.channelAdapter.unsubscribe(timeout).receive("ok", () =>
|
|
102551
|
+
return new Promise((resolve5) => {
|
|
102552
|
+
this.channelAdapter.unsubscribe(timeout).receive("ok", () => resolve5("ok")).receive("timeout", () => resolve5("timed out")).receive("error", () => resolve5("error"));
|
|
102463
102553
|
});
|
|
102464
102554
|
}
|
|
102465
102555
|
/**
|
|
@@ -102540,8 +102630,8 @@ var require_RealtimeChannel = __commonJS({
|
|
|
102540
102630
|
}
|
|
102541
102631
|
/** @internal */
|
|
102542
102632
|
_notThisChannelEvent(event, ref) {
|
|
102543
|
-
const { close, error, leave, join } = constants_1.CHANNEL_EVENTS;
|
|
102544
|
-
const events = [close, error, leave,
|
|
102633
|
+
const { close, error, leave, join: join2 } = constants_1.CHANNEL_EVENTS;
|
|
102634
|
+
const events = [close, error, leave, join2];
|
|
102545
102635
|
return ref && events.includes(event) && ref !== this.joinPush.ref;
|
|
102546
102636
|
}
|
|
102547
102637
|
/** @internal */
|
|
@@ -102663,11 +102753,11 @@ var require_socketAdapter = __commonJS({
|
|
|
102663
102753
|
this.socket.connect();
|
|
102664
102754
|
}
|
|
102665
102755
|
disconnect(callback, code, reason, timeout = 1e4) {
|
|
102666
|
-
return new Promise((
|
|
102667
|
-
setTimeout(() =>
|
|
102756
|
+
return new Promise((resolve5) => {
|
|
102757
|
+
setTimeout(() => resolve5("timeout"), timeout);
|
|
102668
102758
|
this.socket.disconnect(() => {
|
|
102669
102759
|
callback();
|
|
102670
|
-
|
|
102760
|
+
resolve5("ok");
|
|
102671
102761
|
}, code, reason);
|
|
102672
102762
|
});
|
|
102673
102763
|
}
|
|
@@ -104213,7 +104303,7 @@ var require_dist3 = __commonJS({
|
|
|
104213
104303
|
return _objectSpread24(_objectSpread24({}, params), parameters);
|
|
104214
104304
|
};
|
|
104215
104305
|
async function _handleRequest2(fetcher, method, url, options, parameters, body, namespace) {
|
|
104216
|
-
return new Promise((
|
|
104306
|
+
return new Promise((resolve5, reject2) => {
|
|
104217
104307
|
fetcher(url, _getRequestParams2(method, options, parameters, body)).then((result2) => {
|
|
104218
104308
|
if (!result2.ok) throw result2;
|
|
104219
104309
|
if (options === null || options === void 0 ? void 0 : options.noResolveJson) return result2;
|
|
@@ -104223,7 +104313,7 @@ var require_dist3 = __commonJS({
|
|
|
104223
104313
|
if (!contentType || !contentType.includes("application/json")) return {};
|
|
104224
104314
|
}
|
|
104225
104315
|
return result2.json();
|
|
104226
|
-
}).then((data) =>
|
|
104316
|
+
}).then((data) => resolve5(data)).catch((error) => handleError2(error, reject2, options, namespace));
|
|
104227
104317
|
});
|
|
104228
104318
|
}
|
|
104229
104319
|
function createFetchApi2(namespace = "storage") {
|
|
@@ -114757,11 +114847,11 @@ var require_dist4 = __commonJS({
|
|
|
114757
114847
|
};
|
|
114758
114848
|
function __awaiter3(thisArg, _arguments, P, generator) {
|
|
114759
114849
|
function adopt(value) {
|
|
114760
|
-
return value instanceof P ? value : new P(function(
|
|
114761
|
-
|
|
114850
|
+
return value instanceof P ? value : new P(function(resolve5) {
|
|
114851
|
+
resolve5(value);
|
|
114762
114852
|
});
|
|
114763
114853
|
}
|
|
114764
|
-
return new (P || (P = Promise))(function(
|
|
114854
|
+
return new (P || (P = Promise))(function(resolve5, reject2) {
|
|
114765
114855
|
function fulfilled(value) {
|
|
114766
114856
|
try {
|
|
114767
114857
|
step(generator.next(value));
|
|
@@ -114777,7 +114867,7 @@ var require_dist4 = __commonJS({
|
|
|
114777
114867
|
}
|
|
114778
114868
|
}
|
|
114779
114869
|
function step(result2) {
|
|
114780
|
-
result2.done ?
|
|
114870
|
+
result2.done ? resolve5(result2.value) : adopt(result2.value).then(fulfilled, rejected);
|
|
114781
114871
|
}
|
|
114782
114872
|
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
114783
114873
|
});
|
|
@@ -118758,18 +118848,18 @@ var init_streamNormalizer = __esm({
|
|
|
118758
118848
|
|
|
118759
118849
|
// node_modules/@supabase/postgrest-js/dist/index.mjs
|
|
118760
118850
|
function sleep(ms, signal) {
|
|
118761
|
-
return new Promise((
|
|
118851
|
+
return new Promise((resolve5) => {
|
|
118762
118852
|
if (signal === null || signal === void 0 ? void 0 : signal.aborted) {
|
|
118763
|
-
|
|
118853
|
+
resolve5();
|
|
118764
118854
|
return;
|
|
118765
118855
|
}
|
|
118766
118856
|
const id = setTimeout(() => {
|
|
118767
118857
|
signal === null || signal === void 0 || signal.removeEventListener("abort", onAbort);
|
|
118768
|
-
|
|
118858
|
+
resolve5();
|
|
118769
118859
|
}, ms);
|
|
118770
118860
|
function onAbort() {
|
|
118771
118861
|
clearTimeout(id);
|
|
118772
|
-
|
|
118862
|
+
resolve5();
|
|
118773
118863
|
}
|
|
118774
118864
|
signal === null || signal === void 0 || signal.addEventListener("abort", onAbort);
|
|
118775
118865
|
});
|
|
@@ -124304,7 +124394,7 @@ function normalizeHeaders(headers) {
|
|
|
124304
124394
|
return result2;
|
|
124305
124395
|
}
|
|
124306
124396
|
async function _handleRequest(fetcher, method, url, options, parameters, body, namespace) {
|
|
124307
|
-
return new Promise((
|
|
124397
|
+
return new Promise((resolve5, reject2) => {
|
|
124308
124398
|
fetcher(url, _getRequestParams(method, options, parameters, body)).then((result2) => {
|
|
124309
124399
|
if (!result2.ok) throw result2;
|
|
124310
124400
|
if (options === null || options === void 0 ? void 0 : options.noResolveJson) return result2;
|
|
@@ -124314,7 +124404,7 @@ async function _handleRequest(fetcher, method, url, options, parameters, body, n
|
|
|
124314
124404
|
if (!contentType || !contentType.includes("application/json")) return {};
|
|
124315
124405
|
}
|
|
124316
124406
|
return result2.json();
|
|
124317
|
-
}).then((data) =>
|
|
124407
|
+
}).then((data) => resolve5(data)).catch((error) => handleError(error, reject2, options, namespace));
|
|
124318
124408
|
});
|
|
124319
124409
|
}
|
|
124320
124410
|
function createFetchApi(namespace = "storage") {
|
|
@@ -126932,11 +127022,11 @@ __export(dist_exports, {
|
|
|
126932
127022
|
});
|
|
126933
127023
|
function __awaiter2(thisArg, _arguments, P, generator) {
|
|
126934
127024
|
function adopt(value) {
|
|
126935
|
-
return value instanceof P ? value : new P(function(
|
|
126936
|
-
|
|
127025
|
+
return value instanceof P ? value : new P(function(resolve5) {
|
|
127026
|
+
resolve5(value);
|
|
126937
127027
|
});
|
|
126938
127028
|
}
|
|
126939
|
-
return new (P || (P = Promise))(function(
|
|
127029
|
+
return new (P || (P = Promise))(function(resolve5, reject2) {
|
|
126940
127030
|
function fulfilled(value) {
|
|
126941
127031
|
try {
|
|
126942
127032
|
step(generator.next(value));
|
|
@@ -126952,7 +127042,7 @@ function __awaiter2(thisArg, _arguments, P, generator) {
|
|
|
126952
127042
|
}
|
|
126953
127043
|
}
|
|
126954
127044
|
function step(result2) {
|
|
126955
|
-
result2.done ?
|
|
127045
|
+
result2.done ? resolve5(result2.value) : adopt(result2.value).then(fulfilled, rejected);
|
|
126956
127046
|
}
|
|
126957
127047
|
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
126958
127048
|
});
|
|
@@ -128257,12 +128347,12 @@ async function callAutoRaced(opts, parallelism) {
|
|
|
128257
128347
|
}
|
|
128258
128348
|
async function firstSuccessful(promises) {
|
|
128259
128349
|
const pending = new Set(promises);
|
|
128260
|
-
return new Promise((
|
|
128350
|
+
return new Promise((resolve5, reject2) => {
|
|
128261
128351
|
promises.forEach((promise) => {
|
|
128262
128352
|
promise.then((outcome) => {
|
|
128263
128353
|
pending.delete(promise);
|
|
128264
128354
|
if ("result" in outcome) {
|
|
128265
|
-
|
|
128355
|
+
resolve5(outcome);
|
|
128266
128356
|
} else if (pending.size === 0) {
|
|
128267
128357
|
reject2(new Error(`All ${promises.length} racers failed`));
|
|
128268
128358
|
}
|
|
@@ -130156,7 +130246,7 @@ function createProviderAbortSignal(parent, timeoutMs = AUTO_ROUTER_PROVIDER_TIME
|
|
|
130156
130246
|
};
|
|
130157
130247
|
}
|
|
130158
130248
|
function readStreamChunkWithIdleTimeout(reader, idleMs, abortSignal) {
|
|
130159
|
-
return new Promise((
|
|
130249
|
+
return new Promise((resolve5, reject2) => {
|
|
130160
130250
|
const timer = setTimeout(
|
|
130161
130251
|
() => reject2(new Error(`stream idle timeout after ${idleMs}ms`)),
|
|
130162
130252
|
idleMs
|
|
@@ -130177,7 +130267,7 @@ function readStreamChunkWithIdleTimeout(reader, idleMs, abortSignal) {
|
|
|
130177
130267
|
(result2) => {
|
|
130178
130268
|
clearTimeout(timer);
|
|
130179
130269
|
if (abortSignal) abortSignal.removeEventListener("abort", onAbort);
|
|
130180
|
-
|
|
130270
|
+
resolve5(result2);
|
|
130181
130271
|
},
|
|
130182
130272
|
(err) => {
|
|
130183
130273
|
clearTimeout(timer);
|
|
@@ -133824,8 +133914,8 @@ function validateArgs(name, args) {
|
|
|
133824
133914
|
return `${name}.path must be a safe path.`;
|
|
133825
133915
|
return null;
|
|
133826
133916
|
case TOOL_NAMES.writeLocalFile:
|
|
133827
|
-
if (!
|
|
133828
|
-
return "writeLocalFile.path must be a
|
|
133917
|
+
if (!isSafeFilePath(args.path))
|
|
133918
|
+
return "writeLocalFile.path must be a safe local path.";
|
|
133829
133919
|
if (typeof args.content !== "string")
|
|
133830
133920
|
return "writeLocalFile.content must be a string.";
|
|
133831
133921
|
if (args.overwrite !== void 0 && typeof args.overwrite !== "boolean")
|
|
@@ -133833,20 +133923,20 @@ function validateArgs(name, args) {
|
|
|
133833
133923
|
return null;
|
|
133834
133924
|
case TOOL_NAMES.moveLocalFile:
|
|
133835
133925
|
case TOOL_NAMES.copyLocalFile:
|
|
133836
|
-
if (!
|
|
133837
|
-
return `${name}.from must be a safe
|
|
133838
|
-
if (!
|
|
133839
|
-
return `${name}.to must be a safe
|
|
133926
|
+
if (!isSafeFilePath(args.from))
|
|
133927
|
+
return `${name}.from must be a safe local path.`;
|
|
133928
|
+
if (!isSafeFilePath(args.to))
|
|
133929
|
+
return `${name}.to must be a safe local path.`;
|
|
133840
133930
|
return null;
|
|
133841
133931
|
case TOOL_NAMES.createDirectory:
|
|
133842
133932
|
case TOOL_NAMES.deleteLocalFile:
|
|
133843
133933
|
case TOOL_NAMES.printFile:
|
|
133844
|
-
if (!
|
|
133845
|
-
return `${name}.path must be a safe
|
|
133934
|
+
if (!isSafeFilePath(args.path))
|
|
133935
|
+
return `${name}.path must be a safe local path.`;
|
|
133846
133936
|
return null;
|
|
133847
133937
|
case TOOL_NAMES.editLocalFile:
|
|
133848
|
-
if (!
|
|
133849
|
-
return "editLocalFile.path must be a safe
|
|
133938
|
+
if (!isSafeFilePath(args.path))
|
|
133939
|
+
return "editLocalFile.path must be a safe local path.";
|
|
133850
133940
|
if (typeof args.oldText !== "string" || !args.oldText)
|
|
133851
133941
|
return "editLocalFile.oldText must be a non-empty string.";
|
|
133852
133942
|
if (typeof args.newText !== "string")
|
|
@@ -133871,8 +133961,8 @@ function validateArgs(name, args) {
|
|
|
133871
133961
|
return "listLocalSources.maxResults must be a positive number.";
|
|
133872
133962
|
return null;
|
|
133873
133963
|
case TOOL_NAMES.readLocalSourceFile:
|
|
133874
|
-
if (!isSafeLocalSourceId(args.localSourceId) && !
|
|
133875
|
-
return "readLocalSourceFile.localSourceId must be a valid local source id or safe
|
|
133964
|
+
if (!isSafeLocalSourceId(args.localSourceId) && !isSafeFilePath(args.localSourceId))
|
|
133965
|
+
return "readLocalSourceFile.localSourceId must be a valid local source id or safe local path.";
|
|
133876
133966
|
return null;
|
|
133877
133967
|
case TOOL_NAMES.generateAPAuditPacket:
|
|
133878
133968
|
if (typeof args.folderPath !== "string" || !args.folderPath.trim())
|
|
@@ -134140,7 +134230,7 @@ function isSafeFilePath(value) {
|
|
|
134140
134230
|
if (typeof value !== "string") return false;
|
|
134141
134231
|
const trimmed = value.trim();
|
|
134142
134232
|
if (!trimmed) return false;
|
|
134143
|
-
if (/^file:/i.test(trimmed) || trimmed.includes("::")
|
|
134233
|
+
if (/^file:/i.test(trimmed) || trimmed.includes("::"))
|
|
134144
134234
|
return false;
|
|
134145
134235
|
return !trimmed.split(/[\\/]+/).includes("..");
|
|
134146
134236
|
}
|
|
@@ -134423,13 +134513,13 @@ function getDesktopToolDefinitions() {
|
|
|
134423
134513
|
type: "function",
|
|
134424
134514
|
function: {
|
|
134425
134515
|
name: TOOL_NAMES.writeLocalFile,
|
|
134426
|
-
description: "Create or overwrite a local UTF-8 text file. Permission mode controls whether it runs immediately or asks for approval.",
|
|
134516
|
+
description: "Create or overwrite a local UTF-8 text file. Accepts absolute paths, ~/ paths, or paths relative to the current local working directory. Permission mode controls whether it runs immediately or asks for approval.",
|
|
134427
134517
|
parameters: {
|
|
134428
134518
|
type: "object",
|
|
134429
134519
|
properties: {
|
|
134430
134520
|
path: {
|
|
134431
134521
|
type: "string",
|
|
134432
|
-
description: "
|
|
134522
|
+
description: "Path to write. May be absolute, ~/..., or relative to the current local working directory."
|
|
134433
134523
|
},
|
|
134434
134524
|
content: {
|
|
134435
134525
|
type: "string",
|
|
@@ -134449,17 +134539,17 @@ function getDesktopToolDefinitions() {
|
|
|
134449
134539
|
type: "function",
|
|
134450
134540
|
function: {
|
|
134451
134541
|
name: TOOL_NAMES.moveLocalFile,
|
|
134452
|
-
description: "Move or rename a file
|
|
134542
|
+
description: "Move or rename a local file. Accepts absolute paths, ~/ paths, or paths relative to the current local working directory. Write-tier risk.",
|
|
134453
134543
|
parameters: {
|
|
134454
134544
|
type: "object",
|
|
134455
134545
|
properties: {
|
|
134456
134546
|
from: {
|
|
134457
134547
|
type: "string",
|
|
134458
|
-
description: "
|
|
134548
|
+
description: "Source path to move."
|
|
134459
134549
|
},
|
|
134460
134550
|
to: {
|
|
134461
134551
|
type: "string",
|
|
134462
|
-
description: "
|
|
134552
|
+
description: "Destination path."
|
|
134463
134553
|
}
|
|
134464
134554
|
},
|
|
134465
134555
|
required: ["from", "to"],
|
|
@@ -134471,17 +134561,17 @@ function getDesktopToolDefinitions() {
|
|
|
134471
134561
|
type: "function",
|
|
134472
134562
|
function: {
|
|
134473
134563
|
name: TOOL_NAMES.copyLocalFile,
|
|
134474
|
-
description: "Copy a file
|
|
134564
|
+
description: "Copy a local file. Accepts absolute paths, ~/ paths, or paths relative to the current local working directory. Write-tier risk.",
|
|
134475
134565
|
parameters: {
|
|
134476
134566
|
type: "object",
|
|
134477
134567
|
properties: {
|
|
134478
134568
|
from: {
|
|
134479
134569
|
type: "string",
|
|
134480
|
-
description: "
|
|
134570
|
+
description: "Source path to copy."
|
|
134481
134571
|
},
|
|
134482
134572
|
to: {
|
|
134483
134573
|
type: "string",
|
|
134484
|
-
description: "
|
|
134574
|
+
description: "Destination path."
|
|
134485
134575
|
}
|
|
134486
134576
|
},
|
|
134487
134577
|
required: ["from", "to"],
|
|
@@ -134493,13 +134583,13 @@ function getDesktopToolDefinitions() {
|
|
|
134493
134583
|
type: "function",
|
|
134494
134584
|
function: {
|
|
134495
134585
|
name: TOOL_NAMES.createDirectory,
|
|
134496
|
-
description: "Create a
|
|
134586
|
+
description: "Create a local directory recursively (mkdir -p). Accepts absolute paths, ~/ paths, or paths relative to the current local working directory. Write-tier risk.",
|
|
134497
134587
|
parameters: {
|
|
134498
134588
|
type: "object",
|
|
134499
134589
|
properties: {
|
|
134500
134590
|
path: {
|
|
134501
134591
|
type: "string",
|
|
134502
|
-
description: "
|
|
134592
|
+
description: "Directory path to create."
|
|
134503
134593
|
}
|
|
134504
134594
|
},
|
|
134505
134595
|
required: ["path"],
|
|
@@ -134511,13 +134601,13 @@ function getDesktopToolDefinitions() {
|
|
|
134511
134601
|
type: "function",
|
|
134512
134602
|
function: {
|
|
134513
134603
|
name: TOOL_NAMES.deleteLocalFile,
|
|
134514
|
-
description: "Delete a single
|
|
134604
|
+
description: "Delete a single local file. Accepts absolute paths, ~/ paths, or paths relative to the current local working directory. Lower permission modes ask for approval; Take the Wheel runs it without asking.",
|
|
134515
134605
|
parameters: {
|
|
134516
134606
|
type: "object",
|
|
134517
134607
|
properties: {
|
|
134518
134608
|
path: {
|
|
134519
134609
|
type: "string",
|
|
134520
|
-
description: "
|
|
134610
|
+
description: "File path to delete."
|
|
134521
134611
|
}
|
|
134522
134612
|
},
|
|
134523
134613
|
required: ["path"],
|
|
@@ -134529,13 +134619,13 @@ function getDesktopToolDefinitions() {
|
|
|
134529
134619
|
type: "function",
|
|
134530
134620
|
function: {
|
|
134531
134621
|
name: TOOL_NAMES.printFile,
|
|
134532
|
-
description: "Send a
|
|
134622
|
+
description: "Send a local file to the default printer using the system print command. Write-tier risk.",
|
|
134533
134623
|
parameters: {
|
|
134534
134624
|
type: "object",
|
|
134535
134625
|
properties: {
|
|
134536
134626
|
path: {
|
|
134537
134627
|
type: "string",
|
|
134538
|
-
description: "
|
|
134628
|
+
description: "File path to print."
|
|
134539
134629
|
}
|
|
134540
134630
|
},
|
|
134541
134631
|
required: ["path"],
|
|
@@ -134547,13 +134637,13 @@ function getDesktopToolDefinitions() {
|
|
|
134547
134637
|
type: "function",
|
|
134548
134638
|
function: {
|
|
134549
134639
|
name: TOOL_NAMES.editLocalFile,
|
|
134550
|
-
description: "Exact find/replace edit in a
|
|
134640
|
+
description: "Exact find/replace edit in a local UTF-8 text file. Accepts absolute paths, ~/ paths, or paths relative to the current local working directory. Lower permission modes ask for approval; Take the Wheel runs it without asking.",
|
|
134551
134641
|
parameters: {
|
|
134552
134642
|
type: "object",
|
|
134553
134643
|
properties: {
|
|
134554
134644
|
path: {
|
|
134555
134645
|
type: "string",
|
|
134556
|
-
description: "
|
|
134646
|
+
description: "Path to edit."
|
|
134557
134647
|
},
|
|
134558
134648
|
oldText: { type: "string", description: "Exact text to replace." },
|
|
134559
134649
|
newText: { type: "string", description: "Replacement text." },
|
|
@@ -138738,8 +138828,8 @@ var init_capabilityBus = __esm({
|
|
|
138738
138828
|
}
|
|
138739
138829
|
let resolvePromise = () => {
|
|
138740
138830
|
};
|
|
138741
|
-
const promise = new Promise((
|
|
138742
|
-
resolvePromise =
|
|
138831
|
+
const promise = new Promise((resolve5) => {
|
|
138832
|
+
resolvePromise = resolve5;
|
|
138743
138833
|
});
|
|
138744
138834
|
const createdAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
138745
138835
|
const request = {
|
|
@@ -138796,7 +138886,7 @@ var init_capabilityBus = __esm({
|
|
|
138796
138886
|
return true;
|
|
138797
138887
|
}
|
|
138798
138888
|
getPending(sessionId) {
|
|
138799
|
-
return Array.from(this.pending.values()).filter((entry) => !sessionId || entry.sessionId === sessionId).map(({ resolve:
|
|
138889
|
+
return Array.from(this.pending.values()).filter((entry) => !sessionId || entry.sessionId === sessionId).map(({ resolve: resolve5, promise, ...request }) => request);
|
|
138800
138890
|
}
|
|
138801
138891
|
dispatchBrowserEvent(type, payload) {
|
|
138802
138892
|
if (typeof window === "undefined") return;
|
|
@@ -139236,7 +139326,7 @@ function createAbortableBrowserDriver(driver, signal, timeoutMs = DEFAULT_BROWSE
|
|
|
139236
139326
|
};
|
|
139237
139327
|
}
|
|
139238
139328
|
function withAbortAndTimeout(promise, signal, timeoutMs, label) {
|
|
139239
|
-
return new Promise((
|
|
139329
|
+
return new Promise((resolve5, reject2) => {
|
|
139240
139330
|
if (signal?.aborted) {
|
|
139241
139331
|
reject2(abortError(`${label} cancelled.`));
|
|
139242
139332
|
return;
|
|
@@ -139262,7 +139352,7 @@ function withAbortAndTimeout(promise, signal, timeoutMs, label) {
|
|
|
139262
139352
|
);
|
|
139263
139353
|
}
|
|
139264
139354
|
promise.then(
|
|
139265
|
-
(value) => finish(() =>
|
|
139355
|
+
(value) => finish(() => resolve5(value)),
|
|
139266
139356
|
(error) => finish(() => reject2(error))
|
|
139267
139357
|
);
|
|
139268
139358
|
});
|
|
@@ -140021,7 +140111,7 @@ async function maybeWaitForCapabilityAndRetry(failureKind, input, runtime, snaps
|
|
|
140021
140111
|
function waitForAbortable(promise, signal) {
|
|
140022
140112
|
if (!signal) return promise;
|
|
140023
140113
|
if (signal.aborted) return Promise.reject(new DOMException("Browser action cancelled.", "AbortError"));
|
|
140024
|
-
return new Promise((
|
|
140114
|
+
return new Promise((resolve5, reject2) => {
|
|
140025
140115
|
const onAbort = () => {
|
|
140026
140116
|
signal.removeEventListener("abort", onAbort);
|
|
140027
140117
|
reject2(new DOMException("Browser action cancelled.", "AbortError"));
|
|
@@ -140030,7 +140120,7 @@ function waitForAbortable(promise, signal) {
|
|
|
140030
140120
|
promise.then(
|
|
140031
140121
|
(value) => {
|
|
140032
140122
|
signal.removeEventListener("abort", onAbort);
|
|
140033
|
-
|
|
140123
|
+
resolve5(value);
|
|
140034
140124
|
},
|
|
140035
140125
|
(error) => {
|
|
140036
140126
|
signal.removeEventListener("abort", onAbort);
|
|
@@ -140726,8 +140816,8 @@ function pasteShortcut() {
|
|
|
140726
140816
|
}
|
|
140727
140817
|
function browserShortcut(key) {
|
|
140728
140818
|
const override = (typeof process !== "undefined" ? process.env?.PERCH_PLAYWRIGHT_OS : "")?.toLowerCase();
|
|
140729
|
-
const
|
|
140730
|
-
const isMac = override === "mac" || override !== "windows" && override !== "linux" &&
|
|
140819
|
+
const platform3 = (typeof process !== "undefined" ? process.platform : "") ?? "";
|
|
140820
|
+
const isMac = override === "mac" || override !== "windows" && override !== "linux" && platform3 === "darwin";
|
|
140731
140821
|
return isMac ? `Meta+${key}` : `Control+${key}`;
|
|
140732
140822
|
}
|
|
140733
140823
|
function failureMessage(kind) {
|
|
@@ -140766,12 +140856,12 @@ function isAbortError(err) {
|
|
|
140766
140856
|
return err instanceof DOMException && err.name === "AbortError";
|
|
140767
140857
|
}
|
|
140768
140858
|
function delay(ms, signal) {
|
|
140769
|
-
return new Promise((
|
|
140859
|
+
return new Promise((resolve5, reject2) => {
|
|
140770
140860
|
if (signal?.aborted) {
|
|
140771
140861
|
reject2(new DOMException("Browser action cancelled.", "AbortError"));
|
|
140772
140862
|
return;
|
|
140773
140863
|
}
|
|
140774
|
-
const timeout = globalThis.setTimeout(
|
|
140864
|
+
const timeout = globalThis.setTimeout(resolve5, ms);
|
|
140775
140865
|
signal?.addEventListener(
|
|
140776
140866
|
"abort",
|
|
140777
140867
|
() => {
|
|
@@ -141197,12 +141287,12 @@ function toStringArray2(value) {
|
|
|
141197
141287
|
return result2.length > 0 ? result2 : void 0;
|
|
141198
141288
|
}
|
|
141199
141289
|
function pause(ms, signal) {
|
|
141200
|
-
return new Promise((
|
|
141290
|
+
return new Promise((resolve5, reject2) => {
|
|
141201
141291
|
if (signal?.aborted) {
|
|
141202
141292
|
reject2(new DOMException("Browser research cancelled.", "AbortError"));
|
|
141203
141293
|
return;
|
|
141204
141294
|
}
|
|
141205
|
-
const timer = setTimeout(
|
|
141295
|
+
const timer = setTimeout(resolve5, ms);
|
|
141206
141296
|
signal?.addEventListener(
|
|
141207
141297
|
"abort",
|
|
141208
141298
|
() => {
|
|
@@ -141589,7 +141679,7 @@ async function fetchData(url, type = "text") {
|
|
|
141589
141679
|
}
|
|
141590
141680
|
return response.text();
|
|
141591
141681
|
}
|
|
141592
|
-
return new Promise((
|
|
141682
|
+
return new Promise((resolve5, reject2) => {
|
|
141593
141683
|
const request = new XMLHttpRequest();
|
|
141594
141684
|
request.open("GET", url, true);
|
|
141595
141685
|
request.responseType = type;
|
|
@@ -141602,10 +141692,10 @@ async function fetchData(url, type = "text") {
|
|
|
141602
141692
|
case "arraybuffer":
|
|
141603
141693
|
case "blob":
|
|
141604
141694
|
case "json":
|
|
141605
|
-
|
|
141695
|
+
resolve5(request.response);
|
|
141606
141696
|
return;
|
|
141607
141697
|
}
|
|
141608
|
-
|
|
141698
|
+
resolve5(request.responseText);
|
|
141609
141699
|
return;
|
|
141610
141700
|
}
|
|
141611
141701
|
reject2(new Error(request.statusText));
|
|
@@ -144612,7 +144702,7 @@ var init_pdf = __esm({
|
|
|
144612
144702
|
var defineProperty = Object.defineProperty;
|
|
144613
144703
|
var stringSlice = uncurryThis("".slice);
|
|
144614
144704
|
var replace = uncurryThis("".replace);
|
|
144615
|
-
var
|
|
144705
|
+
var join2 = uncurryThis([].join);
|
|
144616
144706
|
var CONFIGURABLE_LENGTH = DESCRIPTORS && !fails(function() {
|
|
144617
144707
|
return defineProperty(function() {
|
|
144618
144708
|
}, "length", { value: 8 }).length !== 8;
|
|
@@ -144639,7 +144729,7 @@ var init_pdf = __esm({
|
|
|
144639
144729
|
}
|
|
144640
144730
|
var state = enforceInternalState(value);
|
|
144641
144731
|
if (!hasOwn(state, "source")) {
|
|
144642
|
-
state.source =
|
|
144732
|
+
state.source = join2(TEMPLATE, typeof name == "string" ? name : "");
|
|
144643
144733
|
}
|
|
144644
144734
|
return value;
|
|
144645
144735
|
};
|
|
@@ -144667,13 +144757,13 @@ var init_pdf = __esm({
|
|
|
144667
144757
|
var aCallable = __webpack_require__2(9306);
|
|
144668
144758
|
var $TypeError = TypeError;
|
|
144669
144759
|
var PromiseCapability = function(C) {
|
|
144670
|
-
var
|
|
144760
|
+
var resolve5, reject2;
|
|
144671
144761
|
this.promise = new C(function($$resolve, $$reject) {
|
|
144672
|
-
if (
|
|
144673
|
-
|
|
144762
|
+
if (resolve5 !== void 0 || reject2 !== void 0) throw new $TypeError("Bad Promise constructor");
|
|
144763
|
+
resolve5 = $$resolve;
|
|
144674
144764
|
reject2 = $$reject;
|
|
144675
144765
|
});
|
|
144676
|
-
this.resolve = aCallable(
|
|
144766
|
+
this.resolve = aCallable(resolve5);
|
|
144677
144767
|
this.reject = aCallable(reject2);
|
|
144678
144768
|
};
|
|
144679
144769
|
module2.exports.f = function(C) {
|
|
@@ -147791,11 +147881,11 @@ var init_pdf = __esm({
|
|
|
147791
147881
|
const mustRemoveAspectRatioPromise = _ImageManager._isSVGFittingCanvas;
|
|
147792
147882
|
const fileReader = new FileReader();
|
|
147793
147883
|
const imageElement = new Image();
|
|
147794
|
-
const imagePromise = new Promise((
|
|
147884
|
+
const imagePromise = new Promise((resolve5, reject2) => {
|
|
147795
147885
|
imageElement.onload = () => {
|
|
147796
147886
|
data.bitmap = imageElement;
|
|
147797
147887
|
data.isSvg = true;
|
|
147798
|
-
|
|
147888
|
+
resolve5();
|
|
147799
147889
|
};
|
|
147800
147890
|
fileReader.onload = async () => {
|
|
147801
147891
|
const url = data.svgUrl = fileReader.result;
|
|
@@ -151644,8 +151734,8 @@ var init_pdf = __esm({
|
|
|
151644
151734
|
if (this.isSyncFontLoadingSupported) {
|
|
151645
151735
|
return;
|
|
151646
151736
|
}
|
|
151647
|
-
await new Promise((
|
|
151648
|
-
const request = this._queueLoadingCallback(
|
|
151737
|
+
await new Promise((resolve5) => {
|
|
151738
|
+
const request = this._queueLoadingCallback(resolve5);
|
|
151649
151739
|
this._prepareFontLoadEvent(font, request);
|
|
151650
151740
|
});
|
|
151651
151741
|
}
|
|
@@ -155985,8 +156075,8 @@ var init_pdf = __esm({
|
|
|
155985
156075
|
this._readCapability = Promise.withResolvers();
|
|
155986
156076
|
this._headersCapability = Promise.withResolvers();
|
|
155987
156077
|
const fs14 = process.getBuiltinModule("fs");
|
|
155988
|
-
fs14.promises.lstat(this._url).then((
|
|
155989
|
-
this._contentLength =
|
|
156078
|
+
fs14.promises.lstat(this._url).then((stat2) => {
|
|
156079
|
+
this._contentLength = stat2.size;
|
|
155990
156080
|
this._setReadableStream(fs14.createReadStream(this._url));
|
|
155991
156081
|
this._headersCapability.resolve();
|
|
155992
156082
|
}, (error) => {
|
|
@@ -157002,14 +157092,14 @@ var init_pdf = __esm({
|
|
|
157002
157092
|
return this.getXfa().then((xfa) => XfaText.textContent(xfa));
|
|
157003
157093
|
}
|
|
157004
157094
|
const readableStream = this.streamTextContent(params);
|
|
157005
|
-
return new Promise(function(
|
|
157095
|
+
return new Promise(function(resolve5, reject2) {
|
|
157006
157096
|
function pump() {
|
|
157007
157097
|
reader.read().then(function({
|
|
157008
157098
|
value,
|
|
157009
157099
|
done
|
|
157010
157100
|
}) {
|
|
157011
157101
|
if (done) {
|
|
157012
|
-
|
|
157102
|
+
resolve5(textContent);
|
|
157013
157103
|
return;
|
|
157014
157104
|
}
|
|
157015
157105
|
textContent.lang ??= value.lang;
|
|
@@ -165106,7 +165196,7 @@ var init_pdf = __esm({
|
|
|
165106
165196
|
input.type = "file";
|
|
165107
165197
|
input.accept = _StampEditor.supportedTypesStr;
|
|
165108
165198
|
const signal = this._uiManager._signal;
|
|
165109
|
-
this.#bitmapPromise = new Promise((
|
|
165199
|
+
this.#bitmapPromise = new Promise((resolve5) => {
|
|
165110
165200
|
input.addEventListener("change", async () => {
|
|
165111
165201
|
if (!input.files || input.files.length === 0) {
|
|
165112
165202
|
this.remove();
|
|
@@ -165121,13 +165211,13 @@ var init_pdf = __esm({
|
|
|
165121
165211
|
});
|
|
165122
165212
|
this.#getBitmapFetched(data);
|
|
165123
165213
|
}
|
|
165124
|
-
|
|
165214
|
+
resolve5();
|
|
165125
165215
|
}, {
|
|
165126
165216
|
signal
|
|
165127
165217
|
});
|
|
165128
165218
|
input.addEventListener("cancel", () => {
|
|
165129
165219
|
this.remove();
|
|
165130
|
-
|
|
165220
|
+
resolve5();
|
|
165131
165221
|
}, {
|
|
165132
165222
|
signal
|
|
165133
165223
|
});
|
|
@@ -170434,13 +170524,13 @@ var require_thenables = __commonJS({
|
|
|
170434
170524
|
promise._captureStackTrace();
|
|
170435
170525
|
if (context) context._popContext();
|
|
170436
170526
|
var synchronous = true;
|
|
170437
|
-
var result2 = util.tryCatch(then).call(x,
|
|
170527
|
+
var result2 = util.tryCatch(then).call(x, resolve5, reject2);
|
|
170438
170528
|
synchronous = false;
|
|
170439
170529
|
if (promise && result2 === errorObj2) {
|
|
170440
170530
|
promise._rejectCallback(result2.e, true, true);
|
|
170441
170531
|
promise = null;
|
|
170442
170532
|
}
|
|
170443
|
-
function
|
|
170533
|
+
function resolve5(value) {
|
|
170444
170534
|
if (!promise) return;
|
|
170445
170535
|
promise._resolveCallback(value);
|
|
170446
170536
|
promise = null;
|
|
@@ -170975,9 +171065,9 @@ var require_debuggability = __commonJS({
|
|
|
170975
171065
|
return false;
|
|
170976
171066
|
}
|
|
170977
171067
|
Promise2.prototype._fireEvent = defaultFireEvent;
|
|
170978
|
-
Promise2.prototype._execute = function(executor,
|
|
171068
|
+
Promise2.prototype._execute = function(executor, resolve5, reject2) {
|
|
170979
171069
|
try {
|
|
170980
|
-
executor(
|
|
171070
|
+
executor(resolve5, reject2);
|
|
170981
171071
|
} catch (e) {
|
|
170982
171072
|
return e;
|
|
170983
171073
|
}
|
|
@@ -171000,10 +171090,10 @@ var require_debuggability = __commonJS({
|
|
|
171000
171090
|
;
|
|
171001
171091
|
;
|
|
171002
171092
|
};
|
|
171003
|
-
function cancellationExecute(executor,
|
|
171093
|
+
function cancellationExecute(executor, resolve5, reject2) {
|
|
171004
171094
|
var promise = this;
|
|
171005
171095
|
try {
|
|
171006
|
-
executor(
|
|
171096
|
+
executor(resolve5, reject2, function(onCancel) {
|
|
171007
171097
|
if (typeof onCancel !== "function") {
|
|
171008
171098
|
throw new TypeError("onCancel must be a function, got: " + util.toString(onCancel));
|
|
171009
171099
|
}
|
|
@@ -173026,15 +173116,15 @@ var require_generators = __commonJS({
|
|
|
173026
173116
|
var stack = new Error().stack;
|
|
173027
173117
|
return function() {
|
|
173028
173118
|
var generator = generatorFunction.apply(this, arguments);
|
|
173029
|
-
var
|
|
173119
|
+
var spawn3 = new PromiseSpawn$(
|
|
173030
173120
|
void 0,
|
|
173031
173121
|
void 0,
|
|
173032
173122
|
yieldHandler,
|
|
173033
173123
|
stack
|
|
173034
173124
|
);
|
|
173035
|
-
var ret2 =
|
|
173036
|
-
|
|
173037
|
-
|
|
173125
|
+
var ret2 = spawn3.promise();
|
|
173126
|
+
spawn3._generator = generator;
|
|
173127
|
+
spawn3._promiseFulfilled(void 0);
|
|
173038
173128
|
return ret2;
|
|
173039
173129
|
};
|
|
173040
173130
|
};
|
|
@@ -173049,9 +173139,9 @@ var require_generators = __commonJS({
|
|
|
173049
173139
|
if (typeof generatorFunction !== "function") {
|
|
173050
173140
|
return apiRejection("generatorFunction must be a function\n\n See http://goo.gl/MqrFmX\n");
|
|
173051
173141
|
}
|
|
173052
|
-
var
|
|
173053
|
-
var ret2 =
|
|
173054
|
-
|
|
173142
|
+
var spawn3 = new PromiseSpawn(generatorFunction, this);
|
|
173143
|
+
var ret2 = spawn3.promise();
|
|
173144
|
+
spawn3._run(Promise2.spawn);
|
|
173055
173145
|
return ret2;
|
|
173056
173146
|
};
|
|
173057
173147
|
};
|
|
@@ -174649,14 +174739,14 @@ var require_promises = __commonJS({
|
|
|
174649
174739
|
});
|
|
174650
174740
|
};
|
|
174651
174741
|
function defer() {
|
|
174652
|
-
var
|
|
174742
|
+
var resolve5;
|
|
174653
174743
|
var reject2;
|
|
174654
174744
|
var promise = new bluebird.Promise(function(resolveArg, rejectArg) {
|
|
174655
|
-
|
|
174745
|
+
resolve5 = resolveArg;
|
|
174656
174746
|
reject2 = rejectArg;
|
|
174657
174747
|
});
|
|
174658
174748
|
return {
|
|
174659
|
-
resolve:
|
|
174749
|
+
resolve: resolve5,
|
|
174660
174750
|
reject: reject2,
|
|
174661
174751
|
promise
|
|
174662
174752
|
};
|
|
@@ -175345,7 +175435,7 @@ var require_BufferList = __commonJS({
|
|
|
175345
175435
|
this.head = this.tail = null;
|
|
175346
175436
|
this.length = 0;
|
|
175347
175437
|
};
|
|
175348
|
-
BufferList.prototype.join = function
|
|
175438
|
+
BufferList.prototype.join = function join2(s) {
|
|
175349
175439
|
if (this.length === 0) return "";
|
|
175350
175440
|
var p = this.head;
|
|
175351
175441
|
var ret2 = "" + p.data;
|
|
@@ -177320,8 +177410,8 @@ var require_lib4 = __commonJS({
|
|
|
177320
177410
|
return this;
|
|
177321
177411
|
}
|
|
177322
177412
|
var p = this.constructor;
|
|
177323
|
-
return this.then(
|
|
177324
|
-
function
|
|
177413
|
+
return this.then(resolve6, reject3);
|
|
177414
|
+
function resolve6(value) {
|
|
177325
177415
|
function yes() {
|
|
177326
177416
|
return value;
|
|
177327
177417
|
}
|
|
@@ -177474,8 +177564,8 @@ var require_lib4 = __commonJS({
|
|
|
177474
177564
|
}
|
|
177475
177565
|
return out;
|
|
177476
177566
|
}
|
|
177477
|
-
Promise2.resolve =
|
|
177478
|
-
function
|
|
177567
|
+
Promise2.resolve = resolve5;
|
|
177568
|
+
function resolve5(value) {
|
|
177479
177569
|
if (value instanceof this) {
|
|
177480
177570
|
return value;
|
|
177481
177571
|
}
|
|
@@ -178006,10 +178096,10 @@ var require_utils2 = __commonJS({
|
|
|
178006
178096
|
var promise = external.Promise.resolve(inputData).then(function(data) {
|
|
178007
178097
|
var isBlob = support.blob && (data instanceof Blob || ["[object File]", "[object Blob]"].indexOf(Object.prototype.toString.call(data)) !== -1);
|
|
178008
178098
|
if (isBlob && typeof FileReader !== "undefined") {
|
|
178009
|
-
return new external.Promise(function(
|
|
178099
|
+
return new external.Promise(function(resolve5, reject2) {
|
|
178010
178100
|
var reader = new FileReader();
|
|
178011
178101
|
reader.onload = function(e) {
|
|
178012
|
-
|
|
178102
|
+
resolve5(e.target.result);
|
|
178013
178103
|
};
|
|
178014
178104
|
reader.onerror = function(e) {
|
|
178015
178105
|
reject2(e.target.error);
|
|
@@ -178564,7 +178654,7 @@ var require_StreamHelper = __commonJS({
|
|
|
178564
178654
|
}
|
|
178565
178655
|
}
|
|
178566
178656
|
function accumulate(helper, updateCallback) {
|
|
178567
|
-
return new external.Promise(function(
|
|
178657
|
+
return new external.Promise(function(resolve5, reject2) {
|
|
178568
178658
|
var dataArray = [];
|
|
178569
178659
|
var chunkType = helper._internalType, resultType = helper._outputType, mimeType = helper._mimeType;
|
|
178570
178660
|
helper.on("data", function(data, meta) {
|
|
@@ -178578,7 +178668,7 @@ var require_StreamHelper = __commonJS({
|
|
|
178578
178668
|
}).on("end", function() {
|
|
178579
178669
|
try {
|
|
178580
178670
|
var result2 = transformZipOutput(resultType, concat(chunkType, dataArray), mimeType);
|
|
178581
|
-
|
|
178671
|
+
resolve5(result2);
|
|
178582
178672
|
} catch (e) {
|
|
178583
178673
|
reject2(e);
|
|
178584
178674
|
}
|
|
@@ -183370,7 +183460,7 @@ var require_ZipFileWorker = __commonJS({
|
|
|
183370
183460
|
var generateDosExternalFileAttr = function(dosPermissions) {
|
|
183371
183461
|
return (dosPermissions || 0) & 63;
|
|
183372
183462
|
};
|
|
183373
|
-
var generateZipParts = function(streamInfo, streamedContent, streamingEnded, offset,
|
|
183463
|
+
var generateZipParts = function(streamInfo, streamedContent, streamingEnded, offset, platform3, encodeFileName) {
|
|
183374
183464
|
var file = streamInfo["file"], compression = streamInfo["compression"], useCustomEncoding = encodeFileName !== utf8.utf8encode, encodedFileName = utils3.transformTo("string", encodeFileName(file.name)), utfEncodedFileName = utils3.transformTo("string", utf8.utf8encode(file.name)), comment = file.comment, encodedComment = utils3.transformTo("string", encodeFileName(comment)), utfEncodedComment = utils3.transformTo("string", utf8.utf8encode(comment)), useUTF8ForFileName = utfEncodedFileName.length !== file.name.length, useUTF8ForComment = utfEncodedComment.length !== comment.length, dosTime, dosDate, extraFields = "", unicodePathExtraField = "", unicodeCommentExtraField = "", dir = file.dir, date = file.date;
|
|
183375
183465
|
var dataInfo = {
|
|
183376
183466
|
crc32: 0,
|
|
@@ -183394,7 +183484,7 @@ var require_ZipFileWorker = __commonJS({
|
|
|
183394
183484
|
if (dir) {
|
|
183395
183485
|
extFileAttr |= 16;
|
|
183396
183486
|
}
|
|
183397
|
-
if (
|
|
183487
|
+
if (platform3 === "UNIX") {
|
|
183398
183488
|
versionMadeBy = 798;
|
|
183399
183489
|
extFileAttr |= generateUnixExternalFileAttr(file.unixPermissions, dir);
|
|
183400
183490
|
} else {
|
|
@@ -183479,11 +183569,11 @@ var require_ZipFileWorker = __commonJS({
|
|
|
183479
183569
|
decToHex(streamInfo["uncompressedSize"], 4);
|
|
183480
183570
|
return descriptor;
|
|
183481
183571
|
};
|
|
183482
|
-
function ZipFileWorker(streamFiles, comment,
|
|
183572
|
+
function ZipFileWorker(streamFiles, comment, platform3, encodeFileName) {
|
|
183483
183573
|
GenericWorker.call(this, "ZipFileWorker");
|
|
183484
183574
|
this.bytesWritten = 0;
|
|
183485
183575
|
this.zipComment = comment;
|
|
183486
|
-
this.zipPlatform =
|
|
183576
|
+
this.zipPlatform = platform3;
|
|
183487
183577
|
this.encodeFileName = encodeFileName;
|
|
183488
183578
|
this.streamFiles = streamFiles;
|
|
183489
183579
|
this.accumulate = false;
|
|
@@ -184691,7 +184781,7 @@ var require_load = __commonJS({
|
|
|
184691
184781
|
var Crc32Probe = require_Crc32Probe();
|
|
184692
184782
|
var nodejsUtils = require_nodejsUtils();
|
|
184693
184783
|
function checkEntryCRC32(zipEntry) {
|
|
184694
|
-
return new external.Promise(function(
|
|
184784
|
+
return new external.Promise(function(resolve5, reject2) {
|
|
184695
184785
|
var worker = zipEntry.decompressed.getContentWorker().pipe(new Crc32Probe());
|
|
184696
184786
|
worker.on("error", function(e) {
|
|
184697
184787
|
reject2(e);
|
|
@@ -184699,7 +184789,7 @@ var require_load = __commonJS({
|
|
|
184699
184789
|
if (worker.streamInfo.crc32 !== zipEntry.decompressed.crc32) {
|
|
184700
184790
|
reject2(new Error("Corrupted zip : CRC32 mismatch"));
|
|
184701
184791
|
} else {
|
|
184702
|
-
|
|
184792
|
+
resolve5();
|
|
184703
184793
|
}
|
|
184704
184794
|
}).resume();
|
|
184705
184795
|
});
|
|
@@ -194523,7 +194613,7 @@ var require_files = __commonJS({
|
|
|
194523
194613
|
var fs14 = __require("fs");
|
|
194524
194614
|
var url = __require("url");
|
|
194525
194615
|
var os6 = __require("os");
|
|
194526
|
-
var
|
|
194616
|
+
var dirname2 = __require("path").dirname;
|
|
194527
194617
|
var resolvePath2 = __require("path").resolve;
|
|
194528
194618
|
var isAbsolutePath2 = require_path_is_absolute();
|
|
194529
194619
|
var promises = require_promises();
|
|
@@ -194538,10 +194628,10 @@ var require_files = __commonJS({
|
|
|
194538
194628
|
}
|
|
194539
194629
|
};
|
|
194540
194630
|
}
|
|
194541
|
-
var base = options.relativeToFile ?
|
|
194631
|
+
var base = options.relativeToFile ? dirname2(options.relativeToFile) : null;
|
|
194542
194632
|
function read(uri, encoding) {
|
|
194543
194633
|
return resolveUri(uri).then(function(path14) {
|
|
194544
|
-
return
|
|
194634
|
+
return readFile4(path14, encoding).caught(function(error) {
|
|
194545
194635
|
var message = "could not open external image: '" + uri + "' (document directory: '" + base + "')\n" + error.message;
|
|
194546
194636
|
return promises.reject(new Error(message));
|
|
194547
194637
|
});
|
|
@@ -194561,15 +194651,15 @@ var require_files = __commonJS({
|
|
|
194561
194651
|
read
|
|
194562
194652
|
};
|
|
194563
194653
|
}
|
|
194564
|
-
var
|
|
194565
|
-
function uriToPath(uriString,
|
|
194566
|
-
if (!
|
|
194567
|
-
|
|
194654
|
+
var readFile4 = promises.promisify(fs14.readFile.bind(fs14));
|
|
194655
|
+
function uriToPath(uriString, platform3) {
|
|
194656
|
+
if (!platform3) {
|
|
194657
|
+
platform3 = os6.platform();
|
|
194568
194658
|
}
|
|
194569
194659
|
var uri = url.parse(uriString);
|
|
194570
194660
|
if (isLocalFileUri(uri) || isRelativeUri(uri)) {
|
|
194571
194661
|
var path14 = decodeURIComponent(uri.path);
|
|
194572
|
-
if (
|
|
194662
|
+
if (platform3 === "win32" && /^\/[a-z]:/i.test(path14)) {
|
|
194573
194663
|
return path14.slice(1);
|
|
194574
194664
|
} else {
|
|
194575
194665
|
return path14;
|
|
@@ -197278,10 +197368,10 @@ var require_unzip = __commonJS({
|
|
|
197278
197368
|
var promises = require_promises();
|
|
197279
197369
|
var zipfile = require_zipfile();
|
|
197280
197370
|
exports2.openZip = openZip;
|
|
197281
|
-
var
|
|
197371
|
+
var readFile4 = promises.promisify(fs14.readFile);
|
|
197282
197372
|
function openZip(options) {
|
|
197283
197373
|
if (options.path) {
|
|
197284
|
-
return
|
|
197374
|
+
return readFile4(options.path).then(zipfile.openArrayBuffer);
|
|
197285
197375
|
} else if (options.buffer) {
|
|
197286
197376
|
return promises.resolve(zipfile.openArrayBuffer(options.buffer));
|
|
197287
197377
|
} else if (options.file) {
|
|
@@ -198417,9 +198507,9 @@ async function resolveScopedLocalSourceId(localSourceIdOrRelativePath, scopedWor
|
|
|
198417
198507
|
if (localSourceIdOrRelativePath.includes("::")) return localSourceIdOrRelativePath;
|
|
198418
198508
|
const scope = await resolveLocalSourceScope(scopedWorkspaceRoot);
|
|
198419
198509
|
if (!scope) return localSourceIdOrRelativePath;
|
|
198420
|
-
const
|
|
198510
|
+
const relative2 = normalizeRelativePath(localSourceIdOrRelativePath);
|
|
198421
198511
|
const prefix = normalizeRelativePath(scope.relativePrefix);
|
|
198422
|
-
const scopedRelative = [prefix,
|
|
198512
|
+
const scopedRelative = [prefix, relative2].filter(Boolean).join("/");
|
|
198423
198513
|
return `${scope.rootId}::${scopedRelative}`;
|
|
198424
198514
|
}
|
|
198425
198515
|
async function resolveApprovedLocalSourceIdForAbsolutePath(pathValue) {
|
|
@@ -201827,8 +201917,8 @@ function buildWorkerSourceManifest(input) {
|
|
|
201827
201917
|
const exactNames = extractExplicitFileNames(input.objective);
|
|
201828
201918
|
const maxEntries = Math.max(1, Math.min(200, input.maxEntries ?? 80));
|
|
201829
201919
|
const candidates = sources.filter((source) => !isExcludedPath(source.relativePath)).filter((source) => {
|
|
201830
|
-
const
|
|
201831
|
-
if (selectedPrefixes.length > 0 && selectedPrefixes.some((prefix) =>
|
|
201920
|
+
const relative2 = normalize2(source.relativePath);
|
|
201921
|
+
if (selectedPrefixes.length > 0 && selectedPrefixes.some((prefix) => relative2.startsWith(`${prefix}/`) || relative2 === prefix)) {
|
|
201832
201922
|
return true;
|
|
201833
201923
|
}
|
|
201834
201924
|
if (exactNames.size > 0 && exactNames.has(source.fileName.toLowerCase())) {
|
|
@@ -201893,17 +201983,17 @@ function extractExplicitFileNames(objective) {
|
|
|
201893
201983
|
return names;
|
|
201894
201984
|
}
|
|
201895
201985
|
function sourceSortScore(source, objective) {
|
|
201896
|
-
const
|
|
201986
|
+
const relative2 = normalize2(source.relativePath);
|
|
201897
201987
|
const file = source.fileName.toLowerCase();
|
|
201898
201988
|
let score = 0;
|
|
201899
201989
|
if (objective.includes(file)) score += 100;
|
|
201900
|
-
if (
|
|
201990
|
+
if (relative2.includes("perch-output") || relative2.includes("perch-artifacts")) score -= 1e3;
|
|
201901
201991
|
if (/_\d{3}\.(?:txt|csv|md)$/i.test(file)) score -= 15;
|
|
201902
201992
|
if (file.endsWith(".csv")) score += 8;
|
|
201903
201993
|
if (file.endsWith(".txt") || file.endsWith(".md")) score += 5;
|
|
201904
201994
|
if (file.endsWith(".pdf")) score -= 3;
|
|
201905
201995
|
for (const token of objective.split(/[^a-z0-9]+/i).filter((t) => t.length >= 4)) {
|
|
201906
|
-
if (
|
|
201996
|
+
if (relative2.includes(token.toLowerCase())) score += 2;
|
|
201907
201997
|
}
|
|
201908
201998
|
return score;
|
|
201909
201999
|
}
|
|
@@ -202331,13 +202421,13 @@ function clamp2(value, min2, max2) {
|
|
|
202331
202421
|
return Math.max(min2, Math.min(max2, value));
|
|
202332
202422
|
}
|
|
202333
202423
|
function loadImage(dataUrl) {
|
|
202334
|
-
return new Promise((
|
|
202424
|
+
return new Promise((resolve5, reject2) => {
|
|
202335
202425
|
if (typeof Image === "undefined") {
|
|
202336
202426
|
reject2(new Error("Image API unavailable"));
|
|
202337
202427
|
return;
|
|
202338
202428
|
}
|
|
202339
202429
|
const image2 = new Image();
|
|
202340
|
-
image2.onload = () =>
|
|
202430
|
+
image2.onload = () => resolve5(image2);
|
|
202341
202431
|
image2.onerror = () => reject2(new Error("Failed to decode screenshot"));
|
|
202342
202432
|
image2.src = dataUrl;
|
|
202343
202433
|
});
|
|
@@ -202465,9 +202555,9 @@ function fitInside(width, height, maxWidth, maxHeight) {
|
|
|
202465
202555
|
};
|
|
202466
202556
|
}
|
|
202467
202557
|
async function loadImageElement(dataUrl) {
|
|
202468
|
-
return new Promise((
|
|
202558
|
+
return new Promise((resolve5, reject2) => {
|
|
202469
202559
|
const img = new Image();
|
|
202470
|
-
img.onload = () =>
|
|
202560
|
+
img.onload = () => resolve5(img);
|
|
202471
202561
|
img.onerror = () => reject2(new Error("Failed to decode screenshot data URL"));
|
|
202472
202562
|
img.src = dataUrl;
|
|
202473
202563
|
});
|
|
@@ -203689,14 +203779,14 @@ function adapterDriver(ctx) {
|
|
|
203689
203779
|
);
|
|
203690
203780
|
}
|
|
203691
203781
|
function adapterDelay(ms, signal) {
|
|
203692
|
-
return new Promise((
|
|
203782
|
+
return new Promise((resolve5, reject2) => {
|
|
203693
203783
|
if (signal?.aborted) {
|
|
203694
203784
|
reject2(new DOMException("Adapter wait cancelled.", "AbortError"));
|
|
203695
203785
|
return;
|
|
203696
203786
|
}
|
|
203697
203787
|
const timeout = setTimeout(() => {
|
|
203698
203788
|
signal?.removeEventListener("abort", onAbort);
|
|
203699
|
-
|
|
203789
|
+
resolve5();
|
|
203700
203790
|
}, ms);
|
|
203701
203791
|
const onAbort = () => {
|
|
203702
203792
|
clearTimeout(timeout);
|
|
@@ -205289,8 +205379,8 @@ var init_GoogleDocsAdapter = __esm({
|
|
|
205289
205379
|
|
|
205290
205380
|
// features/perchTerminal/runtime/playwright/adapters/GoogleSheetsAdapter.ts
|
|
205291
205381
|
function shortcut2(key) {
|
|
205292
|
-
const
|
|
205293
|
-
return /mac/i.test(
|
|
205382
|
+
const platform3 = typeof navigator === "undefined" ? "" : navigator.platform;
|
|
205383
|
+
return /mac/i.test(platform3) ? `Meta+${key}` : `Control+${key}`;
|
|
205294
205384
|
}
|
|
205295
205385
|
var GoogleSheetsAdapter;
|
|
205296
205386
|
var init_GoogleSheetsAdapter = __esm({
|
|
@@ -210307,6 +210397,7 @@ function buildContextSnapshotFromMetrics(threadId, metrics) {
|
|
|
210307
210397
|
consecutiveAutoCompactFailures: metrics.consecutiveAutoCompactFailures ?? 0,
|
|
210308
210398
|
autoCompactedAtIso: metrics.autoCompactedAtIso ?? null,
|
|
210309
210399
|
autoCompactedMessageCount: metrics.autoCompactedMessageCount,
|
|
210400
|
+
compactionReport: metrics.compactionReport,
|
|
210310
210401
|
contextResetAtIso: metrics.resetAtIso ?? null,
|
|
210311
210402
|
builtAtIso: builtAt,
|
|
210312
210403
|
createdAt: builtAt
|
|
@@ -212685,6 +212776,29 @@ var init_localSources = __esm({
|
|
|
212685
212776
|
classification: { native: false },
|
|
212686
212777
|
handler: async (args, ctx) => {
|
|
212687
212778
|
const workspaceRoot = effectiveWorkspaceRoot(ctx);
|
|
212779
|
+
const explicitPath = typeof args.path === "string" && args.path.trim() ? args.path.trim() : "";
|
|
212780
|
+
if (explicitPath) {
|
|
212781
|
+
const query2 = typeof args.query === "string" ? args.query.trim().toLowerCase() : "";
|
|
212782
|
+
const maxResults2 = sanitizeListLocalSourcesMaxResults(args.maxResults);
|
|
212783
|
+
const globbed = await listWorkspaceFilesGlob({
|
|
212784
|
+
workspaceRoot: explicitPath,
|
|
212785
|
+
pattern: "*",
|
|
212786
|
+
maxResults: MAX_LIST_LOCAL_SOURCES_MAX_RESULTS,
|
|
212787
|
+
fsAccessOverride: "allow_once"
|
|
212788
|
+
});
|
|
212789
|
+
const allMatches = globbed?.matches ?? [];
|
|
212790
|
+
const filtered = (query2 ? allMatches.filter((m) => m.toLowerCase().includes(query2)) : allMatches).slice(0, maxResults2);
|
|
212791
|
+
return {
|
|
212792
|
+
ok: true,
|
|
212793
|
+
scopedFolderPath: explicitPath,
|
|
212794
|
+
viaGlob: true,
|
|
212795
|
+
query: query2 || null,
|
|
212796
|
+
sources: filtered,
|
|
212797
|
+
matches: filtered,
|
|
212798
|
+
totalFound: globbed?.totalFound ?? allMatches.length,
|
|
212799
|
+
truncated: allMatches.length > maxResults2
|
|
212800
|
+
};
|
|
212801
|
+
}
|
|
212688
212802
|
const scope = await resolveLocalSourceScope(workspaceRoot);
|
|
212689
212803
|
if (!scope) {
|
|
212690
212804
|
const globRoot = typeof args.path === "string" && args.path.trim() || workspaceRoot?.trim() || "";
|
|
@@ -212746,7 +212860,7 @@ var init_localSources = __esm({
|
|
|
212746
212860
|
const requestedLocalSourceId = String(
|
|
212747
212861
|
args.localSourceId ?? args.path ?? args.filePath ?? ""
|
|
212748
212862
|
);
|
|
212749
|
-
const looksLikePath = isAbsolute3(requestedLocalSourceId.trim()) || !requestedLocalSourceId.includes("::") && requestedLocalSourceId.includes("/");
|
|
212863
|
+
const looksLikePath = isAbsolute3(requestedLocalSourceId.trim()) || requestedLocalSourceId.trim().startsWith("~/") || !requestedLocalSourceId.includes("::") && requestedLocalSourceId.includes("/");
|
|
212750
212864
|
if (looksLikePath) {
|
|
212751
212865
|
const r = await readWorkspaceFile({
|
|
212752
212866
|
workspaceRoot,
|
|
@@ -214051,7 +214165,7 @@ async function resolveFsAccessForTool(input) {
|
|
|
214051
214165
|
function waitForCapabilityResolution(promise, signal) {
|
|
214052
214166
|
if (!signal) return promise;
|
|
214053
214167
|
if (signal.aborted) return Promise.reject(new DOMException("Capability wait cancelled.", "AbortError"));
|
|
214054
|
-
return new Promise((
|
|
214168
|
+
return new Promise((resolve5, reject2) => {
|
|
214055
214169
|
const onAbort = () => {
|
|
214056
214170
|
signal.removeEventListener("abort", onAbort);
|
|
214057
214171
|
reject2(new DOMException("Capability wait cancelled.", "AbortError"));
|
|
@@ -214060,7 +214174,7 @@ function waitForCapabilityResolution(promise, signal) {
|
|
|
214060
214174
|
promise.then(
|
|
214061
214175
|
(value) => {
|
|
214062
214176
|
signal.removeEventListener("abort", onAbort);
|
|
214063
|
-
|
|
214177
|
+
resolve5(value);
|
|
214064
214178
|
},
|
|
214065
214179
|
(error) => {
|
|
214066
214180
|
signal.removeEventListener("abort", onAbort);
|
|
@@ -214799,14 +214913,103 @@ function pruneBrowserArtifactsInMessages(messages) {
|
|
|
214799
214913
|
}
|
|
214800
214914
|
return pruned;
|
|
214801
214915
|
}
|
|
214802
|
-
function
|
|
214803
|
-
|
|
214804
|
-
|
|
214916
|
+
function resolvePostCompactTargetTokens(contextLimitTokens) {
|
|
214917
|
+
const limit = Number.isFinite(contextLimitTokens) && contextLimitTokens > 0 ? Math.floor(contextLimitTokens) : 128e3;
|
|
214918
|
+
const windowScaled = Math.floor(limit * 0.25);
|
|
214919
|
+
return Math.max(
|
|
214920
|
+
POST_COMPACT_MIN_TARGET_TOKENS,
|
|
214921
|
+
Math.min(
|
|
214922
|
+
POST_COMPACT_MAX_TARGET_TOKENS,
|
|
214923
|
+
POST_COMPACT_TARGET_TOKENS,
|
|
214924
|
+
windowScaled
|
|
214925
|
+
)
|
|
214926
|
+
);
|
|
214927
|
+
}
|
|
214928
|
+
function estimateSingleMessageTokens(message, modelContext) {
|
|
214929
|
+
const content = typeof message.content === "string" ? message.content : JSON.stringify(message.content ?? "");
|
|
214930
|
+
let tokens = tokenizeText(`${message.role}: ${content}`, modelContext).tokenCount;
|
|
214931
|
+
if (message.tool_calls?.length) {
|
|
214932
|
+
tokens += tokenizeText(JSON.stringify(message.tool_calls), modelContext).tokenCount;
|
|
214933
|
+
}
|
|
214934
|
+
return Math.max(1, tokens);
|
|
214935
|
+
}
|
|
214936
|
+
function adjustTailStartForToolPairs(messages, startIndex) {
|
|
214937
|
+
if (startIndex <= 0) return startIndex;
|
|
214938
|
+
const missingToolCallIds = /* @__PURE__ */ new Set();
|
|
214939
|
+
for (let i = startIndex; i < messages.length; i += 1) {
|
|
214940
|
+
const msg = messages[i];
|
|
214941
|
+
if (msg?.role === "tool" && msg.tool_call_id) {
|
|
214942
|
+
missingToolCallIds.add(msg.tool_call_id);
|
|
214943
|
+
}
|
|
214944
|
+
if (msg?.role === "assistant" && msg.tool_calls?.length) {
|
|
214945
|
+
for (const call of msg.tool_calls) missingToolCallIds.delete(call.id);
|
|
214946
|
+
}
|
|
214947
|
+
}
|
|
214948
|
+
if (missingToolCallIds.size === 0) return startIndex;
|
|
214949
|
+
let nextStart = startIndex;
|
|
214950
|
+
for (let i = startIndex - 1; i >= 0 && missingToolCallIds.size > 0; i -= 1) {
|
|
214951
|
+
const msg = messages[i];
|
|
214952
|
+
if (msg.role !== "assistant" || !msg.tool_calls?.length) continue;
|
|
214953
|
+
const matches = msg.tool_calls.some((call) => missingToolCallIds.has(call.id));
|
|
214954
|
+
if (!matches) continue;
|
|
214955
|
+
nextStart = i;
|
|
214956
|
+
for (const call of msg.tool_calls) missingToolCallIds.delete(call.id);
|
|
214957
|
+
}
|
|
214958
|
+
return nextStart;
|
|
214959
|
+
}
|
|
214960
|
+
function selectRecentWireMessagesByTokenBudget(wireMessages, input) {
|
|
214961
|
+
if (wireMessages.length === 0) {
|
|
214962
|
+
return { recent: [], recentTailTokens: 0, startIndex: 0 };
|
|
214963
|
+
}
|
|
214964
|
+
const minMessages = Math.max(1, input.minMessages ?? RECENT_MESSAGES_KEEP_COUNT);
|
|
214965
|
+
const tokenBudget = Math.max(1, Math.floor(input.tokenBudget));
|
|
214966
|
+
let startIndex = wireMessages.length;
|
|
214967
|
+
let tokens = 0;
|
|
214968
|
+
for (let i = wireMessages.length - 1; i >= 0; i -= 1) {
|
|
214969
|
+
const messageTokens = estimateSingleMessageTokens(wireMessages[i], input.modelContext);
|
|
214970
|
+
const selectedCount = wireMessages.length - startIndex;
|
|
214971
|
+
const mustKeep = selectedCount === 0;
|
|
214972
|
+
if (!mustKeep && tokens + messageTokens > tokenBudget) break;
|
|
214973
|
+
tokens += messageTokens;
|
|
214974
|
+
startIndex = i;
|
|
214975
|
+
if (selectedCount + 1 >= minMessages && tokens >= tokenBudget) break;
|
|
214976
|
+
}
|
|
214977
|
+
const adjustedStart = adjustTailStartForToolPairs(wireMessages, startIndex);
|
|
214978
|
+
if (adjustedStart !== startIndex) {
|
|
214979
|
+
startIndex = adjustedStart;
|
|
214980
|
+
tokens = wireMessages.slice(startIndex).reduce(
|
|
214981
|
+
(sum, message) => sum + estimateSingleMessageTokens(message, input.modelContext),
|
|
214982
|
+
0
|
|
214983
|
+
);
|
|
214805
214984
|
}
|
|
214806
|
-
const splitAt = wireMessages.length - keepCount;
|
|
214807
214985
|
return {
|
|
214808
|
-
|
|
214809
|
-
|
|
214986
|
+
recent: wireMessages.slice(startIndex),
|
|
214987
|
+
recentTailTokens: tokens,
|
|
214988
|
+
startIndex
|
|
214989
|
+
};
|
|
214990
|
+
}
|
|
214991
|
+
function resolveRecentTailBudgetTokens(input) {
|
|
214992
|
+
const nonMessageTokens = input.breakdownAfterPrune.system + input.breakdownAfterPrune.tools + input.breakdownAfterPrune.overhead;
|
|
214993
|
+
const available = input.postCompactTargetTokens - nonMessageTokens - COMPACT_SUMMARY_RESERVE_TOKENS;
|
|
214994
|
+
return Math.max(
|
|
214995
|
+
POST_COMPACT_RECENT_TAIL_MIN_TOKENS,
|
|
214996
|
+
Math.min(POST_COMPACT_RECENT_TAIL_MAX_TOKENS, available)
|
|
214997
|
+
);
|
|
214998
|
+
}
|
|
214999
|
+
function splitMessagesForCompaction(wireMessages, input) {
|
|
215000
|
+
const { recent, recentTailTokens, startIndex } = selectRecentWireMessagesByTokenBudget(
|
|
215001
|
+
wireMessages,
|
|
215002
|
+
{
|
|
215003
|
+
modelContext: input.modelContext,
|
|
215004
|
+
tokenBudget: input.recentTailTokenBudget,
|
|
215005
|
+
minMessages: input.minMessages
|
|
215006
|
+
}
|
|
215007
|
+
);
|
|
215008
|
+
return {
|
|
215009
|
+
toSummarize: wireMessages.slice(0, startIndex),
|
|
215010
|
+
recent,
|
|
215011
|
+
recentTailTokens,
|
|
215012
|
+
compactedThroughWireIndex: startIndex > 0 ? startIndex - 1 : null
|
|
214810
215013
|
};
|
|
214811
215014
|
}
|
|
214812
215015
|
function formatMessagesForSummary(messages) {
|
|
@@ -214901,6 +215104,11 @@ async function prepareLoopMessagesForSend(input) {
|
|
|
214901
215104
|
});
|
|
214902
215105
|
const contextLimitTokens = resolveEffectiveContextLimit(input.option);
|
|
214903
215106
|
const compactThreshold = getAutoCompactThreshold(input.option);
|
|
215107
|
+
const postCompactTargetTokens = resolvePostCompactTargetTokens(contextLimitTokens);
|
|
215108
|
+
const recentTailTokenBudget = resolveRecentTailBudgetTokens({
|
|
215109
|
+
postCompactTargetTokens,
|
|
215110
|
+
breakdownAfterPrune
|
|
215111
|
+
});
|
|
214904
215112
|
let breakdown = breakdownAfterPrune;
|
|
214905
215113
|
const calibrationRatio = typeof input.priorApiContextTokens === "number" && input.priorApiContextTokens > 0 && typeof input.priorEstimateTokens === "number" && input.priorEstimateTokens > 0 ? Math.min(4, Math.max(1, input.priorApiContextTokens / input.priorEstimateTokens)) : 1;
|
|
214906
215114
|
const anchoredTokens = (estimateTotal) => Math.ceil(estimateTotal * calibrationRatio);
|
|
@@ -214929,10 +215137,16 @@ async function prepareLoopMessagesForSend(input) {
|
|
|
214929
215137
|
}
|
|
214930
215138
|
}
|
|
214931
215139
|
if (autoCompactEnabled && anchoredTokens(breakdown.total) >= compactThreshold) {
|
|
214932
|
-
const {
|
|
214933
|
-
|
|
214934
|
-
|
|
214935
|
-
|
|
215140
|
+
const {
|
|
215141
|
+
toSummarize,
|
|
215142
|
+
recent,
|
|
215143
|
+
recentTailTokens,
|
|
215144
|
+
compactedThroughWireIndex
|
|
215145
|
+
} = splitMessagesForCompaction(working, {
|
|
215146
|
+
modelContext,
|
|
215147
|
+
recentTailTokenBudget,
|
|
215148
|
+
minMessages: RECENT_MESSAGES_KEEP_COUNT
|
|
215149
|
+
});
|
|
214936
215150
|
if (toSummarize.length > 0) {
|
|
214937
215151
|
const summary = await summarizeMessagesForCompaction({
|
|
214938
215152
|
priorSummary: input.compactedSummary,
|
|
@@ -214946,6 +215160,7 @@ async function prepareLoopMessagesForSend(input) {
|
|
|
214946
215160
|
signal: input.signal
|
|
214947
215161
|
});
|
|
214948
215162
|
if (summary) {
|
|
215163
|
+
const compactedAtIso = (/* @__PURE__ */ new Date()).toISOString();
|
|
214949
215164
|
const compactedMessages = buildCompactedWireMessages(summary, recent);
|
|
214950
215165
|
working.length = 0;
|
|
214951
215166
|
working.push(...compactedMessages);
|
|
@@ -214956,20 +215171,45 @@ async function prepareLoopMessagesForSend(input) {
|
|
|
214956
215171
|
toolDefinitionsJson,
|
|
214957
215172
|
modelContext
|
|
214958
215173
|
});
|
|
215174
|
+
const tokensAfter = anchoredTokens(breakdown.total);
|
|
215175
|
+
const summaryTokens = tokenizeText(summary, modelContext).tokenCount;
|
|
215176
|
+
const compactionReport = {
|
|
215177
|
+
tokensBefore: tokensBeforeCompact,
|
|
215178
|
+
tokensAfter,
|
|
215179
|
+
targetTokens: postCompactTargetTokens,
|
|
215180
|
+
summaryTokens,
|
|
215181
|
+
recentTailTokens,
|
|
215182
|
+
recentTailMessages: recent.length,
|
|
215183
|
+
summarizedMessages: toSummarize.length,
|
|
215184
|
+
restoredToolsOrFiles: 0
|
|
215185
|
+
};
|
|
214959
215186
|
compactionState = {
|
|
214960
215187
|
compactedSummary: summary,
|
|
214961
215188
|
tokensBefore: tokensBeforeCompact,
|
|
214962
|
-
tokensAfter
|
|
215189
|
+
tokensAfter,
|
|
214963
215190
|
autoCompactEnabled: true,
|
|
214964
215191
|
effectiveContextLimitTokens: contextLimitTokens,
|
|
214965
|
-
compactedAtIso
|
|
215192
|
+
compactedAtIso,
|
|
215193
|
+
compactBoundary: {
|
|
215194
|
+
kind: "auto",
|
|
215195
|
+
compactedAtIso,
|
|
215196
|
+
compactedThroughWireIndex
|
|
215197
|
+
},
|
|
215198
|
+
compactionReport
|
|
214966
215199
|
};
|
|
214967
215200
|
input.onEvent?.({
|
|
214968
215201
|
type: "context_compacted",
|
|
214969
215202
|
tokensBefore: tokensBeforeCompact,
|
|
214970
|
-
tokensAfter
|
|
215203
|
+
tokensAfter,
|
|
214971
215204
|
summary,
|
|
214972
|
-
|
|
215205
|
+
compactionKind: "auto",
|
|
215206
|
+
targetTokens: postCompactTargetTokens,
|
|
215207
|
+
summaryTokens,
|
|
215208
|
+
recentTailTokens,
|
|
215209
|
+
recentTailMessages: recent.length,
|
|
215210
|
+
summarizedMessages: toSummarize.length,
|
|
215211
|
+
restoredToolsOrFiles: 0,
|
|
215212
|
+
ts: compactedAtIso
|
|
214973
215213
|
});
|
|
214974
215214
|
}
|
|
214975
215215
|
}
|
|
@@ -215005,7 +215245,7 @@ async function prepareLoopMessagesForSend(input) {
|
|
|
215005
215245
|
microcompactedToolResults
|
|
215006
215246
|
};
|
|
215007
215247
|
}
|
|
215008
|
-
var OPERATOR_SCREENSHOT_MARKER2, KEPT_SNAPSHOT_MAX_CHARS, KEPT_SNAPSHOT_TRUNCATED_MARKER, BROWSER_TOOL_NAMES, RECENT_MESSAGES_KEEP_COUNT, RECENT_TOOL_RESULTS_KEEP_COUNT, MICROCOMPACT_CLEARED_MARKER, COMPACT_SUMMARY_RESERVE_TOKENS, COMPACT_SYSTEM_PROMPT;
|
|
215248
|
+
var OPERATOR_SCREENSHOT_MARKER2, KEPT_SNAPSHOT_MAX_CHARS, KEPT_SNAPSHOT_TRUNCATED_MARKER, BROWSER_TOOL_NAMES, RECENT_MESSAGES_KEEP_COUNT, RECENT_TOOL_RESULTS_KEEP_COUNT, POST_COMPACT_TARGET_TOKENS, POST_COMPACT_MIN_TARGET_TOKENS, POST_COMPACT_MAX_TARGET_TOKENS, POST_COMPACT_RECENT_TAIL_MIN_TOKENS, POST_COMPACT_RECENT_TAIL_MAX_TOKENS, MICROCOMPACT_CLEARED_MARKER, COMPACT_SUMMARY_RESERVE_TOKENS, COMPACT_SYSTEM_PROMPT;
|
|
215009
215249
|
var init_contextLoopCompaction = __esm({
|
|
215010
215250
|
"features/perchTerminal/runtime/services/contextLoopCompaction.ts"() {
|
|
215011
215251
|
"use strict";
|
|
@@ -215035,6 +215275,11 @@ var init_contextLoopCompaction = __esm({
|
|
|
215035
215275
|
]);
|
|
215036
215276
|
RECENT_MESSAGES_KEEP_COUNT = 12;
|
|
215037
215277
|
RECENT_TOOL_RESULTS_KEEP_COUNT = 6;
|
|
215278
|
+
POST_COMPACT_TARGET_TOKENS = 32e3;
|
|
215279
|
+
POST_COMPACT_MIN_TARGET_TOKENS = 2e4;
|
|
215280
|
+
POST_COMPACT_MAX_TARGET_TOKENS = 4e4;
|
|
215281
|
+
POST_COMPACT_RECENT_TAIL_MIN_TOKENS = 4e3;
|
|
215282
|
+
POST_COMPACT_RECENT_TAIL_MAX_TOKENS = 24e3;
|
|
215038
215283
|
MICROCOMPACT_CLEARED_MARKER = "[Old tool result content cleared to free context]";
|
|
215039
215284
|
COMPACT_SUMMARY_RESERVE_TOKENS = 4096;
|
|
215040
215285
|
COMPACT_SYSTEM_PROMPT = `You summarize conversation history for a delivery assistant using Google Docs, Gmail, Calendar, and browser tools.
|
|
@@ -217109,15 +217354,15 @@ async function dumpModelPayloadIfRequested(input) {
|
|
|
217109
217354
|
const dumpDir = process.env.PERCH_MODEL_PAYLOAD_DUMP_DIR;
|
|
217110
217355
|
if (process.env.PERCH_DUMP_MODEL_PAYLOAD !== "1" && !dumpDir) return;
|
|
217111
217356
|
try {
|
|
217112
|
-
const [{ mkdir, writeFile:
|
|
217357
|
+
const [{ mkdir: mkdir2, writeFile: writeFile3 }, { join: join2 }] = await Promise.all([
|
|
217113
217358
|
import("node:fs/promises"),
|
|
217114
217359
|
import("node:path")
|
|
217115
217360
|
]);
|
|
217116
|
-
const dir = dumpDir ||
|
|
217117
|
-
await
|
|
217118
|
-
const
|
|
217119
|
-
await
|
|
217120
|
-
|
|
217361
|
+
const dir = dumpDir || join2(process.cwd(), ".perch", "debug", "model-payloads");
|
|
217362
|
+
await mkdir2(dir, { recursive: true });
|
|
217363
|
+
const safeRunId2 = (input.runId || "local").replace(/[^a-zA-Z0-9_.-]/g, "_").slice(0, 80);
|
|
217364
|
+
await writeFile3(
|
|
217365
|
+
join2(dir, `${safeRunId2}-iter-${input.iteration}.json`),
|
|
217121
217366
|
JSON.stringify({
|
|
217122
217367
|
dumpedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
217123
217368
|
runId: input.runId,
|
|
@@ -217605,13 +217850,18 @@ async function runLiveAgentsLoop(input) {
|
|
|
217605
217850
|
effectiveContextLimitTokens: state.effectiveContextLimitTokens,
|
|
217606
217851
|
compactedAtIso: state.compactedAtIso,
|
|
217607
217852
|
autoCompactedAtIso: state.compactedAtIso,
|
|
217853
|
+
autoCompactedMessageCount: state.compactionReport.summarizedMessages,
|
|
217854
|
+
compactBoundary: state.compactBoundary,
|
|
217855
|
+
compactionReport: state.compactionReport,
|
|
217608
217856
|
consecutiveAutoCompactFailures: 0
|
|
217609
217857
|
},
|
|
217610
217858
|
contextMetrics: latest?.contextMetrics ? {
|
|
217611
217859
|
...latest.contextMetrics,
|
|
217612
217860
|
effectiveLimitTokens: state.effectiveContextLimitTokens,
|
|
217613
217861
|
autoCompactEnabled: state.autoCompactEnabled,
|
|
217614
|
-
autoCompactedAtIso: state.compactedAtIso
|
|
217862
|
+
autoCompactedAtIso: state.compactedAtIso,
|
|
217863
|
+
autoCompactedMessageCount: state.compactionReport.summarizedMessages,
|
|
217864
|
+
compactionReport: state.compactionReport
|
|
217615
217865
|
} : latest?.contextMetrics,
|
|
217616
217866
|
updatedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
217617
217867
|
},
|
|
@@ -219818,7 +220068,13 @@ function emitProgressForRuntimeEvent(event, emit, state = {
|
|
|
219818
220068
|
case "context_compacted":
|
|
219819
220069
|
emitInstantItem(emit, state, turnId, "context", itemId(turnId, "context-compacted", ts), "Context compacted", event.summary, ts, {
|
|
219820
220070
|
tokensBefore: event.tokensBefore,
|
|
219821
|
-
tokensAfter: event.tokensAfter
|
|
220071
|
+
tokensAfter: event.tokensAfter,
|
|
220072
|
+
targetTokens: event.targetTokens,
|
|
220073
|
+
summaryTokens: event.summaryTokens,
|
|
220074
|
+
recentTailTokens: event.recentTailTokens,
|
|
220075
|
+
recentTailMessages: event.recentTailMessages,
|
|
220076
|
+
summarizedMessages: event.summarizedMessages,
|
|
220077
|
+
restoredToolsOrFiles: event.restoredToolsOrFiles
|
|
219822
220078
|
});
|
|
219823
220079
|
break;
|
|
219824
220080
|
case "plan_card_generated": {
|
|
@@ -221003,6 +221259,7 @@ function resolveThreadContextAccounting(input) {
|
|
|
221003
221259
|
consecutiveAutoCompactFailures: priorCompaction?.consecutiveAutoCompactFailures ?? priorMetrics?.consecutiveAutoCompactFailures ?? 0,
|
|
221004
221260
|
autoCompactedAtIso: priorCompaction?.autoCompactedAtIso ?? priorMetrics?.autoCompactedAtIso ?? null,
|
|
221005
221261
|
autoCompactedMessageCount: priorCompaction?.autoCompactedMessageCount ?? priorMetrics?.autoCompactedMessageCount,
|
|
221262
|
+
compactionReport: priorCompaction?.compactionReport ?? priorMetrics?.compactionReport,
|
|
221006
221263
|
tokenCountMethod: fill.tokenCountMethod,
|
|
221007
221264
|
accountingMethod: "thread_fill_v4: headline = retained window fill high-water until compaction; provider usage is last-call detail; workers off-thread only.",
|
|
221008
221265
|
resetAtIso: compactedAtIso,
|
|
@@ -221126,6 +221383,7 @@ function buildClientContextSnapshot(input) {
|
|
|
221126
221383
|
consecutiveAutoCompactFailures: accounting.consecutiveAutoCompactFailures ?? 0,
|
|
221127
221384
|
autoCompactedAtIso: accounting.autoCompactedAtIso ?? null,
|
|
221128
221385
|
autoCompactedMessageCount: accounting.autoCompactedMessageCount,
|
|
221386
|
+
compactionReport: accounting.compactionReport,
|
|
221129
221387
|
builtAtIso: input.builtAtIso,
|
|
221130
221388
|
createdAt: input.builtAtIso,
|
|
221131
221389
|
...wireDisplay ? {
|
|
@@ -222671,8 +222929,849 @@ var init_runOperatorTurn = __esm({
|
|
|
222671
222929
|
}
|
|
222672
222930
|
});
|
|
222673
222931
|
|
|
222674
|
-
//
|
|
222932
|
+
// electron/localSandboxHost.ts
|
|
222933
|
+
import { copyFile, mkdir, mkdtemp, readdir, readFile as readFile3, rm, stat, writeFile as writeFile2 } from "node:fs/promises";
|
|
222934
|
+
import { createHash as createHash2, randomUUID } from "node:crypto";
|
|
222935
|
+
import { basename, dirname, extname, join, relative, resolve as resolve4 } from "node:path";
|
|
222936
|
+
import { homedir, platform, tmpdir } from "node:os";
|
|
222675
222937
|
import { spawn } from "node:child_process";
|
|
222938
|
+
function buildSandboxRuntimeInfo(networkPolicy) {
|
|
222939
|
+
return {
|
|
222940
|
+
networkPolicy,
|
|
222941
|
+
packageInstalls: networkPolicy === "disabled" ? "disabled" : "enabled",
|
|
222942
|
+
pythonCommand: "python3",
|
|
222943
|
+
pipCommand: "python3 -m pip",
|
|
222944
|
+
inputManifestPath: "input_manifest.json",
|
|
222945
|
+
helperModule: "perch_helpers",
|
|
222946
|
+
helperFunctions: [
|
|
222947
|
+
"input_files",
|
|
222948
|
+
"load_tabular",
|
|
222949
|
+
"extract_pdf_text",
|
|
222950
|
+
"extract_invoice_fields",
|
|
222951
|
+
"extract_pdf_tables",
|
|
222952
|
+
"find_duplicates",
|
|
222953
|
+
"write_report",
|
|
222954
|
+
"sandbox_runtime_info"
|
|
222955
|
+
],
|
|
222956
|
+
notes: [
|
|
222957
|
+
"Read copied sources from paths listed in input_manifest.json.",
|
|
222958
|
+
networkPolicy === "disabled" ? "Package installs and network egress are disabled for this run." : "Package installs are allowed for this run; use python3 -m pip install <package> when needed.",
|
|
222959
|
+
"perch_helpers.extract_pdf_text has a stdlib raw-stream fallback for simple invoice PDFs, so PDF parsing should not require pdfplumber/pypdf for text fields."
|
|
222960
|
+
]
|
|
222961
|
+
};
|
|
222962
|
+
}
|
|
222963
|
+
async function writeSandboxManifestFiles(input) {
|
|
222964
|
+
const payload = {
|
|
222965
|
+
...input.inputManifest,
|
|
222966
|
+
runtime: input.runtimeInfo
|
|
222967
|
+
};
|
|
222968
|
+
const text = JSON.stringify(payload, null, 2);
|
|
222969
|
+
await writeFile2(join(input.workspaceRoot, "input_manifest.json"), text, "utf-8");
|
|
222970
|
+
await writeFile2(join(input.workspaceRoot, "sandbox_runtime.json"), JSON.stringify(input.runtimeInfo, null, 2), "utf-8");
|
|
222971
|
+
}
|
|
222972
|
+
async function runDesktopSandboxCodeJob(spec, deps) {
|
|
222973
|
+
const runId = safeRunId(spec.runId) ?? makeRunId2("sandbox-code");
|
|
222974
|
+
const startedAt = Date.now();
|
|
222975
|
+
const now13 = () => (deps.now?.() ?? /* @__PURE__ */ new Date()).toISOString();
|
|
222976
|
+
const emitLive = (type, payload) => {
|
|
222977
|
+
deps.onEvent?.({ runId, type, payload, ts: now13() });
|
|
222978
|
+
};
|
|
222979
|
+
const commandText = typeof spec.command === "string" ? spec.command.trim() : "";
|
|
222980
|
+
const code = typeof spec.code === "string" ? spec.code : "";
|
|
222981
|
+
const language = spec.language === "node" ? "node" : "python";
|
|
222982
|
+
const executionMode = commandText ? "command" : "script";
|
|
222983
|
+
const executableText = executionMode === "command" ? commandText : code;
|
|
222984
|
+
const codeSha256 = createHash2("sha256").update(executableText).digest("hex");
|
|
222985
|
+
const networkPolicy = spec.networkPolicy ?? "disabled";
|
|
222986
|
+
if (!executableText.trim()) {
|
|
222987
|
+
return { ok: false, kind: "blocked", message: "run_sandbox_code requires either command or code.", executionHost: "electron-main", runId, codeSha256 };
|
|
222988
|
+
}
|
|
222989
|
+
emitLive("sandbox_started", {
|
|
222990
|
+
executionHost: "electron-main",
|
|
222991
|
+
runnerKind: "dev-local",
|
|
222992
|
+
networkPolicy,
|
|
222993
|
+
label: spec.label ?? null,
|
|
222994
|
+
codeSha256,
|
|
222995
|
+
language: executionMode === "command" ? "shell" : language
|
|
222996
|
+
});
|
|
222997
|
+
const validationReasons = executionMode === "script" ? validateScript(code, language) : [];
|
|
222998
|
+
if (validationReasons.length > 0) {
|
|
222999
|
+
emitLive("sandbox_failed", {
|
|
223000
|
+
stopReason: "validation_rejected",
|
|
223001
|
+
message: "The model-written sandbox code was rejected by validation.",
|
|
223002
|
+
validationReasons,
|
|
223003
|
+
codeSha256
|
|
223004
|
+
});
|
|
223005
|
+
return {
|
|
223006
|
+
ok: false,
|
|
223007
|
+
kind: "failed",
|
|
223008
|
+
message: "The model-written sandbox code was rejected by validation.",
|
|
223009
|
+
runnerKind: "dev-local",
|
|
223010
|
+
executionHost: "electron-main",
|
|
223011
|
+
runId,
|
|
223012
|
+
error: validationReasons.join("; "),
|
|
223013
|
+
validationReasons,
|
|
223014
|
+
codeSha256
|
|
223015
|
+
};
|
|
223016
|
+
}
|
|
223017
|
+
let resolved = [];
|
|
223018
|
+
if (Array.isArray(spec.sources) && spec.sources.length > 0) {
|
|
223019
|
+
try {
|
|
223020
|
+
emitLive("inputs_preparing", { sourceCount: spec.sources.length });
|
|
223021
|
+
resolved = await resolveApprovedInputs(spec.sources, deps);
|
|
223022
|
+
} catch (err) {
|
|
223023
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
223024
|
+
emitLive("sandbox_failed", { message, stopReason: "input_resolution_failed" });
|
|
223025
|
+
return { ok: false, kind: "blocked", message, executionHost: "electron-main", runId, error: message, codeSha256 };
|
|
223026
|
+
}
|
|
223027
|
+
}
|
|
223028
|
+
const workspaceKey = safeWorkspaceKey(spec.workspaceKey) ?? runId;
|
|
223029
|
+
const workspaceRoot = await ensureCodeWorkspace(workspaceKey);
|
|
223030
|
+
const scriptName = language === "python" ? `run-${runId}.py` : `run-${runId}.js`;
|
|
223031
|
+
const command = executionMode === "command" ? commandText : language === "python" ? buildPythonCommand(scriptName) : `"$PERCH_ELECTRON_EXEC" "${scriptName}"`;
|
|
223032
|
+
emitLive("script_planned", {
|
|
223033
|
+
source: "model",
|
|
223034
|
+
fallbackReason: null,
|
|
223035
|
+
script: redactUserVisibleText(executableText),
|
|
223036
|
+
publicPlan: spec.label ?? (executionMode === "command" ? "Sandbox shell command." : "Model-written sandbox code."),
|
|
223037
|
+
plannerContent: null,
|
|
223038
|
+
provider: null,
|
|
223039
|
+
codeSha256,
|
|
223040
|
+
language: executionMode === "command" ? "shell" : language
|
|
223041
|
+
});
|
|
223042
|
+
emitLive("command_started", { command: redactUserVisibleText(command), language: executionMode === "command" ? "shell" : language, codeSha256 });
|
|
223043
|
+
const runResult = await runCodeSandbox({
|
|
223044
|
+
runId,
|
|
223045
|
+
command,
|
|
223046
|
+
workspaceRoot,
|
|
223047
|
+
inputs: resolved,
|
|
223048
|
+
timeoutMs: Math.min(spec.timeoutMs ?? DEFAULT_TIMEOUT_MS2, DEFAULT_TIMEOUT_MS2),
|
|
223049
|
+
onEvent: emitLive,
|
|
223050
|
+
networkPolicy,
|
|
223051
|
+
scriptFile: executionMode === "script" ? { name: scriptName, content: code } : null
|
|
223052
|
+
});
|
|
223053
|
+
const outputBundle = buildOutputBundle(runResult);
|
|
223054
|
+
const hasReport = runResult.structuredOutput?.reportJson != null;
|
|
223055
|
+
const completedWithoutReport = runResult.status === "completed" && !hasReport;
|
|
223056
|
+
const eventKind = runResult.status === "completed" ? "completed" : "failed";
|
|
223057
|
+
const stopReason = hasReport ? "completed" : completedWithoutReport ? "completed_unstructured" : runResult.status === "timed_out" ? "run_timed_out" : "run_failed";
|
|
223058
|
+
emitLive(eventKind === "completed" ? "sandbox_completed" : "sandbox_failed", {
|
|
223059
|
+
stopReason,
|
|
223060
|
+
runnerKind: "dev-local",
|
|
223061
|
+
executionHost: "electron-main",
|
|
223062
|
+
codeSha256,
|
|
223063
|
+
outputSummary: {
|
|
223064
|
+
files: outputBundle?.files.length ?? 0,
|
|
223065
|
+
tables: outputBundle?.tables.length ?? 0,
|
|
223066
|
+
charts: outputBundle?.charts.length ?? 0,
|
|
223067
|
+
logs: outputBundle?.logs.length ?? 0,
|
|
223068
|
+
reportJsonPresent: hasReport
|
|
223069
|
+
}
|
|
223070
|
+
});
|
|
223071
|
+
if (runResult.status !== "completed") {
|
|
223072
|
+
return {
|
|
223073
|
+
ok: false,
|
|
223074
|
+
kind: "failed",
|
|
223075
|
+
message: "Model-written sandbox code failed.",
|
|
223076
|
+
runnerKind: "dev-local",
|
|
223077
|
+
executionHost: "electron-main",
|
|
223078
|
+
runId,
|
|
223079
|
+
error: runResult.stderr || stopReason,
|
|
223080
|
+
codeSha256,
|
|
223081
|
+
status: runResult.status,
|
|
223082
|
+
exitCode: runResult.exitCode,
|
|
223083
|
+
durationMs: Date.now() - startedAt,
|
|
223084
|
+
stdout: runResult.stdout,
|
|
223085
|
+
stderr: runResult.stderr,
|
|
223086
|
+
stdoutTruncated: runResult.stdoutTruncated,
|
|
223087
|
+
stderrTruncated: runResult.stderrTruncated,
|
|
223088
|
+
producedFiles: runResult.producedFiles,
|
|
223089
|
+
inputManifest: runResult.inputManifest,
|
|
223090
|
+
runtimeInfo: runResult.runtimeInfo,
|
|
223091
|
+
structuredOutput: runResult.structuredOutput,
|
|
223092
|
+
workspacePath: runResult.workspacePath,
|
|
223093
|
+
language,
|
|
223094
|
+
reportJsonPresent: hasReport,
|
|
223095
|
+
warnings: runResult.warnings
|
|
223096
|
+
};
|
|
223097
|
+
}
|
|
223098
|
+
const kind = "completed";
|
|
223099
|
+
return {
|
|
223100
|
+
ok: true,
|
|
223101
|
+
kind,
|
|
223102
|
+
message: hasReport ? "Sandbox execution completed and emitted output/report.json." : "Sandbox execution completed; stdout/stderr and produced files were captured.",
|
|
223103
|
+
runnerKind: "dev-local",
|
|
223104
|
+
executionHost: "electron-main",
|
|
223105
|
+
runId,
|
|
223106
|
+
status: runResult.status,
|
|
223107
|
+
exitCode: runResult.exitCode,
|
|
223108
|
+
durationMs: Date.now() - startedAt,
|
|
223109
|
+
stdout: runResult.stdout,
|
|
223110
|
+
stderr: runResult.stderr,
|
|
223111
|
+
stdoutTruncated: runResult.stdoutTruncated,
|
|
223112
|
+
stderrTruncated: runResult.stderrTruncated,
|
|
223113
|
+
producedFiles: runResult.producedFiles,
|
|
223114
|
+
inputManifest: runResult.inputManifest,
|
|
223115
|
+
runtimeInfo: runResult.runtimeInfo,
|
|
223116
|
+
structuredOutput: runResult.structuredOutput,
|
|
223117
|
+
workspacePath: runResult.workspacePath,
|
|
223118
|
+
codeSha256,
|
|
223119
|
+
language: executionMode === "command" ? "shell" : language,
|
|
223120
|
+
reportJsonPresent: hasReport,
|
|
223121
|
+
warnings: runResult.warnings
|
|
223122
|
+
};
|
|
223123
|
+
}
|
|
223124
|
+
async function resolveApprovedInputs(sources, deps) {
|
|
223125
|
+
const out = [];
|
|
223126
|
+
const seen = /* @__PURE__ */ new Set();
|
|
223127
|
+
for (const source of sources.slice(0, MAX_SOURCES)) {
|
|
223128
|
+
if (!source.localSourceId || seen.has(source.localSourceId)) continue;
|
|
223129
|
+
seen.add(source.localSourceId);
|
|
223130
|
+
const resolved = resolveSandboxInputRef(source.localSourceId, deps);
|
|
223131
|
+
if (!resolved) continue;
|
|
223132
|
+
const { absPath, relPath } = resolved;
|
|
223133
|
+
const fileName = basename(absPath);
|
|
223134
|
+
if (deps.shouldIgnore(fileName)) continue;
|
|
223135
|
+
const s = await stat(absPath);
|
|
223136
|
+
if (!s.isFile()) continue;
|
|
223137
|
+
if (s.size > MAX_SOURCE_BYTES) continue;
|
|
223138
|
+
out.push({
|
|
223139
|
+
localSourceId: source.localSourceId,
|
|
223140
|
+
fileName: safeRelativeName(source.fileName || fileName),
|
|
223141
|
+
fileType: source.fileType || guessFileTypeFromExt(extname(fileName).toLowerCase()),
|
|
223142
|
+
sizeBytes: s.size,
|
|
223143
|
+
description: source.description,
|
|
223144
|
+
relativePath: safeRelativeName(relPath),
|
|
223145
|
+
sourcePath: absPath
|
|
223146
|
+
});
|
|
223147
|
+
}
|
|
223148
|
+
return out;
|
|
223149
|
+
}
|
|
223150
|
+
function resolveSandboxInputRef(inputRef, deps) {
|
|
223151
|
+
const sep = inputRef.indexOf("::");
|
|
223152
|
+
if (sep >= 0) {
|
|
223153
|
+
const rootId = inputRef.slice(0, sep);
|
|
223154
|
+
const relPath2 = inputRef.slice(sep + 2);
|
|
223155
|
+
const root3 = deps.getApprovedRoot(rootId);
|
|
223156
|
+
if (!root3) return null;
|
|
223157
|
+
if (!deps.isPathSafe(root3.path, relPath2)) return null;
|
|
223158
|
+
const absPath2 = resolve4(root3.path, relPath2);
|
|
223159
|
+
if (!deps.isInsideApprovedRoot(absPath2)) return null;
|
|
223160
|
+
return { absPath: absPath2, relPath: relPath2 };
|
|
223161
|
+
}
|
|
223162
|
+
const absPath = resolve4(inputRef);
|
|
223163
|
+
const root2 = deps.isInsideApprovedRoot(absPath);
|
|
223164
|
+
if (!root2) return null;
|
|
223165
|
+
const relPath = relative(root2.path, absPath);
|
|
223166
|
+
if (!deps.isPathSafe(root2.path, relPath)) return null;
|
|
223167
|
+
return { absPath, relPath };
|
|
223168
|
+
}
|
|
223169
|
+
function validateScript(script, language = "node") {
|
|
223170
|
+
if (language === "python") return validatePythonScript(script);
|
|
223171
|
+
const reasons = [];
|
|
223172
|
+
const blocked3 = [
|
|
223173
|
+
"child_process",
|
|
223174
|
+
"exec(",
|
|
223175
|
+
"spawn(",
|
|
223176
|
+
"process.env",
|
|
223177
|
+
"require('http')",
|
|
223178
|
+
'require("http")',
|
|
223179
|
+
"require('https')",
|
|
223180
|
+
'require("https")',
|
|
223181
|
+
"fetch(",
|
|
223182
|
+
"eval(",
|
|
223183
|
+
"Function("
|
|
223184
|
+
];
|
|
223185
|
+
for (const token of blocked3) {
|
|
223186
|
+
if (script.includes(token)) reasons.push(`blocked token: ${token}`);
|
|
223187
|
+
}
|
|
223188
|
+
return reasons;
|
|
223189
|
+
}
|
|
223190
|
+
function validatePythonScript(script) {
|
|
223191
|
+
const reasons = [];
|
|
223192
|
+
const blocked3 = [
|
|
223193
|
+
"subprocess",
|
|
223194
|
+
"os.system(",
|
|
223195
|
+
"os.popen(",
|
|
223196
|
+
"os.exec",
|
|
223197
|
+
"shutil.rmtree",
|
|
223198
|
+
"__import__(",
|
|
223199
|
+
"importlib",
|
|
223200
|
+
"ctypes",
|
|
223201
|
+
"requests.get",
|
|
223202
|
+
"requests.post",
|
|
223203
|
+
"urllib.request",
|
|
223204
|
+
"http.client",
|
|
223205
|
+
"socket.",
|
|
223206
|
+
"open('/etc",
|
|
223207
|
+
"open('/proc",
|
|
223208
|
+
"open('/sys"
|
|
223209
|
+
];
|
|
223210
|
+
for (const token of blocked3) {
|
|
223211
|
+
if (script.includes(token)) reasons.push(`blocked token: ${token}`);
|
|
223212
|
+
}
|
|
223213
|
+
return reasons;
|
|
223214
|
+
}
|
|
223215
|
+
function buildPythonCommand(scriptPath) {
|
|
223216
|
+
return `python3 "${scriptPath}"`;
|
|
223217
|
+
}
|
|
223218
|
+
async function ensureCodeWorkspace(workspaceKey) {
|
|
223219
|
+
const existing = codeWorkspaces.get(workspaceKey);
|
|
223220
|
+
if (existing) {
|
|
223221
|
+
try {
|
|
223222
|
+
const s = await stat(existing);
|
|
223223
|
+
if (s.isDirectory()) return existing;
|
|
223224
|
+
} catch {
|
|
223225
|
+
codeWorkspaces.delete(workspaceKey);
|
|
223226
|
+
}
|
|
223227
|
+
}
|
|
223228
|
+
const workspaceRoot = await mkdtemp(join(tmpdir(), `perch-code-${workspaceKey.slice(0, 16)}-`));
|
|
223229
|
+
await mkdir(join(workspaceRoot, "input"), { recursive: true });
|
|
223230
|
+
await mkdir(join(workspaceRoot, "output"), { recursive: true });
|
|
223231
|
+
await writeFile2(join(workspaceRoot, "perch_helpers.py"), PYTHON_HELPERS_SOURCE, "utf-8");
|
|
223232
|
+
codeWorkspaces.set(workspaceKey, workspaceRoot);
|
|
223233
|
+
return workspaceRoot;
|
|
223234
|
+
}
|
|
223235
|
+
async function runCodeSandbox(opts) {
|
|
223236
|
+
const warnings = [];
|
|
223237
|
+
const copiedInputFiles = [];
|
|
223238
|
+
const skippedInputFiles = [];
|
|
223239
|
+
const inputManifestFiles = [];
|
|
223240
|
+
const skippedManifestEntries = [];
|
|
223241
|
+
const runtimeInfo = buildSandboxRuntimeInfo(opts.networkPolicy);
|
|
223242
|
+
const inputDir = join(opts.workspaceRoot, "input");
|
|
223243
|
+
const outputDir = join(opts.workspaceRoot, "output");
|
|
223244
|
+
await rm(inputDir, { recursive: true, force: true });
|
|
223245
|
+
await rm(outputDir, { recursive: true, force: true });
|
|
223246
|
+
await mkdir(inputDir, { recursive: true });
|
|
223247
|
+
await mkdir(outputDir, { recursive: true });
|
|
223248
|
+
if (opts.scriptFile) {
|
|
223249
|
+
await writeFile2(join(opts.workspaceRoot, opts.scriptFile.name), opts.scriptFile.content, "utf-8");
|
|
223250
|
+
}
|
|
223251
|
+
await writeFile2(join(opts.workspaceRoot, "perch_helpers.py"), PYTHON_HELPERS_SOURCE, "utf-8");
|
|
223252
|
+
for (const input of opts.inputs) {
|
|
223253
|
+
const safeRel = safeRelativeName(input.relativePath || input.fileName);
|
|
223254
|
+
if (!safeRel) {
|
|
223255
|
+
skippedInputFiles.push(input.fileName);
|
|
223256
|
+
skippedManifestEntries.push({
|
|
223257
|
+
sourcePath: input.sourcePath,
|
|
223258
|
+
localSourceId: input.localSourceId,
|
|
223259
|
+
fileName: input.fileName,
|
|
223260
|
+
sizeBytes: input.sizeBytes,
|
|
223261
|
+
fileType: input.fileType,
|
|
223262
|
+
reason: "invalid_sandbox_relative_path"
|
|
223263
|
+
});
|
|
223264
|
+
continue;
|
|
223265
|
+
}
|
|
223266
|
+
try {
|
|
223267
|
+
const dest = join(inputDir, safeRel);
|
|
223268
|
+
await mkdir(dirname(dest), { recursive: true });
|
|
223269
|
+
await copyFile(input.sourcePath, dest);
|
|
223270
|
+
copiedInputFiles.push(safeRel);
|
|
223271
|
+
inputManifestFiles.push({
|
|
223272
|
+
sandboxPath: `input/${safeRel}`,
|
|
223273
|
+
sourcePath: input.sourcePath,
|
|
223274
|
+
localSourceId: input.localSourceId,
|
|
223275
|
+
fileName: input.fileName || basename(safeRel),
|
|
223276
|
+
sizeBytes: input.sizeBytes,
|
|
223277
|
+
fileType: input.fileType || null
|
|
223278
|
+
});
|
|
223279
|
+
opts.onEvent?.("input_copied", {
|
|
223280
|
+
relativePath: safeRel,
|
|
223281
|
+
fileName: input.fileName,
|
|
223282
|
+
fileType: input.fileType,
|
|
223283
|
+
sizeBytes: input.sizeBytes
|
|
223284
|
+
});
|
|
223285
|
+
} catch (err) {
|
|
223286
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
223287
|
+
skippedInputFiles.push(safeRel);
|
|
223288
|
+
skippedManifestEntries.push({
|
|
223289
|
+
sandboxPath: `input/${safeRel}`,
|
|
223290
|
+
sourcePath: input.sourcePath,
|
|
223291
|
+
localSourceId: input.localSourceId,
|
|
223292
|
+
fileName: input.fileName || basename(safeRel),
|
|
223293
|
+
sizeBytes: input.sizeBytes,
|
|
223294
|
+
fileType: input.fileType,
|
|
223295
|
+
reason: msg
|
|
223296
|
+
});
|
|
223297
|
+
warnings.push(`Failed to copy input ${safeRel}: ${msg}`);
|
|
223298
|
+
}
|
|
223299
|
+
}
|
|
223300
|
+
opts.onEvent?.("inputs_ready", {
|
|
223301
|
+
requestedInputFileCount: opts.inputs.length,
|
|
223302
|
+
copiedInputFiles,
|
|
223303
|
+
skippedInputFiles,
|
|
223304
|
+
workspacePath: redactUserVisibleText(opts.workspaceRoot),
|
|
223305
|
+
inputManifestPath: "input_manifest.json",
|
|
223306
|
+
runtimeInfo
|
|
223307
|
+
});
|
|
223308
|
+
const inputManifest = {
|
|
223309
|
+
root: "input",
|
|
223310
|
+
files: inputManifestFiles,
|
|
223311
|
+
skipped: skippedManifestEntries
|
|
223312
|
+
};
|
|
223313
|
+
await writeSandboxManifestFiles({
|
|
223314
|
+
workspaceRoot: opts.workspaceRoot,
|
|
223315
|
+
inputManifest,
|
|
223316
|
+
runtimeInfo
|
|
223317
|
+
});
|
|
223318
|
+
const execResult = await executeCommand(
|
|
223319
|
+
opts.command,
|
|
223320
|
+
opts.workspaceRoot,
|
|
223321
|
+
opts.timeoutMs,
|
|
223322
|
+
opts.networkPolicy,
|
|
223323
|
+
opts.onEvent
|
|
223324
|
+
);
|
|
223325
|
+
const producedFiles = await collectOutputFiles(outputDir, warnings, opts.onEvent);
|
|
223326
|
+
opts.onEvent?.("outputs_collected", { producedFiles });
|
|
223327
|
+
const structuredOutput = await readStructuredOutput(outputDir, execResult.stdout);
|
|
223328
|
+
if (structuredOutput?.reportJson) opts.onEvent?.("report_detected", { source: "report.json" });
|
|
223329
|
+
return {
|
|
223330
|
+
runId: opts.runId,
|
|
223331
|
+
status: execResult.timedOut ? "timed_out" : execResult.exitCode === 0 ? "completed" : "failed",
|
|
223332
|
+
exitCode: execResult.exitCode,
|
|
223333
|
+
stdout: execResult.stdout,
|
|
223334
|
+
stderr: execResult.stderr,
|
|
223335
|
+
stdoutTruncated: execResult.stdoutTruncated,
|
|
223336
|
+
stderrTruncated: execResult.stderrTruncated,
|
|
223337
|
+
producedFiles,
|
|
223338
|
+
inputManifest,
|
|
223339
|
+
runtimeInfo,
|
|
223340
|
+
structuredOutput,
|
|
223341
|
+
warnings,
|
|
223342
|
+
durationMs: 0,
|
|
223343
|
+
workspacePath: opts.workspaceRoot,
|
|
223344
|
+
cleanedUp: false,
|
|
223345
|
+
executionEvidence: {
|
|
223346
|
+
requestedInputFileCount: opts.inputs.length,
|
|
223347
|
+
copiedInputFiles,
|
|
223348
|
+
skippedInputFiles,
|
|
223349
|
+
command: opts.command
|
|
223350
|
+
}
|
|
223351
|
+
};
|
|
223352
|
+
}
|
|
223353
|
+
async function executeCommand(command, cwd2, timeoutMs, networkPolicy, onEvent) {
|
|
223354
|
+
const launch = await prepareSandboxLaunch(command, cwd2, networkPolicy);
|
|
223355
|
+
if ("error" in launch) {
|
|
223356
|
+
return {
|
|
223357
|
+
stdout: "",
|
|
223358
|
+
stderr: launch.error,
|
|
223359
|
+
exitCode: 126,
|
|
223360
|
+
timedOut: false,
|
|
223361
|
+
stdoutTruncated: false,
|
|
223362
|
+
stderrTruncated: false
|
|
223363
|
+
};
|
|
223364
|
+
}
|
|
223365
|
+
return new Promise((resolvePromise) => {
|
|
223366
|
+
let stdout = "";
|
|
223367
|
+
let stderr = "";
|
|
223368
|
+
let stdoutBytes = 0;
|
|
223369
|
+
let stderrBytes = 0;
|
|
223370
|
+
let stdoutTruncated = false;
|
|
223371
|
+
let stderrTruncated = false;
|
|
223372
|
+
let timedOut = false;
|
|
223373
|
+
const childEnv = {
|
|
223374
|
+
NODE_ENV: "sandbox",
|
|
223375
|
+
PERCH_SANDBOX_NETWORK: networkPolicy,
|
|
223376
|
+
LANG: "en_US.UTF-8",
|
|
223377
|
+
HOME: cwd2,
|
|
223378
|
+
TMPDIR: join(cwd2, "tmp"),
|
|
223379
|
+
PYTHONDONTWRITEBYTECODE: "1",
|
|
223380
|
+
PATH: process.env.PATH ?? "/usr/local/bin:/usr/bin:/bin",
|
|
223381
|
+
ELECTRON_RUN_AS_NODE: "1",
|
|
223382
|
+
PERCH_ELECTRON_EXEC: process.execPath,
|
|
223383
|
+
...launch.env
|
|
223384
|
+
};
|
|
223385
|
+
const child = spawn(launch.command, launch.args, {
|
|
223386
|
+
cwd: cwd2,
|
|
223387
|
+
env: childEnv,
|
|
223388
|
+
stdio: ["ignore", "pipe", "pipe"]
|
|
223389
|
+
});
|
|
223390
|
+
const timer = setTimeout(() => {
|
|
223391
|
+
timedOut = true;
|
|
223392
|
+
child.kill("SIGKILL");
|
|
223393
|
+
}, timeoutMs);
|
|
223394
|
+
child.stdout?.on("data", (data) => {
|
|
223395
|
+
stdoutBytes += data.length;
|
|
223396
|
+
const chunk2 = data.toString("utf8");
|
|
223397
|
+
onEvent?.("stdout", { chunk: redactUserVisibleText(chunk2) });
|
|
223398
|
+
if (stdoutBytes <= MAX_STDOUT_BYTES) stdout += chunk2;
|
|
223399
|
+
else stdoutTruncated = true;
|
|
223400
|
+
});
|
|
223401
|
+
child.stderr?.on("data", (data) => {
|
|
223402
|
+
stderrBytes += data.length;
|
|
223403
|
+
const chunk2 = data.toString("utf8");
|
|
223404
|
+
onEvent?.("stderr", { chunk: redactUserVisibleText(chunk2) });
|
|
223405
|
+
if (stderrBytes <= MAX_STDERR_BYTES) stderr += chunk2;
|
|
223406
|
+
else stderrTruncated = true;
|
|
223407
|
+
});
|
|
223408
|
+
child.on("close", (code) => {
|
|
223409
|
+
clearTimeout(timer);
|
|
223410
|
+
resolvePromise({ stdout, stderr, exitCode: code, timedOut, stdoutTruncated, stderrTruncated });
|
|
223411
|
+
});
|
|
223412
|
+
child.on("error", (err) => {
|
|
223413
|
+
clearTimeout(timer);
|
|
223414
|
+
resolvePromise({ stdout, stderr: err.message, exitCode: 1, timedOut: false, stdoutTruncated, stderrTruncated });
|
|
223415
|
+
});
|
|
223416
|
+
});
|
|
223417
|
+
}
|
|
223418
|
+
async function prepareSandboxLaunch(command, cwd2, networkPolicy) {
|
|
223419
|
+
await mkdir(join(cwd2, "tmp"), { recursive: true });
|
|
223420
|
+
if (networkPolicy !== "disabled") {
|
|
223421
|
+
return { command: "bash", args: ["-c", command] };
|
|
223422
|
+
}
|
|
223423
|
+
if (platform() !== "darwin") {
|
|
223424
|
+
return {
|
|
223425
|
+
error: "Sandbox execution requires macOS sandbox-exec for disabled-network local code runs in this build."
|
|
223426
|
+
};
|
|
223427
|
+
}
|
|
223428
|
+
const sandboxExec = "/usr/bin/sandbox-exec";
|
|
223429
|
+
try {
|
|
223430
|
+
const s = await stat(sandboxExec);
|
|
223431
|
+
if (!s.isFile()) throw new Error("not a file");
|
|
223432
|
+
} catch {
|
|
223433
|
+
return {
|
|
223434
|
+
error: "macOS sandbox-exec is unavailable; refusing to run model-written code without OS-level isolation."
|
|
223435
|
+
};
|
|
223436
|
+
}
|
|
223437
|
+
const profilePath = join(cwd2, ".perch-sandbox.sb");
|
|
223438
|
+
await writeFile2(profilePath, buildSeatbeltProfile(cwd2), "utf-8");
|
|
223439
|
+
return {
|
|
223440
|
+
command: sandboxExec,
|
|
223441
|
+
args: ["-f", profilePath, "/bin/bash", "-c", command],
|
|
223442
|
+
env: { PERCH_SANDBOX_PROFILE: profilePath }
|
|
223443
|
+
};
|
|
223444
|
+
}
|
|
223445
|
+
function buildSeatbeltProfile(workspaceRoot) {
|
|
223446
|
+
const home = homedir();
|
|
223447
|
+
const deniedUserDataRoots = Array.from(/* @__PURE__ */ new Set([
|
|
223448
|
+
home,
|
|
223449
|
+
"/Users/Shared",
|
|
223450
|
+
"/Volumes"
|
|
223451
|
+
])).map((path14) => `(subpath ${seatbeltString(path14)})`).join("\n ");
|
|
223452
|
+
return `
|
|
223453
|
+
(version 1)
|
|
223454
|
+
(allow default)
|
|
223455
|
+
(deny network*)
|
|
223456
|
+
(deny file-read*
|
|
223457
|
+
${deniedUserDataRoots})
|
|
223458
|
+
(deny file-write*
|
|
223459
|
+
${deniedUserDataRoots})
|
|
223460
|
+
(allow file-read*
|
|
223461
|
+
(subpath ${seatbeltString(workspaceRoot)})
|
|
223462
|
+
(subpath ${seatbeltString(dirname(process.execPath))}))
|
|
223463
|
+
(allow file-write*
|
|
223464
|
+
(subpath ${seatbeltString(workspaceRoot)}))
|
|
223465
|
+
`.trim();
|
|
223466
|
+
}
|
|
223467
|
+
function seatbeltString(value) {
|
|
223468
|
+
return `"${value.replace(/\\/g, "\\\\").replace(/"/g, '\\"')}"`;
|
|
223469
|
+
}
|
|
223470
|
+
async function collectOutputFiles(outputDir, warnings, onEvent) {
|
|
223471
|
+
const files = [];
|
|
223472
|
+
let totalBytes = 0;
|
|
223473
|
+
async function walk2(dir, base) {
|
|
223474
|
+
let entries;
|
|
223475
|
+
try {
|
|
223476
|
+
entries = await readdir(dir, { withFileTypes: true });
|
|
223477
|
+
} catch {
|
|
223478
|
+
return;
|
|
223479
|
+
}
|
|
223480
|
+
for (const entry of entries) {
|
|
223481
|
+
if (files.length >= MAX_OUTPUT_FILES) return;
|
|
223482
|
+
const rel = base ? `${base}/${entry.name}` : entry.name;
|
|
223483
|
+
const full = join(dir, entry.name);
|
|
223484
|
+
if (entry.isDirectory()) {
|
|
223485
|
+
await walk2(full, rel);
|
|
223486
|
+
continue;
|
|
223487
|
+
}
|
|
223488
|
+
const s = await stat(full);
|
|
223489
|
+
totalBytes += s.size;
|
|
223490
|
+
if (totalBytes > MAX_OUTPUT_BYTES) {
|
|
223491
|
+
warnings.push("Produced file byte limit exceeded");
|
|
223492
|
+
return;
|
|
223493
|
+
}
|
|
223494
|
+
const file = { relativePath: rel, sizeBytes: s.size, mimeType: guessMimeTypeFromName(entry.name) };
|
|
223495
|
+
files.push(file);
|
|
223496
|
+
onEvent?.("output_detected", file);
|
|
223497
|
+
}
|
|
223498
|
+
}
|
|
223499
|
+
await walk2(outputDir, "");
|
|
223500
|
+
return files;
|
|
223501
|
+
}
|
|
223502
|
+
async function readStructuredOutput(outputDir, stdout) {
|
|
223503
|
+
let parsedStdout = null;
|
|
223504
|
+
const line = stdout.trim().split(/\r?\n/).reverse().find((candidate) => candidate.trim().startsWith("{"));
|
|
223505
|
+
if (line) {
|
|
223506
|
+
try {
|
|
223507
|
+
parsedStdout = JSON.parse(line);
|
|
223508
|
+
} catch {
|
|
223509
|
+
parsedStdout = null;
|
|
223510
|
+
}
|
|
223511
|
+
}
|
|
223512
|
+
let reportJson = parsedStdout?.reportJson;
|
|
223513
|
+
if (!reportJson) {
|
|
223514
|
+
try {
|
|
223515
|
+
reportJson = JSON.parse(await readFile3(join(outputDir, "report.json"), "utf8"));
|
|
223516
|
+
} catch {
|
|
223517
|
+
reportJson = void 0;
|
|
223518
|
+
}
|
|
223519
|
+
}
|
|
223520
|
+
const tables = Array.isArray(parsedStdout?.tables) ? parsedStdout.tables : [];
|
|
223521
|
+
const charts = Array.isArray(parsedStdout?.charts) ? parsedStdout.charts : [];
|
|
223522
|
+
const logs = Array.isArray(parsedStdout?.logs) ? parsedStdout.logs.filter((x) => typeof x === "string") : [];
|
|
223523
|
+
if (!reportJson && tables.length === 0 && charts.length === 0 && logs.length === 0) return null;
|
|
223524
|
+
return { reportJson, tables, charts, logs };
|
|
223525
|
+
}
|
|
223526
|
+
function buildOutputBundle(run) {
|
|
223527
|
+
const structured = run.structuredOutput;
|
|
223528
|
+
if (!structured && run.producedFiles.length === 0) return null;
|
|
223529
|
+
return {
|
|
223530
|
+
status: run.status,
|
|
223531
|
+
files: run.producedFiles.map((file) => ({
|
|
223532
|
+
fileName: safeRelativeName(file.relativePath),
|
|
223533
|
+
sizeBytes: file.sizeBytes,
|
|
223534
|
+
mimeType: file.mimeType
|
|
223535
|
+
})),
|
|
223536
|
+
tables: structured?.tables ?? [],
|
|
223537
|
+
charts: structured?.charts ?? [],
|
|
223538
|
+
logs: structured?.logs ?? [],
|
|
223539
|
+
reportJson: structured?.reportJson ?? null
|
|
223540
|
+
};
|
|
223541
|
+
}
|
|
223542
|
+
function makeRunId2(prefix) {
|
|
223543
|
+
try {
|
|
223544
|
+
return `${prefix}-${randomUUID().slice(0, 12)}`;
|
|
223545
|
+
} catch {
|
|
223546
|
+
return `${prefix}-${Date.now().toString(36)}`;
|
|
223547
|
+
}
|
|
223548
|
+
}
|
|
223549
|
+
function safeRunId(value) {
|
|
223550
|
+
if (!value) return null;
|
|
223551
|
+
return /^[a-zA-Z0-9_-]{1,80}$/.test(value) ? value : null;
|
|
223552
|
+
}
|
|
223553
|
+
function safeWorkspaceKey(value) {
|
|
223554
|
+
if (!value) return null;
|
|
223555
|
+
const cleaned = value.replace(/[^a-zA-Z0-9_-]/g, "_").slice(0, 80);
|
|
223556
|
+
return cleaned || null;
|
|
223557
|
+
}
|
|
223558
|
+
function safeRelativeName(value) {
|
|
223559
|
+
return value.split(/[\\/]+/).filter((part) => part && part !== "." && part !== "..").join("/") || "unnamed";
|
|
223560
|
+
}
|
|
223561
|
+
function redactUserVisibleText(text) {
|
|
223562
|
+
if (!text) return "";
|
|
223563
|
+
return text.replace(/\/Users\/[^/\s"'`]+/g, "[home]").replace(/\/home\/[^/\s"'`]+/g, "[home]").replace(/\/private\/var\/folders\/[^\s"'`]+/g, "[temp]").replace(/\/var\/folders\/[^\s"'`]+/g, "[temp]").replace(/\/tmp\/perch-sandbox-[^\s"'`]+/g, "[sandbox]").replace(/\/var\/tmp\/perch-sandbox-[^\s"'`]+/g, "[sandbox]");
|
|
223564
|
+
}
|
|
223565
|
+
function guessFileTypeFromExt(ext) {
|
|
223566
|
+
if ([".xlsx", ".xls"].includes(ext)) return "spreadsheet";
|
|
223567
|
+
if (ext === ".csv" || ext === ".tsv") return "csv";
|
|
223568
|
+
if (ext === ".pdf") return "pdf";
|
|
223569
|
+
if ([".png", ".jpg", ".jpeg", ".gif", ".webp", ".svg"].includes(ext)) return "image";
|
|
223570
|
+
if ([".doc", ".docx", ".txt", ".md", ".rtf"].includes(ext)) return "document";
|
|
223571
|
+
return "unknown";
|
|
223572
|
+
}
|
|
223573
|
+
function guessMimeTypeFromName(fileName) {
|
|
223574
|
+
const ext = extname(fileName).toLowerCase();
|
|
223575
|
+
const map2 = {
|
|
223576
|
+
".json": "application/json",
|
|
223577
|
+
".csv": "text/csv",
|
|
223578
|
+
".tsv": "text/tab-separated-values",
|
|
223579
|
+
".txt": "text/plain",
|
|
223580
|
+
".md": "text/markdown",
|
|
223581
|
+
".html": "text/html"
|
|
223582
|
+
};
|
|
223583
|
+
return map2[ext] ?? "application/octet-stream";
|
|
223584
|
+
}
|
|
223585
|
+
var MAX_SOURCES, MAX_SOURCE_BYTES, MAX_STDOUT_BYTES, MAX_STDERR_BYTES, MAX_OUTPUT_FILES, MAX_OUTPUT_BYTES, DEFAULT_TIMEOUT_MS2, codeWorkspaces, PYTHON_HELPERS_SOURCE;
|
|
223586
|
+
var init_localSandboxHost = __esm({
|
|
223587
|
+
"electron/localSandboxHost.ts"() {
|
|
223588
|
+
MAX_SOURCES = 20;
|
|
223589
|
+
MAX_SOURCE_BYTES = 20 * 1024 * 1024;
|
|
223590
|
+
MAX_STDOUT_BYTES = 512 * 1024;
|
|
223591
|
+
MAX_STDERR_BYTES = 128 * 1024;
|
|
223592
|
+
MAX_OUTPUT_FILES = 50;
|
|
223593
|
+
MAX_OUTPUT_BYTES = 50 * 1024 * 1024;
|
|
223594
|
+
DEFAULT_TIMEOUT_MS2 = 3e4;
|
|
223595
|
+
codeWorkspaces = /* @__PURE__ */ new Map();
|
|
223596
|
+
PYTHON_HELPERS_SOURCE = `
|
|
223597
|
+
import csv
|
|
223598
|
+
import json
|
|
223599
|
+
import re
|
|
223600
|
+
import sys
|
|
223601
|
+
import zlib
|
|
223602
|
+
from pathlib import Path
|
|
223603
|
+
from collections import Counter
|
|
223604
|
+
|
|
223605
|
+
def sandbox_runtime_info(path="sandbox_runtime.json"):
|
|
223606
|
+
p = Path(path)
|
|
223607
|
+
if p.exists():
|
|
223608
|
+
return json.loads(p.read_text(encoding="utf-8"))
|
|
223609
|
+
return {
|
|
223610
|
+
"networkPolicy": "unknown",
|
|
223611
|
+
"packageInstalls": "unknown",
|
|
223612
|
+
"pythonCommand": sys.executable,
|
|
223613
|
+
"helperModule": "perch_helpers",
|
|
223614
|
+
}
|
|
223615
|
+
|
|
223616
|
+
def input_manifest(path="input_manifest.json"):
|
|
223617
|
+
p = Path(path)
|
|
223618
|
+
if not p.exists():
|
|
223619
|
+
return {"root": "input", "files": [], "skipped": []}
|
|
223620
|
+
return json.loads(p.read_text(encoding="utf-8"))
|
|
223621
|
+
|
|
223622
|
+
def input_files(root="input"):
|
|
223623
|
+
base = Path(root)
|
|
223624
|
+
if not base.exists():
|
|
223625
|
+
return []
|
|
223626
|
+
return [str(p) for p in base.rglob("*") if p.is_file()]
|
|
223627
|
+
|
|
223628
|
+
def load_tabular(path):
|
|
223629
|
+
p = Path(path)
|
|
223630
|
+
suffix = p.suffix.lower()
|
|
223631
|
+
if suffix in {".csv", ".tsv"}:
|
|
223632
|
+
try:
|
|
223633
|
+
import pandas as pd
|
|
223634
|
+
return pd.read_csv(p, sep="\\t" if suffix == ".tsv" else ",")
|
|
223635
|
+
except Exception:
|
|
223636
|
+
with p.open(newline="", encoding="utf-8-sig") as fh:
|
|
223637
|
+
return list(csv.DictReader(fh, delimiter="\\t" if suffix == ".tsv" else ","))
|
|
223638
|
+
if suffix in {".xlsx", ".xls"}:
|
|
223639
|
+
try:
|
|
223640
|
+
import pandas as pd
|
|
223641
|
+
return pd.read_excel(p)
|
|
223642
|
+
except Exception as exc:
|
|
223643
|
+
raise RuntimeError("Excel loading requires pandas/openpyxl in the local Python environment") from exc
|
|
223644
|
+
raise ValueError(f"Unsupported tabular file type: {p.suffix}")
|
|
223645
|
+
|
|
223646
|
+
def extract_pdf_tables(path):
|
|
223647
|
+
try:
|
|
223648
|
+
import pdfplumber
|
|
223649
|
+
except Exception as exc:
|
|
223650
|
+
raise RuntimeError("PDF table extraction requires pdfplumber in the local Python environment") from exc
|
|
223651
|
+
rows = []
|
|
223652
|
+
with pdfplumber.open(path) as pdf:
|
|
223653
|
+
for page_index, page in enumerate(pdf.pages, start=1):
|
|
223654
|
+
for table in page.extract_tables() or []:
|
|
223655
|
+
rows.append({"page": page_index, "table": table})
|
|
223656
|
+
return rows
|
|
223657
|
+
|
|
223658
|
+
def _pdf_literal_unescape(value):
|
|
223659
|
+
out = []
|
|
223660
|
+
i = 0
|
|
223661
|
+
while i < len(value):
|
|
223662
|
+
ch = value[i]
|
|
223663
|
+
if ch != "\\\\":
|
|
223664
|
+
out.append(ch)
|
|
223665
|
+
i += 1
|
|
223666
|
+
continue
|
|
223667
|
+
i += 1
|
|
223668
|
+
if i >= len(value):
|
|
223669
|
+
break
|
|
223670
|
+
esc = value[i]
|
|
223671
|
+
i += 1
|
|
223672
|
+
mapping = {"n": "\\n", "r": "\\r", "t": "\\t", "b": "\\b", "f": "\\f", "\\\\": "\\\\", "(": "(", ")": ")"}
|
|
223673
|
+
if esc in mapping:
|
|
223674
|
+
out.append(mapping[esc])
|
|
223675
|
+
elif esc in "01234567":
|
|
223676
|
+
octal = esc
|
|
223677
|
+
for _ in range(2):
|
|
223678
|
+
if i < len(value) and value[i] in "01234567":
|
|
223679
|
+
octal += value[i]
|
|
223680
|
+
i += 1
|
|
223681
|
+
else:
|
|
223682
|
+
break
|
|
223683
|
+
try:
|
|
223684
|
+
out.append(chr(int(octal, 8)))
|
|
223685
|
+
except Exception:
|
|
223686
|
+
pass
|
|
223687
|
+
else:
|
|
223688
|
+
out.append(esc)
|
|
223689
|
+
return "".join(out)
|
|
223690
|
+
|
|
223691
|
+
def _extract_pdf_text_raw(path):
|
|
223692
|
+
data = Path(path).read_bytes()
|
|
223693
|
+
chunks = []
|
|
223694
|
+
for match in re.finditer(rb"stream\\r?\\n(.*?)\\r?\\nendstream", data, re.S):
|
|
223695
|
+
raw = match.group(1)
|
|
223696
|
+
candidates = [raw]
|
|
223697
|
+
try:
|
|
223698
|
+
candidates.insert(0, zlib.decompress(raw))
|
|
223699
|
+
except Exception:
|
|
223700
|
+
pass
|
|
223701
|
+
for candidate in candidates:
|
|
223702
|
+
try:
|
|
223703
|
+
decoded = candidate.decode("latin-1", errors="ignore")
|
|
223704
|
+
except Exception:
|
|
223705
|
+
continue
|
|
223706
|
+
literals = [_pdf_literal_unescape(x) for x in re.findall(r"\\((.*?)\\)", decoded, re.S)]
|
|
223707
|
+
if literals:
|
|
223708
|
+
chunks.extend(literals)
|
|
223709
|
+
break
|
|
223710
|
+
return " ".join(part.strip() for part in chunks if part and part.strip())
|
|
223711
|
+
|
|
223712
|
+
def extract_pdf_text(path):
|
|
223713
|
+
p = Path(path)
|
|
223714
|
+
if not p.exists():
|
|
223715
|
+
raise FileNotFoundError(str(p))
|
|
223716
|
+
errors = []
|
|
223717
|
+
for module_name in ("pypdf", "PyPDF2"):
|
|
223718
|
+
try:
|
|
223719
|
+
module = __import__(module_name)
|
|
223720
|
+
reader_cls = getattr(module, "PdfReader")
|
|
223721
|
+
reader = reader_cls(str(p))
|
|
223722
|
+
text = "\\n".join((page.extract_text() or "") for page in reader.pages)
|
|
223723
|
+
if text.strip():
|
|
223724
|
+
return text
|
|
223725
|
+
except Exception as exc:
|
|
223726
|
+
errors.append(f"{module_name}: {exc}")
|
|
223727
|
+
try:
|
|
223728
|
+
from pdfminer.high_level import extract_text
|
|
223729
|
+
text = extract_text(str(p))
|
|
223730
|
+
if text.strip():
|
|
223731
|
+
return text
|
|
223732
|
+
except Exception as exc:
|
|
223733
|
+
errors.append(f"pdfminer: {exc}")
|
|
223734
|
+
raw = _extract_pdf_text_raw(p)
|
|
223735
|
+
if raw.strip():
|
|
223736
|
+
return raw
|
|
223737
|
+
raise RuntimeError("No extractable PDF text found; tried pypdf, PyPDF2, pdfminer, and raw PDF streams. " + "; ".join(errors))
|
|
223738
|
+
|
|
223739
|
+
def extract_invoice_fields(path):
|
|
223740
|
+
text = extract_pdf_text(path)
|
|
223741
|
+
def find(pattern):
|
|
223742
|
+
m = re.search(pattern, text, re.I)
|
|
223743
|
+
return m.group(1).strip() if m else None
|
|
223744
|
+
amount = find(r"Amount\\s+Due:\\s*(?:USD\\s*)?([0-9,]+(?:\\.\\d+)?)")
|
|
223745
|
+
return {
|
|
223746
|
+
"file": str(path),
|
|
223747
|
+
"text": text,
|
|
223748
|
+
"vendor_name": text.split(" EIN")[0].strip() if " EIN" in text else None,
|
|
223749
|
+
"ein": find(r"EIN:\\s*([0-9-]+)"),
|
|
223750
|
+
"invoice_number": find(r"Invoice\\s+Number:\\s*(INV-[0-9]+)"),
|
|
223751
|
+
"invoice_date": find(r"Date:\\s*([0-9]{4}-[0-9]{2}-[0-9]{2})"),
|
|
223752
|
+
"po_number": find(r"Purchase\\s+Order:\\s*(PO-[0-9]+)"),
|
|
223753
|
+
"amount_due": float(amount.replace(",", "")) if amount else None,
|
|
223754
|
+
}
|
|
223755
|
+
|
|
223756
|
+
def find_duplicates(rows, keys):
|
|
223757
|
+
if hasattr(rows, "to_dict"):
|
|
223758
|
+
records = rows.to_dict("records")
|
|
223759
|
+
else:
|
|
223760
|
+
records = list(rows)
|
|
223761
|
+
counts = Counter(tuple(str(row.get(k, "")).strip().lower() for k in keys) for row in records)
|
|
223762
|
+
return [row for row in records if counts[tuple(str(row.get(k, "")).strip().lower() for k in keys)] > 1]
|
|
223763
|
+
|
|
223764
|
+
def write_report(report, path="output/report.json"):
|
|
223765
|
+
out = Path(path)
|
|
223766
|
+
out.parent.mkdir(parents=True, exist_ok=True)
|
|
223767
|
+
out.write_text(json.dumps(report, indent=2, default=str), encoding="utf-8")
|
|
223768
|
+
return str(out)
|
|
223769
|
+
`.trim();
|
|
223770
|
+
}
|
|
223771
|
+
});
|
|
223772
|
+
|
|
223773
|
+
// features/perchTerminal/runtime/cliHost/nodeLocalBridge.ts
|
|
223774
|
+
import { spawn as spawn2 } from "node:child_process";
|
|
222676
223775
|
import fs9 from "node:fs";
|
|
222677
223776
|
import fsp from "node:fs/promises";
|
|
222678
223777
|
import os from "node:os";
|
|
@@ -222692,6 +223791,12 @@ function installCliNodeLocalBridge(input) {
|
|
|
222692
223791
|
function createCliNodeLocalBridge(input) {
|
|
222693
223792
|
const workspaceRoot = path10.resolve(input.workspaceRoot);
|
|
222694
223793
|
const now13 = () => (/* @__PURE__ */ new Date()).toISOString();
|
|
223794
|
+
const sandboxHandlers = /* @__PURE__ */ new Map();
|
|
223795
|
+
const emitSandboxEvent = (event) => {
|
|
223796
|
+
const handlers = sandboxHandlers.get(event.runId);
|
|
223797
|
+
if (!handlers) return;
|
|
223798
|
+
for (const handler of handlers) handler(event);
|
|
223799
|
+
};
|
|
222695
223800
|
const terminalSession = () => ({
|
|
222696
223801
|
sessionId: "cli-terminal",
|
|
222697
223802
|
title: "Perch CLI",
|
|
@@ -222726,17 +223831,9 @@ function createCliNodeLocalBridge(input) {
|
|
|
222726
223831
|
}),
|
|
222727
223832
|
checkFsAccess: async (request) => {
|
|
222728
223833
|
const absolutePath = path10.resolve(expandHome4(request.absolutePath));
|
|
222729
|
-
if (request.fsAccessOverride === "allow_once" || isInside(workspaceRoot, absolutePath)) {
|
|
222730
|
-
return {
|
|
222731
|
-
decision: "allow",
|
|
222732
|
-
reason: "Allowed by Perch CLI local workspace.",
|
|
222733
|
-
absolutePath,
|
|
222734
|
-
approvalPath: absolutePath
|
|
222735
|
-
};
|
|
222736
|
-
}
|
|
222737
223834
|
return {
|
|
222738
|
-
decision: "
|
|
222739
|
-
reason:
|
|
223835
|
+
decision: "allow",
|
|
223836
|
+
reason: "Allowed by Perch CLI local filesystem access.",
|
|
222740
223837
|
absolutePath,
|
|
222741
223838
|
approvalPath: absolutePath
|
|
222742
223839
|
};
|
|
@@ -222762,7 +223859,7 @@ function createCliNodeLocalBridge(input) {
|
|
|
222762
223859
|
executionHost: "electron_desktop"
|
|
222763
223860
|
}),
|
|
222764
223861
|
runLocalBash: async (request) => runShellCommand({
|
|
222765
|
-
workspaceRoot,
|
|
223862
|
+
workspaceRoot: resolveRequestRoot(workspaceRoot, request.workspaceRoot),
|
|
222766
223863
|
command: request.command,
|
|
222767
223864
|
cwd: request.cwd,
|
|
222768
223865
|
timeoutMs: request.timeoutMs
|
|
@@ -222798,45 +223895,45 @@ function createCliNodeLocalBridge(input) {
|
|
|
222798
223895
|
offBashTerminalEvent: () => {
|
|
222799
223896
|
},
|
|
222800
223897
|
readWorkspaceFile: async (request) => {
|
|
222801
|
-
const
|
|
222802
|
-
|
|
222803
|
-
const
|
|
222804
|
-
if (!
|
|
222805
|
-
if (
|
|
222806
|
-
return { ok: false, error: `File is too large for direct text read (${
|
|
223898
|
+
const baseRoot = resolveRequestRoot(workspaceRoot, request.workspaceRoot);
|
|
223899
|
+
const target = resolveReadPath(baseRoot, request.relativePath);
|
|
223900
|
+
const stat2 = await safeStat(target);
|
|
223901
|
+
if (!stat2?.isFile()) return { ok: false, error: `File does not exist: ${target}` };
|
|
223902
|
+
if (stat2.size > MAX_READ_BYTES && request.encoding !== "base64") {
|
|
223903
|
+
return { ok: false, error: `File is too large for direct text read (${stat2.size} bytes). Use grep or a narrower file.` };
|
|
222807
223904
|
}
|
|
222808
223905
|
const buffer = await fsp.readFile(target);
|
|
222809
223906
|
return {
|
|
222810
223907
|
ok: true,
|
|
222811
|
-
relativePath:
|
|
223908
|
+
relativePath: displayPath(baseRoot, target, request.relativePath),
|
|
222812
223909
|
content: request.encoding === "base64" ? buffer.toString("base64") : buffer.toString("utf8"),
|
|
222813
|
-
sizeBytes:
|
|
223910
|
+
sizeBytes: stat2.size,
|
|
222814
223911
|
...request.encoding === "base64" ? { encoding: "base64" } : {}
|
|
222815
223912
|
};
|
|
222816
223913
|
},
|
|
222817
223914
|
writeWorkspaceFile: async (request) => {
|
|
222818
|
-
const
|
|
222819
|
-
|
|
223915
|
+
const baseRoot = resolveRequestRoot(workspaceRoot, request.workspaceRoot);
|
|
223916
|
+
const target = resolveWritePath(baseRoot, request.relativePath);
|
|
222820
223917
|
await fsp.mkdir(path10.dirname(target), { recursive: true });
|
|
222821
223918
|
const flag = request.overwrite === true ? "w" : "wx";
|
|
223919
|
+
const payload = request.encoding === "base64" && typeof request.contentBase64 === "string" ? Buffer.from(request.contentBase64, "base64") : request.content ?? "";
|
|
222822
223920
|
try {
|
|
222823
|
-
await fsp.writeFile(target,
|
|
223921
|
+
await fsp.writeFile(target, payload, typeof payload === "string" ? { encoding: "utf8", flag } : { flag });
|
|
222824
223922
|
} catch (error) {
|
|
222825
223923
|
if (error.code === "EEXIST") {
|
|
222826
|
-
return { ok: false, error: `File already exists: ${
|
|
223924
|
+
return { ok: false, error: `File already exists: ${displayPath(baseRoot, target, request.relativePath)}. Pass overwrite=true to replace it.` };
|
|
222827
223925
|
}
|
|
222828
223926
|
throw error;
|
|
222829
223927
|
}
|
|
222830
223928
|
return {
|
|
222831
223929
|
ok: true,
|
|
222832
|
-
relativePath:
|
|
222833
|
-
bytesWritten: Buffer.byteLength(
|
|
223930
|
+
relativePath: displayPath(baseRoot, target, request.relativePath),
|
|
223931
|
+
bytesWritten: Buffer.byteLength(payload)
|
|
222834
223932
|
};
|
|
222835
223933
|
},
|
|
222836
223934
|
moveLocalFile: async (request) => {
|
|
222837
223935
|
const src = resolveReadPath(workspaceRoot, request.src);
|
|
222838
223936
|
const dest = resolveWritePath(workspaceRoot, request.dest);
|
|
222839
|
-
if (!isInside(workspaceRoot, src) || !isInside(workspaceRoot, dest)) return { ok: false, error: "Move paths must stay inside the CLI workspace." };
|
|
222840
223937
|
await fsp.mkdir(path10.dirname(dest), { recursive: true });
|
|
222841
223938
|
await fsp.rename(src, dest);
|
|
222842
223939
|
return { ok: true, fromPath: src, toPath: dest };
|
|
@@ -222844,37 +223941,32 @@ function createCliNodeLocalBridge(input) {
|
|
|
222844
223941
|
copyLocalFile: async (request) => {
|
|
222845
223942
|
const src = resolveReadPath(workspaceRoot, request.src);
|
|
222846
223943
|
const dest = resolveWritePath(workspaceRoot, request.dest);
|
|
222847
|
-
if (!isInside(workspaceRoot, src) || !isInside(workspaceRoot, dest)) return { ok: false, error: "Copy paths must stay inside the CLI workspace." };
|
|
222848
223944
|
await fsp.mkdir(path10.dirname(dest), { recursive: true });
|
|
222849
223945
|
await fsp.copyFile(src, dest);
|
|
222850
223946
|
return { ok: true, fromPath: src, toPath: dest };
|
|
222851
223947
|
},
|
|
222852
223948
|
createDirectory: async (request) => {
|
|
222853
223949
|
const target = resolveWritePath(workspaceRoot, request.path);
|
|
222854
|
-
if (!isInside(workspaceRoot, target)) return { ok: false, error: `Refusing to create directory outside CLI workspace: ${target}` };
|
|
222855
223950
|
await fsp.mkdir(target, { recursive: true });
|
|
222856
223951
|
return { ok: true, path: target };
|
|
222857
223952
|
},
|
|
222858
223953
|
deleteLocalFile: async (request) => {
|
|
222859
223954
|
const target = resolveWritePath(workspaceRoot, request.path);
|
|
222860
|
-
|
|
222861
|
-
|
|
222862
|
-
if (!
|
|
222863
|
-
if (!stat.isFile() && !stat.isSymbolicLink()) return { ok: false, error: "deleteLocalFile only deletes files, not directories." };
|
|
223955
|
+
const stat2 = await safeStat(target);
|
|
223956
|
+
if (!stat2) return { ok: false, error: `File does not exist: ${target}` };
|
|
223957
|
+
if (!stat2.isFile() && !stat2.isSymbolicLink()) return { ok: false, error: "deleteLocalFile only deletes files, not directories." };
|
|
222864
223958
|
await fsp.rm(target);
|
|
222865
223959
|
return { ok: true, path: target };
|
|
222866
223960
|
},
|
|
222867
223961
|
printFile: async () => ({ ok: false, error: "Printing is not supported from Perch CLI local mode." }),
|
|
222868
223962
|
listWorkspaceFilesGlob: async (request) => {
|
|
222869
|
-
const
|
|
222870
|
-
|
|
222871
|
-
return { ok: false, matches: [], totalFound: 0, truncated: false, resolvedRoot: workspaceRoot, executionHost: "electron_desktop", errorCode: "path_outside_workspace", errorMessage: `Path is outside CLI workspace: ${root2}` };
|
|
222872
|
-
}
|
|
223963
|
+
const baseRoot = resolveRequestRoot(workspaceRoot, request.workspaceRoot);
|
|
223964
|
+
const root2 = request.path ? resolveReadPath(baseRoot, request.path) : baseRoot;
|
|
222873
223965
|
const maxResults = sanitizeMaxResults(request.maxResults);
|
|
222874
223966
|
const pattern = request.pattern?.trim() || "**/*";
|
|
222875
223967
|
const regex2 = globToRegex(pattern);
|
|
222876
223968
|
const files = await collectFiles(root2, { maxVisits: Math.max(maxResults * 20, 1e3) });
|
|
222877
|
-
const matches = files.map((file) => path10.relative(root2, file).replace(/\\/g, "/")).filter((
|
|
223969
|
+
const matches = files.map((file) => path10.relative(root2, file).replace(/\\/g, "/")).filter((relative2) => regex2.test(relative2)).slice(0, maxResults);
|
|
222878
223970
|
return {
|
|
222879
223971
|
ok: true,
|
|
222880
223972
|
matches,
|
|
@@ -222884,23 +223976,21 @@ function createCliNodeLocalBridge(input) {
|
|
|
222884
223976
|
dirsVisited: 0,
|
|
222885
223977
|
pattern,
|
|
222886
223978
|
searchPath: root2,
|
|
222887
|
-
resolvedRoot:
|
|
223979
|
+
resolvedRoot: root2,
|
|
222888
223980
|
executionHost: "electron_desktop"
|
|
222889
223981
|
};
|
|
222890
223982
|
},
|
|
222891
223983
|
searchWorkspaceFilesGrep: async (request) => {
|
|
222892
|
-
const
|
|
222893
|
-
|
|
222894
|
-
return { ok: false, matches: [], totalMatches: 0, truncated: false, resolvedRoot: workspaceRoot, executionHost: "electron_desktop", errorCode: "path_outside_workspace", errorMessage: `Path is outside CLI workspace: ${root2}` };
|
|
222895
|
-
}
|
|
223984
|
+
const baseRoot = resolveRequestRoot(workspaceRoot, request.workspaceRoot);
|
|
223985
|
+
const root2 = request.path ? resolveReadPath(baseRoot, request.path) : baseRoot;
|
|
222896
223986
|
const maxResults = sanitizeMaxResults(request.maxResults);
|
|
222897
223987
|
const includeRegex = request.include ? globToRegex(request.include) : null;
|
|
222898
223988
|
const queryRegex = compileQueryRegex(request.query, request.caseSensitive !== false);
|
|
222899
223989
|
const files = await collectFiles(root2, { maxVisits: 5e3 });
|
|
222900
223990
|
const matches = [];
|
|
222901
223991
|
for (const file of files) {
|
|
222902
|
-
const
|
|
222903
|
-
if (includeRegex && !includeRegex.test(
|
|
223992
|
+
const relative2 = path10.relative(root2, file).replace(/\\/g, "/");
|
|
223993
|
+
if (includeRegex && !includeRegex.test(relative2)) continue;
|
|
222904
223994
|
const text = await readTextFileIfReasonable(file);
|
|
222905
223995
|
if (text === null) continue;
|
|
222906
223996
|
const lines = text.split(/\r?\n/);
|
|
@@ -222910,7 +224000,7 @@ function createCliNodeLocalBridge(input) {
|
|
|
222910
224000
|
queryRegex.lastIndex = 0;
|
|
222911
224001
|
if (!match) continue;
|
|
222912
224002
|
matches.push({
|
|
222913
|
-
file:
|
|
224003
|
+
file: relative2,
|
|
222914
224004
|
line: index + 1,
|
|
222915
224005
|
column: match.index + 1,
|
|
222916
224006
|
match: match[0],
|
|
@@ -222928,35 +224018,34 @@ function createCliNodeLocalBridge(input) {
|
|
|
222928
224018
|
filesSearched: files.length,
|
|
222929
224019
|
query: request.query,
|
|
222930
224020
|
searchPath: root2,
|
|
222931
|
-
resolvedRoot:
|
|
224021
|
+
resolvedRoot: root2,
|
|
222932
224022
|
executionHost: "electron_desktop"
|
|
222933
224023
|
};
|
|
222934
224024
|
},
|
|
222935
224025
|
statWorkspacePath: async (request) => {
|
|
222936
|
-
const
|
|
222937
|
-
|
|
222938
|
-
|
|
222939
|
-
}
|
|
222940
|
-
const stat = await safeStat(target);
|
|
224026
|
+
const baseRoot = resolveRequestRoot(workspaceRoot, request.workspaceRoot);
|
|
224027
|
+
const target = resolveReadPath(baseRoot, request.relativePath);
|
|
224028
|
+
const stat2 = await safeStat(target);
|
|
222941
224029
|
return {
|
|
222942
224030
|
ok: true,
|
|
222943
|
-
relativePath: path10.relative(
|
|
222944
|
-
exists: Boolean(
|
|
222945
|
-
isFile:
|
|
222946
|
-
isDirectory:
|
|
222947
|
-
sizeBytes:
|
|
222948
|
-
modifiedAt:
|
|
224031
|
+
relativePath: path10.isAbsolute(request.relativePath) || request.relativePath.startsWith("~") ? target : path10.relative(baseRoot, target) || ".",
|
|
224032
|
+
exists: Boolean(stat2),
|
|
224033
|
+
isFile: stat2?.isFile() ?? false,
|
|
224034
|
+
isDirectory: stat2?.isDirectory() ?? false,
|
|
224035
|
+
sizeBytes: stat2?.size,
|
|
224036
|
+
modifiedAt: stat2?.mtime.toISOString(),
|
|
222949
224037
|
executionHost: "electron_desktop"
|
|
222950
224038
|
};
|
|
222951
224039
|
},
|
|
222952
224040
|
listLocalSources: async (request) => {
|
|
222953
224041
|
const query = typeof request === "object" && request ? request.query?.toLowerCase().trim() ?? "" : "";
|
|
222954
224042
|
const maxResults = typeof request === "object" && request ? sanitizeMaxResults(request.maxResults) : DEFAULT_MAX_RESULTS;
|
|
222955
|
-
const
|
|
222956
|
-
const
|
|
224043
|
+
const root2 = typeof request === "object" && request?.path ? resolveReadPath(workspaceRoot, request.path) : workspaceRoot;
|
|
224044
|
+
const files = await collectFiles(root2, { maxVisits: Math.max(maxResults * 20, 1e3) });
|
|
224045
|
+
const entries = files.map((file) => localSourceEntry(root2, file, root2 !== workspaceRoot)).filter((entry) => !query || entry.relativePath.toLowerCase().includes(query) || entry.fileName.toLowerCase().includes(query)).slice(0, maxResults);
|
|
222957
224046
|
return {
|
|
222958
224047
|
ok: true,
|
|
222959
|
-
rootId: CLI_ROOT_ID,
|
|
224048
|
+
rootId: root2 === workspaceRoot ? CLI_ROOT_ID : "cli-absolute-root",
|
|
222960
224049
|
entries,
|
|
222961
224050
|
totalFound: files.length,
|
|
222962
224051
|
truncated: files.length > maxResults,
|
|
@@ -222967,16 +224056,15 @@ function createCliNodeLocalBridge(input) {
|
|
|
222967
224056
|
},
|
|
222968
224057
|
readLocalFile: async (localSourceId) => {
|
|
222969
224058
|
const target = resolveLocalSourceId(workspaceRoot, localSourceId);
|
|
222970
|
-
|
|
222971
|
-
|
|
222972
|
-
if (!stat?.isFile()) return { ok: false, error: `File does not exist: ${target}` };
|
|
224059
|
+
const stat2 = await safeStat(target);
|
|
224060
|
+
if (!stat2?.isFile()) return { ok: false, error: `File does not exist: ${target}` };
|
|
222973
224061
|
const buffer = await fsp.readFile(target);
|
|
222974
224062
|
return {
|
|
222975
224063
|
ok: true,
|
|
222976
224064
|
data: buffer.toString("base64"),
|
|
222977
224065
|
fileName: path10.relative(workspaceRoot, target) || path10.basename(target),
|
|
222978
224066
|
mimeType: inferMimeType(target),
|
|
222979
|
-
sizeBytes:
|
|
224067
|
+
sizeBytes: stat2.size,
|
|
222980
224068
|
encoding: "base64"
|
|
222981
224069
|
};
|
|
222982
224070
|
},
|
|
@@ -222992,34 +224080,282 @@ function createCliNodeLocalBridge(input) {
|
|
|
222992
224080
|
listMcpTools: async () => [],
|
|
222993
224081
|
callMcpTool: async () => ({ ok: false, error: "MCP tools are not available in CLI local mode." }),
|
|
222994
224082
|
reconnectMcp: async () => ({ ok: false, error: "MCP tools are not available in CLI local mode." }),
|
|
222995
|
-
|
|
222996
|
-
|
|
224083
|
+
runLocalAPAuditPacket: async (request) => runCliAPAuditPacket(workspaceRoot, request),
|
|
224084
|
+
runLocalPrepareAPEvidence: async (request) => runCliPrepareAPEvidence(workspaceRoot, request),
|
|
224085
|
+
runLocalQueryAPCases: async (request) => runCliQueryAPCases(workspaceRoot, request),
|
|
224086
|
+
runLocalRenderAPControlGraph: async (request) => runCliRenderAPControlGraph(workspaceRoot, request),
|
|
224087
|
+
prepareSandboxInputs: async (request) => prepareCliSandboxInputs(workspaceRoot, request),
|
|
224088
|
+
runSandboxCodeJob: async (request) => runCliSandboxCodeJob(workspaceRoot, request, emitSandboxEvent),
|
|
224089
|
+
onSandboxEvent: (runId, handler) => {
|
|
224090
|
+
const handlers = sandboxHandlers.get(runId) ?? /* @__PURE__ */ new Set();
|
|
224091
|
+
handlers.add(handler);
|
|
224092
|
+
sandboxHandlers.set(runId, handlers);
|
|
224093
|
+
return () => {
|
|
224094
|
+
handlers.delete(handler);
|
|
224095
|
+
if (handlers.size === 0) sandboxHandlers.delete(runId);
|
|
224096
|
+
};
|
|
222997
224097
|
},
|
|
222998
224098
|
offSandboxEvent: () => {
|
|
222999
224099
|
}
|
|
223000
224100
|
};
|
|
223001
224101
|
}
|
|
223002
|
-
async function
|
|
223003
|
-
const
|
|
223004
|
-
|
|
223005
|
-
|
|
224102
|
+
async function runCliAPAuditPacket(workspaceRoot, request) {
|
|
224103
|
+
const startMs = Date.now();
|
|
224104
|
+
try {
|
|
224105
|
+
const result2 = await generateAPCorePacket({
|
|
224106
|
+
folderPath: resolveReadPath(workspaceRoot, request.folderPath),
|
|
224107
|
+
outputRoot: request.outputRoot ? resolveWritePath(workspaceRoot, request.outputRoot) : void 0,
|
|
224108
|
+
timestamp: request.timestamp,
|
|
224109
|
+
writingStudioNarrativeHtml: request.writingStudioNarrativeHtml,
|
|
224110
|
+
writingStudioNarrativeText: request.writingStudioNarrativeText,
|
|
224111
|
+
writingStudioNarrativeDiagnostic: request.writingStudioNarrativeDiagnostic,
|
|
224112
|
+
requireWritingStudioNarrative: request.requireWritingStudioNarrative
|
|
224113
|
+
});
|
|
223006
224114
|
return {
|
|
223007
|
-
ok:
|
|
223008
|
-
|
|
223009
|
-
|
|
223010
|
-
|
|
223011
|
-
|
|
223012
|
-
|
|
223013
|
-
|
|
223014
|
-
cwd: cwd2,
|
|
224115
|
+
ok: true,
|
|
224116
|
+
data: {
|
|
224117
|
+
packet: result2.payload.packet,
|
|
224118
|
+
outputDir: result2.run.outputDir,
|
|
224119
|
+
outputFiles: result2.payload.packet.outputFiles,
|
|
224120
|
+
summary: result2.summary
|
|
224121
|
+
},
|
|
223015
224122
|
executionHost: "electron_desktop",
|
|
223016
|
-
|
|
223017
|
-
errorMessage: `Command cwd is outside CLI workspace: ${cwd2}`
|
|
224123
|
+
durationMs: Date.now() - startMs
|
|
223018
224124
|
};
|
|
224125
|
+
} catch (error) {
|
|
224126
|
+
return cliAPAuditError(startMs, error);
|
|
223019
224127
|
}
|
|
224128
|
+
}
|
|
224129
|
+
async function runCliPrepareAPEvidence(workspaceRoot, request) {
|
|
224130
|
+
const startMs = Date.now();
|
|
224131
|
+
try {
|
|
224132
|
+
const result2 = await prepareAPCoreEvidence({
|
|
224133
|
+
folderPath: resolveReadPath(workspaceRoot, request.folderPath),
|
|
224134
|
+
artifactRoot: request.artifactRoot ? resolveWritePath(workspaceRoot, request.artifactRoot) : void 0,
|
|
224135
|
+
timestamp: request.timestamp,
|
|
224136
|
+
mode: request.mode
|
|
224137
|
+
});
|
|
224138
|
+
const artifact = result2.payload.artifact;
|
|
224139
|
+
return {
|
|
224140
|
+
ok: true,
|
|
224141
|
+
data: {
|
|
224142
|
+
artifactId: artifact.artifactId,
|
|
224143
|
+
outputDir: artifact.outputDir,
|
|
224144
|
+
outputFiles: artifact.outputFiles,
|
|
224145
|
+
coverage: artifact.coverage,
|
|
224146
|
+
metrics: artifact.metrics,
|
|
224147
|
+
caseSummary: summarizeCliCases(artifact.cases ?? []),
|
|
224148
|
+
topCases: (artifact.cases ?? []).slice(0, 12),
|
|
224149
|
+
duplicateCases: result2.payload.duplicateCases,
|
|
224150
|
+
controlGraph: result2.payload.controlGraph,
|
|
224151
|
+
relativeOutputDir: typeof artifact.outputDir === "string" ? path10.basename(artifact.outputDir) : null,
|
|
224152
|
+
approvedRootMatch: true
|
|
224153
|
+
},
|
|
224154
|
+
executionHost: "electron_desktop",
|
|
224155
|
+
durationMs: Date.now() - startMs
|
|
224156
|
+
};
|
|
224157
|
+
} catch (error) {
|
|
224158
|
+
return cliAPError(startMs, error);
|
|
224159
|
+
}
|
|
224160
|
+
}
|
|
224161
|
+
async function runCliQueryAPCases(workspaceRoot, request) {
|
|
224162
|
+
const startMs = Date.now();
|
|
224163
|
+
try {
|
|
224164
|
+
const result2 = await queryAPCases(
|
|
224165
|
+
normalizeCliArtifactRequest(workspaceRoot, request)
|
|
224166
|
+
);
|
|
224167
|
+
return {
|
|
224168
|
+
ok: result2.ok,
|
|
224169
|
+
data: result2,
|
|
224170
|
+
error: result2.ok ? void 0 : result2.error,
|
|
224171
|
+
errorCode: result2.ok ? void 0 : result2.errorCode,
|
|
224172
|
+
executionHost: "electron_desktop",
|
|
224173
|
+
durationMs: Date.now() - startMs
|
|
224174
|
+
};
|
|
224175
|
+
} catch (error) {
|
|
224176
|
+
return cliAPError(startMs, error);
|
|
224177
|
+
}
|
|
224178
|
+
}
|
|
224179
|
+
async function runCliRenderAPControlGraph(workspaceRoot, request) {
|
|
224180
|
+
const startMs = Date.now();
|
|
224181
|
+
try {
|
|
224182
|
+
const result2 = await renderAPControlGraph(normalizeCliArtifactRequest(workspaceRoot, request));
|
|
224183
|
+
return {
|
|
224184
|
+
ok: result2.ok,
|
|
224185
|
+
data: result2,
|
|
224186
|
+
error: result2.ok ? void 0 : result2.error,
|
|
224187
|
+
errorCode: result2.ok ? void 0 : result2.errorCode,
|
|
224188
|
+
executionHost: "electron_desktop",
|
|
224189
|
+
durationMs: Date.now() - startMs
|
|
224190
|
+
};
|
|
224191
|
+
} catch (error) {
|
|
224192
|
+
return cliAPError(startMs, error);
|
|
224193
|
+
}
|
|
224194
|
+
}
|
|
224195
|
+
function normalizeCliArtifactRequest(workspaceRoot, request) {
|
|
224196
|
+
return {
|
|
224197
|
+
...request,
|
|
224198
|
+
folderPath: request.folderPath ? resolveReadPath(workspaceRoot, request.folderPath) : void 0,
|
|
224199
|
+
artifactRoot: request.artifactRoot ? resolveWritePath(workspaceRoot, request.artifactRoot) : void 0
|
|
224200
|
+
};
|
|
224201
|
+
}
|
|
224202
|
+
function cliAPError(startMs, error) {
|
|
224203
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
224204
|
+
return {
|
|
224205
|
+
ok: false,
|
|
224206
|
+
error: message,
|
|
224207
|
+
errorCode: classifyCliAPError(message),
|
|
224208
|
+
executionHost: "electron_desktop",
|
|
224209
|
+
durationMs: Date.now() - startMs
|
|
224210
|
+
};
|
|
224211
|
+
}
|
|
224212
|
+
function cliAPAuditError(startMs, error) {
|
|
224213
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
224214
|
+
return {
|
|
224215
|
+
ok: false,
|
|
224216
|
+
error: message,
|
|
224217
|
+
errorCode: classifyCliAPError(message),
|
|
224218
|
+
executionHost: "electron_desktop",
|
|
224219
|
+
durationMs: Date.now() - startMs
|
|
224220
|
+
};
|
|
224221
|
+
}
|
|
224222
|
+
function classifyCliAPError(message) {
|
|
224223
|
+
if (/folderPath is required|invalid/i.test(message)) return "invalid_input";
|
|
224224
|
+
if (/not a directory/i.test(message)) return "invalid_folder";
|
|
224225
|
+
if (/not found|ENOENT/i.test(message)) return "folder_not_found";
|
|
224226
|
+
return "execution_failed";
|
|
224227
|
+
}
|
|
224228
|
+
function summarizeCliCases(cases) {
|
|
224229
|
+
const counts = {};
|
|
224230
|
+
for (const item of cases) {
|
|
224231
|
+
const severity = item.severity ?? "unknown";
|
|
224232
|
+
counts[severity] = (counts[severity] ?? 0) + 1;
|
|
224233
|
+
}
|
|
224234
|
+
return counts;
|
|
224235
|
+
}
|
|
224236
|
+
async function prepareCliSandboxInputs(workspaceRoot, request) {
|
|
224237
|
+
const jobId = request.jobId?.trim() || `cli-sandbox-${Date.now()}`;
|
|
224238
|
+
const maxFiles = Math.max(1, Math.min(request.maxFiles ?? 20, 100));
|
|
224239
|
+
const maxBytesPerFile = Math.max(1, Math.min(request.maxBytesPerFile ?? 20 * 1024 * 1024, 50 * 1024 * 1024));
|
|
224240
|
+
const tempDir = await fsp.mkdtemp(path10.join(os.tmpdir(), `${jobId}-`));
|
|
224241
|
+
const entries = [];
|
|
224242
|
+
const skipped = [];
|
|
224243
|
+
for (const localSourceId of request.localSourceIds.slice(0, maxFiles)) {
|
|
224244
|
+
const sourcePath = resolveLocalSourceId(workspaceRoot, localSourceId);
|
|
224245
|
+
const stat2 = await safeStat(sourcePath);
|
|
224246
|
+
if (!stat2?.isFile()) {
|
|
224247
|
+
skipped.push({ localSourceId, reason: `File does not exist: ${sourcePath}` });
|
|
224248
|
+
continue;
|
|
224249
|
+
}
|
|
224250
|
+
if (stat2.size > maxBytesPerFile) {
|
|
224251
|
+
skipped.push({ localSourceId, reason: `File is too large: ${stat2.size} bytes.` });
|
|
224252
|
+
continue;
|
|
224253
|
+
}
|
|
224254
|
+
const relativePath = safeSandboxRelativePath(path10.isAbsolute(localSourceId) || localSourceId.startsWith("~") ? path10.basename(sourcePath) : path10.relative(workspaceRoot, sourcePath));
|
|
224255
|
+
const tempPath = path10.join(tempDir, relativePath);
|
|
224256
|
+
await fsp.mkdir(path10.dirname(tempPath), { recursive: true });
|
|
224257
|
+
await fsp.copyFile(sourcePath, tempPath);
|
|
224258
|
+
entries.push({
|
|
224259
|
+
localSourceId,
|
|
224260
|
+
fileName: path10.basename(sourcePath),
|
|
224261
|
+
relativePath,
|
|
224262
|
+
tempPath,
|
|
224263
|
+
sizeBytes: stat2.size,
|
|
224264
|
+
mimeType: inferMimeType(sourcePath),
|
|
224265
|
+
fileType: guessCliFileType(sourcePath)
|
|
224266
|
+
});
|
|
224267
|
+
}
|
|
224268
|
+
return { ok: true, jobId, tempDir, entries, skipped };
|
|
224269
|
+
}
|
|
224270
|
+
async function runCliSandboxCodeJob(workspaceRoot, request, onEvent) {
|
|
224271
|
+
const hasCommand = typeof request?.command === "string" && request.command.trim().length > 0;
|
|
224272
|
+
const hasCode = typeof request?.code === "string" && request.code.trim().length > 0;
|
|
224273
|
+
if (!request || !hasCommand && !hasCode) {
|
|
224274
|
+
return {
|
|
224275
|
+
ok: false,
|
|
224276
|
+
kind: "blocked",
|
|
224277
|
+
message: "run_sandbox_code requires either command or code.",
|
|
224278
|
+
error: "invalid_input",
|
|
224279
|
+
executionHost: "electron-main"
|
|
224280
|
+
};
|
|
224281
|
+
}
|
|
224282
|
+
const hostResult = await runDesktopSandboxCodeJob(
|
|
224283
|
+
{
|
|
224284
|
+
runId: request.runId,
|
|
224285
|
+
workspaceKey: request.workspaceKey ?? request.runId ?? null,
|
|
224286
|
+
command: request.command,
|
|
224287
|
+
language: request.language,
|
|
224288
|
+
code: request.code,
|
|
224289
|
+
label: request.label ?? null,
|
|
224290
|
+
sources: Array.isArray(request.sources) ? request.sources : [],
|
|
224291
|
+
timeoutMs: request.timeoutMs,
|
|
224292
|
+
networkPolicy: request.networkPolicy ?? "disabled"
|
|
224293
|
+
},
|
|
224294
|
+
{
|
|
224295
|
+
getApprovedRoot: (rootId) => rootId === CLI_ROOT_ID ? { id: CLI_ROOT_ID, path: workspaceRoot, approvedAt: (/* @__PURE__ */ new Date()).toISOString() } : null,
|
|
224296
|
+
isPathSafe: (_rootPath, targetPath) => !targetPath.split(/[\\/]+/).includes(".."),
|
|
224297
|
+
isInsideApprovedRoot: (filePath) => {
|
|
224298
|
+
const absolute = path10.resolve(expandHome4(filePath));
|
|
224299
|
+
if (isInside(workspaceRoot, absolute)) {
|
|
224300
|
+
return { id: CLI_ROOT_ID, path: workspaceRoot, approvedAt: (/* @__PURE__ */ new Date()).toISOString() };
|
|
224301
|
+
}
|
|
224302
|
+
return { id: "cli-absolute-root", path: path10.dirname(absolute), approvedAt: (/* @__PURE__ */ new Date()).toISOString() };
|
|
224303
|
+
},
|
|
224304
|
+
shouldIgnore: (fileName) => IGNORED_DIRS.has(fileName),
|
|
224305
|
+
guessMimeType: inferMimeType,
|
|
224306
|
+
onEvent
|
|
224307
|
+
}
|
|
224308
|
+
);
|
|
224309
|
+
const data = sandboxHostData(hostResult);
|
|
224310
|
+
return {
|
|
224311
|
+
ok: hostResult.ok,
|
|
224312
|
+
kind: hostResult.kind,
|
|
224313
|
+
message: hostResult.message,
|
|
224314
|
+
error: hostResult.ok ? void 0 : "execution_failed",
|
|
224315
|
+
executionHost: "electron-main",
|
|
224316
|
+
runId: hostResult.runId,
|
|
224317
|
+
data
|
|
224318
|
+
};
|
|
224319
|
+
}
|
|
224320
|
+
function sandboxHostData(result2) {
|
|
224321
|
+
return {
|
|
224322
|
+
status: result2.status,
|
|
224323
|
+
exitCode: result2.exitCode,
|
|
224324
|
+
durationMs: result2.durationMs,
|
|
224325
|
+
stdout: result2.stdout,
|
|
224326
|
+
stderr: result2.stderr,
|
|
224327
|
+
stdoutTruncated: result2.stdoutTruncated,
|
|
224328
|
+
stderrTruncated: result2.stderrTruncated,
|
|
224329
|
+
producedFiles: result2.producedFiles,
|
|
224330
|
+
inputManifest: result2.inputManifest,
|
|
224331
|
+
runtimeInfo: result2.runtimeInfo,
|
|
224332
|
+
structuredOutput: result2.structuredOutput,
|
|
224333
|
+
workspacePath: result2.workspacePath,
|
|
224334
|
+
language: result2.language,
|
|
224335
|
+
reportJsonPresent: result2.reportJsonPresent,
|
|
224336
|
+
codeSha256: result2.codeSha256,
|
|
224337
|
+
warnings: result2.warnings
|
|
224338
|
+
};
|
|
224339
|
+
}
|
|
224340
|
+
function safeSandboxRelativePath(value) {
|
|
224341
|
+
const clean = value.replace(/\\/g, "/").split("/").filter((part) => part && part !== "." && part !== "..").join("/");
|
|
224342
|
+
return clean || "input";
|
|
224343
|
+
}
|
|
224344
|
+
function guessCliFileType(filePath) {
|
|
224345
|
+
const ext = path10.extname(filePath).toLowerCase();
|
|
224346
|
+
if ([".xlsx", ".xls"].includes(ext)) return "spreadsheet";
|
|
224347
|
+
if (ext === ".csv" || ext === ".tsv") return "csv";
|
|
224348
|
+
if (ext === ".pdf") return "pdf";
|
|
224349
|
+
if ([".png", ".jpg", ".jpeg", ".gif", ".webp", ".svg"].includes(ext)) return "image";
|
|
224350
|
+
if ([".doc", ".docx", ".txt", ".md", ".rtf"].includes(ext)) return "document";
|
|
224351
|
+
return "unknown";
|
|
224352
|
+
}
|
|
224353
|
+
async function runShellCommand(input) {
|
|
224354
|
+
const startedAt = Date.now();
|
|
224355
|
+
const cwd2 = input.cwd ? resolveReadPath(input.workspaceRoot, input.cwd) : input.workspaceRoot;
|
|
223020
224356
|
const timeoutMs = Math.max(1e3, Math.min(input.timeoutMs ?? 3e4, 12e4));
|
|
223021
|
-
return new Promise((
|
|
223022
|
-
const child =
|
|
224357
|
+
return new Promise((resolve5) => {
|
|
224358
|
+
const child = spawn2(process.env.SHELL || "/bin/zsh", ["-lc", input.command], {
|
|
223023
224359
|
cwd: cwd2,
|
|
223024
224360
|
env: process.env,
|
|
223025
224361
|
stdio: ["ignore", "pipe", "pipe"]
|
|
@@ -223039,7 +224375,7 @@ async function runShellCommand(input) {
|
|
|
223039
224375
|
});
|
|
223040
224376
|
child.on("error", (error) => {
|
|
223041
224377
|
clearTimeout(timer);
|
|
223042
|
-
|
|
224378
|
+
resolve5({
|
|
223043
224379
|
ok: false,
|
|
223044
224380
|
stdout,
|
|
223045
224381
|
stderr,
|
|
@@ -223056,7 +224392,7 @@ async function runShellCommand(input) {
|
|
|
223056
224392
|
child.on("close", (code, signal) => {
|
|
223057
224393
|
clearTimeout(timer);
|
|
223058
224394
|
const capped = capOutput(stdout, stderr);
|
|
223059
|
-
|
|
224395
|
+
resolve5({
|
|
223060
224396
|
ok: code === 0 && !timedOut,
|
|
223061
224397
|
stdout: capped.stdout,
|
|
223062
224398
|
stderr: capped.stderr,
|
|
@@ -223077,8 +224413,18 @@ function resolveReadPath(root2, inputPath) {
|
|
|
223077
224413
|
const expanded = expandHome4(inputPath || ".");
|
|
223078
224414
|
return path10.resolve(path10.isAbsolute(expanded) ? expanded : path10.join(root2, expanded));
|
|
223079
224415
|
}
|
|
224416
|
+
function resolveRequestRoot(defaultRoot, requestRoot) {
|
|
224417
|
+
const trimmed = requestRoot?.trim();
|
|
224418
|
+
return trimmed ? resolveReadPath(defaultRoot, trimmed) : defaultRoot;
|
|
224419
|
+
}
|
|
223080
224420
|
function resolveWritePath(root2, inputPath) {
|
|
223081
|
-
|
|
224421
|
+
const expanded = expandHome4(inputPath || ".");
|
|
224422
|
+
return path10.resolve(path10.isAbsolute(expanded) ? expanded : path10.join(root2, expanded));
|
|
224423
|
+
}
|
|
224424
|
+
function displayPath(root2, target, requestedPath) {
|
|
224425
|
+
const expanded = expandHome4(requestedPath || ".");
|
|
224426
|
+
if (path10.isAbsolute(expanded) || requestedPath.startsWith("~")) return target;
|
|
224427
|
+
return path10.relative(root2, target) || path10.basename(target);
|
|
223082
224428
|
}
|
|
223083
224429
|
function resolveLocalSourceId(root2, localSourceId) {
|
|
223084
224430
|
const raw = localSourceId.includes("::") ? localSourceId.split("::").slice(1).join("::") : localSourceId;
|
|
@@ -223090,8 +224436,8 @@ function expandHome4(inputPath) {
|
|
|
223090
224436
|
return inputPath;
|
|
223091
224437
|
}
|
|
223092
224438
|
function isInside(root2, candidate) {
|
|
223093
|
-
const
|
|
223094
|
-
return
|
|
224439
|
+
const relative2 = path10.relative(path10.resolve(root2), path10.resolve(candidate));
|
|
224440
|
+
return relative2 === "" || !relative2.startsWith("..") && !path10.isAbsolute(relative2);
|
|
223095
224441
|
}
|
|
223096
224442
|
async function safeStat(target) {
|
|
223097
224443
|
try {
|
|
@@ -223154,8 +224500,8 @@ function escapeRegex2(value) {
|
|
|
223154
224500
|
return value.replace(/[|\\{}()[\]^$+*?.]/g, "\\$&");
|
|
223155
224501
|
}
|
|
223156
224502
|
async function readTextFileIfReasonable(file) {
|
|
223157
|
-
const
|
|
223158
|
-
if (!
|
|
224503
|
+
const stat2 = await safeStat(file);
|
|
224504
|
+
if (!stat2?.isFile() || stat2.size > 1e6) return null;
|
|
223159
224505
|
const buffer = await fsp.readFile(file);
|
|
223160
224506
|
if (buffer.includes(0)) return null;
|
|
223161
224507
|
return buffer.toString("utf8");
|
|
@@ -223163,18 +224509,18 @@ async function readTextFileIfReasonable(file) {
|
|
|
223163
224509
|
function sanitizeMaxResults(value) {
|
|
223164
224510
|
return Math.max(1, Math.min(typeof value === "number" ? Math.floor(value) : DEFAULT_MAX_RESULTS, 1e3));
|
|
223165
224511
|
}
|
|
223166
|
-
function localSourceEntry(root2, file) {
|
|
223167
|
-
const
|
|
224512
|
+
function localSourceEntry(root2, file, absoluteId = false) {
|
|
224513
|
+
const stat2 = fs9.statSync(file);
|
|
223168
224514
|
const relativePath = path10.relative(root2, file);
|
|
223169
224515
|
const extension2 = path10.extname(file).toLowerCase();
|
|
223170
224516
|
return {
|
|
223171
|
-
localSourceId: `${CLI_ROOT_ID}::${relativePath}`,
|
|
223172
|
-
rootId: CLI_ROOT_ID,
|
|
224517
|
+
localSourceId: absoluteId ? file : `${CLI_ROOT_ID}::${relativePath}`,
|
|
224518
|
+
rootId: absoluteId ? "cli-absolute-root" : CLI_ROOT_ID,
|
|
223173
224519
|
relativePath,
|
|
223174
224520
|
fileName: path10.basename(file),
|
|
223175
224521
|
extension: extension2,
|
|
223176
|
-
sizeBytes:
|
|
223177
|
-
modifiedAt:
|
|
224522
|
+
sizeBytes: stat2.size,
|
|
224523
|
+
modifiedAt: stat2.mtime.toISOString(),
|
|
223178
224524
|
mimeType: inferMimeType(file),
|
|
223179
224525
|
isDirectory: false
|
|
223180
224526
|
};
|
|
@@ -223214,6 +224560,9 @@ var CLI_ROOT_ID, DEFAULT_MAX_RESULTS, MAX_READ_BYTES, IGNORED_DIRS;
|
|
|
223214
224560
|
var init_nodeLocalBridge = __esm({
|
|
223215
224561
|
"features/perchTerminal/runtime/cliHost/nodeLocalBridge.ts"() {
|
|
223216
224562
|
"use strict";
|
|
224563
|
+
init_perchCore();
|
|
224564
|
+
init_perchBusinessTools();
|
|
224565
|
+
init_localSandboxHost();
|
|
223217
224566
|
CLI_ROOT_ID = "cli-root";
|
|
223218
224567
|
DEFAULT_MAX_RESULTS = 200;
|
|
223219
224568
|
MAX_READ_BYTES = 2e6;
|
|
@@ -223867,8 +225216,8 @@ function createMemoryAuthStorage() {
|
|
|
223867
225216
|
}
|
|
223868
225217
|
async function createOAuthCallbackServer(input) {
|
|
223869
225218
|
let resolveResult = null;
|
|
223870
|
-
const resultPromise = new Promise((
|
|
223871
|
-
resolveResult =
|
|
225219
|
+
const resultPromise = new Promise((resolve5) => {
|
|
225220
|
+
resolveResult = resolve5;
|
|
223872
225221
|
});
|
|
223873
225222
|
const server = http.createServer((request, response) => {
|
|
223874
225223
|
const requestUrl = new URL(request.url ?? "/", `http://${input.host}`);
|
|
@@ -223895,11 +225244,11 @@ async function createOAuthCallbackServer(input) {
|
|
|
223895
225244
|
resolveResult?.({ ok: true, code });
|
|
223896
225245
|
resolveResult = null;
|
|
223897
225246
|
});
|
|
223898
|
-
await new Promise((
|
|
225247
|
+
await new Promise((resolve5, reject2) => {
|
|
223899
225248
|
server.once("error", reject2);
|
|
223900
225249
|
server.listen(0, input.host, () => {
|
|
223901
225250
|
server.off("error", reject2);
|
|
223902
|
-
|
|
225251
|
+
resolve5();
|
|
223903
225252
|
});
|
|
223904
225253
|
});
|
|
223905
225254
|
const address = server.address();
|
|
@@ -223917,7 +225266,7 @@ async function createOAuthCallbackServer(input) {
|
|
|
223917
225266
|
waitForCode: async () => resultPromise,
|
|
223918
225267
|
close: async () => {
|
|
223919
225268
|
clearTimeout(timeout);
|
|
223920
|
-
await new Promise((
|
|
225269
|
+
await new Promise((resolve5) => server.close(() => resolve5()));
|
|
223921
225270
|
}
|
|
223922
225271
|
};
|
|
223923
225272
|
}
|
|
@@ -224871,21 +226220,21 @@ var require_react_development = __commonJS({
|
|
|
224871
226220
|
);
|
|
224872
226221
|
actScopeDepth = prevActScopeDepth;
|
|
224873
226222
|
}
|
|
224874
|
-
function recursivelyFlushAsyncActWork(returnValue,
|
|
226223
|
+
function recursivelyFlushAsyncActWork(returnValue, resolve5, reject2) {
|
|
224875
226224
|
var queue2 = ReactSharedInternals.actQueue;
|
|
224876
226225
|
if (null !== queue2)
|
|
224877
226226
|
if (0 !== queue2.length)
|
|
224878
226227
|
try {
|
|
224879
226228
|
flushActQueue(queue2);
|
|
224880
226229
|
enqueueTask(function() {
|
|
224881
|
-
return recursivelyFlushAsyncActWork(returnValue,
|
|
226230
|
+
return recursivelyFlushAsyncActWork(returnValue, resolve5, reject2);
|
|
224882
226231
|
});
|
|
224883
226232
|
return;
|
|
224884
226233
|
} catch (error) {
|
|
224885
226234
|
ReactSharedInternals.thrownErrors.push(error);
|
|
224886
226235
|
}
|
|
224887
226236
|
else ReactSharedInternals.actQueue = null;
|
|
224888
|
-
0 < ReactSharedInternals.thrownErrors.length ? (queue2 = aggregateErrors(ReactSharedInternals.thrownErrors), ReactSharedInternals.thrownErrors.length = 0, reject2(queue2)) :
|
|
226237
|
+
0 < ReactSharedInternals.thrownErrors.length ? (queue2 = aggregateErrors(ReactSharedInternals.thrownErrors), ReactSharedInternals.thrownErrors.length = 0, reject2(queue2)) : resolve5(returnValue);
|
|
224889
226238
|
}
|
|
224890
226239
|
function flushActQueue(queue2) {
|
|
224891
226240
|
if (!isFlushing) {
|
|
@@ -225072,7 +226421,7 @@ var require_react_development = __commonJS({
|
|
|
225072
226421
|
));
|
|
225073
226422
|
});
|
|
225074
226423
|
return {
|
|
225075
|
-
then: function(
|
|
226424
|
+
then: function(resolve5, reject2) {
|
|
225076
226425
|
didAwaitActCall = true;
|
|
225077
226426
|
thenable.then(
|
|
225078
226427
|
function(returnValue) {
|
|
@@ -225082,7 +226431,7 @@ var require_react_development = __commonJS({
|
|
|
225082
226431
|
flushActQueue(queue2), enqueueTask(function() {
|
|
225083
226432
|
return recursivelyFlushAsyncActWork(
|
|
225084
226433
|
returnValue,
|
|
225085
|
-
|
|
226434
|
+
resolve5,
|
|
225086
226435
|
reject2
|
|
225087
226436
|
);
|
|
225088
226437
|
});
|
|
@@ -225096,7 +226445,7 @@ var require_react_development = __commonJS({
|
|
|
225096
226445
|
ReactSharedInternals.thrownErrors.length = 0;
|
|
225097
226446
|
reject2(_thrownError);
|
|
225098
226447
|
}
|
|
225099
|
-
} else
|
|
226448
|
+
} else resolve5(returnValue);
|
|
225100
226449
|
},
|
|
225101
226450
|
function(error) {
|
|
225102
226451
|
popActScope(prevActQueue, prevActScopeDepth);
|
|
@@ -225118,15 +226467,15 @@ var require_react_development = __commonJS({
|
|
|
225118
226467
|
if (0 < ReactSharedInternals.thrownErrors.length)
|
|
225119
226468
|
throw callback = aggregateErrors(ReactSharedInternals.thrownErrors), ReactSharedInternals.thrownErrors.length = 0, callback;
|
|
225120
226469
|
return {
|
|
225121
|
-
then: function(
|
|
226470
|
+
then: function(resolve5, reject2) {
|
|
225122
226471
|
didAwaitActCall = true;
|
|
225123
226472
|
0 === prevActScopeDepth ? (ReactSharedInternals.actQueue = queue2, enqueueTask(function() {
|
|
225124
226473
|
return recursivelyFlushAsyncActWork(
|
|
225125
226474
|
returnValue$jscomp$0,
|
|
225126
|
-
|
|
226475
|
+
resolve5,
|
|
225127
226476
|
reject2
|
|
225128
226477
|
);
|
|
225129
|
-
})) :
|
|
226478
|
+
})) : resolve5(returnValue$jscomp$0);
|
|
225130
226479
|
}
|
|
225131
226480
|
};
|
|
225132
226481
|
};
|
|
@@ -225553,7 +226902,7 @@ var init_compat = __esm({
|
|
|
225553
226902
|
});
|
|
225554
226903
|
|
|
225555
226904
|
// node_modules/environment/index.js
|
|
225556
|
-
var isBrowser, isNode2, isBun, isDeno, isElectron, isJsDom, isWebWorker, isDedicatedWorker, isSharedWorker, isServiceWorker,
|
|
226905
|
+
var isBrowser, isNode2, isBun, isDeno, isElectron, isJsDom, isWebWorker, isDedicatedWorker, isSharedWorker, isServiceWorker, platform2, isMacOs, isWindows, isLinux, isIos, isAndroid;
|
|
225557
226906
|
var init_environment = __esm({
|
|
225558
226907
|
"node_modules/environment/index.js"() {
|
|
225559
226908
|
isBrowser = globalThis.window?.document !== void 0;
|
|
@@ -225566,12 +226915,12 @@ var init_environment = __esm({
|
|
|
225566
226915
|
isDedicatedWorker = typeof DedicatedWorkerGlobalScope !== "undefined" && globalThis instanceof DedicatedWorkerGlobalScope;
|
|
225567
226916
|
isSharedWorker = typeof SharedWorkerGlobalScope !== "undefined" && globalThis instanceof SharedWorkerGlobalScope;
|
|
225568
226917
|
isServiceWorker = typeof ServiceWorkerGlobalScope !== "undefined" && globalThis instanceof ServiceWorkerGlobalScope;
|
|
225569
|
-
|
|
225570
|
-
isMacOs =
|
|
225571
|
-
isWindows =
|
|
225572
|
-
isLinux =
|
|
225573
|
-
isIos =
|
|
225574
|
-
isAndroid =
|
|
226918
|
+
platform2 = globalThis.navigator?.userAgentData?.platform;
|
|
226919
|
+
isMacOs = platform2 === "macOS" || globalThis.navigator?.platform === "MacIntel" || globalThis.navigator?.userAgent?.includes(" Mac ") === true || globalThis.process?.platform === "darwin";
|
|
226920
|
+
isWindows = platform2 === "Windows" || globalThis.navigator?.platform === "Win32" || globalThis.process?.platform === "win32";
|
|
226921
|
+
isLinux = platform2 === "Linux" || globalThis.navigator?.platform?.startsWith("Linux") === true || globalThis.navigator?.userAgent?.includes(" Linux ") === true || globalThis.process?.platform === "linux";
|
|
226922
|
+
isIos = platform2 === "iOS" || globalThis.navigator?.platform === "MacIntel" && globalThis.navigator?.maxTouchPoints > 1 || /iPad|iPhone|iPod/.test(globalThis.navigator?.platform);
|
|
226923
|
+
isAndroid = platform2 === "Android" || globalThis.navigator?.platform === "Android" || globalThis.navigator?.userAgent?.includes(" Android ") === true || globalThis.process?.platform === "android";
|
|
225575
226924
|
}
|
|
225576
226925
|
});
|
|
225577
226926
|
|
|
@@ -229888,8 +231237,8 @@ var require_react_reconciler_production = __commonJS({
|
|
|
229888
231237
|
currentEntangledActionThenable = {
|
|
229889
231238
|
status: "pending",
|
|
229890
231239
|
value: void 0,
|
|
229891
|
-
then: function(
|
|
229892
|
-
entangledListeners.push(
|
|
231240
|
+
then: function(resolve5) {
|
|
231241
|
+
entangledListeners.push(resolve5);
|
|
229893
231242
|
}
|
|
229894
231243
|
};
|
|
229895
231244
|
}
|
|
@@ -229912,8 +231261,8 @@ var require_react_reconciler_production = __commonJS({
|
|
|
229912
231261
|
status: "pending",
|
|
229913
231262
|
value: null,
|
|
229914
231263
|
reason: null,
|
|
229915
|
-
then: function(
|
|
229916
|
-
listeners.push(
|
|
231264
|
+
then: function(resolve5) {
|
|
231265
|
+
listeners.push(resolve5);
|
|
229917
231266
|
}
|
|
229918
231267
|
};
|
|
229919
231268
|
thenable.then(
|
|
@@ -239512,8 +240861,8 @@ var require_react_reconciler_development = __commonJS({
|
|
|
239512
240861
|
currentEntangledActionThenable = {
|
|
239513
240862
|
status: "pending",
|
|
239514
240863
|
value: void 0,
|
|
239515
|
-
then: function(
|
|
239516
|
-
entangledListeners.push(
|
|
240864
|
+
then: function(resolve5) {
|
|
240865
|
+
entangledListeners.push(resolve5);
|
|
239517
240866
|
}
|
|
239518
240867
|
};
|
|
239519
240868
|
}
|
|
@@ -239536,8 +240885,8 @@ var require_react_reconciler_development = __commonJS({
|
|
|
239536
240885
|
status: "pending",
|
|
239537
240886
|
value: null,
|
|
239538
240887
|
reason: null,
|
|
239539
|
-
then: function(
|
|
239540
|
-
listeners.push(
|
|
240888
|
+
then: function(resolve5) {
|
|
240889
|
+
listeners.push(resolve5);
|
|
239541
240890
|
}
|
|
239542
240891
|
};
|
|
239543
240892
|
thenable.then(
|
|
@@ -254995,7 +256344,7 @@ var require_websocket = __commonJS({
|
|
|
254995
256344
|
var http2 = __require("http");
|
|
254996
256345
|
var net = __require("net");
|
|
254997
256346
|
var tls = __require("tls");
|
|
254998
|
-
var { randomBytes, createHash:
|
|
256347
|
+
var { randomBytes, createHash: createHash3 } = __require("crypto");
|
|
254999
256348
|
var { Duplex, Readable } = __require("stream");
|
|
255000
256349
|
var { URL: URL2 } = __require("url");
|
|
255001
256350
|
var PerMessageDeflate2 = require_permessage_deflate();
|
|
@@ -255663,7 +257012,7 @@ var require_websocket = __commonJS({
|
|
|
255663
257012
|
abortHandshake(websocket, socket, "Invalid Upgrade header");
|
|
255664
257013
|
return;
|
|
255665
257014
|
}
|
|
255666
|
-
const digest =
|
|
257015
|
+
const digest = createHash3("sha1").update(key + GUID).digest("base64");
|
|
255667
257016
|
if (res.headers["sec-websocket-accept"] !== digest) {
|
|
255668
257017
|
abortHandshake(websocket, socket, "Invalid Sec-WebSocket-Accept header");
|
|
255669
257018
|
return;
|
|
@@ -256032,7 +257381,7 @@ var require_websocket_server = __commonJS({
|
|
|
256032
257381
|
var EventEmitter3 = __require("events");
|
|
256033
257382
|
var http2 = __require("http");
|
|
256034
257383
|
var { Duplex } = __require("stream");
|
|
256035
|
-
var { createHash:
|
|
257384
|
+
var { createHash: createHash3 } = __require("crypto");
|
|
256036
257385
|
var extension2 = require_extension();
|
|
256037
257386
|
var PerMessageDeflate2 = require_permessage_deflate();
|
|
256038
257387
|
var subprotocol2 = require_subprotocol();
|
|
@@ -256339,7 +257688,7 @@ var require_websocket_server = __commonJS({
|
|
|
256339
257688
|
);
|
|
256340
257689
|
}
|
|
256341
257690
|
if (this._state > RUNNING) return abortHandshake(socket, 503);
|
|
256342
|
-
const digest =
|
|
257691
|
+
const digest = createHash3("sha1").update(key + GUID).digest("base64");
|
|
256343
257692
|
const headers = [
|
|
256344
257693
|
"HTTP/1.1 101 Switching Protocols",
|
|
256345
257694
|
"Upgrade: websocket",
|
|
@@ -277257,8 +278606,8 @@ var init_ink = __esm({
|
|
|
277257
278606
|
}
|
|
277258
278607
|
}
|
|
277259
278608
|
async waitUntilExit() {
|
|
277260
|
-
this.exitPromise ||= new Promise((
|
|
277261
|
-
this.resolveExitPromise =
|
|
278609
|
+
this.exitPromise ||= new Promise((resolve5, reject2) => {
|
|
278610
|
+
this.resolveExitPromise = resolve5;
|
|
277262
278611
|
this.rejectExitPromise = reject2;
|
|
277263
278612
|
});
|
|
277264
278613
|
if (!this.beforeExitHandler) {
|
|
@@ -279641,7 +280990,7 @@ async function runAuthCommand(parsed, writer) {
|
|
|
279641
280990
|
`);
|
|
279642
280991
|
return 0;
|
|
279643
280992
|
}
|
|
279644
|
-
await new Promise((
|
|
280993
|
+
await new Promise((resolve5) => setTimeout(resolve5, 1500));
|
|
279645
280994
|
}
|
|
279646
280995
|
writer.stderr("No CLI session arrived. Try `perch login` again after confirming the browser sign-in completed.\n");
|
|
279647
280996
|
return 2;
|
|
@@ -279774,14 +281123,14 @@ function writeAPScenarioResult(result2, json, writer) {
|
|
|
279774
281123
|
}
|
|
279775
281124
|
function resolveFolderPath(input) {
|
|
279776
281125
|
const resolved = resolvePath(input);
|
|
279777
|
-
const
|
|
279778
|
-
if (!
|
|
281126
|
+
const stat2 = fs13.existsSync(resolved) ? fs13.statSync(resolved) : null;
|
|
281127
|
+
if (!stat2?.isDirectory()) throw new Error(`Folder does not exist: ${resolved}`);
|
|
279779
281128
|
return resolved;
|
|
279780
281129
|
}
|
|
279781
281130
|
function resolveExistingDirectory(input) {
|
|
279782
281131
|
const resolved = resolvePath(input);
|
|
279783
|
-
const
|
|
279784
|
-
if (!
|
|
281132
|
+
const stat2 = fs13.existsSync(resolved) ? fs13.statSync(resolved) : null;
|
|
281133
|
+
if (!stat2?.isDirectory()) throw new Error(`Directory does not exist: ${resolved}`);
|
|
279785
281134
|
return resolved;
|
|
279786
281135
|
}
|
|
279787
281136
|
function resolvePath(input) {
|