@wenathlan/extension 1.1.47 → 1.1.49

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.
@@ -2,7 +2,7 @@
2
2
  "manifest_version": 3,
3
3
  "key": "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAnOEjO8Z0PDgQyfvawGcaO2j+o0GLCFTLNj7TkYC/Avo9l2NenMRq7gp90Nfd7E9MViv/OMcCKSYZ5unv12QPRtv31C+a5UQWDFAOP/cH5mwMd6hsayElrSoW8ta+FwFqmr9dIFkn7cQEU3YhZr4Gcbs+ycUHOxVgDA4NBKB0rQ6e9VW5LvTw0isRYUrqM+M72vKxHk9zUIYYn/LGPvottKBYi2GLr0PHSeC2UE+Shmq7vcFIXj6hDjvD4kLJ5sKoUllEcZ1TPuBcnHUQ9ndKA5iktXDQOIJCUJmi7a0YJ2PGg7fvpYfT9k0ai/qZ+pIoRfoOEwE01bPoDn7NjeYnNQIDAQAB",
4
4
  "name": "Devthink",
5
- "version": "1.1.47",
5
+ "version": "1.1.49",
6
6
  "description": "A consent-first bridge for reviewed browser-agent tasks.",
7
7
  "permissions": [
8
8
  "activeTab",
@@ -32,6 +32,106 @@
32
32
  return { urlpattern, source };
33
33
  }
34
34
 
