@wenathlan/extension 1.1.44 → 1.1.45

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/index.js CHANGED
@@ -1828,6 +1828,103 @@ var sessionmemory = class {
1828
1828
  if (live.length !== records.length) await this.adapter.set("ratelimits", live);
1829
1829
  return live;
1830
1830
  }
1831
+ /** Stores one run timeline entry; the user configured timeline retention window expires the oldest entries while their level counts survive in the per run level summaries. */
1832
+ async addtimelineentry(entry) {
1833
+ const records = await this.gettimeline();
1834
+ const combined = [entry, ...records];
1835
+ const retention = (await this.getsettings())?.timelineretention;
1836
+ if (retention === void 0) {
1837
+ await this.adapter.set("timelineentries", combined);
1838
+ return;
1839
+ }
1840
+ const kept = combined.slice(0, retention);
1841
+ const expired = combined.slice(retention);
1842
+ if (expired.length > 0) {
1843
+ const expiredcounts = /* @__PURE__ */ new Map();
1844
+ for (const item of expired) {
1845
+ const counts = expiredcounts.get(item.runid) ?? {};
1846
+ counts[item.level] = (counts[item.level] ?? 0) + 1;
1847
+ expiredcounts.set(item.runid, counts);
1848
+ }
1849
+ for (const [runid, counts] of expiredcounts) await this.mergelevelsummary(runid, counts, Date.now());
1850
+ }
1851
+ await this.adapter.set("timelineentries", kept);
1852
+ }
1853
+ /** Returns every stored run timeline entry, newest first. */
1854
+ async gettimeline() {
1855
+ return await this.adapter.get("timelineentries") ?? [];
1856
+ }
1857
+ /** Returns the run timeline entries filtered by run, level and step id. */
1858
+ async listtimeline(filter) {
1859
+ const records = await this.gettimeline();
1860
+ return records.filter((item) => (filter.runid === void 0 || item.runid === filter.runid) && (filter.level === void 0 || item.level === filter.level) && (filter.stepid === void 0 || item.stepid === filter.stepid));
1861
+ }
1862
+ /** Stores one captured javascript error record with its stack frames, source url and line. */
1863
+ async adderrorrecord(record2) {
1864
+ const records = await this.adapter.get("errorrecords") ?? [];
1865
+ await this.adapter.set("errorrecords", [record2, ...records]);
1866
+ }
1867
+ /** Returns every stored error record, newest first. */
1868
+ async geterrorrecords() {
1869
+ return await this.adapter.get("errorrecords") ?? [];
1870
+ }
1871
+ /** Stores one captured unhandled rejection record with its reason and stack frames. */
1872
+ async addrejectionrecord(record2) {
1873
+ const records = await this.adapter.get("rejectionrecords") ?? [];
1874
+ await this.adapter.set("rejectionrecords", [record2, ...records]);
1875
+ }
1876
+ /** Returns every stored rejection record, newest first. */
1877
+ async getrejectionrecords() {
1878
+ return await this.adapter.get("rejectionrecords") ?? [];
1879
+ }
1880
+ /** Stores one captured long task entry with its duration, start time and attribution names. */
1881
+ async addlongtask(record2) {
1882
+ const records = await this.adapter.get("longtasks") ?? [];
1883
+ await this.adapter.set("longtasks", [record2, ...records]);
1884
+ }
1885
+ /** Returns every stored long task entry, newest first. */
1886
+ async getlongtasks() {
1887
+ return await this.adapter.get("longtasks") ?? [];
1888
+ }
1889
+ /** Stores one console diff result between two runs, replacing the previous one. */
1890
+ async addconsolediff(diff) {
1891
+ return this.adapter.set("consolediff", diff);
1892
+ }
1893
+ /** Returns the one stored console diff result. */
1894
+ async getdiff() {
1895
+ return this.adapter.get("consolediff");
1896
+ }
1897
+ /** Stores one log rotation target record with its overflow entry counts, replacing the previous record of that target and run. */
1898
+ async addrotationtarget(record2) {
1899
+ const records = (await this.adapter.get("rotationtargets") ?? []).filter((item) => !(item.target === record2.target && item.runid === record2.runid));
1900
+ await this.adapter.set("rotationtargets", [record2, ...records]);
1901
+ }
1902
+ /** Returns every stored rotation target record with its overflow entry counts, newest first. */
1903
+ async getrotationtargets() {
1904
+ return await this.adapter.get("rotationtargets") ?? [];
1905
+ }
1906
+ /** Stores one console capture consent decision per origin; the approved decision persists so console watching on that origin prompts once. */
1907
+ async setconsoleconsent(consent) {
1908
+ const records = (await this.adapter.get("consoleconsents") ?? []).filter((item) => item.id !== consent.id);
1909
+ await this.adapter.set("consoleconsents", [consent, ...records]);
1910
+ }
1911
+ /** Returns every console capture consent decision, newest first. */
1912
+ async getconsoleconsents() {
1913
+ return await this.adapter.get("consoleconsents") ?? [];
1914
+ }
1915
+ /** Merges expired entry counts into the per run level count summary that survives the retention window. */
1916
+ async mergelevelsummary(runid, counts, now) {
1917
+ const records = await this.getlevelsummaries();
1918
+ const existing = records.find((item) => item.runid === runid);
1919
+ const merged = { ...existing?.counts ?? {} };
1920
+ for (const [level, count] of Object.entries(counts)) merged[level] = (merged[level] ?? 0) + count;
1921
+ const updated = { runid, counts: merged, at: now };
1922
+ await this.adapter.set("levelsummaries", [updated, ...records.filter((item) => item.runid !== runid)]);
1923
+ }
1924
+ /** Returns every per run level count summary, newest first. */
1925
+ async getlevelsummaries() {
1926
+ return await this.adapter.get("levelsummaries") ?? [];
1927
+ }
1831
1928
  };
