@runcofactor/cli 0.17.0 → 0.18.0
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/{chunk-JZWJFG4M.js → chunk-2R6544Z3.js} +2 -2
- package/dist/{chunk-MO5G5TP5.js → chunk-7OO3RJYR.js} +994 -91
- package/dist/chunk-7OO3RJYR.js.map +1 -0
- package/dist/{chunk-FGB6PS2T.js → chunk-A6TH5VUI.js} +206 -76
- package/dist/chunk-A6TH5VUI.js.map +1 -0
- package/dist/{chunk-HGPZ2QWV.js → chunk-E2FUQJVO.js} +3 -3
- package/dist/{chunk-A4ISG3VX.js → chunk-U7OMQJ7V.js} +52 -4
- package/dist/chunk-U7OMQJ7V.js.map +1 -0
- package/dist/{dist-WW2S733L.js → dist-4COOAKY3.js} +22 -2
- package/dist/index.js +6 -6
- package/dist/{mcp-V4GKEL2J.js → mcp-57VVZTXM.js} +3 -3
- package/dist/{record-LDNKS42Y.js → record-RWVGZZSW.js} +2 -2
- package/dist/{sandbox-PLYUNOFX.js → sandbox-6D54ZQCG.js} +2 -2
- package/dist/{session-Y6RO7GFC.js → session-GDCMTNB3.js} +3 -3
- package/dist/skills/optimize-cache/SKILL.md +25 -0
- package/dist/{src-ECFPDE5X.js → src-5YXGM2KB.js} +2 -2
- package/dist/{src-PDYXACRP.js → src-B7CPYFLS.js} +4 -2
- package/dist/{src-OWPS5DCK.js → src-GRO2QR7U.js} +3 -3
- package/dist/{trace-BCSP7PCX.js → trace-7LRHSPWN.js} +3 -3
- package/dist/{workflow-76EKT3DS.js → workflow-5BFRS4CE.js} +5 -5
- package/dist/{workflow-cache-UDTTNIHT.js → workflow-cache-VVP3SPFM.js} +4 -4
- package/dist/{workflow-debug-WO7D32EI.js → workflow-debug-XGOHNZ4E.js} +4 -4
- package/package.json +3 -3
- package/dist/chunk-A4ISG3VX.js.map +0 -1
- package/dist/chunk-FGB6PS2T.js.map +0 -1
- package/dist/chunk-MO5G5TP5.js.map +0 -1
- /package/dist/{chunk-JZWJFG4M.js.map → chunk-2R6544Z3.js.map} +0 -0
- /package/dist/{chunk-HGPZ2QWV.js.map → chunk-E2FUQJVO.js.map} +0 -0
- /package/dist/{dist-WW2S733L.js.map → dist-4COOAKY3.js.map} +0 -0
- /package/dist/{mcp-V4GKEL2J.js.map → mcp-57VVZTXM.js.map} +0 -0
- /package/dist/{record-LDNKS42Y.js.map → record-RWVGZZSW.js.map} +0 -0
- /package/dist/{sandbox-PLYUNOFX.js.map → sandbox-6D54ZQCG.js.map} +0 -0
- /package/dist/{session-Y6RO7GFC.js.map → session-GDCMTNB3.js.map} +0 -0
- /package/dist/{src-ECFPDE5X.js.map → src-5YXGM2KB.js.map} +0 -0
- /package/dist/{src-PDYXACRP.js.map → src-B7CPYFLS.js.map} +0 -0
- /package/dist/{src-OWPS5DCK.js.map → src-GRO2QR7U.js.map} +0 -0
- /package/dist/{trace-BCSP7PCX.js.map → trace-7LRHSPWN.js.map} +0 -0
- /package/dist/{workflow-76EKT3DS.js.map → workflow-5BFRS4CE.js.map} +0 -0
- /package/dist/{workflow-cache-UDTTNIHT.js.map → workflow-cache-VVP3SPFM.js.map} +0 -0
- /package/dist/{workflow-debug-WO7D32EI.js.map → workflow-debug-XGOHNZ4E.js.map} +0 -0
|
@@ -3877,13 +3877,13 @@ var require_gifutil = __commonJS({
|
|
|
3877
3877
|
}
|
|
3878
3878
|
_quantize(imageOrImages, "WuQuant", maxColorIndexes, significantBits, dither);
|
|
3879
3879
|
};
|
|
3880
|
-
exports.read = function(source,
|
|
3881
|
-
|
|
3880
|
+
exports.read = function(source, decoder2) {
|
|
3881
|
+
decoder2 = decoder2 || defaultCodec;
|
|
3882
3882
|
if (Buffer.isBuffer(source)) {
|
|
3883
|
-
return
|
|
3883
|
+
return decoder2.decodeGif(source);
|
|
3884
3884
|
}
|
|
3885
3885
|
return _readBinary(source).then((buffer) => {
|
|
3886
|
-
return
|
|
3886
|
+
return decoder2.decodeGif(buffer);
|
|
3887
3887
|
});
|
|
3888
3888
|
};
|
|
3889
3889
|
exports.shareAsJimp = function(jimp, bitmapImageToShare) {
|
|
@@ -3895,13 +3895,13 @@ var require_gifutil = __commonJS({
|
|
|
3895
3895
|
jimpImage.bitmap.data = bitmapImageToShare.bitmap.data;
|
|
3896
3896
|
return jimpImage;
|
|
3897
3897
|
};
|
|
3898
|
-
exports.write = function(path6, frames, spec,
|
|
3899
|
-
|
|
3898
|
+
exports.write = function(path6, frames, spec, encoder2) {
|
|
3899
|
+
encoder2 = encoder2 || defaultCodec;
|
|
3900
3900
|
const matches = path6.match(/\.[a-zA-Z]+$/);
|
|
3901
3901
|
if (matches !== null && INVALID_SUFFIXES.includes(matches[0].toLowerCase())) {
|
|
3902
3902
|
throw new Error(`GIF '${path6}' has an unexpected suffix`);
|
|
3903
3903
|
}
|
|
3904
|
-
return
|
|
3904
|
+
return encoder2.encodeGif(frames, spec).then((gif2) => {
|
|
3905
3905
|
return _writeBinary(path6, gif2.buffer).then(() => {
|
|
3906
3906
|
return gif2;
|
|
3907
3907
|
});
|
|
@@ -5449,8 +5449,8 @@ var require_encoder = __commonJS({
|
|
|
5449
5449
|
}
|
|
5450
5450
|
function encode3(imgData, qu) {
|
|
5451
5451
|
if (typeof qu === "undefined") qu = 50;
|
|
5452
|
-
var
|
|
5453
|
-
var data2 =
|
|
5452
|
+
var encoder2 = new JPEGEncoder(qu);
|
|
5453
|
+
var data2 = encoder2.encode(imgData, qu);
|
|
5454
5454
|
return {
|
|
5455
5455
|
data: data2,
|
|
5456
5456
|
width: imgData.width,
|
|
@@ -6489,22 +6489,22 @@ var require_decoder = __commonJS({
|
|
|
6489
6489
|
};
|
|
6490
6490
|
var opts = { ...defaultOpts, ...userOpts };
|
|
6491
6491
|
var arr = new Uint8Array(jpegData);
|
|
6492
|
-
var
|
|
6493
|
-
|
|
6492
|
+
var decoder2 = new JpegImage();
|
|
6493
|
+
decoder2.opts = opts;
|
|
6494
6494
|
JpegImage.resetMaxMemoryUsage(opts.maxMemoryUsageInMB * 1024 * 1024);
|
|
6495
|
-
|
|
6495
|
+
decoder2.parse(arr);
|
|
6496
6496
|
var channels = opts.formatAsRGBA ? 4 : 3;
|
|
6497
|
-
var bytesNeeded =
|
|
6497
|
+
var bytesNeeded = decoder2.width * decoder2.height * channels;
|
|
6498
6498
|
try {
|
|
6499
6499
|
JpegImage.requestMemoryAllocation(bytesNeeded);
|
|
6500
6500
|
var image2 = {
|
|
6501
|
-
width:
|
|
6502
|
-
height:
|
|
6503
|
-
exifBuffer:
|
|
6501
|
+
width: decoder2.width,
|
|
6502
|
+
height: decoder2.height,
|
|
6503
|
+
exifBuffer: decoder2.exifBuffer,
|
|
6504
6504
|
data: opts.useTArray ? new Uint8Array(bytesNeeded) : Buffer.alloc(bytesNeeded)
|
|
6505
6505
|
};
|
|
6506
|
-
if (
|
|
6507
|
-
image2["comments"] =
|
|
6506
|
+
if (decoder2.comments.length > 0) {
|
|
6507
|
+
image2["comments"] = decoder2.comments;
|
|
6508
6508
|
}
|
|
6509
6509
|
} catch (err) {
|
|
6510
6510
|
if (err instanceof RangeError) {
|
|
@@ -6517,7 +6517,7 @@ var require_decoder = __commonJS({
|
|
|
6517
6517
|
}
|
|
6518
6518
|
throw err;
|
|
6519
6519
|
}
|
|
6520
|
-
|
|
6520
|
+
decoder2.copyToImageData(image2, opts.formatAsRGBA);
|
|
6521
6521
|
return image2;
|
|
6522
6522
|
}
|
|
6523
6523
|
}
|
|
@@ -24616,14 +24616,14 @@ var require_merge_deep = __commonJS({
|
|
|
24616
24616
|
}
|
|
24617
24617
|
});
|
|
24618
24618
|
|
|
24619
|
-
// ../../node_modules/.bun/puppeteer-extra-plugin@3.2.3+
|
|
24619
|
+
// ../../node_modules/.bun/puppeteer-extra-plugin@3.2.3+174067defc7674c7/node_modules/puppeteer-extra-plugin/dist/index.esm.js
|
|
24620
24620
|
var index_esm_exports = {};
|
|
24621
24621
|
__export(index_esm_exports, {
|
|
24622
24622
|
PuppeteerExtraPlugin: () => PuppeteerExtraPlugin
|
|
24623
24623
|
});
|
|
24624
24624
|
var import_debug2, merge, PuppeteerExtraPlugin;
|
|
24625
24625
|
var init_index_esm = __esm({
|
|
24626
|
-
"../../node_modules/.bun/puppeteer-extra-plugin@3.2.3+
|
|
24626
|
+
"../../node_modules/.bun/puppeteer-extra-plugin@3.2.3+174067defc7674c7/node_modules/puppeteer-extra-plugin/dist/index.esm.js"() {
|
|
24627
24627
|
"use strict";
|
|
24628
24628
|
import_debug2 = __toESM(require_src());
|
|
24629
24629
|
merge = require_merge_deep();
|
|
@@ -25086,9 +25086,9 @@ var init_index_esm = __esm({
|
|
|
25086
25086
|
}
|
|
25087
25087
|
});
|
|
25088
25088
|
|
|
25089
|
-
// ../../node_modules/.bun/puppeteer-extra-plugin-stealth@2.11.2+
|
|
25089
|
+
// ../../node_modules/.bun/puppeteer-extra-plugin-stealth@2.11.2+174067defc7674c7/node_modules/puppeteer-extra-plugin-stealth/index.js
|
|
25090
25090
|
var require_puppeteer_extra_plugin_stealth = __commonJS({
|
|
25091
|
-
"../../node_modules/.bun/puppeteer-extra-plugin-stealth@2.11.2+
|
|
25091
|
+
"../../node_modules/.bun/puppeteer-extra-plugin-stealth@2.11.2+174067defc7674c7/node_modules/puppeteer-extra-plugin-stealth/index.js"(exports, module) {
|
|
25092
25092
|
"use strict";
|
|
25093
25093
|
var { PuppeteerExtraPlugin: PuppeteerExtraPlugin2 } = (init_index_esm(), __toCommonJS(index_esm_exports));
|
|
25094
25094
|
var StealthPlugin2 = class extends PuppeteerExtraPlugin2 {
|
|
@@ -40257,11 +40257,17 @@ import * as path2 from "path";
|
|
|
40257
40257
|
import * as path3 from "path";
|
|
40258
40258
|
import * as fs22 from "fs/promises";
|
|
40259
40259
|
import * as crypto3 from "crypto";
|
|
40260
|
+
import { cpus } from "os";
|
|
40261
|
+
import { spawn as spawn2 } from "child_process";
|
|
40262
|
+
import { existsSync as existsSync2 } from "fs";
|
|
40263
|
+
import { createRequire } from "module";
|
|
40264
|
+
import { dirname, join as join2 } from "path";
|
|
40265
|
+
import { fileURLToPath } from "url";
|
|
40260
40266
|
import {
|
|
40261
40267
|
chromium as playwrightChromium
|
|
40262
40268
|
} from "playwright";
|
|
40263
40269
|
|
|
40264
|
-
// ../../node_modules/.bun/playwright-extra@4.3.6+
|
|
40270
|
+
// ../../node_modules/.bun/playwright-extra@4.3.6+0a2747ebf12ccdf9/node_modules/playwright-extra/dist/index.esm.js
|
|
40265
40271
|
var import_debug = __toESM(require_src());
|
|
40266
40272
|
var Loader = class {
|
|
40267
40273
|
constructor(moduleName, packageNames) {
|
|
@@ -41654,6 +41660,16 @@ var TIMEOUTS = {
|
|
|
41654
41660
|
GET_TITLE: 2e4,
|
|
41655
41661
|
GET_LINKS: 2e4,
|
|
41656
41662
|
SNAPSHOT: 3e4,
|
|
41663
|
+
// Driver-side hard cap for a single `page.ariaSnapshot()` call. ariaSnapshot
|
|
41664
|
+
// has NO Playwright timeout and ignores AbortSignal: on a jammed renderer
|
|
41665
|
+
// (blocked main thread / native dialog) the op parks for minutes, and the
|
|
41666
|
+
// per-tool timeout's abort can't cancel it — the orphan kept running until
|
|
41667
|
+
// the 1800s job-stall watchdog tore down the whole job (prod, June 2026).
|
|
41668
|
+
// This cap makes the *driver* give up and fall back to an empty snapshot so
|
|
41669
|
+
// the agent keeps moving; the wedged page is then reaped by step-level
|
|
41670
|
+
// force-recovery. Kept below POST_ACTION_SNAPSHOT (15s) and SNAPSHOT (30s) so
|
|
41671
|
+
// the inner cap wins; a healthy ariaSnapshot returns in <1s.
|
|
41672
|
+
ARIA_SNAPSHOT_CAP: 12e3,
|
|
41657
41673
|
CLICK: 1e4,
|
|
41658
41674
|
TYPE: 1e4,
|
|
41659
41675
|
FILL_FORM: 2e4,
|
|
@@ -42004,6 +42020,9 @@ function extractAndStripV2Fields(attributes) {
|
|
|
42004
42020
|
out.visibility = value;
|
|
42005
42021
|
}
|
|
42006
42022
|
break;
|
|
42023
|
+
case "~dialog-inert":
|
|
42024
|
+
if (value === "true") out.dialogInert = true;
|
|
42025
|
+
break;
|
|
42007
42026
|
case "~bbox": {
|
|
42008
42027
|
const parts = value.split(":").map((s2) => parseFloat(s2));
|
|
42009
42028
|
if (parts.length === 4 && parts.every((n2) => Number.isFinite(n2))) {
|
|
@@ -42348,6 +42367,192 @@ function appendAttrToLine(line, segment) {
|
|
|
42348
42367
|
function errorMessage(error) {
|
|
42349
42368
|
return error instanceof Error ? error.message : String(error);
|
|
42350
42369
|
}
|
|
42370
|
+
var ICON_FAMILY_PREFIXES = [
|
|
42371
|
+
// FontAwesome family + style tokens
|
|
42372
|
+
"fa-solid-",
|
|
42373
|
+
"fa-regular-",
|
|
42374
|
+
"fa-light-",
|
|
42375
|
+
"fa-thin-",
|
|
42376
|
+
"fa-duotone-",
|
|
42377
|
+
"fa-brands-",
|
|
42378
|
+
"fa-sharp-",
|
|
42379
|
+
"fa-",
|
|
42380
|
+
"fas-",
|
|
42381
|
+
"far-",
|
|
42382
|
+
"fal-",
|
|
42383
|
+
"fad-",
|
|
42384
|
+
"fab-",
|
|
42385
|
+
// Telerik / Kendo
|
|
42386
|
+
"k-svg-i-",
|
|
42387
|
+
"k-i-",
|
|
42388
|
+
// Bootstrap Icons, Material Design Icons, Glyphicons, Ionicons
|
|
42389
|
+
"bi-",
|
|
42390
|
+
"mdi-",
|
|
42391
|
+
"glyphicon-",
|
|
42392
|
+
"ion-",
|
|
42393
|
+
"material-icons-",
|
|
42394
|
+
// Generic convention
|
|
42395
|
+
"icon-"
|
|
42396
|
+
];
|
|
42397
|
+
var ICON_NOISE_TOKENS = /* @__PURE__ */ new Set([
|
|
42398
|
+
"fa",
|
|
42399
|
+
"fa-solid",
|
|
42400
|
+
"fa-regular",
|
|
42401
|
+
"fa-light",
|
|
42402
|
+
"fa-thin",
|
|
42403
|
+
"fa-duotone",
|
|
42404
|
+
"fa-brands",
|
|
42405
|
+
"fa-sharp",
|
|
42406
|
+
"fas",
|
|
42407
|
+
"far",
|
|
42408
|
+
"fal",
|
|
42409
|
+
"fad",
|
|
42410
|
+
"fab",
|
|
42411
|
+
"fa-lg",
|
|
42412
|
+
"fa-sm",
|
|
42413
|
+
"fa-xs",
|
|
42414
|
+
"fa-xl",
|
|
42415
|
+
"fa-fw",
|
|
42416
|
+
"fa-spin",
|
|
42417
|
+
"fa-pulse",
|
|
42418
|
+
"fa-border",
|
|
42419
|
+
"fa-pull-left",
|
|
42420
|
+
"fa-pull-right",
|
|
42421
|
+
"k-icon",
|
|
42422
|
+
"k-svg-icon",
|
|
42423
|
+
"k-button-icon"
|
|
42424
|
+
]);
|
|
42425
|
+
var ICON_NAME_MAP = {
|
|
42426
|
+
// export / data movement
|
|
42427
|
+
"file-export": "Export",
|
|
42428
|
+
"file-arrow-down": "Export",
|
|
42429
|
+
"arrow-up-from-bracket": "Export",
|
|
42430
|
+
export: "Export",
|
|
42431
|
+
download: "Download",
|
|
42432
|
+
"file-download": "Download",
|
|
42433
|
+
"cloud-arrow-down": "Download",
|
|
42434
|
+
"arrow-down-to-line": "Download",
|
|
42435
|
+
upload: "Upload",
|
|
42436
|
+
"file-upload": "Upload",
|
|
42437
|
+
"cloud-arrow-up": "Upload",
|
|
42438
|
+
"file-import": "Import",
|
|
42439
|
+
"file-arrow-up": "Import",
|
|
42440
|
+
import: "Import",
|
|
42441
|
+
// filtering / search / columns
|
|
42442
|
+
filter: "Filter",
|
|
42443
|
+
"filter-circle-xmark": "Clear filter",
|
|
42444
|
+
funnel: "Filter",
|
|
42445
|
+
sliders: "Filter",
|
|
42446
|
+
"magnifying-glass": "Search",
|
|
42447
|
+
search: "Search",
|
|
42448
|
+
"table-columns": "Columns",
|
|
42449
|
+
columns: "Columns",
|
|
42450
|
+
"table-cells": "Columns",
|
|
42451
|
+
table: "Columns",
|
|
42452
|
+
// settings
|
|
42453
|
+
gear: "Settings",
|
|
42454
|
+
gears: "Settings",
|
|
42455
|
+
cog: "Settings",
|
|
42456
|
+
cogs: "Settings",
|
|
42457
|
+
wrench: "Settings",
|
|
42458
|
+
sliders2: "Settings",
|
|
42459
|
+
// CRUD
|
|
42460
|
+
plus: "Add",
|
|
42461
|
+
"plus-circle": "Add",
|
|
42462
|
+
"circle-plus": "Add",
|
|
42463
|
+
add: "Add",
|
|
42464
|
+
pen: "Edit",
|
|
42465
|
+
pencil: "Edit",
|
|
42466
|
+
"pen-to-square": "Edit",
|
|
42467
|
+
"pencil-alt": "Edit",
|
|
42468
|
+
edit: "Edit",
|
|
42469
|
+
trash: "Delete",
|
|
42470
|
+
"trash-can": "Delete",
|
|
42471
|
+
"trash-alt": "Delete",
|
|
42472
|
+
delete: "Delete",
|
|
42473
|
+
"floppy-disk": "Save",
|
|
42474
|
+
save: "Save",
|
|
42475
|
+
copy: "Copy",
|
|
42476
|
+
clone: "Copy",
|
|
42477
|
+
// navigation / disclosure
|
|
42478
|
+
xmark: "Close",
|
|
42479
|
+
times: "Close",
|
|
42480
|
+
x: "Close",
|
|
42481
|
+
"circle-xmark": "Close",
|
|
42482
|
+
close: "Close",
|
|
42483
|
+
"chevron-down": "Expand",
|
|
42484
|
+
"chevron-up": "Collapse",
|
|
42485
|
+
"chevron-left": "Previous",
|
|
42486
|
+
"chevron-right": "Next",
|
|
42487
|
+
"angle-down": "Expand",
|
|
42488
|
+
"angle-up": "Collapse",
|
|
42489
|
+
"angle-left": "Previous",
|
|
42490
|
+
"angle-right": "Next",
|
|
42491
|
+
"caret-down": "Expand",
|
|
42492
|
+
"caret-up": "Collapse",
|
|
42493
|
+
"caret-left": "Previous",
|
|
42494
|
+
"caret-right": "Next",
|
|
42495
|
+
"arrow-left": "Back",
|
|
42496
|
+
"arrow-right": "Forward",
|
|
42497
|
+
// misc actions
|
|
42498
|
+
ellipsis: "More",
|
|
42499
|
+
"ellipsis-vertical": "More",
|
|
42500
|
+
"ellipsis-v": "More",
|
|
42501
|
+
"ellipsis-h": "More",
|
|
42502
|
+
bars: "Menu",
|
|
42503
|
+
bell: "Notifications",
|
|
42504
|
+
"circle-info": "Info",
|
|
42505
|
+
"info-circle": "Info",
|
|
42506
|
+
info: "Info",
|
|
42507
|
+
"circle-question": "Help",
|
|
42508
|
+
"question-circle": "Help",
|
|
42509
|
+
question: "Help",
|
|
42510
|
+
check: "Confirm",
|
|
42511
|
+
"circle-check": "Confirm",
|
|
42512
|
+
eye: "Show",
|
|
42513
|
+
"eye-slash": "Hide",
|
|
42514
|
+
"arrows-rotate": "Refresh",
|
|
42515
|
+
"arrow-rotate-right": "Refresh",
|
|
42516
|
+
rotate: "Refresh",
|
|
42517
|
+
refresh: "Refresh",
|
|
42518
|
+
sync: "Refresh",
|
|
42519
|
+
print: "Print",
|
|
42520
|
+
printer: "Print",
|
|
42521
|
+
share: "Share",
|
|
42522
|
+
"share-nodes": "Share",
|
|
42523
|
+
calendar: "Calendar",
|
|
42524
|
+
"calendar-days": "Calendar",
|
|
42525
|
+
star: "Favorite",
|
|
42526
|
+
print2: "Print"
|
|
42527
|
+
};
|
|
42528
|
+
function stripIconFamilyPrefix(raw) {
|
|
42529
|
+
let name = raw.trim().toLowerCase();
|
|
42530
|
+
if (!name) return void 0;
|
|
42531
|
+
let changed = true;
|
|
42532
|
+
while (changed) {
|
|
42533
|
+
changed = false;
|
|
42534
|
+
for (const prefix of ICON_FAMILY_PREFIXES) {
|
|
42535
|
+
if (name.startsWith(prefix) && name.length > prefix.length) {
|
|
42536
|
+
name = name.slice(prefix.length);
|
|
42537
|
+
changed = true;
|
|
42538
|
+
break;
|
|
42539
|
+
}
|
|
42540
|
+
}
|
|
42541
|
+
}
|
|
42542
|
+
if (!name || ICON_NOISE_TOKENS.has(name) || ICON_NOISE_TOKENS.has(raw.trim().toLowerCase())) {
|
|
42543
|
+
return void 0;
|
|
42544
|
+
}
|
|
42545
|
+
return name;
|
|
42546
|
+
}
|
|
42547
|
+
function resolveIconClassName(raw) {
|
|
42548
|
+
const name = stripIconFamilyPrefix(raw);
|
|
42549
|
+
if (!name) return void 0;
|
|
42550
|
+
const mapped = ICON_NAME_MAP[name];
|
|
42551
|
+
if (mapped) return mapped;
|
|
42552
|
+
const base = name.replace(/-\d+$/, "");
|
|
42553
|
+
if (base !== name && ICON_NAME_MAP[base]) return ICON_NAME_MAP[base];
|
|
42554
|
+
return name.split("-").filter(Boolean).map((part) => part[0].toUpperCase() + part.slice(1)).join(" ");
|
|
42555
|
+
}
|
|
42351
42556
|
async function resolveRefs(scope, refs, fn) {
|
|
42352
42557
|
if (refs.length === 0) return {};
|
|
42353
42558
|
const handles = await Promise.all(
|
|
@@ -42438,20 +42643,31 @@ async function resolveRefsWithArgs(scope, items, globals, fn) {
|
|
|
42438
42643
|
);
|
|
42439
42644
|
}
|
|
42440
42645
|
}
|
|
42646
|
+
function isFrameworkMarkerClass(cls) {
|
|
42647
|
+
if (cls === "telerik-blazor") return true;
|
|
42648
|
+
return /^(k|mat|mdc|ng|chakra|ant|el|v|q)-/.test(cls) || /^mui[A-Z-]/.test(cls);
|
|
42649
|
+
}
|
|
42441
42650
|
function extractSemanticHint(className) {
|
|
42442
42651
|
if (!className) return void 0;
|
|
42443
42652
|
const classes = className.split(/\s+/).filter(Boolean);
|
|
42653
|
+
const isNoise = (cls) => {
|
|
42654
|
+
if (/^(css|sc|emotion|styled|svelte)-/.test(cls)) return true;
|
|
42655
|
+
if (/^(clickable-element|bubble-element|bubble-r-container|bubble-r-vertical-center)/.test(cls)) return true;
|
|
42656
|
+
if (/^_[a-zA-Z0-9]{4,}$/.test(cls)) return true;
|
|
42657
|
+
if (/^(p|m|w|h|gap|text|bg|border|rounded|shadow|opacity|z|flex|grid|block|inline|hidden|relative|absolute|fixed|sticky|overflow|cursor|transition|ring|outline|sr|not|group|peer|dark|hover|focus|active|disabled|data|aria)-/.test(cls)) return true;
|
|
42658
|
+
if (/^(items|justify|self|place|space|divide|whitespace|break|font|leading|tracking|decoration|underline|overline|line|list|placeholder|align|content|object|max|min|inset|top|right|bottom|left|order|auto|grow|shrink|basis|table|caption|scale|rotate|translate|skew|origin|select|snap|scroll|touch|resize|appearance|columns|aspect|accent|caret|fill|stroke|will|animate|delay|duration|ease)-./.test(cls)) return true;
|
|
42659
|
+
if (/^(flex|grid|block|inline|hidden|table|contents)$/.test(cls)) return true;
|
|
42660
|
+
if (isFrameworkMarkerClass(cls)) return true;
|
|
42661
|
+
return false;
|
|
42662
|
+
};
|
|
42663
|
+
const KEYWORD_RE = /delete|remove|trash|edit|save|close|submit|cancel|add|create|copy|refresh|back|forward|next|prev|menu|nav|icon|btn|button|action|toggle|collapse|expand|upload|download|export|import|filter|search|settings|help|info|warning|error/i;
|
|
42444
42664
|
for (const cls of classes) {
|
|
42445
|
-
if (
|
|
42446
|
-
if (
|
|
42447
|
-
|
|
42448
|
-
|
|
42449
|
-
if (
|
|
42450
|
-
if (/^(
|
|
42451
|
-
if (/delete|remove|trash|edit|save|close|submit|cancel|add|create|copy|refresh|back|forward|next|prev|menu|nav|icon|btn|button|action|toggle|collapse|expand|upload|download|settings|help|info|warning|error/i.test(cls)) {
|
|
42452
|
-
return cls;
|
|
42453
|
-
}
|
|
42454
|
-
if (/^[a-z][a-z0-9]*(-[a-z][a-z0-9]*)+$/.test(cls) && cls.length >= 6) {
|
|
42665
|
+
if (isNoise(cls)) continue;
|
|
42666
|
+
if (KEYWORD_RE.test(cls)) return cls;
|
|
42667
|
+
}
|
|
42668
|
+
for (const cls of classes) {
|
|
42669
|
+
if (isNoise(cls)) continue;
|
|
42670
|
+
if (/^[a-z][a-z0-9]*((-{1,2}|__)[a-z][a-z0-9]*)+$/.test(cls) && cls.length >= 6) {
|
|
42455
42671
|
return cls;
|
|
42456
42672
|
}
|
|
42457
42673
|
}
|
|
@@ -42547,6 +42763,9 @@ function planChecks(elements, opts) {
|
|
|
42547
42763
|
if (opts.v2 && el.role === "generic" && hasInteractive(el)) {
|
|
42548
42764
|
addCheck(el.ref, "modalV2");
|
|
42549
42765
|
}
|
|
42766
|
+
if (el.role === "dialog" || el.role === "alertdialog") {
|
|
42767
|
+
addCheck(el.ref, "dialogModality");
|
|
42768
|
+
}
|
|
42550
42769
|
if ((el.role === "button" || el.role === "link") && (!el.text || hasOnlyPrivateUseGlyphs(el.text))) {
|
|
42551
42770
|
addCheck(el.ref, "iconButton");
|
|
42552
42771
|
}
|
|
@@ -42789,6 +43008,46 @@ function pageSideFn(el, _ref, args, G) {
|
|
|
42789
43008
|
}
|
|
42790
43009
|
}
|
|
42791
43010
|
}
|
|
43011
|
+
if (checks.has("dialogModality")) {
|
|
43012
|
+
out.dialogModality = { inert: false };
|
|
43013
|
+
try {
|
|
43014
|
+
const isVisibleStyle = (n2) => {
|
|
43015
|
+
const he = n2;
|
|
43016
|
+
if (he.offsetWidth === 0 && he.offsetHeight === 0 && he.getClientRects().length === 0) {
|
|
43017
|
+
return false;
|
|
43018
|
+
}
|
|
43019
|
+
const style = window.getComputedStyle(n2);
|
|
43020
|
+
if (style.display === "none" || style.visibility === "hidden" || style.visibility === "collapse") {
|
|
43021
|
+
return false;
|
|
43022
|
+
}
|
|
43023
|
+
if (parseFloat(style.opacity || "1") === 0) return false;
|
|
43024
|
+
return true;
|
|
43025
|
+
};
|
|
43026
|
+
let visible = true;
|
|
43027
|
+
let cur = el;
|
|
43028
|
+
for (let i2 = 0; i2 < 25 && cur; i2++) {
|
|
43029
|
+
if (!isVisibleStyle(cur)) {
|
|
43030
|
+
visible = false;
|
|
43031
|
+
break;
|
|
43032
|
+
}
|
|
43033
|
+
cur = cur.parentElement;
|
|
43034
|
+
}
|
|
43035
|
+
let onScreen = true;
|
|
43036
|
+
if (visible) {
|
|
43037
|
+
const rect = el.getBoundingClientRect();
|
|
43038
|
+
const vw = window.innerWidth || document.documentElement.clientWidth || 0;
|
|
43039
|
+
const vh = window.innerHeight || document.documentElement.clientHeight || 0;
|
|
43040
|
+
if (rect.width === 0 || rect.height === 0) {
|
|
43041
|
+
onScreen = false;
|
|
43042
|
+
} else if (rect.right <= 0 || rect.bottom <= 0 || rect.left >= vw || rect.top >= vh) {
|
|
43043
|
+
onScreen = false;
|
|
43044
|
+
}
|
|
43045
|
+
}
|
|
43046
|
+
out.dialogModality = { inert: !(visible && onScreen) };
|
|
43047
|
+
} catch {
|
|
43048
|
+
out.dialogModality = null;
|
|
43049
|
+
}
|
|
43050
|
+
}
|
|
42792
43051
|
const extractSvgHint = (root) => {
|
|
42793
43052
|
const svg = root.querySelector("svg");
|
|
42794
43053
|
if (!svg) return {};
|
|
@@ -42815,6 +43074,38 @@ function pageSideFn(el, _ref, args, G) {
|
|
|
42815
43074
|
if (m) lucideIconClass = m[0].toLowerCase();
|
|
42816
43075
|
return { svgHint, lucideIconClass };
|
|
42817
43076
|
};
|
|
43077
|
+
const extractIconClass = (root) => {
|
|
43078
|
+
const FA_STYLE = /^fa-(solid|regular|light|thin|duotone|brands|sharp)$/;
|
|
43079
|
+
const FA_SIZE = /^fa-(2?xs|sm|lg|xl|2xl|fw|spin|pulse|border|inverse|stack(-[12]x)?|pull-left|pull-right|beat|fade|flip|shake|bounce|spin-pulse|rotate-[0-9a-z]+|flip-[a-z]+)$/;
|
|
43080
|
+
const classOf = (node) => typeof node.className === "string" ? node.className : node.getAttribute("class") || "";
|
|
43081
|
+
const pick = (raw, allowGeneric) => {
|
|
43082
|
+
const tokens = raw.split(/\s+/).filter(Boolean);
|
|
43083
|
+
for (const t2 of tokens) {
|
|
43084
|
+
if (/^fa-/.test(t2) && t2 !== "fa" && !FA_STYLE.test(t2) && !FA_SIZE.test(t2)) return t2;
|
|
43085
|
+
}
|
|
43086
|
+
for (const t2 of tokens) {
|
|
43087
|
+
if (/^k-svg-i-/.test(t2) || /^k-i-/.test(t2)) return t2;
|
|
43088
|
+
}
|
|
43089
|
+
if (allowGeneric) {
|
|
43090
|
+
for (const t2 of tokens) if (/^icon-[a-z]/.test(t2)) return t2;
|
|
43091
|
+
}
|
|
43092
|
+
return void 0;
|
|
43093
|
+
};
|
|
43094
|
+
const rootHit = pick(classOf(root), false);
|
|
43095
|
+
if (rootHit) return rootHit;
|
|
43096
|
+
let kids = [];
|
|
43097
|
+
try {
|
|
43098
|
+
kids = Array.from(root.querySelectorAll("i, svg, em, span"));
|
|
43099
|
+
} catch {
|
|
43100
|
+
kids = [];
|
|
43101
|
+
}
|
|
43102
|
+
for (const node of kids) {
|
|
43103
|
+
const tag = node.tagName;
|
|
43104
|
+
const hit = pick(classOf(node), tag === "I" || tag === "SVG" || tag === "EM");
|
|
43105
|
+
if (hit) return hit;
|
|
43106
|
+
}
|
|
43107
|
+
return void 0;
|
|
43108
|
+
};
|
|
42818
43109
|
if (checks.has("iconButton")) {
|
|
42819
43110
|
try {
|
|
42820
43111
|
const ariaLabel = el.getAttribute("aria-label") || void 0;
|
|
@@ -42872,6 +43163,7 @@ function pageSideFn(el, _ref, args, G) {
|
|
|
42872
43163
|
}
|
|
42873
43164
|
}
|
|
42874
43165
|
}
|
|
43166
|
+
const iconClass = extractIconClass(el);
|
|
42875
43167
|
out.iconButton = {
|
|
42876
43168
|
ariaLabel,
|
|
42877
43169
|
title,
|
|
@@ -42889,7 +43181,8 @@ function pageSideFn(el, _ref, args, G) {
|
|
|
42889
43181
|
reactComponentName,
|
|
42890
43182
|
id: el.id || void 0,
|
|
42891
43183
|
className: typeof el.className === "string" ? el.className : void 0,
|
|
42892
|
-
lucideIconClass
|
|
43184
|
+
lucideIconClass,
|
|
43185
|
+
iconClass
|
|
42893
43186
|
};
|
|
42894
43187
|
} catch {
|
|
42895
43188
|
out.iconButton = null;
|
|
@@ -42902,9 +43195,19 @@ function pageSideFn(el, _ref, args, G) {
|
|
|
42902
43195
|
const id = el.id || void 0;
|
|
42903
43196
|
const className = typeof el.className === "string" ? el.className : void 0;
|
|
42904
43197
|
const { svgHint, lucideIconClass } = extractSvgHint(el);
|
|
43198
|
+
const iconClass = extractIconClass(el);
|
|
42905
43199
|
const rawInnerText = el instanceof HTMLElement ? el.innerText : void 0;
|
|
42906
43200
|
const innerText = rawInnerText?.replace(/\n+/g, " ").trim().slice(0, 80) || void 0;
|
|
42907
|
-
out.genericClickable = {
|
|
43201
|
+
out.genericClickable = {
|
|
43202
|
+
title,
|
|
43203
|
+
ariaLabel,
|
|
43204
|
+
svgHint,
|
|
43205
|
+
id,
|
|
43206
|
+
className,
|
|
43207
|
+
innerText,
|
|
43208
|
+
lucideIconClass,
|
|
43209
|
+
iconClass
|
|
43210
|
+
};
|
|
42908
43211
|
} catch {
|
|
42909
43212
|
out.genericClickable = null;
|
|
42910
43213
|
}
|
|
@@ -43192,6 +43495,9 @@ async function runPerRefAugmentations(scope, yaml, logger2, opts = {}) {
|
|
|
43192
43495
|
if (r2.hclip) {
|
|
43193
43496
|
lines[i2] = appendAttributeIfMissing(lines[i2], "~hclip", r2.hclip);
|
|
43194
43497
|
}
|
|
43498
|
+
if (r2.dialogModality?.inert) {
|
|
43499
|
+
lines[i2] = appendAttributeIfMissing(lines[i2], "~dialog-inert", "true");
|
|
43500
|
+
}
|
|
43195
43501
|
if (r2.gridCellValue) {
|
|
43196
43502
|
const escaped = r2.gridCellValue.replace(/\\/g, "\\\\").replace(/"/g, '\\"');
|
|
43197
43503
|
lines[i2] = appendValueTail(lines[i2], escaped);
|
|
@@ -43240,7 +43546,7 @@ async function runPerRefAugmentations(scope, yaml, logger2, opts = {}) {
|
|
|
43240
43546
|
const linePreLabel = lines[i2];
|
|
43241
43547
|
const role = linePreLabel.includes("- link") ? "link" : "button";
|
|
43242
43548
|
const pathnameLabel = role === "link" ? labelFromPathname(h.pathname) : void 0;
|
|
43243
|
-
const hint = h.title || h.ariaLabel || h.svgHint || h.srText || h.imgAlt || pathnameLabel || h.reactComponentName || (h.id || void 0) || extractSemanticHint(h.className);
|
|
43549
|
+
const hint = h.title || h.ariaLabel || h.svgHint || h.srText || h.imgAlt || (h.iconClass ? resolveIconClassName(h.iconClass) : void 0) || pathnameLabel || h.reactComponentName || (h.id || void 0) || extractSemanticHint(h.className);
|
|
43244
43550
|
if (hint) {
|
|
43245
43551
|
lines[i2] = injectElementLabel(lines[i2], role, hint);
|
|
43246
43552
|
tagAugmentedNameSource(i2);
|
|
@@ -43254,6 +43560,8 @@ async function runPerRefAugmentations(scope, yaml, logger2, opts = {}) {
|
|
|
43254
43560
|
if (h.ariaCurrent) line = appendAttributeIfMissing(line, "aria-current", h.ariaCurrent);
|
|
43255
43561
|
if (h.lucideIconClass) {
|
|
43256
43562
|
line = appendAttributeIfMissing(line, "~icon-class", h.lucideIconClass);
|
|
43563
|
+
} else if (h.iconClass) {
|
|
43564
|
+
line = appendAttributeIfMissing(line, "~icon-class", h.iconClass);
|
|
43257
43565
|
}
|
|
43258
43566
|
const semanticToken = extractSemanticHint(h.className);
|
|
43259
43567
|
if (semanticToken) {
|
|
@@ -43269,7 +43577,7 @@ async function runPerRefAugmentations(scope, yaml, logger2, opts = {}) {
|
|
|
43269
43577
|
}
|
|
43270
43578
|
if (r2.genericClickable) {
|
|
43271
43579
|
const h = r2.genericClickable;
|
|
43272
|
-
const hint = h.title || h.ariaLabel || h.innerText || h.svgHint || (h.id || void 0) || extractSemanticHint(h.className);
|
|
43580
|
+
const hint = h.title || h.ariaLabel || h.innerText || h.svgHint || (h.iconClass ? resolveIconClassName(h.iconClass) : void 0) || (h.id || void 0) || extractSemanticHint(h.className);
|
|
43273
43581
|
if (hint) {
|
|
43274
43582
|
lines[i2] = injectElementLabel(lines[i2], "generic", hint);
|
|
43275
43583
|
tagAugmentedNameSource(i2);
|
|
@@ -43277,6 +43585,8 @@ async function runPerRefAugmentations(scope, yaml, logger2, opts = {}) {
|
|
|
43277
43585
|
let line = lines[i2];
|
|
43278
43586
|
if (h.lucideIconClass) {
|
|
43279
43587
|
line = appendAttributeIfMissing(line, "~icon-class", h.lucideIconClass);
|
|
43588
|
+
} else if (h.iconClass) {
|
|
43589
|
+
line = appendAttributeIfMissing(line, "~icon-class", h.iconClass);
|
|
43280
43590
|
}
|
|
43281
43591
|
const semanticToken = extractSemanticHint(h.className);
|
|
43282
43592
|
if (semanticToken) {
|
|
@@ -44805,7 +45115,7 @@ var CdpScreencastManager = class {
|
|
|
44805
45115
|
return;
|
|
44806
45116
|
}
|
|
44807
45117
|
const framerate = Math.round(1e3 / this.legacyOptions.minIntervalMs);
|
|
44808
|
-
const
|
|
45118
|
+
const encoder2 = this.encoderFactory.create({
|
|
44809
45119
|
framerate,
|
|
44810
45120
|
onInitSegment: videoCallbacks.onInitSegment,
|
|
44811
45121
|
onMediaSegment: videoCallbacks.onMediaSegment,
|
|
@@ -44816,11 +45126,11 @@ var CdpScreencastManager = class {
|
|
|
44816
45126
|
videoCallbacks.onError?.(err);
|
|
44817
45127
|
}
|
|
44818
45128
|
});
|
|
44819
|
-
|
|
45129
|
+
encoder2.start();
|
|
44820
45130
|
const encoderSub = await this.subscribe(page, {
|
|
44821
45131
|
onJpeg: (jpeg2) => {
|
|
44822
45132
|
try {
|
|
44823
|
-
|
|
45133
|
+
encoder2.pushFrame(jpeg2);
|
|
44824
45134
|
} catch (err) {
|
|
44825
45135
|
getLogger().warn("[CdpScreencast] Failed to push frame to encoder", {
|
|
44826
45136
|
error: err instanceof Error ? err.message : String(err)
|
|
@@ -44834,7 +45144,7 @@ var CdpScreencastManager = class {
|
|
|
44834
45144
|
maxHeight: this.legacyOptions.maxHeight,
|
|
44835
45145
|
everyNthFrame: this.legacyOptions.everyNthFrame
|
|
44836
45146
|
});
|
|
44837
|
-
this.legacyEncoder =
|
|
45147
|
+
this.legacyEncoder = encoder2;
|
|
44838
45148
|
this.legacyEncoderSubscription = encoderSub;
|
|
44839
45149
|
this._videoEncodingActive = true;
|
|
44840
45150
|
getLogger().info("[CdpScreencast] Video encoding enabled", { framerate });
|
|
@@ -48168,7 +48478,11 @@ function buildSection(element, depth) {
|
|
|
48168
48478
|
if (dismissRef) {
|
|
48169
48479
|
section.dismissActionRef = dismissRef;
|
|
48170
48480
|
}
|
|
48171
|
-
|
|
48481
|
+
const inert = element.dialogInert === true || element.visibility === "hidden" || element.visibility === "off-screen";
|
|
48482
|
+
if (inert) {
|
|
48483
|
+
section.isInertDialog = true;
|
|
48484
|
+
}
|
|
48485
|
+
if (element.attributes["aria-modal"] === "true" && !inert) {
|
|
48172
48486
|
section.isBlockingModal = true;
|
|
48173
48487
|
}
|
|
48174
48488
|
}
|
|
@@ -48305,7 +48619,7 @@ function sortSectionsByFocus(sections) {
|
|
|
48305
48619
|
dialogStack.unshift(focusedDialog.heading);
|
|
48306
48620
|
}
|
|
48307
48621
|
for (const dialog of dialogs) {
|
|
48308
|
-
if (!dialog.containsActive) {
|
|
48622
|
+
if (!dialog.containsActive && !dialog.isInertDialog) {
|
|
48309
48623
|
dialogStack.push(dialog.heading);
|
|
48310
48624
|
}
|
|
48311
48625
|
}
|
|
@@ -50116,6 +50430,354 @@ async function extractElementMetadata(locator, ref2, _logger3) {
|
|
|
50116
50430
|
childImgAlt: domProps.childImgAlt
|
|
50117
50431
|
};
|
|
50118
50432
|
}
|
|
50433
|
+
init_logger();
|
|
50434
|
+
init_logger();
|
|
50435
|
+
var READY_ID = 0;
|
|
50436
|
+
var HEADER_BYTES = 4;
|
|
50437
|
+
var MAX_FRAME_BYTES = 64 * 1024 * 1024;
|
|
50438
|
+
var encoder = new TextEncoder();
|
|
50439
|
+
var decoder = new TextDecoder();
|
|
50440
|
+
function encodeFrame(obj) {
|
|
50441
|
+
const body = encoder.encode(JSON.stringify(obj));
|
|
50442
|
+
const frame = new Uint8Array(HEADER_BYTES + body.length);
|
|
50443
|
+
new DataView(frame.buffer).setUint32(0, body.length, false);
|
|
50444
|
+
frame.set(body, HEADER_BYTES);
|
|
50445
|
+
return frame;
|
|
50446
|
+
}
|
|
50447
|
+
var FrameDecoder = class {
|
|
50448
|
+
buf = new Uint8Array(0);
|
|
50449
|
+
/** Append a chunk and return every frame that is now complete. */
|
|
50450
|
+
push(chunk) {
|
|
50451
|
+
const next = new Uint8Array(this.buf.length + chunk.length);
|
|
50452
|
+
next.set(this.buf, 0);
|
|
50453
|
+
next.set(chunk, this.buf.length);
|
|
50454
|
+
this.buf = next;
|
|
50455
|
+
const out = [];
|
|
50456
|
+
let offset2 = 0;
|
|
50457
|
+
while (this.buf.length - offset2 >= HEADER_BYTES) {
|
|
50458
|
+
const len = new DataView(this.buf.buffer, this.buf.byteOffset + offset2).getUint32(0, false);
|
|
50459
|
+
if (len > MAX_FRAME_BYTES) {
|
|
50460
|
+
throw new Error(`cpu-offload frame length ${len} exceeds ${MAX_FRAME_BYTES} (corrupt stream)`);
|
|
50461
|
+
}
|
|
50462
|
+
if (this.buf.length - offset2 - HEADER_BYTES < len) break;
|
|
50463
|
+
const start = offset2 + HEADER_BYTES;
|
|
50464
|
+
const body = this.buf.subarray(start, start + len);
|
|
50465
|
+
out.push(JSON.parse(decoder.decode(body)));
|
|
50466
|
+
offset2 = start + len;
|
|
50467
|
+
}
|
|
50468
|
+
if (offset2 > 0) this.buf = this.buf.subarray(offset2);
|
|
50469
|
+
return out;
|
|
50470
|
+
}
|
|
50471
|
+
};
|
|
50472
|
+
var CpuOffloadTimeoutError = class extends Error {
|
|
50473
|
+
_tag = "CpuOffloadTimeoutError";
|
|
50474
|
+
constructor(task, timeoutMs) {
|
|
50475
|
+
super(`cpu-offload task '${task}' exceeded ${timeoutMs}ms and was terminated`);
|
|
50476
|
+
this.name = "CpuOffloadTimeoutError";
|
|
50477
|
+
}
|
|
50478
|
+
};
|
|
50479
|
+
var CpuOffloadWorkerError = class extends Error {
|
|
50480
|
+
_tag = "CpuOffloadWorkerError";
|
|
50481
|
+
constructor(message) {
|
|
50482
|
+
super(message);
|
|
50483
|
+
this.name = "CpuOffloadWorkerError";
|
|
50484
|
+
}
|
|
50485
|
+
};
|
|
50486
|
+
var READY_HANDSHAKE_TIMEOUT_MS = 1e4;
|
|
50487
|
+
function resolveCpuOffloadWorkerPath() {
|
|
50488
|
+
const candidates = [
|
|
50489
|
+
new URL("./worker-process.ts", import.meta.url),
|
|
50490
|
+
new URL("./worker-process.js", import.meta.url),
|
|
50491
|
+
new URL("./cpu-offload/worker-process.js", import.meta.url)
|
|
50492
|
+
].map((u2) => fileURLToPath(u2));
|
|
50493
|
+
const found = candidates.find((p2) => existsSync2(p2));
|
|
50494
|
+
if (found) return found;
|
|
50495
|
+
try {
|
|
50496
|
+
const pkgJson = createRequire(import.meta.url).resolve("@chatsdet/browser-core/package.json");
|
|
50497
|
+
const viaPkg = join2(dirname(pkgJson), "dist", "cpu-offload", "worker-process.js");
|
|
50498
|
+
if (existsSync2(viaPkg)) return viaPkg;
|
|
50499
|
+
candidates.push(viaPkg);
|
|
50500
|
+
} catch {
|
|
50501
|
+
}
|
|
50502
|
+
throw new CpuOffloadWorkerError(`worker entry not found; looked in: ${candidates.join(", ")}`);
|
|
50503
|
+
}
|
|
50504
|
+
var CpuOffloadPool = class {
|
|
50505
|
+
opts;
|
|
50506
|
+
logger;
|
|
50507
|
+
workers = /* @__PURE__ */ new Set();
|
|
50508
|
+
idle = [];
|
|
50509
|
+
waiters = [];
|
|
50510
|
+
nextId = 1;
|
|
50511
|
+
shuttingDown = false;
|
|
50512
|
+
constructor(options) {
|
|
50513
|
+
this.logger = options.logger ?? consoleLogger;
|
|
50514
|
+
this.opts = {
|
|
50515
|
+
size: Math.max(1, options.size),
|
|
50516
|
+
defaultTimeoutMs: options.defaultTimeoutMs,
|
|
50517
|
+
spawn: options.spawn ?? spawn2,
|
|
50518
|
+
workerPath: options.workerPath ?? resolveCpuOffloadWorkerPath(),
|
|
50519
|
+
execPath: options.execPath ?? process.execPath
|
|
50520
|
+
};
|
|
50521
|
+
}
|
|
50522
|
+
/** Run a registered task. Rejects with a typed error on timeout/crash. */
|
|
50523
|
+
async run(task, payload, runOpts) {
|
|
50524
|
+
if (this.shuttingDown) {
|
|
50525
|
+
throw new CpuOffloadWorkerError("pool is shutting down");
|
|
50526
|
+
}
|
|
50527
|
+
const worker = await this.acquire();
|
|
50528
|
+
const timeoutMs = runOpts?.timeoutMs ?? this.opts.defaultTimeoutMs;
|
|
50529
|
+
return new Promise((resolve, reject) => {
|
|
50530
|
+
const id = this.nextId++;
|
|
50531
|
+
const timer = setTimeout(() => this.onTimeout(worker), timeoutMs);
|
|
50532
|
+
worker.current = {
|
|
50533
|
+
id,
|
|
50534
|
+
task,
|
|
50535
|
+
timeoutMs,
|
|
50536
|
+
timer,
|
|
50537
|
+
resolve,
|
|
50538
|
+
reject
|
|
50539
|
+
};
|
|
50540
|
+
const req = { id, task, payload };
|
|
50541
|
+
const stdin = worker.child.stdin;
|
|
50542
|
+
if (!stdin) {
|
|
50543
|
+
this.retireWorker(worker, new CpuOffloadWorkerError("worker has no stdin"));
|
|
50544
|
+
return;
|
|
50545
|
+
}
|
|
50546
|
+
try {
|
|
50547
|
+
stdin.write(encodeFrame(req));
|
|
50548
|
+
} catch (err) {
|
|
50549
|
+
this.retireWorker(
|
|
50550
|
+
worker,
|
|
50551
|
+
new CpuOffloadWorkerError(
|
|
50552
|
+
`failed to write to worker: ${err instanceof Error ? err.message : String(err)}`
|
|
50553
|
+
)
|
|
50554
|
+
);
|
|
50555
|
+
}
|
|
50556
|
+
});
|
|
50557
|
+
}
|
|
50558
|
+
stats() {
|
|
50559
|
+
return {
|
|
50560
|
+
total: this.workers.size,
|
|
50561
|
+
idle: this.idle.length,
|
|
50562
|
+
busy: this.workers.size - this.idle.length,
|
|
50563
|
+
waiting: this.waiters.length
|
|
50564
|
+
};
|
|
50565
|
+
}
|
|
50566
|
+
async shutdown() {
|
|
50567
|
+
this.shuttingDown = true;
|
|
50568
|
+
for (const waiter of this.waiters) {
|
|
50569
|
+
waiter.reject(new CpuOffloadWorkerError("pool shutting down"));
|
|
50570
|
+
}
|
|
50571
|
+
this.waiters.length = 0;
|
|
50572
|
+
for (const w of this.workers) {
|
|
50573
|
+
w.retired = true;
|
|
50574
|
+
if (w.current) {
|
|
50575
|
+
clearTimeout(w.current.timer);
|
|
50576
|
+
w.current.reject(new CpuOffloadWorkerError("pool shutting down"));
|
|
50577
|
+
}
|
|
50578
|
+
w.child.kill("SIGKILL");
|
|
50579
|
+
}
|
|
50580
|
+
this.workers.clear();
|
|
50581
|
+
this.idle.length = 0;
|
|
50582
|
+
}
|
|
50583
|
+
// ── internals ──────────────────────────────────────────────────────────
|
|
50584
|
+
acquire() {
|
|
50585
|
+
const free = this.idle.pop();
|
|
50586
|
+
if (free) return Promise.resolve(free);
|
|
50587
|
+
if (this.workers.size < this.opts.size) return this.spawnWorker();
|
|
50588
|
+
return new Promise((resolve, reject) => this.waiters.push({ resolve, reject }));
|
|
50589
|
+
}
|
|
50590
|
+
release(worker) {
|
|
50591
|
+
if (worker.retired || this.shuttingDown) return;
|
|
50592
|
+
const waiter = this.waiters.shift();
|
|
50593
|
+
if (waiter) waiter.resolve(worker);
|
|
50594
|
+
else this.idle.push(worker);
|
|
50595
|
+
}
|
|
50596
|
+
spawnWorker() {
|
|
50597
|
+
const child = this.opts.spawn(this.opts.execPath, [this.opts.workerPath], {
|
|
50598
|
+
stdio: ["pipe", "pipe", "inherit"]
|
|
50599
|
+
});
|
|
50600
|
+
const worker = { child, decoder: new FrameDecoder(), current: null, retired: false };
|
|
50601
|
+
this.workers.add(worker);
|
|
50602
|
+
return new Promise((resolve, reject) => {
|
|
50603
|
+
let ready = false;
|
|
50604
|
+
let spawnFailed = false;
|
|
50605
|
+
const failSpawn = (err) => {
|
|
50606
|
+
if (ready || spawnFailed) return;
|
|
50607
|
+
spawnFailed = true;
|
|
50608
|
+
clearTimeout(readyTimer);
|
|
50609
|
+
this.workers.delete(worker);
|
|
50610
|
+
worker.child.kill("SIGKILL");
|
|
50611
|
+
reject(err);
|
|
50612
|
+
};
|
|
50613
|
+
const readyTimer = setTimeout(
|
|
50614
|
+
() => failSpawn(new CpuOffloadWorkerError("worker did not become ready in time")),
|
|
50615
|
+
READY_HANDSHAKE_TIMEOUT_MS
|
|
50616
|
+
);
|
|
50617
|
+
child.stdout?.on("data", (chunk) => {
|
|
50618
|
+
let frames;
|
|
50619
|
+
try {
|
|
50620
|
+
frames = worker.decoder.push(chunk);
|
|
50621
|
+
} catch (err) {
|
|
50622
|
+
const wrapped = new CpuOffloadWorkerError(
|
|
50623
|
+
`worker protocol error: ${err instanceof Error ? err.message : String(err)}`
|
|
50624
|
+
);
|
|
50625
|
+
if (ready) this.retireWorker(worker, wrapped);
|
|
50626
|
+
else failSpawn(wrapped);
|
|
50627
|
+
return;
|
|
50628
|
+
}
|
|
50629
|
+
for (const msg of frames) {
|
|
50630
|
+
const resp = msg;
|
|
50631
|
+
if (resp.id === READY_ID) {
|
|
50632
|
+
ready = true;
|
|
50633
|
+
clearTimeout(readyTimer);
|
|
50634
|
+
resolve(worker);
|
|
50635
|
+
} else {
|
|
50636
|
+
this.onResponse(worker, resp);
|
|
50637
|
+
}
|
|
50638
|
+
}
|
|
50639
|
+
});
|
|
50640
|
+
child.on("exit", (code, signal) => {
|
|
50641
|
+
if (!ready) {
|
|
50642
|
+
failSpawn(
|
|
50643
|
+
new CpuOffloadWorkerError(`worker exited before ready (code=${code}, signal=${signal})`)
|
|
50644
|
+
);
|
|
50645
|
+
return;
|
|
50646
|
+
}
|
|
50647
|
+
if (!worker.retired) {
|
|
50648
|
+
this.retireWorker(
|
|
50649
|
+
worker,
|
|
50650
|
+
new CpuOffloadWorkerError(`worker exited unexpectedly (code=${code}, signal=${signal})`)
|
|
50651
|
+
);
|
|
50652
|
+
}
|
|
50653
|
+
});
|
|
50654
|
+
child.on("error", (err) => {
|
|
50655
|
+
if (!ready) {
|
|
50656
|
+
failSpawn(new CpuOffloadWorkerError(`worker spawn failed: ${err.message}`));
|
|
50657
|
+
} else if (!worker.retired) {
|
|
50658
|
+
this.retireWorker(worker, new CpuOffloadWorkerError(`worker error: ${err.message}`));
|
|
50659
|
+
}
|
|
50660
|
+
});
|
|
50661
|
+
});
|
|
50662
|
+
}
|
|
50663
|
+
onResponse(worker, resp) {
|
|
50664
|
+
const call = worker.current;
|
|
50665
|
+
if (!call || call.id !== resp.id) return;
|
|
50666
|
+
clearTimeout(call.timer);
|
|
50667
|
+
worker.current = null;
|
|
50668
|
+
if (resp.ok) call.resolve(resp.result);
|
|
50669
|
+
else call.reject(new CpuOffloadWorkerError(resp.error.message));
|
|
50670
|
+
this.release(worker);
|
|
50671
|
+
}
|
|
50672
|
+
onTimeout(worker) {
|
|
50673
|
+
const call = worker.current;
|
|
50674
|
+
if (!call) return;
|
|
50675
|
+
this.retireWorker(worker, new CpuOffloadTimeoutError(call.task, call.timeoutMs));
|
|
50676
|
+
}
|
|
50677
|
+
/**
|
|
50678
|
+
* Reject any in-flight call, kill the process, drop the worker, and — unless
|
|
50679
|
+
* shutting down — spawn a replacement to keep capacity up and drain waiters.
|
|
50680
|
+
* Idempotent: the SIGKILL's own `exit` event re-enters here as a no-op.
|
|
50681
|
+
*/
|
|
50682
|
+
retireWorker(worker, error) {
|
|
50683
|
+
if (worker.retired) return;
|
|
50684
|
+
worker.retired = true;
|
|
50685
|
+
this.workers.delete(worker);
|
|
50686
|
+
const idx = this.idle.indexOf(worker);
|
|
50687
|
+
if (idx >= 0) this.idle.splice(idx, 1);
|
|
50688
|
+
this.logger.warn("[CpuOffloadPool] retiring worker", {
|
|
50689
|
+
pid: worker.child.pid,
|
|
50690
|
+
task: worker.current?.task,
|
|
50691
|
+
reason: error.message,
|
|
50692
|
+
timedOut: error instanceof CpuOffloadTimeoutError
|
|
50693
|
+
});
|
|
50694
|
+
if (worker.current) {
|
|
50695
|
+
clearTimeout(worker.current.timer);
|
|
50696
|
+
worker.current.reject(error);
|
|
50697
|
+
worker.current = null;
|
|
50698
|
+
}
|
|
50699
|
+
worker.child.kill("SIGKILL");
|
|
50700
|
+
if (this.shuttingDown) return;
|
|
50701
|
+
if (this.waiters.length > 0 || this.workers.size < this.opts.size) {
|
|
50702
|
+
this.spawnWorker().then((w) => this.release(w)).catch((err) => {
|
|
50703
|
+
this.logger.error("[CpuOffloadPool] failed to respawn worker; rejecting waiters", {
|
|
50704
|
+
error: err instanceof Error ? err.message : String(err),
|
|
50705
|
+
waiting: this.waiters.length
|
|
50706
|
+
});
|
|
50707
|
+
const drained = this.waiters.splice(0);
|
|
50708
|
+
for (const waiter of drained) {
|
|
50709
|
+
waiter.reject(
|
|
50710
|
+
new CpuOffloadWorkerError(
|
|
50711
|
+
`worker respawn failed: ${err instanceof Error ? err.message : String(err)}`
|
|
50712
|
+
)
|
|
50713
|
+
);
|
|
50714
|
+
}
|
|
50715
|
+
});
|
|
50716
|
+
}
|
|
50717
|
+
}
|
|
50718
|
+
};
|
|
50719
|
+
var DEFAULT_CPU_OFFLOAD_TIMEOUT_MS = 15e3;
|
|
50720
|
+
var defaultCpuOffloadSize = () => Math.min(8, Math.max(2, Math.floor(cpus().length / 2)));
|
|
50721
|
+
var config = { enabled: false };
|
|
50722
|
+
var pool = null;
|
|
50723
|
+
function configureCpuOffload(next) {
|
|
50724
|
+
config = next;
|
|
50725
|
+
if (typeof next.enabled === "boolean" && next.enabled === false) {
|
|
50726
|
+
void shutdownCpuOffload();
|
|
50727
|
+
}
|
|
50728
|
+
}
|
|
50729
|
+
function isCpuOffloadEnabled() {
|
|
50730
|
+
const { enabled } = config;
|
|
50731
|
+
return typeof enabled === "function" ? !!enabled() : enabled;
|
|
50732
|
+
}
|
|
50733
|
+
function getPool() {
|
|
50734
|
+
if (!pool) {
|
|
50735
|
+
pool = new CpuOffloadPool({
|
|
50736
|
+
size: config.size ?? defaultCpuOffloadSize(),
|
|
50737
|
+
defaultTimeoutMs: config.timeoutMs ?? DEFAULT_CPU_OFFLOAD_TIMEOUT_MS,
|
|
50738
|
+
logger: config.logger ?? consoleLogger
|
|
50739
|
+
});
|
|
50740
|
+
}
|
|
50741
|
+
return pool;
|
|
50742
|
+
}
|
|
50743
|
+
async function shutdownCpuOffload() {
|
|
50744
|
+
const p2 = pool;
|
|
50745
|
+
pool = null;
|
|
50746
|
+
if (p2) await p2.shutdown();
|
|
50747
|
+
}
|
|
50748
|
+
var TIMEOUT_MARKER = "---\nSEMANTIC SNAPSHOT - formatting timed out\nThe page was too large to format within the time budget. Narrow with browser_snapshot search=\u2026 or scroll to a region.\n---";
|
|
50749
|
+
async function formatSnapshotMaybeOffloaded(yaml, options) {
|
|
50750
|
+
if (!isCpuOffloadEnabled()) {
|
|
50751
|
+
return formatSemanticSnapshot(yaml, options);
|
|
50752
|
+
}
|
|
50753
|
+
const logger2 = config.logger ?? consoleLogger;
|
|
50754
|
+
try {
|
|
50755
|
+
const { elementHints, matchedHintIds: _drop, ...rest } = options ?? {};
|
|
50756
|
+
const payload = {
|
|
50757
|
+
yaml,
|
|
50758
|
+
options: rest,
|
|
50759
|
+
...elementHints ? { elementHints: [...elementHints] } : {}
|
|
50760
|
+
};
|
|
50761
|
+
const result = await getPool().run("format-snapshot", payload);
|
|
50762
|
+
if (options && result.matchedHintIds) {
|
|
50763
|
+
options.matchedHintIds = result.matchedHintIds;
|
|
50764
|
+
}
|
|
50765
|
+
return result.text;
|
|
50766
|
+
} catch (err) {
|
|
50767
|
+
if (err instanceof CpuOffloadTimeoutError) {
|
|
50768
|
+
logger2.warn("[CpuOffload] format-snapshot timed out; returning marker (NOT inlining)", {
|
|
50769
|
+
task: "format-snapshot",
|
|
50770
|
+
error: err.message
|
|
50771
|
+
});
|
|
50772
|
+
return TIMEOUT_MARKER;
|
|
50773
|
+
}
|
|
50774
|
+
logger2.warn("[CpuOffload] format-snapshot offload failed; running inline", {
|
|
50775
|
+
task: "format-snapshot",
|
|
50776
|
+
error: err instanceof Error ? err.message : String(err)
|
|
50777
|
+
});
|
|
50778
|
+
return formatSemanticSnapshot(yaml, options);
|
|
50779
|
+
}
|
|
50780
|
+
}
|
|
50119
50781
|
var ToolAbortedError = class extends Error {
|
|
50120
50782
|
constructor(stage) {
|
|
50121
50783
|
super(`Browser action aborted at stage: ${stage}`);
|
|
@@ -51057,7 +51719,7 @@ ${effectiveShowCoordinateGrid ? "Coordinate grid enabled - read coordinates from
|
|
|
51057
51719
|
elementHints,
|
|
51058
51720
|
matchedHintIds: void 0
|
|
51059
51721
|
};
|
|
51060
|
-
let semanticText =
|
|
51722
|
+
let semanticText = await formatSnapshotMaybeOffloaded(yaml, snapshotOpts);
|
|
51061
51723
|
const formattedRefs = extractFormattedSnapshotRefs(semanticText);
|
|
51062
51724
|
if (formattedRefs.length > LARGE_PAGE_REF_THRESHOLD) {
|
|
51063
51725
|
semanticText = `[Large page: ~${formattedRefs.length.toLocaleString()} interactive elements \u2014 scroll-position hints reduced for speed. Narrow with browser_snapshot search=\u2026 or scroll to a region.]
|
|
@@ -51881,7 +52543,7 @@ ${recoveryHint}`;
|
|
|
51881
52543
|
await fs22.writeFile(snapshotFilePath, yaml, "utf-8");
|
|
51882
52544
|
} catch {
|
|
51883
52545
|
}
|
|
51884
|
-
const semanticText =
|
|
52546
|
+
const semanticText = await formatSnapshotMaybeOffloaded(yaml, {
|
|
51885
52547
|
snapshotFilePath,
|
|
51886
52548
|
currentTime: (/* @__PURE__ */ new Date()).toISOString(),
|
|
51887
52549
|
capturedToasts: this.client.getCapturedToasts?.() ?? [],
|
|
@@ -55075,6 +55737,16 @@ function normalizeDateInputValue(value) {
|
|
|
55075
55737
|
}
|
|
55076
55738
|
return value;
|
|
55077
55739
|
}
|
|
55740
|
+
var OperationTimeoutError = class extends Error {
|
|
55741
|
+
label;
|
|
55742
|
+
timeoutMs;
|
|
55743
|
+
constructor(label, timeoutMs) {
|
|
55744
|
+
super(`${label} timed out after ${timeoutMs}ms`);
|
|
55745
|
+
this.name = "OperationTimeoutError";
|
|
55746
|
+
this.label = label;
|
|
55747
|
+
this.timeoutMs = timeoutMs;
|
|
55748
|
+
}
|
|
55749
|
+
};
|
|
55078
55750
|
function asEmitter(page) {
|
|
55079
55751
|
return page;
|
|
55080
55752
|
}
|
|
@@ -55094,6 +55766,15 @@ function stripNewListeners(page, event, baseline) {
|
|
|
55094
55766
|
}
|
|
55095
55767
|
return stripped;
|
|
55096
55768
|
}
|
|
55769
|
+
var runCodePageRequestMethods = /* @__PURE__ */ new Set([
|
|
55770
|
+
"delete",
|
|
55771
|
+
"fetch",
|
|
55772
|
+
"get",
|
|
55773
|
+
"head",
|
|
55774
|
+
"patch",
|
|
55775
|
+
"post",
|
|
55776
|
+
"put"
|
|
55777
|
+
]);
|
|
55097
55778
|
function logLateRunCodeWaitRejection(logger2, kind, promise) {
|
|
55098
55779
|
promise.catch((err) => {
|
|
55099
55780
|
logger2.debug(`[DirectPlaywright] runCode ${kind} wait rejected after call`, {
|
|
@@ -55112,6 +55793,84 @@ function guardRunCodeFetch(logger2) {
|
|
|
55112
55793
|
return promise;
|
|
55113
55794
|
};
|
|
55114
55795
|
}
|
|
55796
|
+
function isPromiseLike(value) {
|
|
55797
|
+
return typeof value === "object" && value !== null && typeof value.catch === "function";
|
|
55798
|
+
}
|
|
55799
|
+
function logLateRunCodePageRequestRejection(logger2, method, url, promise) {
|
|
55800
|
+
promise.catch((err) => {
|
|
55801
|
+
logger2.debug("[DirectPlaywright] runCode page.request rejected after call", {
|
|
55802
|
+
method,
|
|
55803
|
+
url: url.slice(0, 200),
|
|
55804
|
+
error: err instanceof Error ? err.message : String(err)
|
|
55805
|
+
});
|
|
55806
|
+
});
|
|
55807
|
+
}
|
|
55808
|
+
function guardRunCodePageRequestContext(request2, getPageUrl, logger2) {
|
|
55809
|
+
if (request2 === null || typeof request2 !== "object" && typeof request2 !== "function") {
|
|
55810
|
+
return request2;
|
|
55811
|
+
}
|
|
55812
|
+
const functionCache = /* @__PURE__ */ new Map();
|
|
55813
|
+
return new Proxy(request2, {
|
|
55814
|
+
get(target, property, receiver) {
|
|
55815
|
+
const value = Reflect.get(target, property, receiver);
|
|
55816
|
+
if (typeof value !== "function") {
|
|
55817
|
+
return value;
|
|
55818
|
+
}
|
|
55819
|
+
const cached = functionCache.get(property);
|
|
55820
|
+
if (cached) {
|
|
55821
|
+
return cached;
|
|
55822
|
+
}
|
|
55823
|
+
if (!runCodePageRequestMethods.has(property)) {
|
|
55824
|
+
const bound = value.bind(target);
|
|
55825
|
+
functionCache.set(property, bound);
|
|
55826
|
+
return bound;
|
|
55827
|
+
}
|
|
55828
|
+
const method = property;
|
|
55829
|
+
const guarded = (...args) => {
|
|
55830
|
+
const requestArgs = [...args];
|
|
55831
|
+
const originalUrl = requestArgs[0];
|
|
55832
|
+
let requestUrl = null;
|
|
55833
|
+
if (typeof originalUrl === "string") {
|
|
55834
|
+
requestUrl = resolveBrowserContextRequestUrl(originalUrl, getPageUrl());
|
|
55835
|
+
requestArgs[0] = requestUrl;
|
|
55836
|
+
}
|
|
55837
|
+
const result = value.apply(target, requestArgs);
|
|
55838
|
+
if (isPromiseLike(result) && requestUrl !== null) {
|
|
55839
|
+
logLateRunCodePageRequestRejection(logger2, method, requestUrl, result);
|
|
55840
|
+
}
|
|
55841
|
+
return result;
|
|
55842
|
+
};
|
|
55843
|
+
functionCache.set(property, guarded);
|
|
55844
|
+
return guarded;
|
|
55845
|
+
}
|
|
55846
|
+
});
|
|
55847
|
+
}
|
|
55848
|
+
function guardRunCodePageRequest(page, logger2) {
|
|
55849
|
+
const guardedRequest = guardRunCodePageRequestContext(
|
|
55850
|
+
page.request,
|
|
55851
|
+
() => page.url(),
|
|
55852
|
+
logger2
|
|
55853
|
+
);
|
|
55854
|
+
const functionCache = /* @__PURE__ */ new Map();
|
|
55855
|
+
return new Proxy(page, {
|
|
55856
|
+
get(target, property, receiver) {
|
|
55857
|
+
if (property === "request") {
|
|
55858
|
+
return guardedRequest;
|
|
55859
|
+
}
|
|
55860
|
+
const value = Reflect.get(target, property, receiver);
|
|
55861
|
+
if (typeof value !== "function") {
|
|
55862
|
+
return value;
|
|
55863
|
+
}
|
|
55864
|
+
const cached = functionCache.get(property);
|
|
55865
|
+
if (cached) {
|
|
55866
|
+
return cached;
|
|
55867
|
+
}
|
|
55868
|
+
const bound = value.bind(page);
|
|
55869
|
+
functionCache.set(property, bound);
|
|
55870
|
+
return bound;
|
|
55871
|
+
}
|
|
55872
|
+
});
|
|
55873
|
+
}
|
|
55115
55874
|
function guardFileChooserWaitForEvent(page, logger2) {
|
|
55116
55875
|
const originalWaitForEvent = page.waitForEvent;
|
|
55117
55876
|
let guarded = 0;
|
|
@@ -55541,10 +56300,7 @@ var PlaywrightClient = class _PlaywrightClient {
|
|
|
55541
56300
|
return await Promise.race([
|
|
55542
56301
|
operation,
|
|
55543
56302
|
new Promise((_, reject) => {
|
|
55544
|
-
timer = setTimeout(
|
|
55545
|
-
() => reject(new Error(`${label} timed out after ${timeoutMs}ms`)),
|
|
55546
|
-
timeoutMs
|
|
55547
|
-
);
|
|
56303
|
+
timer = setTimeout(() => reject(new OperationTimeoutError(label, timeoutMs)), timeoutMs);
|
|
55548
56304
|
})
|
|
55549
56305
|
]);
|
|
55550
56306
|
} finally {
|
|
@@ -55642,6 +56398,20 @@ var PlaywrightClient = class _PlaywrightClient {
|
|
|
55642
56398
|
// Tracing state
|
|
55643
56399
|
tracingActive = false;
|
|
55644
56400
|
traceDir = null;
|
|
56401
|
+
// Flushed trace chunk paths (one per browser context). Tracing is bound to a
|
|
56402
|
+
// single Playwright context; when the context is swapped/recreated mid-run we
|
|
56403
|
+
// flush the in-progress trace to disk here and restart tracing on the new
|
|
56404
|
+
// context, so the run-level trace survives the swap instead of being discarded.
|
|
56405
|
+
traceChunks = [];
|
|
56406
|
+
// Every trace temp dir created this session (incl. chunks whose flush failed,
|
|
56407
|
+
// so they aren't in traceChunks) — swept on disconnect so none leak.
|
|
56408
|
+
allTraceDirs = /* @__PURE__ */ new Set();
|
|
56409
|
+
// Context routes (e.g. Cloudflare Access scoped-header injection) last applied
|
|
56410
|
+
// via setupContextRoutes(). Route interception is per-context and is dropped
|
|
56411
|
+
// when the context is recreated; we remember the routes so auto-recovery paths
|
|
56412
|
+
// (restoreBrowser) can re-arm them — otherwise the edge would bounce
|
|
56413
|
+
// post-recovery requests to a login page.
|
|
56414
|
+
storedContextRoutes = [];
|
|
55645
56415
|
// Video recording state.
|
|
55646
56416
|
// The screencast encoder is the single source of truth for the recorded
|
|
55647
56417
|
// file: while it lives, `videoDir`/`videoPath` derive from it. Before the
|
|
@@ -55893,6 +56663,17 @@ var PlaywrightClient = class _PlaywrightClient {
|
|
|
55893
56663
|
supportsContextSwap() {
|
|
55894
56664
|
return !this.extensionsEnabled && (!!this.browser || !!this.browserLease);
|
|
55895
56665
|
}
|
|
56666
|
+
/**
|
|
56667
|
+
* Replace the browser context (e.g. to apply fresh storage state on re-auth),
|
|
56668
|
+
* keeping the same browser. Contract for context-bound state:
|
|
56669
|
+
* - Tracing AUTO-resumes here: the in-progress trace is flushed to a chunk
|
|
56670
|
+
* first (recoverable), then restarted on the new context.
|
|
56671
|
+
* - Context routes (e.g. CF Access scoped headers) are NOT re-armed here —
|
|
56672
|
+
* the caller must re-apply them via setupContextRoutes after the swap,
|
|
56673
|
+
* because the swap may intentionally change the headers (new credential).
|
|
56674
|
+
* (Crash-recovery in restoreBrowser DOES auto re-arm from stored routes,
|
|
56675
|
+
* since the headers are unchanged there.)
|
|
56676
|
+
*/
|
|
55896
56677
|
async swapContext(options) {
|
|
55897
56678
|
if (!this.supportsContextSwap()) {
|
|
55898
56679
|
throw new Error(
|
|
@@ -55916,14 +56697,9 @@ var PlaywrightClient = class _PlaywrightClient {
|
|
|
55916
56697
|
this.logger.info("[DirectPlaywright] Stopping screencast frame delivery for context swap");
|
|
55917
56698
|
await this._stopScreencastFrameDelivery();
|
|
55918
56699
|
}
|
|
55919
|
-
|
|
55920
|
-
|
|
55921
|
-
|
|
55922
|
-
} catch {
|
|
55923
|
-
} finally {
|
|
55924
|
-
this.tracingActive = false;
|
|
55925
|
-
this.traceDir = null;
|
|
55926
|
-
}
|
|
56700
|
+
const resumeTracingAfterSwap = this.tracingActive && !!this.context;
|
|
56701
|
+
if (resumeTracingAfterSwap) {
|
|
56702
|
+
await this.flushTraceChunk();
|
|
55927
56703
|
}
|
|
55928
56704
|
this.contextClosedIntentionally = true;
|
|
55929
56705
|
this.pageClosedIntentionally = true;
|
|
@@ -56015,6 +56791,13 @@ var PlaywrightClient = class _PlaywrightClient {
|
|
|
56015
56791
|
if (wasScreencasting && this.page && this.screencastHandler) {
|
|
56016
56792
|
await this.startScreencast(this.screencastHandler);
|
|
56017
56793
|
}
|
|
56794
|
+
if (resumeTracingAfterSwap) {
|
|
56795
|
+
await this.beginTracingOnContext().catch((err) => {
|
|
56796
|
+
this.logger.warn("[DirectPlaywright] Failed to resume tracing after context swap", {
|
|
56797
|
+
error: err instanceof Error ? err.message : String(err)
|
|
56798
|
+
});
|
|
56799
|
+
});
|
|
56800
|
+
}
|
|
56018
56801
|
this.logger.info("[DirectPlaywright] Context swapped successfully");
|
|
56019
56802
|
}
|
|
56020
56803
|
/**
|
|
@@ -56347,20 +57130,22 @@ var PlaywrightClient = class _PlaywrightClient {
|
|
|
56347
57130
|
}
|
|
56348
57131
|
this._downloadDir = null;
|
|
56349
57132
|
}
|
|
56350
|
-
|
|
56351
|
-
|
|
56352
|
-
|
|
56353
|
-
|
|
56354
|
-
|
|
56355
|
-
|
|
56356
|
-
|
|
56357
|
-
|
|
56358
|
-
|
|
56359
|
-
|
|
56360
|
-
|
|
56361
|
-
|
|
56362
|
-
|
|
56363
|
-
|
|
57133
|
+
const traceDirsToClean = new Set(this.allTraceDirs);
|
|
57134
|
+
if (this.traceDir) traceDirsToClean.add(this.traceDir);
|
|
57135
|
+
await Promise.allSettled(
|
|
57136
|
+
[...traceDirsToClean].map(
|
|
57137
|
+
(dir) => fs4.rm(dir, { recursive: true, force: true }).catch(
|
|
57138
|
+
(err) => this.logger.warn("[DirectPlaywright] Failed to clean up trace directory", {
|
|
57139
|
+
traceDir: dir,
|
|
57140
|
+
error: err instanceof Error ? err.message : String(err)
|
|
57141
|
+
})
|
|
57142
|
+
)
|
|
57143
|
+
)
|
|
57144
|
+
);
|
|
57145
|
+
this.traceDir = null;
|
|
57146
|
+
this.traceChunks = [];
|
|
57147
|
+
this.allTraceDirs.clear();
|
|
57148
|
+
this.storedContextRoutes = [];
|
|
56364
57149
|
this._capturedDownloads = [];
|
|
56365
57150
|
this._downloadCounter = 0;
|
|
56366
57151
|
this._lastReportedDownloadIndex = 0;
|
|
@@ -56714,6 +57499,7 @@ Use coordinate-based clicking (x, y) to interact with elements visible in the sc
|
|
|
56714
57499
|
let aborted = runController.signal.aborted;
|
|
56715
57500
|
let guardedWaits = { fileChooser: 0, request: 0, response: 0 };
|
|
56716
57501
|
const guardedFetch = guardRunCodeFetch(this.logger);
|
|
57502
|
+
const guardedPage = guardRunCodePageRequest(page, this.logger);
|
|
56717
57503
|
try {
|
|
56718
57504
|
if (!aborted) {
|
|
56719
57505
|
const fn = new Function("page", "fetch", `return (async () => { ${code} })()`);
|
|
@@ -56724,7 +57510,7 @@ Use coordinate-based clicking (x, y) to interact with elements visible in the sc
|
|
|
56724
57510
|
{ once: true }
|
|
56725
57511
|
);
|
|
56726
57512
|
});
|
|
56727
|
-
const inner = fn(
|
|
57513
|
+
const inner = fn(guardedPage, guardedFetch);
|
|
56728
57514
|
inner.catch((err) => {
|
|
56729
57515
|
this.logger.debug("[DirectPlaywright] runCode orphan rejected after race", {
|
|
56730
57516
|
error: err instanceof Error ? err.message : String(err)
|
|
@@ -58096,13 +58882,58 @@ ${warning}` : ""}`,
|
|
|
58096
58882
|
}
|
|
58097
58883
|
// ================ TRACING ================
|
|
58098
58884
|
async startTracing(_opts) {
|
|
58099
|
-
const context = await this.getContext();
|
|
58100
58885
|
this.logger.info("[DirectPlaywright] Starting trace recording");
|
|
58101
|
-
this.
|
|
58102
|
-
|
|
58103
|
-
await
|
|
58886
|
+
this.traceChunks = [];
|
|
58887
|
+
this.allTraceDirs.clear();
|
|
58888
|
+
await this.beginTracingOnContext();
|
|
58889
|
+
}
|
|
58890
|
+
/**
|
|
58891
|
+
* Start a Playwright trace on the current context. Used both for the initial
|
|
58892
|
+
* `startTracing()` and to resume tracing after a context swap. `traceDir` /
|
|
58893
|
+
* `tracingActive` are set ONLY after `tracing.start()` resolves — a thrown
|
|
58894
|
+
* start must not leave `traceDir` set, or a later `stopTracing()` would target
|
|
58895
|
+
* a context that never started tracing ("Must start tracing before stopping").
|
|
58896
|
+
*/
|
|
58897
|
+
async beginTracingOnContext() {
|
|
58898
|
+
const context = await this.getContext();
|
|
58899
|
+
const traceDir = path5.join(
|
|
58900
|
+
this.tmpBaseDir,
|
|
58901
|
+
`playwright-trace-${Date.now()}-${this.traceChunks.length}`
|
|
58902
|
+
);
|
|
58903
|
+
await fs4.mkdir(traceDir, { recursive: true });
|
|
58904
|
+
try {
|
|
58905
|
+
await context.tracing.start({ screenshots: true, snapshots: true });
|
|
58906
|
+
} catch (err) {
|
|
58907
|
+
await fs4.rm(traceDir, { recursive: true, force: true }).catch(() => {
|
|
58908
|
+
});
|
|
58909
|
+
throw err;
|
|
58910
|
+
}
|
|
58911
|
+
this.traceDir = traceDir;
|
|
58912
|
+
this.allTraceDirs.add(traceDir);
|
|
58104
58913
|
this.tracingActive = true;
|
|
58105
58914
|
}
|
|
58915
|
+
/**
|
|
58916
|
+
* Flush the in-progress trace on the current context to disk and record the
|
|
58917
|
+
* chunk. Returns the chunk path, or null when tracing isn't active. Stopping
|
|
58918
|
+
* WITH a path preserves the trace; stopping without one discards it. Errors are
|
|
58919
|
+
* swallowed (best-effort) so a failed flush never blocks a context swap.
|
|
58920
|
+
*/
|
|
58921
|
+
async flushTraceChunk() {
|
|
58922
|
+
if (!this.tracingActive || !this.context || !this.traceDir) return null;
|
|
58923
|
+
const chunkPath = path5.join(this.traceDir, "trace.zip");
|
|
58924
|
+
try {
|
|
58925
|
+
await this.context.tracing.stop({ path: chunkPath });
|
|
58926
|
+
this.traceChunks.push(chunkPath);
|
|
58927
|
+
return chunkPath;
|
|
58928
|
+
} catch (err) {
|
|
58929
|
+
this.logger.warn("[DirectPlaywright] Failed to flush trace chunk", {
|
|
58930
|
+
error: err instanceof Error ? err.message : String(err)
|
|
58931
|
+
});
|
|
58932
|
+
return null;
|
|
58933
|
+
} finally {
|
|
58934
|
+
this.tracingActive = false;
|
|
58935
|
+
}
|
|
58936
|
+
}
|
|
58106
58937
|
async traceGroup(name) {
|
|
58107
58938
|
if (!this.tracingActive) return;
|
|
58108
58939
|
const context = await this.getContext();
|
|
@@ -58122,20 +58953,26 @@ ${warning}` : ""}`,
|
|
|
58122
58953
|
* The trace.zip can be viewed at https://trace.playwright.dev/
|
|
58123
58954
|
*/
|
|
58124
58955
|
async stopTracing(_opts) {
|
|
58125
|
-
const context = await this.getContext();
|
|
58126
|
-
if (!this.traceDir) throw new Error("Tracing not started");
|
|
58127
58956
|
this.logger.info("[DirectPlaywright] Stopping trace recording");
|
|
58128
|
-
|
|
58129
|
-
|
|
58130
|
-
|
|
58957
|
+
await this.flushTraceChunk();
|
|
58958
|
+
if (this.traceChunks.length === 0) {
|
|
58959
|
+
throw new Error("No trace chunks captured (tracing not started, or all flushes failed)");
|
|
58960
|
+
}
|
|
58961
|
+
const chunks = [...this.traceChunks];
|
|
58962
|
+
if (chunks.length > 1) {
|
|
58963
|
+
this.logger.info("[DirectPlaywright] Captured multiple trace chunks across context swaps", {
|
|
58964
|
+
chunkCount: chunks.length
|
|
58965
|
+
});
|
|
58966
|
+
}
|
|
58131
58967
|
return {
|
|
58132
|
-
trace:
|
|
58968
|
+
trace: chunks[0],
|
|
58969
|
+
traces: chunks,
|
|
58133
58970
|
network: "",
|
|
58134
58971
|
// Playwright bundles network data in trace.zip (not separate file)
|
|
58135
58972
|
resources: "",
|
|
58136
58973
|
// Playwright bundles resources in trace.zip (not separate file)
|
|
58137
|
-
directory:
|
|
58138
|
-
legend: `Trace saved to ${
|
|
58974
|
+
directory: path5.dirname(chunks[0]),
|
|
58975
|
+
legend: `Trace saved to ${chunks[0]}`
|
|
58139
58976
|
};
|
|
58140
58977
|
}
|
|
58141
58978
|
// ================ PRIVATE: Accessibility Snapshot ================
|
|
@@ -58254,11 +59091,22 @@ ${warning}` : ""}`,
|
|
|
58254
59091
|
result = await this.raceAgainstSignal(
|
|
58255
59092
|
"snapshot:aria",
|
|
58256
59093
|
signal,
|
|
58257
|
-
() =>
|
|
59094
|
+
() => this.withOperationTimeout(
|
|
59095
|
+
page.ariaSnapshot({ mode: "ai" }),
|
|
59096
|
+
TIMEOUTS.ARIA_SNAPSHOT_CAP,
|
|
59097
|
+
"snapshot:aria"
|
|
59098
|
+
)
|
|
58258
59099
|
);
|
|
58259
59100
|
break;
|
|
58260
59101
|
} catch (err) {
|
|
58261
59102
|
if (signal?.aborted) return void 0;
|
|
59103
|
+
if (err instanceof OperationTimeoutError && err.label === "snapshot:aria") {
|
|
59104
|
+
this.logger.warn(
|
|
59105
|
+
"[DirectPlaywright] ariaSnapshot exceeded driver cap, using empty fallback",
|
|
59106
|
+
{ capMs: TIMEOUTS.ARIA_SNAPSHOT_CAP, attempt }
|
|
59107
|
+
);
|
|
59108
|
+
break;
|
|
59109
|
+
}
|
|
58262
59110
|
if (attempt < maxRetries) {
|
|
58263
59111
|
this.logger.debug("[DirectPlaywright] Snapshot attempt failed, retrying", {
|
|
58264
59112
|
attempt,
|
|
@@ -59260,6 +60108,8 @@ Legacy two-step (only if you need to change the action between calls): browser_h
|
|
|
59260
60108
|
this.browser = null;
|
|
59261
60109
|
this.attachContextListeners(this.context);
|
|
59262
60110
|
await this.createPageWithListeners(this.context, reason);
|
|
60111
|
+
await this.reapplyStoredContextRoutes();
|
|
60112
|
+
await this.resumeTracingOnRecreatedContext();
|
|
59263
60113
|
await this.restoreUrlAfterRecovery(urlToRestore, crashType);
|
|
59264
60114
|
await restartScreencastIfNeeded();
|
|
59265
60115
|
await restartScreencastRecordingIfNeeded();
|
|
@@ -59305,6 +60155,8 @@ Legacy two-step (only if you need to change the action between calls): browser_h
|
|
|
59305
60155
|
this.attachBrowserListeners(this.browser);
|
|
59306
60156
|
}
|
|
59307
60157
|
await this.createPageWithListeners(this.context, reason);
|
|
60158
|
+
await this.reapplyStoredContextRoutes();
|
|
60159
|
+
await this.resumeTracingOnRecreatedContext();
|
|
59308
60160
|
await this.restoreUrlAfterRecovery(urlToRestore, crashType);
|
|
59309
60161
|
await restartScreencastIfNeeded();
|
|
59310
60162
|
await restartScreencastRecordingIfNeeded();
|
|
@@ -59478,8 +60330,8 @@ Legacy two-step (only if you need to change the action between calls): browser_h
|
|
|
59478
60330
|
});
|
|
59479
60331
|
await Promise.allSettled(stopPromises);
|
|
59480
60332
|
this._screencastDisposables.clear();
|
|
59481
|
-
const
|
|
59482
|
-
if (!
|
|
60333
|
+
const encoder2 = this._screencastEncoder;
|
|
60334
|
+
if (!encoder2) {
|
|
59483
60335
|
this._screencastEncoder = null;
|
|
59484
60336
|
this.logger.warn("[DirectPlaywright] Screencast encoder was never started \u2014 no video produced", {
|
|
59485
60337
|
videoEnabled: this.videoEnabled,
|
|
@@ -59487,9 +60339,9 @@ Legacy two-step (only if you need to change the action between calls): browser_h
|
|
|
59487
60339
|
});
|
|
59488
60340
|
return null;
|
|
59489
60341
|
}
|
|
59490
|
-
this._savedVideoPath =
|
|
60342
|
+
this._savedVideoPath = encoder2.outputFilePath;
|
|
59491
60343
|
this._screencastEncoder = null;
|
|
59492
|
-
const stopResult = await
|
|
60344
|
+
const stopResult = await encoder2.stop();
|
|
59493
60345
|
const {
|
|
59494
60346
|
durationMs,
|
|
59495
60347
|
receivedFrameCount,
|
|
@@ -59731,12 +60583,53 @@ Legacy two-step (only if you need to change the action between calls): browser_h
|
|
|
59731
60583
|
// ================ EMULATION ROUTES ================
|
|
59732
60584
|
async setupContextRoutes(routes) {
|
|
59733
60585
|
const context = await this.getContext();
|
|
60586
|
+
await this.registerContextRoutes(routes, context);
|
|
60587
|
+
this.storedContextRoutes = routes;
|
|
60588
|
+
}
|
|
60589
|
+
async registerContextRoutes(routes, context) {
|
|
59734
60590
|
for (const route of routes) {
|
|
59735
60591
|
await context.route(route.urlPattern, async (pwRoute) => {
|
|
59736
60592
|
await route.handler(createSingleUseContextRouteHandle(pwRoute, this.logger));
|
|
59737
60593
|
});
|
|
59738
60594
|
}
|
|
59739
60595
|
}
|
|
60596
|
+
/**
|
|
60597
|
+
* Restart tracing on a freshly recreated (post-crash/recovery) context. The
|
|
60598
|
+
* pre-recovery trace died with the old context and cannot be flushed, so the
|
|
60599
|
+
* best we can do is capture post-recovery activity and ensure the final
|
|
60600
|
+
* stopTracing() targets a context that actually has tracing started.
|
|
60601
|
+
* Best-effort — no-op when tracing wasn't active.
|
|
60602
|
+
*/
|
|
60603
|
+
async resumeTracingOnRecreatedContext() {
|
|
60604
|
+
if (!this.tracingActive) return;
|
|
60605
|
+
this.tracingActive = false;
|
|
60606
|
+
await this.beginTracingOnContext().catch((err) => {
|
|
60607
|
+
this.logger.warn("[DirectPlaywright] Failed to resume tracing after browser recovery", {
|
|
60608
|
+
error: err instanceof Error ? err.message : String(err),
|
|
60609
|
+
chunksCapturedSoFar: this.traceChunks.length
|
|
60610
|
+
});
|
|
60611
|
+
});
|
|
60612
|
+
}
|
|
60613
|
+
/**
|
|
60614
|
+
* Re-arm the stored context routes on the current (freshly recreated) context.
|
|
60615
|
+
* Called from recovery paths that build a new context — without this, scoped
|
|
60616
|
+
* header injection (e.g. Cloudflare Access) silently stops after a restore and
|
|
60617
|
+
* the edge redirects subsequent requests to a login page. Best-effort.
|
|
60618
|
+
*/
|
|
60619
|
+
async reapplyStoredContextRoutes() {
|
|
60620
|
+
if (this.storedContextRoutes.length === 0 || !this.context) return;
|
|
60621
|
+
try {
|
|
60622
|
+
await this.registerContextRoutes(this.storedContextRoutes, this.context);
|
|
60623
|
+
this.logger.info("[DirectPlaywright] Re-armed context routes on recreated context", {
|
|
60624
|
+
routeCount: this.storedContextRoutes.length
|
|
60625
|
+
});
|
|
60626
|
+
} catch (err) {
|
|
60627
|
+
this.logger.warn("[DirectPlaywright] Failed to re-arm context routes after recreation", {
|
|
60628
|
+
error: err instanceof Error ? err.message : String(err),
|
|
60629
|
+
routeCount: this.storedContextRoutes.length
|
|
60630
|
+
});
|
|
60631
|
+
}
|
|
60632
|
+
}
|
|
59740
60633
|
// ================ PRIVATE: Download Helpers ================
|
|
59741
60634
|
formatFileSize(bytes) {
|
|
59742
60635
|
return formatFileSize(bytes);
|
|
@@ -59929,6 +60822,16 @@ export {
|
|
|
59929
60822
|
guessMimeType,
|
|
59930
60823
|
captureElementAtPoint,
|
|
59931
60824
|
extractElementMetadata,
|
|
60825
|
+
CpuOffloadTimeoutError,
|
|
60826
|
+
CpuOffloadWorkerError,
|
|
60827
|
+
resolveCpuOffloadWorkerPath,
|
|
60828
|
+
CpuOffloadPool,
|
|
60829
|
+
DEFAULT_CPU_OFFLOAD_TIMEOUT_MS,
|
|
60830
|
+
defaultCpuOffloadSize,
|
|
60831
|
+
configureCpuOffload,
|
|
60832
|
+
isCpuOffloadEnabled,
|
|
60833
|
+
shutdownCpuOffload,
|
|
60834
|
+
formatSnapshotMaybeOffloaded,
|
|
59932
60835
|
ToolAbortedError,
|
|
59933
60836
|
isMCPContentWithImages,
|
|
59934
60837
|
coerceResultText,
|
|
@@ -60229,4 +61132,4 @@ playwright-extra/dist/index.esm.js:
|
|
|
60229
61132
|
* @license MIT
|
|
60230
61133
|
*)
|
|
60231
61134
|
*/
|
|
60232
|
-
//# sourceMappingURL=chunk-
|
|
61135
|
+
//# sourceMappingURL=chunk-7OO3RJYR.js.map
|