35
+ // emulation.ts
36
+ var browserpermissions = ["geolocation", "notifications", "camera", "microphone", "clipboard-read", "clipboard-write", "midi", "persistent-storage"];
37
+ var permissionstates = ["granted", "denied", "prompt"];
38
+ function familyofkind(kind) {
39
+ if (kind === "emulatedevice") return "device";
40
+ if (kind === "emulatenetwork") return "network";
41
+ if (kind === "emulatelocate") return "location";
42
+ if (kind === "setuseragent") return "agent";
43
+ if (kind === "overridepermission") return "permission";
44
+ if (kind === "blackboxscripts") return "blackbox";
45
+ return void 0;
46
+ }
47
+ function devicepresetof(value) {
48
+ if (!value || typeof value !== "object" || Array.isArray(value)) return void 0;
49
+ const entry = value;
50
+ const name = typeof entry.name === "string" && entry.name.trim() ? entry.name.trim() : void 0;
51
+ const width = typeof entry.width === "number" && Number.isInteger(entry.width) && entry.width > 0 ? entry.width : void 0;
52
+ const height = typeof entry.height === "number" && Number.isInteger(entry.height) && entry.height > 0 ? entry.height : void 0;
53
+ const pixelratio = typeof entry.pixelratio === "number" && Number.isFinite(entry.pixelratio) && entry.pixelratio > 0 ? entry.pixelratio : void 0;
54
+ if (name === void 0 || width === void 0 || height === void 0 || pixelratio === void 0) return void 0;
55
+ return { name, width, height, pixelratio, mobile: entry.mobile === true };
56
+ }
57
+ function networkpresetof(value) {
58
+ if (!value || typeof value !== "object" || Array.isArray(value)) return void 0;
59
+ const entry = value;
60
+ const name = typeof entry.name === "string" && entry.name.trim() ? entry.name.trim() : void 0;
61
+ const latency = typeof entry.latency === "number" && Number.isFinite(entry.latency) && entry.latency >= 0 ? entry.latency : void 0;
62
+ const download = typeof entry.download === "number" && Number.isFinite(entry.download) && entry.download >= 0 ? entry.download : void 0;
63
+ const upload = typeof entry.upload === "number" && Number.isFinite(entry.upload) && entry.upload >= 0 ? entry.upload : void 0;
64
+ if (name === void 0 || latency === void 0 || download === void 0 || upload === void 0) return void 0;
65
+ return { name, latency, download, upload, offline: entry.offline === true };
66
+ }
67
+ function locationpresetof(value) {
68
+ if (!value || typeof value !== "object" || Array.isArray(value)) return void 0;
69
+ const entry = value;
70
+ const name = typeof entry.name === "string" && entry.name.trim() ? entry.name.trim() : void 0;
71
+ const latitude = typeof entry.latitude === "number" && Number.isFinite(entry.latitude) ? entry.latitude : void 0;
72
+ const longitude = typeof entry.longitude === "number" && Number.isFinite(entry.longitude) ? entry.longitude : void 0;
73
+ const accuracy = typeof entry.accuracy === "number" && Number.isFinite(entry.accuracy) && entry.accuracy >= 0 ? entry.accuracy : void 0;
74
+ if (name === void 0 || latitude === void 0 || longitude === void 0 || accuracy === void 0) return void 0;
75
+ if (!locationrangevalid(latitude, longitude)) return void 0;
76
+ return { name, latitude, longitude, accuracy };
77
+ }
78
+ function agentpresetof(value) {
79
+ if (!value || typeof value !== "object" || Array.isArray(value)) return void 0;
80
+ const entry = value;
81
+ const name = typeof entry.name === "string" && entry.name.trim() ? entry.name.trim() : void 0;
82
+ const useragent = typeof entry.useragent === "string" ? entry.useragent : void 0;
83
+ const platform = typeof entry.platform === "string" && entry.platform.trim() ? entry.platform.trim() : void 0;
84
+ const brands = Array.isArray(entry.brands) ? entry.brands.filter((brand) => typeof brand === "string" && brand.trim().length > 0) : [];
85
+ if (name === void 0 || useragent === void 0 || platform === void 0 || brands.length === 0) return void 0;
86
+ if (!agentgrammarvalid(useragent)) return void 0;
87
+ return { name, useragent, platform, brands: [...new Set(brands)] };
88
+ }
89
+ function permissiongrantof(value) {
90
+ if (!value || typeof value !== "object" || Array.isArray(value)) return void 0;
91
+ const entry = value;
92
+ const name = typeof entry.name === "string" && browserpermissions.includes(entry.name) ? entry.name : void 0;
93
+ const state = typeof entry.state === "string" && permissionstates.includes(entry.state) ? entry.state : void 0;
94
+ if (name === void 0 || state === void 0) return void 0;
95
+ return { name, state, runscope: entry.runscope !== false };
96
+ }
97
+ function blackboxruleof(value) {
98
+ if (!value || typeof value !== "object" || Array.isArray(value)) return void 0;
99
+ const entry = value;
100
+ const urlpatterns = Array.isArray(entry.urlpatterns) ? entry.urlpatterns.filter((pattern) => typeof pattern === "string" && /^https:\/\//.test(pattern)) : [];
101
+ const tracescope = entry.tracescope;
102
+ if (urlpatterns.length === 0) return void 0;
103
+ if (tracescope !== "profiles" && tracescope !== "traces" && tracescope !== "both") return void 0;
104
+ return { urlpatterns: [...new Set(urlpatterns)], tracescope };
105
+ }
106
+ function locationrangevalid(latitude, longitude) {
107
+ return Number.isFinite(latitude) && Number.isFinite(longitude) && latitude >= -90 && latitude <= 90 && longitude >= -180 && longitude <= 180;
108
+ }
109
+ function agentgrammarvalid(useragent) {
110
+ const text = useragent.trim();
111
+ if (text.length === 0 || text.length > 512) return false;
112
+ if (/[\r\n]/.test(text)) return false;
113
+ if (!/^[A-Za-z0-9][A-Za-z0-9._+\-()/:; ,]*$/.test(text)) return false;
114
+ return /\/\d/.test(text) || /\d+\.\d+/.test(text);
115
+ }
116
+ function blackboxmatches(urlpattern, url) {
117
+ const patternmatch = /^(https:\/\/[^/]+)(\/.*)?$/.exec(urlpattern);
118
+ const urlmatch = /^(https:\/\/[^/]+)(\/.*)?$/.exec(url);
119
+ if (!patternmatch || !urlmatch) return false;
120
+ if (patternmatch[1] !== urlmatch[1]) return false;
121
+ const patternpath = (patternmatch[2] ?? "/").split("/").filter((segment) => segment.length > 0);
122
+ const urlpath = (urlmatch[2] ?? "/").split("/").filter((segment) => segment.length > 0);
123
+ const walk = (patternindex, urlindex) => {
124
+ if (patternindex >= patternpath.length) return urlindex >= urlpath.length;
125
+ const segment = patternpath[patternindex];
126
+ if (segment === void 0) return false;
127
+ if (segment === "**") return walk(patternindex + 1, urlindex) || urlindex < urlpath.length && walk(patternindex, urlindex + 1);
128
+ if (urlindex >= urlpath.length) return false;
129
+ if (segment !== "*" && segment !== urlpath[urlindex]) return false;
130
+ return walk(patternindex + 1, urlindex + 1);
131
+ };
132
+ return walk(0, 0);
133
+ }
134
+
35
135
  // runtimeline.ts
36
136
  var loglevels = ["error", "warn", "info", "log", "debug", "trace"];
37
137
  function levelrank(level) {
@@ -120,9 +220,9 @@
120
220
  }
121
221
 
122
222
  // policy.ts
123
- var sensitiveactions = /* @__PURE__ */ new Set(["click", "type", "navigate", "select", "presskey", "drag", "drop", "upload", "clear", "check", "uncheck", "toggle", "submit", "reload", "back", "forward", "writestorage", "setattribute", "removeattribute", "evaluate", "tabcreate", "tabactivate", "tabclose", "tabreload", "windowcreate", "windowclose", "windowresize", "downloadfile", "clickpoint", "shiftclick", "dismissdialog", "enterframe", "typetime", "appendtext", "setvalue", "typeedit", "keyhold", "keyrelease", "submitsearch", "selectmulti", "chooseradio", "setslider", "setdate", "setcolor", "openlink", "openprivate", "reloadcache", "stopnav", "followlink", "spanav", "rewritequery", "setfragment", "navlist", "navprofile", "handleauth", "printpdf", "prefetch", "preconnect", "deeplink", "reopentab", "pausenav", "navrate", "openclipboard", "batchopen", "duplicatetab", "closepattern", "pintab", "mutetab", "movetab", "movetabwindow", "grouptabs", "colorgroup", "collapsegroup", "discardtab", "reloadtabs", "zoomin", "zoomout", "switchtab", "maximizewindow", "minimizewindow", "restorewindow", "focuswindow", "scratchwindow", "incognitowindow", "restoretab", "restorelayout", "reopenrun", "badgetab", "fillform", "filllabel", "fillplaceholder", "submitform", "retryform", "runwizard", "selectchain", "picktypeahead", "pickdate", "attachfile", "fillcard", "fillcode", "consentpassword", "exportcsv", "exportjson", "exportexcel", "copytable", "pushsheets", "streamdisk", "paginateextract", "resumeextract", "batchdownload", "pausedownload", "resumedownload", "interceptmime", "readclipboard", "writeclipboard", "copyscreen", "quarantinedownload", "scanvirus", "cleanupartifacts", "recordscreen", "captureaudio", "downloadimages", "callrest", "callgraphql", "sendmessage", "blockrequest", "mockresponse", "rewriteheaders", "setcookies", "clearcookies", "authflow", "saveapikey", "routeproxy", "postform", "postfiles", "attachcdp", "detachcdp", "cdpcmd", "overridescript", "heapshot", "profilecpu", "capturesourcemaps"]);
223
+ var sensitiveactions = /* @__PURE__ */ new Set(["click", "type", "navigate", "select", "presskey", "drag", "drop", "upload", "clear", "check", "uncheck", "toggle", "submit", "reload", "back", "forward", "writestorage", "setattribute", "removeattribute", "evaluate", "tabcreate", "tabactivate", "tabclose", "tabreload", "windowcreate", "windowclose", "windowresize", "downloadfile", "clickpoint", "shiftclick", "dismissdialog", "enterframe", "typetime", "appendtext", "setvalue", "typeedit", "keyhold", "keyrelease", "submitsearch", "selectmulti", "chooseradio", "setslider", "setdate", "setcolor", "openlink", "openprivate", "reloadcache", "stopnav", "followlink", "spanav", "rewritequery", "setfragment", "navlist", "navprofile", "handleauth", "printpdf", "prefetch", "preconnect", "deeplink", "reopentab", "pausenav", "navrate", "openclipboard", "batchopen", "duplicatetab", "closepattern", "pintab", "mutetab", "movetab", "movetabwindow", "grouptabs", "colorgroup", "collapsegroup", "discardtab", "reloadtabs", "zoomin", "zoomout", "switchtab", "maximizewindow", "minimizewindow", "restorewindow", "focuswindow", "scratchwindow", "incognitowindow", "restoretab", "restorelayout", "reopenrun", "badgetab", "fillform", "filllabel", "fillplaceholder", "submitform", "retryform", "runwizard", "selectchain", "picktypeahead", "pickdate", "attachfile", "fillcard", "fillcode", "consentpassword", "exportcsv", "exportjson", "exportexcel", "copytable", "pushsheets", "streamdisk", "paginateextract", "resumeextract", "batchdownload", "pausedownload", "resumedownload", "interceptmime", "readclipboard", "writeclipboard", "copyscreen", "quarantinedownload", "scanvirus", "cleanupartifacts", "recordscreen", "captureaudio", "downloadimages", "callrest", "callgraphql", "sendmessage", "blockrequest", "mockresponse", "rewriteheaders", "setcookies", "clearcookies", "authflow", "saveapikey", "routeproxy", "postform", "postfiles", "attachcdp", "detachcdp", "cdpcmd", "overridescript", "heapshot", "profilecpu", "capturesourcemaps", "emulatedevice", "emulatenetwork", "emulatelocate", "setuseragent", "overridepermission", "restoresession", "exportsessions", "importsessions"]);
124
224
  var interactionactions = /* @__PURE__ */ new Set(["focus", "scroll", "hover", "clickdeep", "rightclick", "doubleclick", "scrollpage", "scrollby", "scrollend", "scrolltop", "fullscreen", "zoomset", "movepointer", "clicktext", "clickaria", "clickname", "expanddetails", "pierceshadow", "retryaction", "capturebodies", "setbreakpoint", "stepcode", "watchexpr"]);
125
- var readactions = /* @__PURE__ */ new Set(["observe", "inspect", "extract", "wait", "waitfor", "waittext", "readattribute", "readstyle", "readgeometry", "readvalue", "readtext", "readhtml", "countelements", "readtable", "readlinks", "readimages", "readmeta", "readforms", "readstorage", "highlight", "tablist", "windowlist", "tabsnapshot", "mapclicks", "verifyvisible", "verifyenabled", "resolvexpath", "a11ytree", "readvisible", "readertree", "detectlists", "detecttables", "readjson", "watchmutate", "waitquiet", "watchbanner", "detectinfinitescroll", "detectvirtual", "detectlazy", "readscrollpos", "readlang", "readoutline", "countpages", "listshadow", "listframes", "classifypage", "fingerprintsection", "diffsnapshots", "readselection", "watchfocus", "detectsticky", "detectscrolllock", "readopengraph", "detectlanguage", "deriveselector", "waitload", "waiturl", "spawait", "detecthttp", "readredirects", "readfinalurl", "trailaudit", "navintent", "checksafe", "querytabs", "watchtab", "findclones", "searchtabs", "listaudio", "snapshotsession", "savelayout", "attachmeta", "detectfields", "generatevalues", "saveprofiles", "asksubmit", "readerrors", "skiphoneypot", "detectlogin", "detecttemplate", "handoffcaptcha", "scrapetable", "importcsv", "looprows", "transformvalues", "deduperows", "mergepages", "stamplerows", "previewgrid", "logprovenance", "verifydownload", "exportnetlog", "namecaptures", "shotview", "shotfullpage", "shotelement", "shotregion", "contactsheet", "capturepdf", "captureframe", "readmedia", "readassets", "probestream", "timelapse", "shotcanvas", "convertimage", "makethumbs", "fetchurl", "parsejson", "parsehtml", "opensocket", "waitmessage", "watchrequests", "readheaders", "mapapi", "subscribesse", "longpoll", "extractapi", "readcookies", "watchconsole", "watcherrors", "watchtasks", "watchcdp", "measureflow", "trackmemory", "watchshifts", "traceload", "annotatetrace", "replaytrace"]);
225
+ var readactions = /* @__PURE__ */ new Set(["observe", "inspect", "extract", "wait", "waitfor", "waittext", "readattribute", "readstyle", "readgeometry", "readvalue", "readtext", "readhtml", "countelements", "readtable", "readlinks", "readimages", "readmeta", "readforms", "readstorage", "highlight", "tablist", "windowlist", "tabsnapshot", "mapclicks", "verifyvisible", "verifyenabled", "resolvexpath", "a11ytree", "readvisible", "readertree", "detectlists", "detecttables", "readjson", "watchmutate", "waitquiet", "watchbanner", "detectinfinitescroll", "detectvirtual", "detectlazy", "readscrollpos", "readlang", "readoutline", "countpages", "listshadow", "listframes", "classifypage", "fingerprintsection", "diffsnapshots", "readselection", "watchfocus", "detectsticky", "detectscrolllock", "readopengraph", "detectlanguage", "deriveselector", "waitload", "waiturl", "spawait", "detecthttp", "readredirects", "readfinalurl", "trailaudit", "navintent", "checksafe", "querytabs", "watchtab", "findclones", "searchtabs", "listaudio", "snapshotsession", "savelayout", "attachmeta", "detectfields", "generatevalues", "saveprofiles", "asksubmit", "readerrors", "skiphoneypot", "detectlogin", "detecttemplate", "handoffcaptcha", "scrapetable", "importcsv", "looprows", "transformvalues", "deduperows", "mergepages", "stamplerows", "previewgrid", "logprovenance", "verifydownload", "exportnetlog", "namecaptures", "shotview", "shotfullpage", "shotelement", "shotregion", "contactsheet", "capturepdf", "captureframe", "readmedia", "readassets", "probestream", "timelapse", "shotcanvas", "convertimage", "makethumbs", "fetchurl", "parsejson", "parsehtml", "opensocket", "waitmessage", "watchrequests", "readheaders", "mapapi", "subscribesse", "longpoll", "extractapi", "readcookies", "watchconsole", "watcherrors", "watchtasks", "watchcdp", "measureflow", "trackmemory", "watchshifts", "traceload", "annotatetrace", "replaytrace", "blackboxscripts", "persiststate", "capturesession", "namedsessions", "diffsessions", "searchsessions"]);
126
226
  var allowedactions = /* @__PURE__ */ new Set([...sensitiveactions, ...interactionactions, ...readactions]);
127
227
  function parseoptions(step) {
128
228
  if (step.options === void 0) return {};
@@ -2477,6 +2577,185 @@
2477
2577
  }
2478
2578
  }
