@wenathlan/extension 1.1.43 → 1.1.44

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.
@@ -1,5 +1,5 @@
1
1
  <!doctype html>
2
2
  <html lang="en">
3
3
  <head><meta charset="utf-8"><meta name="viewport" content="width=device-width,initial-scale=1"><title>Devthink review</title><link rel="stylesheet" href="style.css"></head>
4
- <body><main class="wide"><header><p class="eyebrow">REVIEW GATE</p><h1>Plan before action</h1><p>Every browser operation remains blocked until the user reviews and approves it here.</p></header><label for="objective">Objective</label><textarea id="objective" rows="4" placeholder="Describe a browser task to turn into a reviewable plan."></textarea><div class="actions"><button id="localplan">Create local observation plan</button><button id="remoteplan" class="secondary">Ask configured endpoint</button><button id="diagnostic" class="secondary">Capture local diagnostics</button></div><p id="status" role="status">Loading session state.</p><p id="capabilitiestext" role="status" class="muted">Optional capabilities unknown.</p><section><h2>Current plan</h2><progress id="planprogress" max="1" value="0"></progress><div id="plan" class="panel"></div></section><section><h2>Clickable map</h2><ol id="map" class="audit maplist"></ol></section><section><h2>Navigation trail</h2><ol id="trail" class="audit"></ol></section><section><h2>Navigation state</h2><div id="navigation" class="panel"></div></section><section><h2>Tabs and windows</h2><div id="tabswindows" class="panel"></div></section><section><h2>Forms and data</h2><div id="forms" class="panel"></div></section><section><h2>Files and downloads</h2><div id="files" class="panel"></div></section><section><h2>Capture gallery</h2><div id="captures" class="panel"></div></section><section><h2>Media</h2><div id="media" class="panel"></div></section><section><h2>Network calls</h2><div id="calls" class="panel"></div></section><section><h2>Network view</h2><div id="netview" class="panel"></div></section><section><h2>Datasets</h2><div id="datasets" class="panel"></div></section><section><h2>Consent banners</h2><div id="banners" class="panel"></div></section><section><h2>Accessibility tree</h2><div id="a11y" class="panel"></div></section><section><h2>Reader view</h2><div id="reader" class="panel"></div></section><section><h2>Detected shapes</h2><ol id="detections" class="audit maplist"></ol></section><section><h2>Watch stream</h2><ol id="stream" class="audit"></ol></section><section><h2>Snapshot diffs</h2><div id="diffs" class="panel"></div></section><section><h2>Derived selectors</h2><ol id="selectors" class="audit maplist"></ol></section><section><h2>Structured diagnostics</h2><ul id="diagnostics" class="audit"></ul></section><section><h2>Local audit</h2><ol id="audit" class="audit"></ol></section></main><script type="module" src="sidepanel.js"></script></body>
4
+ <body><main class="wide"><header><p class="eyebrow">REVIEW GATE</p><h1>Plan before action</h1><p>Every browser operation remains blocked until the user reviews and approves it here.</p></header><label for="objective">Objective</label><textarea id="objective" rows="4" placeholder="Describe a browser task to turn into a reviewable plan."></textarea><div class="actions"><button id="localplan">Create local observation plan</button><button id="remoteplan" class="secondary">Ask configured endpoint</button><button id="diagnostic" class="secondary">Capture local diagnostics</button></div><p id="status" role="status">Loading session state.</p><p id="capabilitiestext" role="status" class="muted">Optional capabilities unknown.</p><section><h2>Current plan</h2><progress id="planprogress" max="1" value="0"></progress><div id="plan" class="panel"></div></section><section><h2>Clickable map</h2><ol id="map" class="audit maplist"></ol></section><section><h2>Navigation trail</h2><ol id="trail" class="audit"></ol></section><section><h2>Navigation state</h2><div id="navigation" class="panel"></div></section><section><h2>Tabs and windows</h2><div id="tabswindows" class="panel"></div></section><section><h2>Forms and data</h2><div id="forms" class="panel"></div></section><section><h2>Files and downloads</h2><div id="files" class="panel"></div></section><section><h2>Capture gallery</h2><div id="captures" class="panel"></div></section><section><h2>Media</h2><div id="media" class="panel"></div></section><section><h2>Network calls</h2><div id="calls" class="panel"></div></section><section><h2>Network view</h2><div id="netview" class="panel"></div></section><section><h2>Traffic control</h2><div id="traffic" class="panel"></div></section><section><h2>Datasets</h2><div id="datasets" class="panel"></div></section><section><h2>Consent banners</h2><div id="banners" class="panel"></div></section><section><h2>Accessibility tree</h2><div id="a11y" class="panel"></div></section><section><h2>Reader view</h2><div id="reader" class="panel"></div></section><section><h2>Detected shapes</h2><ol id="detections" class="audit maplist"></ol></section><section><h2>Watch stream</h2><ol id="stream" class="audit"></ol></section><section><h2>Snapshot diffs</h2><div id="diffs" class="panel"></div></section><section><h2>Derived selectors</h2><ol id="selectors" class="audit maplist"></ol></section><section><h2>Structured diagnostics</h2><ul id="diagnostics" class="audit"></ul></section><section><h2>Local audit</h2><ol id="audit" class="audit"></ol></section></main><script type="module" src="sidepanel.js"></script></body>
5
5
  </html>
