@wenathlan/extension 1.1.49 → 1.1.50
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 +6 -5
- package/dist/index.d.ts +2 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +878 -5
- package/dist/index.js.map +4 -4
- package/dist/memory.d.ts +34 -1
- package/dist/memory.d.ts.map +1 -1
- package/dist/policy.d.ts +16 -1
- package/dist/policy.d.ts.map +1 -1
- package/dist/protocol.d.ts +68 -0
- package/dist/protocol.d.ts.map +1 -1
- package/dist/types.d.ts +157 -3
- package/dist/types.d.ts.map +1 -1
- package/dist/version.d.ts +1 -1
- package/dist/workflow.d.ts +148 -0
- package/dist/workflow.d.ts.map +1 -0
- package/extension/dist/background.js +1189 -48
- package/extension/dist/background.js.map +4 -4
- package/extension/dist/manifest.json +1 -1
- package/extension/dist/pagebridge.js +2 -2
- package/extension/dist/pagebridge.js.map +2 -2
- package/extension/dist/popup.html +1 -1
- package/extension/dist/popup.js +46 -2
- package/extension/dist/popup.js.map +2 -2
- package/extension/dist/sidepanel.html +1 -1
- package/extension/dist/sidepanel.js +179 -2
- 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>Network view</h2><div id="netview" class="panel"></div></section><section><h2>Traffic control</h2><div id="traffic" class="panel"></div></section><section><h2>Run timeline</h2><div id="timeline" class="panel"></div></section><section><h2>Debugger</h2><div id="debugger" class="panel"></div></section><section><h2>Profiling</h2><div id="profiling" class="panel"></div></section><section><h2>Emulation</h2><div id="emulation" class="panel"></div></section><section><h2>Sessions</h2><div id="sessions" class="panel"></div></section><section><h2>Console diff</h2><div id="consolediff" 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>Run timeline</h2><div id="timeline" class="panel"></div></section><section><h2>Debugger</h2><div id="debugger" class="panel"></div></section><section><h2>Profiling</h2><div id="profiling" class="panel"></div></section><section><h2>Emulation</h2><div id="emulation" class="panel"></div></section><section><h2>Sessions</h2><div id="sessions" class="panel"></div></section><section><h2>Workflows</h2><div id="workflows" class="panel"></div></section><section><h2>Console diff</h2><div id="consolediff" 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", "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"]);
|
|
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", "attachcdp", "detachcdp", "cdpcmd", "overridescript", "heapshot", "profilecpu", "capturesourcemaps", "emulatedevice", "emulatenetwork", "emulatelocate", "setuseragent", "overridepermission", "restoresession", "exportsessions", "importsessions", "runworkflow"]);
|
|
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", "setbreakpoint", "stepcode", "watchexpr"]);
|
|
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", "watchconsole", "watcherrors", "watchtasks", "watchcdp", "measureflow", "trackmemory", "watchshifts", "traceload", "annotatetrace", "replaytrace", "blackboxscripts", "persiststate", "capturesession", "namedsessions", "diffsessions", "searchsessions"]);
|
|
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", "watchconsole", "watcherrors", "watchtasks", "watchcdp", "measureflow", "trackmemory", "watchshifts", "traceload", "annotatetrace", "replaytrace", "blackboxscripts", "persiststate", "capturesession", "namedsessions", "diffsessions", "searchsessions", "composeworkflow", "savetemplate", "dryrun", "delay", "waitelement", "compute", "extractvars"]);
|
|
5
5
|
var allowedactions = /* @__PURE__ */ new Set([...sensitiveactions, ...interactionactions, ...readactions]);
|
|
6
6
|
|
|
7
7
|
// extension/tabscommand.ts
|
|
@@ -74,7 +74,9 @@ var profilingroot = document.querySelector("#profiling");
|
|
|
74
74
|
var emulationroot = document.querySelector("#emulation");
|
|
75
75
|
var netviewroot = document.querySelector("#netview");
|
|
76
76
|
var sessionsroot = document.querySelector("#sessions");
|
|
77
|
+
var workflowsroot = document.querySelector("#workflows");
|
|
77
78
|
var sessionsview = { term: "", window: "all", diffselection: [], restorereview: void 0, importreview: void 0 };
|
|
79
|
+
var workflowview = { review: void 0, selected: "" };
|
|
78
80
|
var statusnode = document.querySelector("#status");
|
|
79
81
|
var progressnode = document.querySelector("#planprogress");
|
|
80
82
|
var capabilitiestext = document.querySelector("#capabilitiestext");
|
|
@@ -2536,6 +2538,7 @@ async function refresh() {
|
|
|
2536
2538
|
renderprofiling(context);
|
|
2537
2539
|
renderemulation(context);
|
|
2538
2540
|
rendersessions(context);
|
|
2541
|
+
renderworkflows(context);
|
|
2539
2542
|
renderconsolediff();
|
|
2540
2543
|
renderaudit(context.audit);
|
|
2541
2544
|
rendercapabilities(context.capabilities);
|
|
@@ -2915,4 +2918,178 @@ function renderrestorereview(record) {
|
|
|
2915
2918
|
}));
|
|
2916
2919
|
sessionsroot.append(review);
|
|
2917
2920
|
}
|
|
2921
|
+
function renderworkflows(context) {
|
|
2922
|
+
if (!workflowsroot) return;
|
|
2923
|
+
workflowsroot.replaceChildren();
|
|
2924
|
+
const state = context.workflow;
|
|
2925
|
+
const runs = state?.runs ?? [];
|
|
2926
|
+
const running = runs.filter((run) => run.state === "running");
|
|
2927
|
+
const latest = runs[0];
|
|
2928
|
+
const title = document.createElement("p");
|
|
2929
|
+
title.textContent = `${state?.workflows.length ?? 0} composed workflow${(state?.workflows.length ?? 0) === 1 ? "" : "s"} \xB7 ${running.length} running in the background \xB7 ${state?.templates.length ?? 0} shared step template${(state?.templates.length ?? 0) === 1 ? "" : "s"}.`;
|
|
2930
|
+
workflowsroot.append(title);
|
|
2931
|
+
for (const record of state?.workflows ?? []) {
|
|
2932
|
+
const row = document.createElement("div");
|
|
2933
|
+
row.className = "sessionrow";
|
|
2934
|
+
const headline = document.createElement("p");
|
|
2935
|
+
const badge = document.createElement("span");
|
|
2936
|
+
badge.className = "sessionbadge";
|
|
2937
|
+
badge.dataset.restored = "false";
|
|
2938
|
+
badge.textContent = record.risk === "sensitive" ? "sensitive" : record.risk;
|
|
2939
|
+
headline.append(`${record.name} v${record.version} \xB7 ${record.steps.length} steps \xB7 ${record.origins.join(", ")}`, badge);
|
|
2940
|
+
row.append(headline);
|
|
2941
|
+
const actions = document.createElement("div");
|
|
2942
|
+
actions.className = "actions";
|
|
2943
|
+
const planstep = (kind) => context.plan?.state === "approved" ? context.plan.steps.find((step) => step.kind === kind && (() => {
|
|
2944
|
+
try {
|
|
2945
|
+
return JSON.parse(step.options ?? "{}").workflowid === record.id;
|
|
2946
|
+
} catch {
|
|
2947
|
+
return false;
|
|
2948
|
+
}
|
|
2949
|
+
})()) : void 0;
|
|
2950
|
+
const runstepofplan = planstep("runworkflow");
|
|
2951
|
+
const drystepofplan = planstep("dryrun");
|
|
2952
|
+
actions.append(button("Review expanded steps", async () => {
|
|
2953
|
+
const review = await request({ kind: "workflowreview", workflowid: record.id });
|
|
2954
|
+
workflowview.review = { workflowid: record.id, name: record.name, risk: record.risk, steps: review.steps };
|
|
2955
|
+
status(`Workflow review: ${review.steps.length} expanded steps of ${record.name}.`);
|
|
2956
|
+
await refresh();
|
|
2957
|
+
}));
|
|
2958
|
+
actions.append(" ", button("Approve run review", async () => {
|
|
2959
|
+
const result = await request({ kind: "approveworkflowrun", workflowid: record.id });
|
|
2960
|
+
status(`Run review approved: ${result.steps} steps shown; the plan review still gates every run.`);
|
|
2961
|
+
await refresh();
|
|
2962
|
+
}));
|
|
2963
|
+
actions.append(" ", button("Run reviewed workflow", async () => {
|
|
2964
|
+
if (!runstepofplan) {
|
|
2965
|
+
status("No approved runworkflow step of this workflow is in the plan.", true);
|
|
2966
|
+
return;
|
|
2967
|
+
}
|
|
2968
|
+
const result = await request({ kind: "execute", stepid: runstepofplan.id });
|
|
2969
|
+
status(result.summary);
|
|
2970
|
+
await refresh();
|
|
2971
|
+
}, runstepofplan === void 0));
|
|
2972
|
+
actions.append(" ", button("Dry run", async () => {
|
|
2973
|
+
if (!drystepofplan) {
|
|
2974
|
+
status("No approved dryrun step of this workflow is in the plan.", true);
|
|
2975
|
+
return;
|
|
2976
|
+
}
|
|
2977
|
+
const result = await request({ kind: "execute", stepid: drystepofplan.id });
|
|
2978
|
+
status(result.summary);
|
|
2979
|
+
await refresh();
|
|
2980
|
+
}, drystepofplan === void 0));
|
|
2981
|
+
row.append(actions);
|
|
2982
|
+
workflowsroot.append(row);
|
|
2983
|
+
}
|
|
2984
|
+
if ((state?.workflows.length ?? 0) === 0) {
|
|
2985
|
+
const empty = document.createElement("p");
|
|
2986
|
+
empty.textContent = "No composed workflow yet; run a composeworkflow step to freeze a reviewed step list.";
|
|
2987
|
+
workflowsroot.append(empty);
|
|
2988
|
+
}
|
|
2989
|
+
if (workflowview.review) {
|
|
2990
|
+
const review = document.createElement("div");
|
|
2991
|
+
review.className = "sessionrow";
|
|
2992
|
+
const headline = document.createElement("p");
|
|
2993
|
+
headline.textContent = `Workflow approval of ${workflowview.review.name} (${workflowview.review.risk} for review): every expanded step shows before the first real run.`;
|
|
2994
|
+
review.append(headline);
|
|
2995
|
+
const list = document.createElement("ol");
|
|
2996
|
+
for (const step of workflowview.review.steps) {
|
|
2997
|
+
const line = document.createElement("li");
|
|
2998
|
+
line.textContent = `${step.label} (${step.kind}${step.block !== void 0 ? ` \xB7 block ${step.block}` : ""}${step.target !== void 0 ? ` \xB7 ${step.target}` : ""}${step.expression !== void 0 ? ` \xB7 expression ${step.expression.operator} into ${step.expression.result}` : ""}${step.extract !== void 0 && step.extract.groups.length > 0 ? ` \xB7 extracts ${step.extract.groups.join(", ")}` : ""}${Array.isArray(step.bindings) && step.bindings.length > 0 ? ` \xB7 ${step.bindings.length} binding${step.bindings.length === 1 ? "" : "s"}` : ""}`;
|
|
2999
|
+
list.append(line);
|
|
3000
|
+
}
|
|
3001
|
+
review.append(list);
|
|
3002
|
+
review.append(button("Close workflow review", async () => {
|
|
3003
|
+
workflowview.review = void 0;
|
|
3004
|
+
status("Workflow review closed.");
|
|
3005
|
+
await refresh();
|
|
3006
|
+
}));
|
|
3007
|
+
workflowsroot.append(review);
|
|
3008
|
+
}
|
|
3009
|
+
if (latest) {
|
|
3010
|
+
const timeline = document.createElement("details");
|
|
3011
|
+
timeline.className = "sessiongroup";
|
|
3012
|
+
timeline.open = latest.state === "running" || latest.state === "paused";
|
|
3013
|
+
const summary = document.createElement("summary");
|
|
3014
|
+
summary.textContent = `Run ${latest.id.slice(0, 8)} of ${latest.workflowid.slice(0, 8)}: ${latest.state}${latest.dryrun === true ? " (dry run)" : ""} at step cursor ${latest.cursor}.`;
|
|
3015
|
+
timeline.append(summary);
|
|
3016
|
+
const controls = document.createElement("div");
|
|
3017
|
+
controls.className = "actions";
|
|
3018
|
+
controls.append(button("Pause run", async () => {
|
|
3019
|
+
const result = await request({ kind: "pauseworkflowrun", runid: latest.id });
|
|
3020
|
+
status(`Workflow run ${result.state}.`);
|
|
3021
|
+
await refresh();
|
|
3022
|
+
}, latest.state !== "running"));
|
|
3023
|
+
controls.append(" ", button("Resume run", async () => {
|
|
3024
|
+
const result = await request({ kind: "resumeworkflowrun", runid: latest.id });
|
|
3025
|
+
status(`Workflow run resumed and ended ${result.state} at cursor ${result.cursor}.`);
|
|
3026
|
+
await refresh();
|
|
3027
|
+
}, latest.state !== "paused"));
|
|
3028
|
+
controls.append(" ", button("Cancel run", async () => {
|
|
3029
|
+
const result = await request({ kind: "cancelworkflowrun", runid: latest.id, reason: "sidepanel cancel" });
|
|
3030
|
+
status(`Workflow run ${result.state}.`);
|
|
3031
|
+
await refresh();
|
|
3032
|
+
}, latest.state === "done" || latest.state === "cancelled"));
|
|
3033
|
+
timeline.append(controls);
|
|
3034
|
+
const record = state?.workflows.find((entry) => entry.id === latest.workflowid);
|
|
3035
|
+
if (record) {
|
|
3036
|
+
const steps = document.createElement("ol");
|
|
3037
|
+
for (const [index, step] of record.steps.entries()) {
|
|
3038
|
+
const line = document.createElement("li");
|
|
3039
|
+
const entry = state?.log.find((candidate) => candidate.stepid === step.id);
|
|
3040
|
+
const done = index < latest.cursor;
|
|
3041
|
+
line.textContent = `${step.label} (${step.kind}${step.block !== void 0 ? ` \xB7 block ${step.block}` : ""})${done ? ` \xB7 done${entry?.checkpoint === true ? " \xB7 checkpointed" : ""}` : ""}${entry !== void 0 ? ` \xB7 ${entry.state}: ${entry.summary}` : ""}`;
|
|
3042
|
+
line.dataset.class = entry?.state === "failed" || entry?.state === "refused" ? "changed" : done ? "added" : "unavailable";
|
|
3043
|
+
if (step.block !== void 0 && index === latest.cursor) line.dataset.blockactive = "true";
|
|
3044
|
+
const singlestep = document.createElement("div");
|
|
3045
|
+
singlestep.className = "actions";
|
|
3046
|
+
singlestep.append(button("Run single step", async () => {
|
|
3047
|
+
const outcome = await request({ kind: "executeworkflowstep", runid: latest.id, stepid: step.id });
|
|
3048
|
+
status(outcome.steps[0] ? `Single step ${outcome.steps[0].state}: ${outcome.steps[0].summary}` : "The single step returned no outcome.");
|
|
3049
|
+
await refresh();
|
|
3050
|
+
}));
|
|
3051
|
+
line.append(singlestep);
|
|
3052
|
+
steps.append(line);
|
|
3053
|
+
}
|
|
3054
|
+
timeline.append(steps);
|
|
3055
|
+
}
|
|
3056
|
+
const runlog = document.createElement("div");
|
|
3057
|
+
for (const entry of state?.log ?? []) {
|
|
3058
|
+
const line = document.createElement("p");
|
|
3059
|
+
line.textContent = `${entry.state} \xB7 ${entry.label} \xB7 ${entry.duration} ms${entry.produced !== void 0 && entry.produced.length > 0 ? ` \xB7 produced ${entry.produced.join(", ")}` : ""}${entry.consumed !== void 0 && entry.consumed.length > 0 ? ` \xB7 consumed ${entry.consumed.join(", ")}` : ""} \xB7 ${entry.summary}`;
|
|
3060
|
+
line.dataset.class = entry.state === "failed" || entry.state === "refused" ? "changed" : "added";
|
|
3061
|
+
runlog.append(line);
|
|
3062
|
+
}
|
|
3063
|
+
timeline.append(runlog);
|
|
3064
|
+
workflowsroot.append(timeline);
|
|
3065
|
+
const scopes = state?.scopes ?? [];
|
|
3066
|
+
if (scopes.length > 0) {
|
|
3067
|
+
const scopeview = document.createElement("details");
|
|
3068
|
+
scopeview.className = "sessiongroup";
|
|
3069
|
+
const scopesummary = document.createElement("summary");
|
|
3070
|
+
scopesummary.textContent = `Variables per scope (${scopes.reduce((total, scope) => total + scope.variables.length, 0)} values)`;
|
|
3071
|
+
scopeview.append(scopesummary);
|
|
3072
|
+
for (const scope of scopes) {
|
|
3073
|
+
const line = document.createElement("p");
|
|
3074
|
+
line.textContent = `Scope ${scope.name}${scope.parent !== void 0 ? ` (child of ${scope.parent})` : ""}: ${scope.variables.length === 0 ? "no variable" : scope.variables.map((variable) => `${variable.name} = ${Array.isArray(variable.value) ? `[${variable.value.join(", ")}]` : String(variable.value)} (${variable.kind})`).join(" \xB7 ")}`;
|
|
3075
|
+
scopeview.append(line);
|
|
3076
|
+
}
|
|
3077
|
+
workflowsroot.append(scopeview);
|
|
3078
|
+
}
|
|
3079
|
+
const provenance = state?.provenance ?? [];
|
|
3080
|
+
if (provenance.length > 0) {
|
|
3081
|
+
const provenanceview = document.createElement("details");
|
|
3082
|
+
provenanceview.className = "sessiongroup";
|
|
3083
|
+
const provsummary = document.createElement("summary");
|
|
3084
|
+
provsummary.textContent = `Provenance (${provenance.length} entries)`;
|
|
3085
|
+
provenanceview.append(provsummary);
|
|
3086
|
+
for (const entry of provenance.slice(-12)) {
|
|
3087
|
+
const line = document.createElement("p");
|
|
3088
|
+
line.textContent = `${entry.kind} \xB7 ${entry.name} = ${Array.isArray(entry.value) ? `[${entry.value.join(", ")}]` : String(entry.value)}`;
|
|
3089
|
+
provenanceview.append(line);
|
|
3090
|
+
}
|
|
3091
|
+
workflowsroot.append(provenanceview);
|
|
3092
|
+
}
|
|
3093
|
+
}
|
|
3094
|
+
}
|
|
2918
3095
|
//# sourceMappingURL=sidepanel.js.map
|