2479
2579
 
2580
+ // extension/pageemulate.ts
2581
+ function registry() {
2582
+ const holder = globalThis;
2583
+ if (holder.devthinkemulation === void 0) holder.devthinkemulation = {};
2584
+ return holder.devthinkemulation;
2585
+ }
2586
+ function priorsnapshot(family) {
2587
+ if (family === "device") return { pixelratio: window.devicePixelRatio, viewportwidth: window.innerWidth, viewportheight: window.innerHeight };
2588
+ if (family === "agent") return { useragent: navigator.userAgent, platform: navigator.platform };
2589
+ if (family === "permission") return { note: "the browser permission state stays untouched and the override restores by removing the page-side answer" };
2590
+ return { note: "the layer adds no prior page state to restore" };
2591
+ }
2592
+ function applydevice(width, height, pixelratio, mobile) {
2593
+ const state = registry();
2594
+ if (state.pixelratio === void 0) state.pixelratio = window.devicePixelRatio;
2595
+ Object.defineProperty(window, "devicePixelRatio", { configurable: true, get: () => pixelratio });
2596
+ document.documentElement.dataset.devthinkMobile = mobile ? "true" : "false";
2597
+ document.documentElement.dataset.devthinkViewport = `${width}x${height}`;
2598
+ }
2599
+ function revertdevice(prior) {
2600
+ const state = registry();
2601
+ const restored = typeof prior?.pixelratio === "number" ? prior.pixelratio : state.pixelratio ?? window.devicePixelRatio;
2602
+ Object.defineProperty(window, "devicePixelRatio", { configurable: true, get: () => restored });
2603
+ delete document.documentElement.dataset.devthinkMobile;
2604
+ delete document.documentElement.dataset.devthinkViewport;
2605
+ delete state.pixelratio;
2606
+ }
2607
+ function applylocation(latitude, longitude, accuracy) {
2608
+ const state = registry();
2609
+ if (state.geolocation === void 0) state.geolocation = navigator.geolocation;
2610
+ const position = () => ({
2611
+ coords: { latitude, longitude, accuracy, altitude: null, altitudeAccuracy: null, heading: null, speed: null },
2612
+ timestamp: Date.now()
2613
+ });
2614
+ const overridden = {
2615
+ getCurrentPosition: (success) => {
2616
+ success(position());
2617
+ },
2618
+ watchPosition: (success) => {
2619
+ success(position());
2620
+ return 0;
2621
+ },
2622
+ clearWatch: () => {
2623
+ }
2624
+ };
2625
+ Object.defineProperty(navigator, "geolocation", { configurable: true, get: () => overridden });
2626
+ }
2627
+ function revertlocation() {
2628
+ const state = registry();
2629
+ if (state.geolocation !== void 0) Object.defineProperty(navigator, "geolocation", { configurable: true, get: () => state.geolocation });
2630
+ delete state.geolocation;
2631
+ }
2632
+ function applyagent(useragent, platform, brands) {
2633
+ const state = registry();
2634
+ if (state.useragent === void 0) state.useragent = navigator.userAgent;
2635
+ if (state.platform === void 0) state.platform = navigator.platform;
2636
+ if (state.brands === void 0) state.brands = brands;
2637
+ Object.defineProperty(navigator, "userAgent", { configurable: true, get: () => useragent });
2638
+ Object.defineProperty(navigator, "platform", { configurable: true, get: () => platform });
2639
+ const branded = brands.map((brand, index) => ({ brand, version: `${index + 1}.0.0.0` }));
2640
+ const dataholder = navigator;
2641
+ if (dataholder.userAgentData !== void 0) Object.defineProperty(dataholder, "userAgentData", { configurable: true, get: () => ({ brands: branded }) });
2642
+ }
2643
+ function revertagent(prior) {
2644
+ const state = registry();
2645
+ const useragent = typeof prior?.useragent === "string" ? prior.useragent : state.useragent ?? navigator.userAgent;
2646
+ const platform = typeof prior?.platform === "string" ? prior.platform : state.platform ?? navigator.platform;
2647
+ Object.defineProperty(navigator, "userAgent", { configurable: true, get: () => useragent });
2648
+ Object.defineProperty(navigator, "platform", { configurable: true, get: () => platform });
2649
+ delete state.useragent;
2650
+ delete state.platform;
2651
+ delete state.brands;
2652
+ }
2653
+ function applypermission(name, state) {
2654
+ const holder = navigator;
2655
+ if (holder.devthinkpermission === void 0) holder.devthinkpermission = {};
2656
+ holder.devthinkpermission[name] = state;
2657
+ const state0 = registry();
2658
+ if (state0.permissions === void 0 && navigator.permissions !== void 0) state0.permissions = navigator.permissions;
2659
+ if (navigator.permissions === void 0) return;
2660
+ const overridden = {
2661
+ query: (description) => new Promise((resolve) => {
2662
+ const applied = holder.devthinkpermission?.[description.name];
2663
+ resolve({ state: applied ?? "prompt", name: description.name, onchange: null });
2664
+ })
2665
+ };
2666
+ Object.defineProperty(navigator, "permissions", { configurable: true, get: () => overridden });
2667
+ }
2668
+ function revertpermission() {
2669
+ const state = registry();
2670
+ if (state.permissions !== void 0) Object.defineProperty(navigator, "permissions", { configurable: true, get: () => state.permissions });
2671
+ delete state.permissions;
2672
+ delete navigator.devthinkpermission;
2673
+ }
2674
+ function applyblackbox(patterns) {
2675
+ registry().blackbox = patterns;
2676
+ }
2677
+ function activeblackboxpatterns() {
2678
+ return registry().blackbox ?? [];
2679
+ }
2680
+ async function runemulationstep(step) {
2681
+ const options = (() => {
2682
+ try {
2683
+ return parseoptions(step);
2684
+ } catch {
2685
+ return {};
2686
+ }
2687
+ })();
2688
+ const family = familyofkind(step.kind);
2689
+ const derivation = "The mask is a page-injected override through the scripting api; the browser device metrics, network stack, true location, request headers and permission state stay untouched because no debugger or platform permission exists in the manifest.";
2690
+ if (step.kind === "emulatedevice") {
2691
+ const preset = devicepresetof(options.device);
2692
+ if (!preset) return { ok: false, summary: "The reviewed device preset is absent or malformed." };
2693
+ const prior = priorsnapshot("device");
2694
+ applydevice(preset.width, preset.height, preset.pixelratio, preset.mobile);
2695
+ return { ok: true, summary: `Applied the device preset ${preset.name} of ${preset.width} by ${preset.height} css pixels, pixel ratio ${preset.pixelratio} and the ${preset.mobile ? "mobile" : "desktop"} hint to the run tab.`, details: { prior, preset: { name: preset.name, width: preset.width, height: preset.height, pixelratio: preset.pixelratio, mobile: preset.mobile }, derivation } };
2696
+ }
2697
+ if (step.kind === "emulatenetwork") {
2698
+ const preset = networkpresetof(options.network);
2699
+ if (!preset) return { ok: false, summary: "The reviewed network preset is absent or malformed." };
2700
+ const window0 = typeof options.window === "number" ? options.window : void 0;
2701
+ return { ok: true, summary: `Applied the network preset ${preset.name} with ${preset.latency} milliseconds latency, ${preset.download} and ${preset.upload} kilobit per second bounds${preset.offline ? ` and the offline flag${window0 !== void 0 ? ` for the reviewed window of ${window0} milliseconds` : ""}` : ""}; the bounds shape the traffic the extension itself initiates.`, details: { preset: { name: preset.name, latency: preset.latency, download: preset.download, upload: preset.upload, offline: preset.offline }, ...window0 !== void 0 ? { window: window0 } : {}, derivation } };
2702
+ }
2703
+ if (step.kind === "emulatelocate") {
2704
+ const preset = locationpresetof(options.location);
2705
+ if (!preset) return { ok: false, summary: "The reviewed location preset is absent or malformed." };
2706
+ applylocation(preset.latitude, preset.longitude, preset.accuracy);
2707
+ return { ok: true, summary: `Applied the location preset ${preset.name} of ${preset.latitude}, ${preset.longitude} with the ${preset.accuracy} meter accuracy radius to the run tab.`, details: { preset: { name: preset.name, latitude: preset.latitude, longitude: preset.longitude, accuracy: preset.accuracy }, derivation } };
2708
+ }
2709
+ if (step.kind === "setuseragent") {
2710
+ const preset = agentpresetof(options.agent);
2711
+ if (!preset) return { ok: false, summary: "The reviewed agent preset is absent or malformed." };
2712
+ const prior = priorsnapshot("agent");
2713
+ applyagent(preset.useragent, preset.platform, preset.brands);
2714
+ return { ok: true, summary: `Applied the agent preset ${preset.name} with the reviewed user agent string, platform ${preset.platform} and ${preset.brands.length} brand${preset.brands.length === 1 ? "" : "s"} together, scoped to the run tab only.`, details: { prior, preset: { name: preset.name, platform: preset.platform, brands: preset.brands }, derivation } };
2715
+ }
2716
+ if (step.kind === "overridepermission") {
2717
+ const grant = permissiongrantof(options.permission);
2718
+ if (!grant) return { ok: false, summary: "The reviewed permission override is absent or malformed." };
2719
+ const prior = priorsnapshot("permission");
2720
+ applypermission(grant.name, grant.state);
2721
+ return { ok: true, summary: `Answered the ${grant.name} permission queries of the run tab with the reviewed ${grant.state} state${grant.runscope ? " for the run scope" : ""}; the browser permission itself stays untouched.`, details: { prior, permission: { name: grant.name, state: grant.state, runscope: grant.runscope }, derivation } };
2722
+ }
2723
+ if (step.kind === "blackboxscripts") {
2724
+ const rules = (Array.isArray(options.rules) ? options.rules : []).flatMap((rule) => {
2725
+ const parsed = blackboxruleof(rule);
2726
+ return parsed !== void 0 ? [parsed] : [];
2727
+ });
2728
+ if (rules.length === 0) return { ok: false, summary: "The reviewed blackbox rule list is absent or malformed." };
2729
+ applyblackbox(rules.flatMap((rule) => rule.urlpatterns));
2730
+ return { ok: true, summary: `Marked ${rules.flatMap((rule) => rule.urlpatterns).length} third party url pattern${rules.flatMap((rule) => rule.urlpatterns).length === 1 ? "" : "s"} as blackboxed in the traces of the run; the rules read no page state.`, details: { rules, derivation: "Blackbox rules shape stack traces and profiles of the run only; they read no page state and touch no third party script." } };
2731
+ }
2732
+ void family;
2733
+ return { ok: false, summary: "The emulation step is not part of the mask family." };
2734
+ }
2735
+ function revertemulationlayer(family, prior) {
2736
+ if (family === "device") {
2737
+ revertdevice(prior);
2738
+ return { ok: true, summary: "Restored the prior pixel ratio and cleared the device hint of the run tab." };
2739
+ }
2740
+ if (family === "location") {
2741
+ revertlocation();
2742
+ return { ok: true, summary: "Restored the true navigator geolocation of the run tab." };
2743
+ }
2744
+ if (family === "agent") {
2745
+ revertagent(prior);
2746
+ return { ok: true, summary: "Restored the true navigator user agent, platform and brand list of the run tab." };
2747
+ }
2748
+ if (family === "permission") {
2749
+ revertpermission();
2750
+ return { ok: true, summary: "Removed the page-side permission answers so the browser permission state returns." };
2751
+ }
2752
+ if (family === "blackbox") {
2753
+ delete registry().blackbox;
2754
+ return { ok: true, summary: "Removed the blackbox pattern registry of the run." };
2755
+ }
2756
+ return { ok: true, summary: "The network layer holds no page state to restore; the transport bounds ended with the run." };
2757
+ }
2758
+
2480
2759
  // extension/pagedebug.ts