1832
1929
  function mediakindof(record2) {
1833
1930
  if ("pages" in record2) return "pdf";
@@ -2364,6 +2461,195 @@ function extractvalues(body, paths) {
2364
2461
  return fields.map((field) => ({ path: field.path, ...field.value !== void 0 ? { value: field.value } : {}, ...field.missing ? { missing: true } : {} }));
2365
2462
  }
2366
2463
 
2464
+ // runtimeline.ts
2465
+ var timelinekinds = ["watchconsole", "watcherrors", "watchtasks"];
2466
+ var loglevels = ["error", "warn", "info", "log", "debug", "trace"];
2467
+ var timelinesources = ["console", "error", "rejection", "resource", "longtask", "network"];
2468
+ function levelrank(level) {
2469
+ return loglevels.indexOf(level);
2470
+ }
2471
+ function redactconsoletext(text2, patterns) {
2472
+ let redacted = text2;
2473
+ for (const pattern of patterns) {
2474
+ if (!pattern) continue;
2475
+ while (redacted.includes(pattern)) redacted = redacted.replace(pattern, "[redacted]");
2476
+ }
2477
+ return redacted;
2478
+ }
2479
+ function argkind(value) {
2480
+ if (value === null) return "null";
2481
+ if (Array.isArray(value)) return "array";
2482
+ if (value instanceof Error) return "error";
2483
+ switch (typeof value) {
2484
+ case "string":
2485
+ return "string";
2486
+ case "number":
2487
+ return "number";
2488
+ case "boolean":
2489
+ return "boolean";
2490
+ case "bigint":
2491
+ return "bigint";
2492
+ case "symbol":
2493
+ return "symbol";
2494
+ case "function":
2495
+ return "function";
2496
+ case "undefined":
2497
+ return "undefined";
2498
+ default:
2499
+ return "object";
2500
+ }
2501
+ }
2502
+ function serializearg(value, depth) {
2503
+ const render = (item, remaining) => {
2504
+ if (item instanceof Error) return `${item.name}: ${item.message}`;
2505
+ if (typeof item === "string") return item;
2506
+ if (typeof item === "function") return `[function ${item.name || "anonymous"}]`;
2507
+ if (typeof item === "bigint") return `${item}n`;
2508
+ if (typeof item === "symbol") return item.toString();
2509
+ if (item === null || item === void 0 || typeof item !== "object") return String(item);
2510
+ if (remaining <= 0) {
2511
+ const tag = Array.isArray(item) ? "Array" : item.constructor?.name ?? "Object";
2512
+ return `[${tag}]`;
2513
+ }
2514
+ if (Array.isArray(item)) return `[${item.map((entry) => render(entry, remaining - 1)).join(", ")}]`;
2515
+ const record2 = item;
2516
+ return `{${Object.keys(record2).map((key) => `${key}: ${render(record2[key], remaining - 1)}`).join(", ")}}`;
2517
+ };
2518
+ return render(value, Math.max(0, depth));
2519
+ }
2520
+ function consolecapture(input) {
2521
+ const parts = input.args.map((arg) => serializearg(arg, input.depth));
2522
+ return { level: input.level, text: redactconsoletext(parts.join(" "), input.redact), argkinds: input.args.map((arg) => argkind(arg)), repeat: 1 };
2523
+ }
2524
+ function stackframes(stacktext) {
2525
+ const frames = [];
2526
+ for (const row of stacktext.split("\n")) {
2527
+ const trimmed = row.trim();
2528
+ if (!trimmed.startsWith("at ")) continue;
2529
+ const body = trimmed.slice(3).trim();
2530
+ const location = body.match(/\(([^()]*:\d+:\d+)\)$/) ?? body.match(/^(.*:\d+:\d+)$/);
2531
+ const located = location?.[1];
2532
+ if (!located) continue;
2533
+ const segments = located.split(":");
2534
+ const column = Number.parseInt(segments.pop() ?? "", 10);
2535
+ const lineno = Number.parseInt(segments.pop() ?? "", 10);
2536
+ const url = segments.join(":");
2537
+ if (!Number.isFinite(lineno) || lineno < 0) continue;
2538
+ const name = body.endsWith(`(${located})`) ? body.slice(0, body.length - located.length - 2).trim() : "";
2539
+ frames.push({ ...name ? { functionname: name } : {}, url, line: lineno, ...Number.isFinite(column) ? { column } : {} });
2540
+ }
2541
+ return frames;
2542
+ }
2543
+ function errorcapture(input) {
2544
+ return { message: redactconsoletext(input.message, input.redact), frames: input.stacktext !== void 0 ? stackframes(input.stacktext) : [], sourceurl: input.sourceurl, line: input.line };
2545
+ }
2546
+ function rejectioncapture(input) {
2547
+ return { reason: redactconsoletext(input.reason, input.redact), frames: input.stacktext !== void 0 ? stackframes(input.stacktext) : [] };
2548
+ }
2549
+ function longtaskcapture(input) {
2550
+ return input.entries.filter((entry) => entry.duration >= input.threshold).map((entry) => ({ duration: Math.round(entry.duration), starttime: Math.round(entry.starttime), attributions: [...entry.attributions] }));
2551
+ }
2552
+ function attachtimeline(input) {
2553
+ return { runid: input.runid, origin: input.origin, stepids: [...input.stepids], attachedat: input.now, entries: [] };
2554
+ }
2555
+ function filterentries(entries, levelset) {
2556
+ return entries.filter((entry) => {
2557
+ const floor = levelset.floors?.[entry.stepid] ?? levelset.floors?.["*"];
2558
+ if (floor !== void 0 && levelrank(entry.level) > levelrank(floor)) return false;
2559
+ if (levelset.sources !== void 0 && levelset.sources.length > 0 && !levelset.sources.includes(entry.source)) return false;
2560
+ return true;
2561
+ });
2562
+ }
2563
+ function spamdetect(entries, rule) {
2564
+ const collapsed = [];
2565
+ const counts = /* @__PURE__ */ new Map();
2566
+ for (const entry of entries) {
2567
+ if (rule.pattern !== "" && !entry.message.includes(rule.pattern)) {
2568
+ collapsed.push({ ...entry, repeat: 1 });
2569
+ continue;
2570
+ }
2571
+ const key = `${entry.level}|${entry.source}|${entry.message}`;
2572
+ const previous = collapsed[collapsed.length - 1];
2573
+ if (previous && previous.repeat !== void 0 && `${previous.level}|${previous.source}|${previous.message}` === key && entry.time - previous.time <= rule.windowsize) {
2574
+ previous.repeat += 1;
2575
+ continue;
2576
+ }
2577
+ collapsed.push({ ...entry, repeat: 1 });
2578
+ }
2579
+ for (const entry of collapsed) {
2580
+ if (entry.repeat > 1) counts.set(`${entry.level}|${entry.source}|${entry.message}`, entry.repeat);
2581
+ }
2582
+ const flagged = [...counts.entries()].filter(([, count]) => count > rule.collapse).map(([key, count]) => ({ message: key.split("|").slice(2).join("|"), count }));
2583
+ return { entries: collapsed, flagged };
2584
+ }
2585
+ function rotatelogs(entries, rule) {
2586
+ if (entries.length <= rule.maxentries) return { kept: [...entries], overflow: [] };
2587
+ const kept = entries.slice(entries.length - rule.maxentries);
2588
+ const overflow = entries.slice(0, entries.length - rule.maxentries);
2589
+ return { kept, overflow };
2590
+ }
2591
+ function timelinecounts(entries) {
2592
+ const counts = {};
2593
+ for (const level of loglevels) counts[level] = 0;
2594
+ for (const entry of entries) counts[entry.level] = (counts[entry.level] ?? 0) + 1;
2595
+ return counts;
2596
+ }
2597
+ function blockingduration(tasks, stepid, window) {
2598
+ const inside = tasks.filter((task) => task.starttime >= window.startedat && task.starttime <= window.endedat);
2599
+ return { stepid, blocking: inside.reduce((total, task) => total + task.duration, 0), tasks: inside.length };
2600
+ }
2601
+ function netfailureentryof(input) {
2602
+ const exchange = input.exchange;
2603
+ if (exchange.errorclass === void 0 && exchange.status < 400) return null;
2604
+ return { id: input.id, runid: exchange.runid, stepid: exchange.stepid, url: exchange.url, status: exchange.status, errorclass: exchange.errorclass ?? "httperror", correlationid: exchange.correlationid, at: input.at };
2605
+ }
2606
+ function watcherdetached(input) {
2607
+ for (const navigation of input.navigations) {
2608
+ if (navigation >= input.startedat && navigation <= input.startedat + input.lifetime) return { detached: true, at: navigation };
2609
+ }
2610
+ return { detached: false };
2611
+ }
2612
+ function consolediff(input) {
2613
+ const base = input.baselines;
2614
+ const target = input.targetlines;
2615
+ const basemap = /* @__PURE__ */ new Map();
2616
+ for (const line of base) basemap.set(line, (basemap.get(line) ?? 0) + 1);
2617
+ const targetmap = /* @__PURE__ */ new Map();
2618
+ for (const line of target) targetmap.set(line, (targetmap.get(line) ?? 0) + 1);
2619
+ const lines = [];
2620
+ const added = [];
2621
+ const removed = [];
2622
+ const repeated = [];
2623
+ for (const [line, count] of targetmap) {
2624
+ const basecount = basemap.get(line) ?? 0;
2625
+ if (basecount === 0) {
2626
+ for (let index = 0; index < count; index += 1) {
2627
+ lines.push({ kind: "added", text: line });
2628
+ added.push(line);
2629
+ }
2630
+ continue;
2631
+ }
2632
+ const share = Math.min(basecount, count);
2633
+ for (let index = 0; index < share; index += 1) {
2634
+ lines.push({ kind: "repeated", text: line, count: share });
2635
+ repeated.push(line);
2636
+ }
2637
+ for (let index = share; index < count; index += 1) {
2638
+ lines.push({ kind: "added", text: line });
2639
+ added.push(line);
2640
+ }
2641
+ }
2642
+ for (const [line, count] of basemap) {
2643
+ const targetcount = targetmap.get(line) ?? 0;
2644
+ const missing = Math.max(0, count - targetcount);
2645
+ for (let index = 0; index < missing; index += 1) {
2646
+ lines.push({ kind: "removed", text: line });
2647
+ removed.push(line);
2648
+ }
2649
+ }
2650
+ return { base: input.baseid, target: input.targetid, lines, added: added.length, removed: removed.length, repeated: repeated.length, at: input.now };
2651
+ }
2652
+
2367
2653
  // socketbus.ts
2368
2654
  var socketkinds = ["opensocket", "sendmessage", "waitmessage", "subscribesse", "longpoll"];
2369
2655
  function channelorigin(url) {
@@ -2587,7 +2873,7 @@ function polldecision(input) {
2587
2873
  // policy.ts
2588
2874
  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"]);
2589
2875
  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"]);
2590
- 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"]);
2876
+ 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"]);
2591
2877
  var allowedactions = /* @__PURE__ */ new Set([...sensitiveactions, ...interactionactions, ...readactions]);
2592
2878
  var watchactions = /* @__PURE__ */ new Set(["watchmutate", "watchbanner", "watchfocus", "watchtab"]);
2593
2879
  var targetactions = /* @__PURE__ */ new Set(["inspect", "focus", "click", "type", "scroll", "select", "hover", "clickdeep", "rightclick", "doubleclick", "drag", "drop", "upload", "clear", "check", "uncheck", "toggle", "submit", "readattribute", "readstyle", "readgeometry", "readvalue", "readtext", "readhtml", "countelements", "readtable", "highlight", "setattribute", "removeattribute", "waitfor", "shiftclick", "typetime", "appendtext", "setvalue", "typeedit", "submitsearch", "selectmulti", "chooseradio", "setslider", "setdate", "setcolor", "expanddetails", "verifyvisible", "verifyenabled", "pierceshadow", "deriveselector", "fingerprintsection", "submitform", "retryform", "selectchain", "picktypeahead", "pickdate", "attachfile", "fillcode", "consentpassword", "scrapetable", "paginateextract", "shotelement", "captureframe", "shotcanvas"]);
@@ -2603,6 +2889,7 @@ var httpactions = /* @__PURE__ */ new Set(["fetchurl", "parsejson", "parsehtml",
2603
2889
  var socketactions = /* @__PURE__ */ new Set(["opensocket", "sendmessage", "waitmessage", "subscribesse", "longpoll"]);
2604
2890
  var netwatchactions = /* @__PURE__ */ new Set(["watchrequests", "readheaders", "capturebodies", "mapapi", "extractapi"]);
2605
2891
  var controlactions = /* @__PURE__ */ new Set(["blockrequest", "mockresponse", "rewriteheaders", "setcookies", "readcookies", "clearcookies", "authflow", "saveapikey", "routeproxy", "postform", "postfiles"]);
2892
+ var debugactions = /* @__PURE__ */ new Set(["watchconsole", "watcherrors", "watchtasks"]);
2606
2893
  var credentialheaders = /* @__PURE__ */ new Set(["authorization", "proxy-authorization", "cookie", "cookie2", "set-cookie", "api-key", "x-api-key", "x-auth-token", "x-session-token", "proxy-authorization"]);
2607
2894
  var fieldkinds = ["text", "email", "phone", "date", "number", "select", "check", "radio", "file", "password", "card", "code"];
2608
2895
  var layoutmutationactions = /* @__PURE__ */ new Set(["grouptabs", "colorgroup", "collapsegroup", "savelayout", "restorelayout"]);
@@ -2621,8 +2908,11 @@ function hostpattern(origin) {
2621
2908
  function iswatchkind(kind) {
2622
2909
  return watchactions.has(kind);
2623
2910
  }
2911
+ function isdebugkind(kind) {
2912
+ return debugactions.has(kind);
2913
+ }
2624
2914
  function observationmodeof(kind) {
2625
- if (watchactions.has(kind) || kind === "waitquiet") return "watching";
2915
+ if (watchactions.has(kind) || debugactions.has(kind) || kind === "waitquiet") return "watching";
2626
2916
  if (kind === "diffsnapshots") return "diffing";
2627
2917
  return "passive";
2628
2918
  }
@@ -3755,6 +4045,87 @@ function ratelimitbudgetallowed(wait, budget) {
3755
4045
  if (wait !== void 0 && budget !== void 0 && wait > budget) return { allowed: false, reason: `The rate limit wait of ${wait} milliseconds exceeds the reviewed budget of ${budget} milliseconds; review a wider budget or submit later.` };
3756
4046
  return { allowed: true };
3757
4047
  }
4048
+ function timelinegate(session, tabid, origin, now) {
4049
+ if (!session || session.stoppedat) return { allowed: false, reason: "No active browser session exists for the timeline capture." };
4050
+ if (session.expiresat <= now) return { allowed: false, reason: "The browser session has expired and cannot capture the timeline." };
4051
+ if (session.pausedat) return { allowed: false, reason: "The browser session is paused and cannot capture the timeline." };
4052
+ if (session.tabid !== tabid) return { allowed: false, reason: `The timeline capture needs the run tab ${session.tabid} and refuses tab ${tabid}.` };
4053
+ if (!origingranted(session, origin)) return { allowed: false, reason: `The timeline capture of ${origin} needs the session origin grants first.` };
4054
+ return { allowed: true };
4055
+ }
4056
+ function consoleconsentcovers(origin, consents) {
4057
+ if (consents.some((consent) => consent.origin === origin && consent.approved === true)) return { allowed: true };
4058
+ return { allowed: false, reason: `Console capture on ${origin} needs the reviewed console consent first; approve the prompt in the review panel.` };
4059
+ }
4060
+ function stackgate(session, origin) {
4061
+ if (!origingranted(session, origin)) return { allowed: false, reason: `Stack capture of ${origin} stays outside the session origin grants.` };
4062
+ return { allowed: true };
4063
+ }
4064
+ function debugwaitbudgetallowed(watchwindow, wait) {
4065
+ if (watchwindow !== void 0 && (typeof watchwindow !== "number" || !Number.isFinite(watchwindow) || watchwindow < 0)) return { allowed: false, reason: "The debug watch window must be zero or a positive number of milliseconds." };
4066
+ if (wait !== void 0 && (typeof wait !== "number" || !Number.isFinite(wait) || wait < 0)) return { allowed: false, reason: "The reviewed debug wait budget must be zero or a positive number of milliseconds." };
4067
+ if (watchwindow !== void 0 && wait !== void 0 && watchwindow > wait) return { allowed: false, reason: `The debug watch window of ${watchwindow} milliseconds exceeds the reviewed wait budget of ${wait} milliseconds; review a wider budget or a shorter window.` };
4068
+ return { allowed: true };
4069
+ }
4070
+ function timelineretentionwindow(settings) {
4071
+ return settings?.timelineretention;
4072
+ }
4073
+ function diffreviewgrade() {
4074
+ return { risk: "read", mode: "diffing", evidence: "comparison" };
4075
+ }
4076
+ function validatetimelinegrammar(step, options) {
4077
+ const kind = step.kind;
4078
+ let watchwindow;
4079
+ if (options.watch !== void 0) {
4080
+ const watch = options.watch;
4081
+ if (!watch || typeof watch !== "object" || Array.isArray(watch)) return { allowed: false, reason: "The reviewed debug watch window must be an object." };
4082
+ const reviewed = watch;
4083
+ if (reviewed.window !== void 0) {
4084
+ if (typeof reviewed.window !== "number" || !Number.isFinite(reviewed.window) || reviewed.window < 0) return { allowed: false, reason: "The reviewed debug watch window must be zero or a positive number of milliseconds." };
4085
+ watchwindow = reviewed.window;
4086
+ }
4087
+ }
4088
+ const budgetcheck = debugwaitbudgetallowed(watchwindow, typeof options.wait === "number" ? options.wait : void 0);
4089
+ if (!budgetcheck.allowed) return budgetcheck;
4090
+ if (options.level !== void 0 && !loglevels.includes(options.level)) return { allowed: false, reason: `The reviewed level floor must be one of ${loglevels.join(", ")}.` };
4091
+ if (options.sources !== void 0) {
4092
+ if (!Array.isArray(options.sources) || options.sources.length === 0 || !options.sources.every((source) => timelinesources.includes(source))) return { allowed: false, reason: `The reviewed source filters must be a non-empty list of the reviewed timeline sources: ${timelinesources.join(", ")}.` };
4093
+ }
4094
+ if (kind === "watchconsole") {
4095
+ if (options.redact === void 0 || !Array.isArray(options.redact) || options.redact.length === 0 || !options.redact.every((pattern) => isnonempty(pattern))) return { allowed: false, reason: "Console capture requires a reviewed non-empty redaction pattern list before any console text is captured." };
4096
+ if (options.depth !== void 0 && (typeof options.depth !== "number" || !Number.isInteger(options.depth) || options.depth < 1)) return { allowed: false, reason: "The reviewed serialization depth bound must be a positive integer with no code ceiling." };
4097
+ if (options.spam !== void 0) {
4098
+ const rule = spamruleof(options.spam);
4099
+ if (!rule) return { allowed: false, reason: "The reviewed spam rule needs a pattern, a window size and a collapse threshold." };
4100
+ if (rule.collapse < 1) return { allowed: false, reason: "The reviewed spam collapse threshold must be a positive integer of user configured value with no code ceiling." };
4101
+ }
4102
+ if (options.rotation !== void 0) {
4103
+ const rule = rotationruleof(options.rotation);
4104
+ if (!rule) return { allowed: false, reason: "The reviewed rotation rule needs a max entry count and an overflow target." };
4105
+ }
4106
+ }
4107
+ if (kind === "watchtasks") {
4108
+ if (options.threshold !== void 0 && (typeof options.threshold !== "number" || !Number.isFinite(options.threshold) || options.threshold < 0)) return { allowed: false, reason: "The reviewed long task threshold must be zero or a positive number of milliseconds with no code ceiling." };
4109
+ }
4110
+ return { allowed: true };
4111
+ }
4112
+ function spamruleof(value) {
4113
+ if (!value || typeof value !== "object" || Array.isArray(value)) return void 0;
4114
+ const entry = value;
4115
+ const pattern = typeof entry.pattern === "string" ? entry.pattern : "";
4116
+ const windowsize = typeof entry.windowsize === "number" && Number.isFinite(entry.windowsize) && entry.windowsize >= 0 ? entry.windowsize : void 0;
4117
+ const collapse = typeof entry.collapse === "number" && Number.isInteger(entry.collapse) ? entry.collapse : void 0;
4118
+ if (windowsize === void 0 || collapse === void 0) return void 0;
4119
+ return { pattern, windowsize, collapse };
4120
+ }
4121
+ function rotationruleof(value) {
4122
+ if (!value || typeof value !== "object" || Array.isArray(value)) return void 0;
4123
+ const entry = value;
4124
+ const maxentries = typeof entry.maxentries === "number" && Number.isInteger(entry.maxentries) && entry.maxentries >= 1 ? entry.maxentries : void 0;
4125
+ const overflowtarget = typeof entry.overflowtarget === "string" && entry.overflowtarget.trim() ? entry.overflowtarget.trim() : void 0;
4126
+ if (maxentries === void 0 || overflowtarget === void 0) return void 0;
4127
+ return { maxentries, overflowtarget };
4128
+ }
3758
4129
  function controltarget(step) {
3759
4130
  let options = {};
3760
4131
  try {
@@ -4160,6 +4531,10 @@ function validatestep(step, origin) {
4160
4531
  const controlcheck = validatecontrolgrammar(step, options);
4161
4532
  if (!controlcheck.allowed) return controlcheck;
4162
4533
  }
4534
+ if (isdebugkind(step.kind)) {
4535
+ const timelinecheck = validatetimelinegrammar(step, options);
4536
+ if (!timelinecheck.allowed) return timelinecheck;
4537
+ }
4163
4538
  if (step.kind === "tabcreate") {
4164
4539
  if (options.background !== void 0 && typeof options.background !== "boolean") return { allowed: false, reason: "The reviewed background flag must be a boolean." };
4165
4540
  if (options.window !== void 0 && (typeof options.window !== "number" || !Number.isInteger(options.window) || options.window < 0)) return { allowed: false, reason: "The reviewed target window id must be a non-negative integer." };
@@ -4261,6 +4636,10 @@ function canexecute(input) {
4261
4636
  const watchgatecheck = watchgate(input.session, input.settings, now);
4262
4637
  if (!watchgatecheck.allowed) return watchgatecheck;
4263
4638
  }
4639
+ if (isdebugkind(input.step.kind)) {
4640
+ const timelinegatecheck = timelinegate(input.session, input.tabid, input.origin, now);
4641
+ if (!timelinegatecheck.allowed) return timelinegatecheck;
4642
+ }
4264
4643
  if (iscontrolkind(input.step.kind)) {
4265
4644
  const controlgate = sessiongate({ session: input.session, tabid: input.tabid, origin: input.origin, now, action: "control the network" });
4266
4645
  if (!controlgate.allowed) return controlgate;
@@ -4344,7 +4723,7 @@ function canexecute(input) {
4344
4723
  }
4345
4724
 
4346
4725
  // version.ts
4347
- var packageversion = "1.1.44";
4726
+ var packageversion = "1.1.45";
4348
4727
 
4349
4728
  // types.ts
4350
4729
  var protocolversion = packageversion;
@@ -4402,6 +4781,23 @@ function parseproposal(value, origin, grants) {
4402
4781
  const bypass = proxy && typeof proxy === "object" && !Array.isArray(proxy) ? proxy.bypass : void 0;
4403
4782
  if (!Array.isArray(bypass) || bypass.length === 0) throw new Error("Proxy routes without a bypass list are refused.");
4404
4783
  }
4784
+ if (step.kind === "watchconsole" || step.kind === "watcherrors" || step.kind === "watchtasks") {
4785
+ let debugoptions = {};
4786
+ try {
4787
+ debugoptions = parseoptions(step);
4788
+ } catch {
4789
+ debugoptions = {};
4790
+ }
4791
+ const granted = covered.some((pattern) => {
4792
+ try {
4793
+ return new URL(origin).origin === new URL(pattern).origin;
4794
+ } catch {
4795
+ return false;
4796
+ }
4797
+ });
4798
+ if (!granted) throw new Error(`The ${step.kind} capture of ${origin} targets an origin outside the grants.`);
4799
+ if (debugoptions.level !== void 0 && !loglevels.includes(debugoptions.level)) throw new Error(`The reviewed level floor must be one of ${loglevels.join(", ")}.`);
4800
+ }
4405
4801
  const evaluation = validatestep(step, origin);
4406
4802
  if (!evaluation.allowed) throw new Error(evaluation.reason);
4407
4803
  const target = outboundtarget(step);
@@ -4476,7 +4872,7 @@ function requestbody(input) {
4476
4872
  return JSON.stringify({ version: protocolversion, objective: input.objective, session: input.session, observation: input.observation, capabilities: input.capabilities });
4477
4873
  }
4478
4874
  function outcomeresponse(input) {
4479
- return JSON.stringify({ version: protocolversion, planid: input.plan.id, planstate: input.plan.state, outcome: input.outcome, ...input.resolvedtarget ? { resolvedtarget: input.resolvedtarget } : {}, ...input.capture ? { capture: input.capture } : {}, ...input.media ? { media: input.media } : {}, ...input.transport ? { transport: input.transport } : {}, ...input.network ? { network: input.network } : {}, ...input.control ? { control: input.control } : {} });
4875
+ return JSON.stringify({ version: protocolversion, planid: input.plan.id, planstate: input.plan.state, outcome: input.outcome, ...input.resolvedtarget ? { resolvedtarget: input.resolvedtarget } : {}, ...input.capture ? { capture: input.capture } : {}, ...input.media ? { media: input.media } : {}, ...input.transport ? { transport: input.transport } : {}, ...input.network ? { network: input.network } : {}, ...input.control ? { control: input.control } : {}, ...input.timeline ? { timeline: input.timeline } : {} });
4480
4876
  }
4481
4877
  function mapresponse(input) {
4482
4878
  return JSON.stringify({ version: protocolversion, planid: input.plan.id, planstate: input.plan.state, map: input.map });
@@ -4587,18 +4983,27 @@ function controlreport(input) {
4587
4983
  });
4588
4984
  return { version: protocolversion, blocks: input.blocks, mocks, rewrites: input.rewrites, cookies: input.cookies, proxies: input.proxies, ratelimits: input.ratelimits };
4589
4985
  }
4986
+ function timelinereport(input) {
4987
+ return { version: protocolversion, entries: input.entries, errors: input.errors, rejections: input.rejections, longtasks: input.longtasks, levelcounts: input.levelcounts };
4988
+ }
4989
+ function consolediffreport(input) {
4990
+ return { version: protocolversion, diff: input.diff };
4991
+ }
4590
4992
  export {
4591
4993
  annotationplanof,
4592
4994
  apientries,
4593
4995
  apikeyconsentgranted,
4594
4996
  apireplayspecof,
4595
4997
  applyheaderules,
4998
+ argkind,
4596
4999
  assetentries,
5000
+ attachtimeline,
4597
5001
  authconsentgranted,
4598
5002
  authorizeurl,
4599
5003
  authreport,
4600
5004
  blendrows,
4601
5005
  blockgate,
5006
+ blockingduration,
4602
5007
  blockruleof,
4603
5008
  bodyfilterof,
4604
5009
  bodymatches,
@@ -4627,6 +5032,10 @@ export {
4627
5032
  channelorigin,
4628
5033
  closechannel,
4629
5034
  collectmessages,
5035
+ consolecapture,
5036
+ consoleconsentcovers,
5037
+ consolediff,
5038
+ consolediffreport,
4630
5039
  controlkinds,
4631
5040
  controlreport,
4632
5041
  controltarget,
@@ -4639,10 +5048,13 @@ export {
4639
5048
  crossesviewport,
4640
5049
  cursorfrom,
4641
5050
  datasetresponse,
5051
+ debugwaitbudgetallowed,
4642
5052
  dedupeimages,
4643
5053
  actionrisk as deriveactionrisk,
4644
5054
  diffresponse,
5055
+ diffreviewgrade,
4645
5056
  downloadreport,
5057
+ errorcapture,
4646
5058
  errorreportresponse,
4647
5059
  eventresponse,
4648
5060
  exchangesreport,
@@ -4651,6 +5063,7 @@ export {
4651
5063
  failureclass,
4652
5064
  fetchoptionsof,
4653
5065
  fetchrequestof,
5066
+ filterentries,
4654
5067
  filterexchanges,
4655
5068
  finishrecording,
4656
5069
  fixedheadermatch,
@@ -4670,6 +5083,7 @@ export {
4670
5083
  imagematches,
4671
5084
  imagenames,
4672
5085
  iscontrolkind,
5086
+ isdebugkind,
4673
5087
  isformkind,
4674
5088
  isnetwatchkind,
4675
5089
  issocketkind,
@@ -4678,6 +5092,9 @@ export {
4678
5092
  lapseframes,
4679
5093
  lapseplanof,
4680
5094
  layoutreport,
5095
+ levelrank,
5096
+ loglevels,
5097
+ longtaskcapture,
4681
5098
  mapresponse,
4682
5099
  matchmessage,
4683
5100
  matchurlpattern,
@@ -4690,6 +5107,7 @@ export {
4690
5107
  multipartchunks,
4691
5108
  multipartpayloadof,
4692
5109
  navstateresponse,
5110
+ netfailureentryof,
4693
5111
  netlogreport,
4694
5112
  netwatchkinds,
4695
5113
  newblockrule,
@@ -4740,8 +5158,10 @@ export {
4740
5158
  receivemessage,
4741
5159
  reconnectwaits,
4742
5160
  recordingoptionsof,
5161
+ redactconsoletext,
4743
5162
  redactedcookies,
4744
5163
  regionsteps,
5164
+ rejectioncapture,
4745
5165
  replayurl,
4746
5166
  requestbody,
4747
5167
  resolutionverdict,
@@ -4750,17 +5170,24 @@ export {
4750
5170
  retryafterof,
4751
5171
  revertrule,
4752
5172
  revocationruleof,
5173
+ rotatelogs,
5174
+ rotationruleof,
4753
5175
  safetyresponse,
4754
5176
  scaledrect,
4755
5177
  seamweights,
4756
5178
  selectorresponse,
4757
5179
  sendfetch,
4758
5180
  sequenceintegrity,
5181
+ serializearg,
4759
5182
  sessionmemory,
4760
5183
  signalsreport,
4761
5184
  socketgate,
4762
5185
  socketkinds,
5186
+ spamdetect,
5187
+ spamruleof,
4763
5188
  sserequestheaders,
5189
+ stackframes,
5190
+ stackgate,
4764
5191
  statusclassof,
4765
5192
  streamsummaries,
4766
5193
  streamwindowof,
@@ -4770,6 +5197,12 @@ export {
4770
5197
  templateurl,
4771
5198
  thumbdirectiveof,
4772
5199
  thumbgeometry,
5200
+ timelinecounts,
5201
+ timelinegate,
5202
+ timelinekinds,
5203
+ timelinereport,
5204
+ timelineretentionwindow,
5205
+ timelinesources,
4773
5206
  tokenrequest,
4774
5207
  trailreport,
4775
5208
  transformgrammar,
@@ -4780,6 +5213,7 @@ export {
4780
5213
  validatestep,
4781
5214
  validatetargetref,
4782
5215
  validatevaluegen,
5216
+ watcherdetached,
4783
5217
  watchgate,
4784
5218
  wizardreport
4785
5219
  };