@wenathlan/extension 1.1.42 → 1.1.43
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/README.md +5 -4
- package/dist/index.d.ts +3 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +771 -9
- package/dist/index.js.map +4 -4
- package/dist/memory.d.ts +42 -1
- package/dist/memory.d.ts.map +1 -1
- package/dist/netwatch.d.ts +92 -0
- package/dist/netwatch.d.ts.map +1 -0
- package/dist/policy.d.ts +15 -0
- package/dist/policy.d.ts.map +1 -1
- package/dist/protocol.d.ts +23 -3
- package/dist/protocol.d.ts.map +1 -1
- package/dist/socketbus.d.ts +134 -0
- package/dist/socketbus.d.ts.map +1 -0
- package/dist/types.d.ts +183 -3
- package/dist/types.d.ts.map +1 -1
- package/dist/version.d.ts +1 -1
- package/extension/dist/background.js +3173 -1974
- package/extension/dist/background.js.map +4 -4
- package/extension/dist/manifest.json +1 -1
- package/extension/dist/pagebridge.js +20 -4
- package/extension/dist/pagebridge.js.map +2 -2
- package/extension/dist/popup.html +1 -1
- package/extension/dist/popup.js +11 -3
- package/extension/dist/popup.js.map +2 -2
- package/extension/dist/sidepanel.html +1 -1
- package/extension/dist/sidepanel.js +134 -3
- package/extension/dist/sidepanel.js.map +2 -2
- package/extension/manifest.json +1 -1
- package/package.json +1 -1
|
@@ -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>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>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"]);
|
|
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"]);
|
|
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"]);
|
|
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"]);
|
|
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"]);
|
|
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 netviewroot = document.querySelector("#netview");
|
|
69
70
|
var statusnode = document.querySelector("#status");
|
|
70
71
|
var progressnode = document.querySelector("#planprogress");
|
|
71
72
|
var capabilitiestext = document.querySelector("#capabilitiestext");
|
|
@@ -1833,6 +1834,135 @@ function rendercalls(context) {
|
|
|
1833
1834
|
}
|
|
1834
1835
|
callsroot.append(actions);
|
|
1835
1836
|
}
|
|
1837
|
+
function rendernetview(context) {
|
|
1838
|
+
if (!netviewroot) return;
|
|
1839
|
+
netviewroot.replaceChildren();
|
|
1840
|
+
const active = context.session && !context.session.stoppedat && context.session.expiresat > Date.now();
|
|
1841
|
+
const grantcard = document.createElement("div");
|
|
1842
|
+
grantcard.className = "panel";
|
|
1843
|
+
const grantrow = document.createElement("p");
|
|
1844
|
+
grantrow.textContent = `request watching: ${context.webrequestgrant === true ? "granted" : "not granted"} \u2014 the observation derives from the page timing buffers and adds no manifest permission.`;
|
|
1845
|
+
grantcard.append(grantrow);
|
|
1846
|
+
if (active) {
|
|
1847
|
+
const grantactions = document.createElement("div");
|
|
1848
|
+
grantactions.className = "actions";
|
|
1849
|
+
grantactions.append(button(context.webrequestgrant === true ? "Revoke request watching" : "Grant request watching", () => request({ kind: "setwebrequestgrant", granted: context.webrequestgrant !== true }).then(() => status(context.webrequestgrant === true ? "Request watching revoked." : "Request watching granted; watchrequests steps can run now.")).then(refresh)));
|
|
1850
|
+
grantcard.append(grantactions);
|
|
1851
|
+
}
|
|
1852
|
+
netviewroot.append(grantcard);
|
|
1853
|
+
const channels = context.channels ?? [];
|
|
1854
|
+
const subscriptions = context.subscriptions ?? [];
|
|
1855
|
+
if (channels.length > 0 || subscriptions.length > 0 || (context.socketsactive ?? 0) > 0) {
|
|
1856
|
+
const card = document.createElement("div");
|
|
1857
|
+
card.className = "panel";
|
|
1858
|
+
const head = document.createElement("p");
|
|
1859
|
+
head.textContent = `live channels: ${channels.length} websocket channel${channels.length === 1 ? "" : "s"} \xB7 ${subscriptions.length} event stream${subscriptions.length === 1 ? "" : "s"}`;
|
|
1860
|
+
card.append(head);
|
|
1861
|
+
for (const channel of channels) {
|
|
1862
|
+
const row = document.createElement("p");
|
|
1863
|
+
row.textContent = `${channel.kind} ${channel.state} \xB7 ${channel.origin} \xB7 ${channel.sent} sent \xB7 ${channel.received} received \xB7 ${channel.reconnects} reconnect${channel.reconnects === 1 ? "" : "s"}${channel.lasteventid !== void 0 ? ` \xB7 last event ${channel.lasteventid}` : ""}`;
|
|
1864
|
+
card.append(row);
|
|
1865
|
+
if (channel.state === "open" || channel.state === "connecting") {
|
|
1866
|
+
const actions2 = document.createElement("div");
|
|
1867
|
+
actions2.className = "actions";
|
|
1868
|
+
actions2.append(button(`Close ${channel.id}`, () => request({ kind: "closesocket", id: channel.id }).then(() => status(`Channel ${channel.id} closed cleanly.`)).then(refresh)));
|
|
1869
|
+
card.append(actions2);
|
|
1870
|
+
}
|
|
1871
|
+
}
|
|
1872
|
+
for (const subscription of subscriptions) {
|
|
1873
|
+
const row = document.createElement("p");
|
|
1874
|
+
row.textContent = `sse ${subscription.state} \xB7 ${subscription.origin} \xB7 ${subscription.events} event${subscription.events === 1 ? "" : "s"}${subscription.names.length > 0 ? ` (${subscription.names.slice(0, 4).join(", ")}${subscription.names.length > 4 ? "\u2026" : ""})` : ""}${subscription.lasteventid !== void 0 ? ` \xB7 resume at ${subscription.lasteventid}` : ""} \xB7 cancel on ${subscription.cancel.kind}`;
|
|
1875
|
+
card.append(row);
|
|
1876
|
+
}
|
|
1877
|
+
netviewroot.append(card);
|
|
1878
|
+
}
|
|
1879
|
+
const pollevidence = (context.progress?.outcomes ?? []).filter((outcome) => outcome.details?.poll !== void 0).map((outcome) => outcome.details?.poll);
|
|
1880
|
+
if (pollevidence.length > 0) {
|
|
1881
|
+
const card = document.createElement("div");
|
|
1882
|
+
card.className = "panel";
|
|
1883
|
+
const head = document.createElement("p");
|
|
1884
|
+
head.textContent = `poll loops: ${pollevidence.length} iteration${pollevidence.length === 1 ? "" : "s"}`;
|
|
1885
|
+
card.append(head);
|
|
1886
|
+
for (const poll of pollevidence.slice(0, 8)) {
|
|
1887
|
+
const row = document.createElement("p");
|
|
1888
|
+
row.textContent = `poll ${poll.poll} \xB7 status ${poll.status}${poll.cursor !== void 0 ? ` \xB7 cursor ${poll.cursor}` : ""} \xB7 ${poll.stopped ? `stopped: ${poll.reason}` : "continuing"}`;
|
|
1889
|
+
card.append(row);
|
|
1890
|
+
}
|
|
1891
|
+
card.append(document.createRange().createContextualFragment(""));
|
|
1892
|
+
netviewroot.append(card);
|
|
1893
|
+
}
|
|
1894
|
+
const exchanges = context.exchanges ?? [];
|
|
1895
|
+
const list = document.createElement("div");
|
|
1896
|
+
if (exchanges.length === 0) {
|
|
1897
|
+
list.textContent = "No request of the run has been observed yet; grant request watching and run a watchrequests step.";
|
|
1898
|
+
}
|
|
1899
|
+
for (const exchange of exchanges) {
|
|
1900
|
+
const card = document.createElement("details");
|
|
1901
|
+
card.className = "panel callcard";
|
|
1902
|
+
const summary = document.createElement("summary");
|
|
1903
|
+
summary.textContent = `${exchange.method} ${exchange.status} ${exchange.statusclass} \xB7 ${new URL(exchange.url).host} \xB7 ${exchange.bytes} bytes \xB7 ${exchange.timing} ms \xB7 correlation ${exchange.correlationid} \xB7 ${exchange.source === "page" ? "derived" : "captured"}`;
|
|
1904
|
+
if (exchange.errorclass !== void 0) {
|
|
1905
|
+
const badge = document.createElement("span");
|
|
1906
|
+
badge.className = "credentialbadge";
|
|
1907
|
+
badge.textContent = ` ${exchange.errorclass} `;
|
|
1908
|
+
summary.append(badge);
|
|
1909
|
+
}
|
|
1910
|
+
card.append(summary);
|
|
1911
|
+
const urlrow = document.createElement("p");
|
|
1912
|
+
urlrow.textContent = `url: ${exchange.url}${exchange.mime !== void 0 ? ` \xB7 ${exchange.mime}` : ""}${exchange.bodyref !== void 0 ? ` \xB7 body ${exchange.bodyref}` : ""}${exchange.bodyexpired === true ? " \xB7 body expired from retention" : ""}`;
|
|
1913
|
+
card.append(urlrow);
|
|
1914
|
+
const requestheadernames = Object.keys(exchange.requestheaders ?? {});
|
|
1915
|
+
if (requestheadernames.length > 0 || Object.keys(exchange.responseheaders ?? {}).length > 0) {
|
|
1916
|
+
const headersrow = document.createElement("p");
|
|
1917
|
+
headersrow.textContent = `stored headers (redacted on the redaction list): request ${requestheadernames.length > 0 ? requestheadernames.join(", ") : "none"} \xB7 response ${Object.keys(exchange.responseheaders ?? {}).join(", ") || "none"}`;
|
|
1918
|
+
card.append(headersrow);
|
|
1919
|
+
} else {
|
|
1920
|
+
const headersrow = document.createElement("p");
|
|
1921
|
+
headersrow.className = "muted";
|
|
1922
|
+
headersrow.textContent = "no captured headers: derived page exchanges expose no header names through the timing buffers.";
|
|
1923
|
+
card.append(headersrow);
|
|
1924
|
+
}
|
|
1925
|
+
if (exchange.bodyref !== void 0 && exchange.bodyexpired !== true) {
|
|
1926
|
+
const bodyrow = document.createElement("p");
|
|
1927
|
+
bodyrow.textContent = `captured body ${exchange.bodyref}`;
|
|
1928
|
+
card.append(bodyrow);
|
|
1929
|
+
const actions2 = document.createElement("div");
|
|
1930
|
+
actions2.className = "actions";
|
|
1931
|
+
actions2.append(button(`Preview body ${exchange.bodyref}`, () => request({ kind: "exchangebody", ref: exchange.bodyref }).then((value) => {
|
|
1932
|
+
const record = value;
|
|
1933
|
+
bodyrow.textContent = `captured body ${exchange.bodyref} of ${record.mime} and ${record.bytes} bytes: ${record.body.slice(0, 400)}${record.body.length > 400 ? "\u2026 (display preview truncates; the stored body keeps every byte)" : ""}`;
|
|
1934
|
+
}).catch((error) => status(error instanceof Error ? error.message : String(error), true))));
|
|
1935
|
+
card.append(actions2);
|
|
1936
|
+
}
|
|
1937
|
+
list.append(card);
|
|
1938
|
+
}
|
|
1939
|
+
netviewroot.append(list);
|
|
1940
|
+
const apimap = context.apimap ?? [];
|
|
1941
|
+
if (apimap.length > 0) {
|
|
1942
|
+
const card = document.createElement("div");
|
|
1943
|
+
card.className = "panel";
|
|
1944
|
+
const head = document.createElement("p");
|
|
1945
|
+
head.textContent = `page api map: ${apimap.length} ranked endpoint${apimap.length === 1 ? "" : "s"}`;
|
|
1946
|
+
card.append(head);
|
|
1947
|
+
for (const entry of apimap.slice(0, 10)) {
|
|
1948
|
+
const row = document.createElement("p");
|
|
1949
|
+
row.textContent = `${entry.method} ${entry.endpoint} \xB7 ${entry.frequency} call${entry.frequency === 1 ? "" : "s"} \xB7 json ${Math.round(entry.jsonshare * 100)}% \xB7 stable ${Math.round(entry.stability * 100)}%${entry.payloadshape.length > 0 ? ` \xB7 ${entry.payloadshape.slice(0, 5).join(", ")}` : ""}`;
|
|
1950
|
+
card.append(row);
|
|
1951
|
+
}
|
|
1952
|
+
netviewroot.append(card);
|
|
1953
|
+
}
|
|
1954
|
+
const actions = document.createElement("div");
|
|
1955
|
+
actions.className = "actions";
|
|
1956
|
+
actions.append(button(`Export netlog (${exchanges.length} exchange${exchanges.length === 1 ? "" : "s"})`, () => request({ kind: "exportnetlog" }).then(() => status("Exported the captured run log through the reviewed download flow.")).catch((error) => status(error instanceof Error ? error.message : String(error), true))));
|
|
1957
|
+
if (active) {
|
|
1958
|
+
const retentioninput = document.createElement("input");
|
|
1959
|
+
retentioninput.placeholder = "captured body retention (records)";
|
|
1960
|
+
retentioninput.value = context.bodyretention !== void 0 ? String(context.bodyretention) : "";
|
|
1961
|
+
retentioninput.setAttribute("aria-label", "captured body retention window");
|
|
1962
|
+
actions.append(retentioninput, button("Save body retention", () => request({ kind: "setbodyretention", retention: retentioninput.value === "" ? void 0 : Number(retentioninput.value) }).then(() => status(`Captured body retention saved as ${retentioninput.value === "" ? "keep every body" : retentioninput.value} records; exchange metadata always survives.`)).then(refresh)));
|
|
1963
|
+
}
|
|
1964
|
+
netviewroot.append(actions);
|
|
1965
|
+
}
|
|
1836
1966
|
function rendercapabilities(report) {
|
|
1837
1967
|
if (!capabilitiestext) return;
|
|
1838
1968
|
if (!report) {
|
|
@@ -1885,6 +2015,7 @@ async function refresh() {
|
|
|
1885
2015
|
rendercaptures(context);
|
|
1886
2016
|
rendermedia(context);
|
|
1887
2017
|
rendercalls(context);
|
|
2018
|
+
rendernetview(context);
|
|
1888
2019
|
renderaudit(context.audit);
|
|
1889
2020
|
rendercapabilities(context.capabilities);
|
|
1890
2021
|
if (context.session?.pausedat) status("Session paused. Reviewed actions are blocked until resume.");
|