2481
2760
  var harnesskey = "__devthinkcdp";
2482
2761
  function readharness() {
@@ -2736,14 +3015,16 @@
2736
3015
  }
2737
3016
  }
2738
3017
  if (step.kind === "watcherrors") {
3018
+ const blackbox = activeblackboxpatterns();
3019
+ const hideframes = (record) => ({ ...record, frames: record.frames.filter((frame) => !blackbox.some((pattern) => blackboxmatches(pattern, frame.url))) });
2739
3020
  const onerror = (event) => {
2740
- const record = errorcapture({ message: event.message, sourceurl: event.filename, line: event.lineno, ...event.error instanceof Error ? { stacktext: event.error.stack } : {}, redact: options.redact });
3021
+ const record = hideframes(errorcapture({ message: event.message, sourceurl: event.filename, line: event.lineno, ...event.error instanceof Error ? { stacktext: event.error.stack } : {}, redact: options.redact }));
2741
3022
  errors.push({ ...record, stepid: step.id, at: Date.now() });
2742
3023
  capture("error", "error", record.message, Date.now());
2743
3024
  };
2744
3025
  const onrejection = (event) => {
2745
3026
  const reason = event.reason instanceof Error ? `${event.reason.name}: ${event.reason.message}` : String(event.reason);
2746
- const record = rejectioncapture({ reason, ...event.reason instanceof Error ? { stacktext: event.reason.stack } : {}, redact: options.redact });
3027
+ const record = hideframes(rejectioncapture({ reason, ...event.reason instanceof Error ? { stacktext: event.reason.stack } : {}, redact: options.redact }));
2747
3028
  rejections.push({ ...record, stepid: step.id, at: Date.now() });
2748
3029
  capture("error", "rejection", record.reason, Date.now());
2749
3030
  };
@@ -3800,6 +4081,7 @@
3800
4081
  var debugstepkinds = /* @__PURE__ */ new Set(["watchconsole", "watcherrors", "watchtasks"]);
3801
4082
  var cdpstepkinds = /* @__PURE__ */ new Set(["attachcdp", "detachcdp", "cdpcmd", "watchcdp", "setbreakpoint", "stepcode", "watchexpr", "overridescript"]);
3802
4083
  var profilestepkinds = /* @__PURE__ */ new Set(["measureflow", "heapshot", "trackmemory", "profilecpu", "watchshifts", "traceload", "capturesourcemaps"]);
4084
+ var emulationstepkinds = /* @__PURE__ */ new Set(["emulatedevice", "emulatenetwork", "emulatelocate", "setuseragent", "overridepermission", "blackboxscripts"]);
3803
4085
  var navstepkinds = /* @__PURE__ */ new Set(["waitload", "waiturl", "followlink", "spanav", "spawait", "rewritequery", "setfragment", "stopnav", "prefetch", "preconnect", "printpdf"]);
3804
4086
  var formkinds = /* @__PURE__ */ new Set(["fillform", "filllabel", "fillplaceholder", "detectfields", "generatevalues", "readerrors", "skiphoneypot", "detectlogin", "detecttemplate", "handoffcaptcha", "asksubmit", "submitform", "consentpassword", "attachfile"]);
3805
4087
  var wizardkinds = /* @__PURE__ */ new Set(["runwizard", "selectchain", "picktypeahead", "pickdate", "fillcard", "fillcode"]);
@@ -3868,6 +4150,7 @@
3868
4150
  else if (debugstepkinds.has(step.kind)) return await rundebugwatch(step);
3869
4151
  else if (cdpstepkinds.has(step.kind)) return await runcdpstep(step);
3870
4152
  else if (profilestepkinds.has(step.kind)) return await runprofilestep(step);
4153
+ else if (emulationstepkinds.has(step.kind)) return await runemulationstep(step);
3871
4154
  else if (mutatingkinds.has(step.kind)) result = runpageaction(step, element);
3872
4155
  else {
3873
4156
  if (!element) return { ok: false, summary: "Action target is no longer available." };
@@ -4189,6 +4472,6 @@
4189
4472
  for (const cookie of targets) document.cookie = `${cookie.name}=; path=/; expires=Thu, 01 Jan 1970 00:00:00 GMT`;
4190
4473
  return { cleared: targets.length, summary: `Cleared ${targets.length} cookie${targets.length === 1 ? "" : "s"} through the page cookie jar of ${location.origin}.` };
4191
4474
  }
4192
- Object.assign(globalThis, { devthinkbridge: { capturesnapshot, previewtarget, performstep, readdialogs, measurepage, elementrect, preparecapture, scrollcapture, restorecapture, scrollcontainercapture, waitsettle, pdfsegment, pdfbreaks, videoframe, canvasdata, streamelements, mediaelements, pageassets, pageimages, parsehtmlmarkup, resourcerecords, writecookies, readcookies, clearcookies } });
4475
+ Object.assign(globalThis, { devthinkbridge: { capturesnapshot, previewtarget, performstep, readdialogs, measurepage, elementrect, preparecapture, scrollcapture, restorecapture, scrollcontainercapture, waitsettle, pdfsegment, pdfbreaks, videoframe, canvasdata, streamelements, mediaelements, pageassets, pageimages, parsehtmlmarkup, resourcerecords, writecookies, readcookies, clearcookies, revertemulationlayer } });
4193
4476
  })();
4194
4477
  //# sourceMappingURL=pagebridge.js.map