@@ -1,7 +1,7 @@
1
1
  // policy.ts
2
- 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"]);
2
+ 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"]);
3
3
  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"]);
4
- 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"]);
4
+ 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"]);
5
5
  var allowedactions = /* @__PURE__ */ new Set([...sensitiveactions, ...interactionactions, ...readactions]);
6
6
 
7
7
  // extension/tabscommand.ts
@@ -66,6 +66,7 @@ var filesroot = document.querySelector("#files");
66
66
  var capturesroot = document.querySelector("#captures");
67
67
  var mediaroot = document.querySelector("#media");
68
68
  var callsroot = document.querySelector("#calls");
69
+ var trafficroot = document.querySelector("#traffic");
69
70
  var netviewroot = document.querySelector("#netview");
70
71
  var statusnode = document.querySelector("#status");
71
72
  var progressnode = document.querySelector("#planprogress");
@@ -1689,6 +1690,82 @@ function rendercaptures(context) {
1689
1690
  capturesroot.append(card);
1690
1691
  }
1691
1692
  }
1693
+ function rendertraffic(context) {
1694
+ if (!trafficroot) return;
1695
+ trafficroot.replaceChildren();
1696
+ const head = document.createElement("p");
1697
+ head.textContent = `active traffic rules: ${context.activerules ?? 0} (every rule reverts at run end)`;
1698
+ trafficroot.append(head);
1699
+ const traffic = context.traffic;
1700
+ if (traffic === void 0) return;
1701
+ if (traffic.blocks.length === 0 && traffic.mocks.length === 0 && traffic.rewrites.length === 0 && traffic.cookies.length === 0 && traffic.proxies.length === 0 && traffic.ratelimits.length === 0) {
1702
+ trafficroot.append(Object.assign(document.createElement("p"), { className: "muted", textContent: "No traffic rule has been applied yet; blockrequest, mockresponse, rewriteheaders, setcookies, clearcookies, routeproxy, postform and postfiles steps land here." }));
1703
+ }
1704
+ for (const rule of traffic.blocks) {
1705
+ const row = document.createElement("p");
1706
+ row.textContent = `block ${rule.urlpattern} \xB7 ${rule.hits} blocked \xB7 ${rule.revertedat !== void 0 ? "reverted" : "active"} \xB7 step ${rule.stepid}`;
1707
+ trafficroot.append(row);
1708
+ }
1709
+ for (const spec of traffic.mocks) {
1710
+ const row = document.createElement("p");
1711
+ row.textContent = `mock ${spec.urlpattern} \u2192 ${spec.status} \xB7 ${spec.hits} served \xB7 ${spec.revertedat !== void 0 ? "reverted" : "active"}`;
1712
+ trafficroot.append(row);
1713
+ }
1714
+ for (const rule of traffic.rewrites) {
1715
+ const row = document.createElement("p");
1716
+ row.textContent = `rewrite ${rule.operation} ${rule.name} on ${rule.urlpattern} \xB7 ${rule.hits} applied \xB7 ${rule.revertedat !== void 0 ? "reverted" : "active"}`;
1717
+ trafficroot.append(row);
1718
+ }
1719
+ for (const route of traffic.proxies) {
1720
+ const row = document.createElement("p");
1721
+ row.textContent = `proxy ${route.scheme}://${route.host}:${route.port} \xB7 bypass ${route.bypass.join(", ")} \xB7 ${route.revertedat !== void 0 ? "reverted" : "active"}`;
1722
+ trafficroot.append(row);
1723
+ if (route.revertedat === void 0) {
1724
+ const actions = document.createElement("div");
1725
+ actions.className = "actions";
1726
+ actions.append(button("Revert proxy route", () => request({ kind: "revertproxyroute", id: route.id }).then(() => status(`Proxy route ${route.id} reverted; the previous routing state is restored.`)).then(refresh)));
1727
+ trafficroot.append(actions);
1728
+ }
1729
+ }
1730
+ for (const read of traffic.ratelimits) {
1731
+ const row = document.createElement("p");
1732
+ row.textContent = `rate limit ${read.origin} \xB7 ${read.remaining ?? "?"} of ${read.limit ?? "?"} remaining \xB7 resets ${new Date(read.resetat).toLocaleTimeString()}`;
1733
+ trafficroot.append(row);
1734
+ }
1735
+ for (const flow of context.authflows ?? []) {
1736
+ const row = document.createElement("p");
1737
+ row.textContent = `oauth ${flow.provider} \xB7 scopes ${flow.scopes.join(", ")} \xB7 redirect ${flow.redirectorigin} \xB7 ${flow.stage} in tab ${flow.tabid}`;
1738
+ trafficroot.append(row);
1739
+ }
1740
+ for (const token of context.tokens?.tokens ?? []) {
1741
+ const row = document.createElement("p");
1742
+ row.textContent = `token ${token.provider} \xB7 scopes ${token.scopes.join(", ")} \xB7 ${token.revokedat !== void 0 ? "revoked" : `expires ${new Date(token.expiresat).toLocaleTimeString()}`}${token.refreshedat !== void 0 ? " \xB7 refreshed" : ""}`;
1743
+ trafficroot.append(row);
1744
+ if (token.revokedat === void 0) {
1745
+ const actions = document.createElement("div");
1746
+ actions.className = "actions";
1747
+ actions.append(button("Revoke token", () => request({ kind: "revoketokens", tokenids: [token.id], reason: "review panel demand" }).then(() => status(`Token ${token.id} of ${token.provider} revoked.`)).then(refresh)));
1748
+ trafficroot.append(actions);
1749
+ }
1750
+ }
1751
+ for (const op of traffic.cookies.slice(0, 8)) {
1752
+ const row = document.createElement("p");
1753
+ row.textContent = `cookie ${op.kind} \xB7 ${op.domain} \xB7 ${op.names.length === 0 ? "all cookies" : op.names.join(", ")} \xB7 ${new Date(op.at).toLocaleTimeString()} (values never stored)`;
1754
+ trafficroot.append(row);
1755
+ }
1756
+ for (const ref of context.apikeys ?? []) {
1757
+ const row = document.createElement("p");
1758
+ row.textContent = `api key ${ref.name} \xB7 header ${ref.header} \xB7 scoped to ${ref.origins.join(", ")}${ref.lastuse !== void 0 ? ` \xB7 last use ${new Date(ref.lastuse).toLocaleTimeString()}` : " \xB7 unused"}`;
1759
+ trafficroot.append(row);
1760
+ }
1761
+ const uploads = (context.progress?.outcomes ?? []).filter((outcome) => outcome.details?.upload !== void 0).slice(-4);
1762
+ for (const outcome of uploads) {
1763
+ const entry = outcome.details?.upload;
1764
+ const row = document.createElement("p");
1765
+ row.textContent = `upload chunk ${entry.chunk} of ${entry.chunks} \xB7 ${entry.uploaded} of ${entry.bytes} bytes`;
1766
+ trafficroot.append(row);
1767
+ }
1768
+ }
1692
1769
  function rendercalls(context) {
1693
1770
  if (!callsroot) return;
1694
1771
  callsroot.replaceChildren();
@@ -2016,6 +2093,7 @@ async function refresh() {
2016
2093
  rendermedia(context);
2017
2094
  rendercalls(context);
2018
2095
  rendernetview(context);
2096
+ rendertraffic(context);
2019
2097
  renderaudit(context.audit);
2020
2098
  rendercapabilities(context.capabilities);
2021
2099
  if (context.session?.pausedat) status("Session paused. Reviewed actions are blocked until resume.");