@wenathlan/extension 1.1.38 → 1.1.39
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.js +216 -4
- package/dist/index.js.map +2 -2
- package/dist/memory.d.ts +49 -1
- package/dist/memory.d.ts.map +1 -1
- package/dist/policy.d.ts +17 -1
- package/dist/policy.d.ts.map +1 -1
- package/dist/protocol.d.ts +22 -1
- package/dist/protocol.d.ts.map +1 -1
- package/dist/types.d.ts +116 -3
- package/dist/types.d.ts.map +1 -1
- package/dist/version.d.ts +1 -1
- package/extension/dist/background.js +761 -10
- package/extension/dist/background.js.map +4 -4
- package/extension/dist/manifest.json +1 -1
- package/extension/dist/pagebridge.js +14 -2
- package/extension/dist/pagebridge.js.map +3 -3
- package/extension/dist/popup.html +1 -1
- package/extension/dist/popup.js +31 -2
- package/extension/dist/popup.js.map +2 -2
- package/extension/dist/sidepanel.html +1 -1
- package/extension/dist/sidepanel.js +169 -2
- package/extension/dist/sidepanel.js.map +2 -2
- package/extension/manifest.json +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -2,18 +2,19 @@
|
|
|
2
2
|
|
|
3
3
|
Devthink is a **consent-first browser-agent bridge** distributed as a TypeScript library and a Chromium Manifest V3 extension. It turns a user-provided browser objective into a bounded, reviewable plan. The user must start the active-tab session and approve the plan before any page action reaches the browser.
|
|
4
4
|
|
|
5
|
-
Version: **1.1.
|
|
5
|
+
Version: **1.1.39**. License: **GPL-3.0-only**. The repository is `wenathlan/extension`; the npm-compatible scoped package identifier is `@wenathlan/extension`.
|
|
6
6
|
|
|
7
7
|
## What it does
|
|
8
8
|
|
|
9
|
-
| Capability | Behavior in 1.1.
|
|
9
|
+
| Capability | Behavior in 1.1.39 |
|
|
10
10
|
| --- | --- |
|
|
11
11
|
| Active-tab session | The user starts a short-lived session for one HTTPS tab and one origin; the session records its origin grants. |
|
|
12
12
|
| Page observation | The extension captures the complete semantic inventory: every interactive element, every form control, every select option and the full page text. |
|
|
13
13
|
| Plan proposal | A local plan can be created immediately; an optional user-configured HTTPS endpoint can return a typed plan proposal of any length. |
|
|
14
14
|
| Review gate | Every remote proposal starts in `pending`; it cannot reach the page bridge before explicit approval. |
|
|
15
|
-
| Browser tools | Reviewed plans cover two hundred
|
|
15
|
+
| Browser tools | Reviewed plans cover two hundred thirty one action kinds: pointer paths and coordinate clicks, text, aria, name, xpath, index and point target resolution, timed typing, key holds, sliders, dates, colors, shadow dom piercing, iframe entry, dialog answering, retry rules, a complete read vocabulary with clickable maps and verification reads, page mutation under review, and browser-level tab, window, zoom, snapshot and download commands. |
|
|
16
16
|
| Forms and data | The agent fills forms with review: `fillform` fills from a structured record of field matches, kinds and values, `filllabel` and `fillplaceholder` match controls by label, placeholder or aria label, `detectfields` reports the form map with field kinds, `generatevalues` seeds locale aware values per field kind while real looking card numbers and personal identifiers are refused, `saveprofiles` stores profiles behind origin grants, `asksubmit` opens the submission prompt with the values diff, `submitform` submits only under an approved consent ref, `readerrors` associates inline validation messages with fields, `retryform` retries with reviewed backoff windows, `runwizard`, `selectchain`, `picktypeahead` and `pickdate` drive wizards, dependent selects, typeaheads and calendars, `attachfile` attaches run store artifacts, `fillcard`, `fillcode` and `consentpassword` handle payment and secret fields behind explicit consent, `skiphoneypot` skips trap fields, `detectlogin` and `detecttemplate` flag login, signup and checkout shapes, and `handoffcaptcha` pauses the plan and hands control back to the user. |
|
|
17
|
+
| Files and downloads | The agent moves bytes with review: `batchdownload` downloads reviewed url lists in waves under a user configured concurrent window with per file states and sequence suffixes for filename conflicts, `pausedownload` and `resumedownload` walk the queue through the downloads api, `verifydownload` compares state, size and checksum against reviewed expectations, `interceptmime` arms include, exclude and deny default mime filters that reroute matching downloads into quarantine, `exportnetlog` exports the step correlated network log with every header value redacted, `readclipboard` needs an approved single use consent prompt per read and never persists the payload text, `writeclipboard` writes reviewed text through the page bridge with payload hashes for audit, `copyscreen` copies the visible tab to the clipboard, `quarantinedownload` and `scanvirus` keep files outside the downloads folder until a clean scan verdict releases them, `namecaptures` stamps task, step and sequence filenames with per task counters, and `cleanupartifacts` sweeps artifacts by reviewed age and kind rules while keeping open review references. |
|
|
17
18
|
| Datasets and exports | The agent turns pages into data with audit: `scrapetable` reads tables into normalized column keys with rowspan and colspan expansion and nested child datasets, `paginateextract` follows next controls while waiting for fresh rows, `mergepages` aligns columns across pages, `transformvalues` applies reviewed expressions with per rule error surfacing, `deduperows` deduplicates by reviewed keys, `stamplerows` stamps every row with its source url, timestamp and step ref, `previewgrid` previews the grid before export, `importcsv` parses quoted csv with column mappings for fill loops, `looprows` interpolates `{{column}}` row variables into the wrapped inner step, `exportcsv`, `exportjson` and `exportexcel` write checksummed artifacts into the task artifact store with provenance records, `copytable` uses the clipboard under the optional clipboardWrite capability, `pushsheets` pushes only to a reviewed HTTPS endpoint behind its origin grant and the explicit reviewed flag, `streamdisk` streams chunk by chunk with backpressure and a persisted resume state, `resumeextract` continues an interrupted extraction from its stored cursor, and `logprovenance` logs provenance for audit; exports refuse to leave local memory while the session origin grants do not cover the active origin. |
|
|
18
19
|
| Tabs and windows command | The agent commands the whole browser surface with review: `querytabs` resolves reviewed url, title, id and pattern matchers against the live tab set, `closepattern` closes matching tabs only under the explicit reviewed flag, `pintab`, `mutetab`, `movetab`, `movetabwindow`, `duplicatetab`, `reloadtabs`, `discardtab`, `zoomin`, `zoomout` and `switchtab` mutate tabs, `grouptabs`, `colorgroup` and `collapsegroup` keep group registries, `savelayout` and `restorelayout` save and restore named tab layouts with window bounds, `snapshotsession` and `reopenrun` capture and reopen whole runs, `watchtab` observes title, activation and closure events, `findclones`, `searchtabs` and `listaudio` enumerate the surface read only, `badgetab` and `attachmeta` route task state per tab, and `maximizewindow`, `minimizewindow`, `restorewindow`, `focuswindow`, `scratchwindow` and `incognitowindow` command windows with incognito separated from grant inheritance. |
|
|
19
20
|
| Navigation mastery | The agent moves anywhere with review: `openlink`, `openprivate`, `reopentab`, `deeplink` and `openclipboard` open reviewed targets in resolved containers, `followlink`, `spanav`, `spawait`, `waitload` and `waiturl` navigate pages and single page app routes, `rewritequery` and `setfragment` edit the current url, `navlist` walks a reviewed url list with per entry progress, `navprofile` applies per site wait profiles, `checksafe` verifies urls before unreviewed origins open, `batchopen` opens curated lists with per url safety states, `navrate` enforces per domain rate limits with user configured windows and ceilings, and the navigation trail, redirect chains and final urls stay recorded for audit. |
|
|
@@ -52,7 +53,7 @@ The endpoint field intentionally has no default URL. Enter a URL such as `https:
|
|
|
52
53
|
|
|
53
54
|
```json
|
|
54
55
|
{
|
|
55
|
-
"version": "1.1.
|
|
56
|
+
"version": "1.1.39",
|
|
56
57
|
"objective": "User supplied objective",
|
|
57
58
|
"session": { "id": "uuid", "tabid": 1, "origin": "https://example.com" },
|
|
58
59
|
"observation": { "schemaversion": 3, "url": "https://example.com/path", "interactive": [] },
|
package/dist/index.js
CHANGED
|
@@ -619,23 +619,136 @@ var sessionmemory = class {
|
|
|
619
619
|
async getexports() {
|
|
620
620
|
return await this.adapter.get("exports") ?? [];
|
|
621
621
|
}
|
|
622
|
+
/** Removes one exported data artifact by id and reports whether it existed. */
|
|
623
|
+
async removeexport(id) {
|
|
624
|
+
const records = await this.getexports();
|
|
625
|
+
const remaining = records.filter((item) => item.id !== id);
|
|
626
|
+
await this.adapter.set("exports", remaining);
|
|
627
|
+
return remaining.length !== records.length;
|
|
628
|
+
}
|
|
629
|
+
/** Removes one run store artifact by id and reports whether it existed. */
|
|
630
|
+
async removeartifact(id) {
|
|
631
|
+
const records = await this.getartifacts();
|
|
632
|
+
const remaining = records.filter((item) => item.id !== id);
|
|
633
|
+
await this.adapter.set("artifacts", remaining);
|
|
634
|
+
return remaining.length !== records.length;
|
|
635
|
+
}
|
|
636
|
+
/** Stores one batch download file record with its state, path and checksum, replacing the previous record of that id. */
|
|
637
|
+
async setdownload(record2) {
|
|
638
|
+
const records = (await this.adapter.get("downloads") ?? []).filter((item) => item.id !== record2.id);
|
|
639
|
+
await this.adapter.set("downloads", [record2, ...records]);
|
|
640
|
+
}
|
|
641
|
+
/** Returns every batch download file record with its state, path and checksum, newest first. */
|
|
642
|
+
async getdownloads() {
|
|
643
|
+
return await this.adapter.get("downloads") ?? [];
|
|
644
|
+
}
|
|
645
|
+
/** Records one captured network log record; netlog retention is a user setting and an absent value keeps every record. */
|
|
646
|
+
async addnetlog(record2) {
|
|
647
|
+
const records = await this.getnetlog();
|
|
648
|
+
const combined = [record2, ...records];
|
|
649
|
+
const retention = (await this.getsettings())?.netlogretention;
|
|
650
|
+
await this.adapter.set("netlog", retention === void 0 ? combined : combined.slice(0, retention));
|
|
651
|
+
}
|
|
652
|
+
/** Returns the captured network log of the run with its step correlation, newest first. */
|
|
653
|
+
async getnetlog() {
|
|
654
|
+
return await this.adapter.get("netlog") ?? [];
|
|
655
|
+
}
|
|
656
|
+
/** Stores one clipboard consent record with its prompt and origin, replacing the previous record of that id. */
|
|
657
|
+
async setclipconsent(record2) {
|
|
658
|
+
const records = (await this.adapter.get("clipconsents") ?? []).filter((item) => item.id !== record2.id);
|
|
659
|
+
await this.adapter.set("clipconsents", [record2, ...records]);
|
|
660
|
+
}
|
|
661
|
+
/** Returns every clipboard consent record with its prompt and origin, newest first. */
|
|
662
|
+
async getclipconsents() {
|
|
663
|
+
return await this.adapter.get("clipconsents") ?? [];
|
|
664
|
+
}
|
|
665
|
+
/** Records one clipboard entry hash with its origin provenance; the payload text itself never persists. */
|
|
666
|
+
async addclip(entry) {
|
|
667
|
+
const records = await this.getclips();
|
|
668
|
+
await this.adapter.set("clips", [entry, ...records]);
|
|
669
|
+
}
|
|
670
|
+
/** Returns every clipboard entry hash with its kind and origin provenance, newest first. */
|
|
671
|
+
async getclips() {
|
|
672
|
+
return await this.adapter.get("clips") ?? [];
|
|
673
|
+
}
|
|
674
|
+
/** Stores one quarantine entry with its scan verdict, replacing the previous entry of that id. */
|
|
675
|
+
async setquarantine(entry) {
|
|
676
|
+
const records = (await this.adapter.get("quarantines") ?? []).filter((item) => item.id !== entry.id);
|
|
677
|
+
await this.adapter.set("quarantines", [entry, ...records]);
|
|
678
|
+
}
|
|
679
|
+
/** Returns every quarantine entry with its scan verdict and release ref, newest first. */
|
|
680
|
+
async getquarantines() {
|
|
681
|
+
return await this.adapter.get("quarantines") ?? [];
|
|
682
|
+
}
|
|
683
|
+
/** Stores the reviewed cleanup rule set of the run, replacing the previous set. */
|
|
684
|
+
async setcleanuprules(rules) {
|
|
685
|
+
return this.adapter.set("cleanuprules", rules);
|
|
686
|
+
}
|
|
687
|
+
/** Returns the reviewed cleanup rule set of the run. */
|
|
688
|
+
async getcleanuprules() {
|
|
689
|
+
return await this.adapter.get("cleanuprules") ?? [];
|
|
690
|
+
}
|
|
691
|
+
/** Records one cleanup run in the run history. */
|
|
692
|
+
async addcleanuprun(run) {
|
|
693
|
+
const records = await this.getcleanupruns();
|
|
694
|
+
await this.adapter.set("cleanupruns", [run, ...records]);
|
|
695
|
+
}
|
|
696
|
+
/** Returns every cleanup run history record with removed and kept counts, newest first. */
|
|
697
|
+
async getcleanupruns() {
|
|
698
|
+
return await this.adapter.get("cleanupruns") ?? [];
|
|
699
|
+
}
|
|
700
|
+
/** Stores the capture naming counters of one task, replacing the previous counters of that task. */
|
|
701
|
+
async setcapturecounter(counter) {
|
|
702
|
+
const records = (await this.adapter.get("capturecounters") ?? []).filter((item) => item.taskid !== counter.taskid);
|
|
703
|
+
await this.adapter.set("capturecounters", [counter, ...records]);
|
|
704
|
+
}
|
|
705
|
+
/** Returns every stored capture naming counter per task, newest first. */
|
|
706
|
+
async getcapturecounters() {
|
|
707
|
+
return await this.adapter.get("capturecounters") ?? [];
|
|
708
|
+
}
|
|
709
|
+
/** Replaces the artifact inventory the cleanup sweeper plans against. */
|
|
710
|
+
async setinventory(entries) {
|
|
711
|
+
return this.adapter.set("inventory", entries);
|
|
712
|
+
}
|
|
713
|
+
/** Returns the artifact inventory with sizes and ages for the cleanup sweeper. */
|
|
714
|
+
async getinventory() {
|
|
715
|
+
return await this.adapter.get("inventory") ?? [];
|
|
716
|
+
}
|
|
717
|
+
/** Stores one user configured virus scanning hook, replacing the previous hook of that scanner name. */
|
|
718
|
+
async setscanhook(config) {
|
|
719
|
+
const records = (await this.adapter.get("scanhooks") ?? []).filter((item) => item.scanner !== config.scanner);
|
|
720
|
+
await this.adapter.set("scanhooks", [config, ...records]);
|
|
721
|
+
}
|
|
722
|
+
/** Returns every configured virus scanning hook, newest first. */
|
|
723
|
+
async getscanhooks() {
|
|
724
|
+
return await this.adapter.get("scanhooks") ?? [];
|
|
725
|
+
}
|
|
726
|
+
/** Stores the armed mime interception filters of the run, newest first. */
|
|
727
|
+
async setmimefilters(filters) {
|
|
728
|
+
return this.adapter.set("mimefilters", filters);
|
|
729
|
+
}
|
|
730
|
+
/** Returns the armed mime interception filters of the run, newest first. */
|
|
731
|
+
async getmimefilters() {
|
|
732
|
+
return await this.adapter.get("mimefilters") ?? [];
|
|
733
|
+
}
|
|
622
734
|
};
|
|
623
735
|
function randomid() {
|
|
624
736
|
return crypto.randomUUID();
|
|
625
737
|
}
|
|
626
738
|
|
|
627
739
|
// policy.ts
|
|
628
|
-
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"]);
|
|
740
|
+
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"]);
|
|
629
741
|
var interactionactions = /* @__PURE__ */ new Set(["focus", "scroll", "hover", "clickdeep", "rightclick", "doubleclick", "scrollpage", "scrollby", "scrollend", "scrolltop", "fullscreen", "zoomset", "movepointer", "clicktext", "clickaria", "clickname", "expanddetails", "pierceshadow", "retryaction"]);
|
|
630
|
-
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"]);
|
|
742
|
+
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"]);
|
|
631
743
|
var allowedactions = /* @__PURE__ */ new Set([...sensitiveactions, ...interactionactions, ...readactions]);
|
|
632
744
|
var watchactions = /* @__PURE__ */ new Set(["watchmutate", "watchbanner", "watchfocus", "watchtab"]);
|
|
633
745
|
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"]);
|
|
634
|
-
var valueactions = /* @__PURE__ */ new Set(["presskey", "drag", "drop", "upload", "readattribute", "removeattribute", "waittext", "evaluate", "zoomset", "tabactivate", "tabclose", "tabreload", "windowclose", "windowresize", "tabcreate", "windowcreate", "downloadfile", "typetime", "appendtext", "setvalue", "typeedit", "keyhold", "keyrelease", "chooseradio", "setslider", "setdate", "setcolor", "followlink", "setfragment", "handleauth", "navintent", "openclipboard", "checksafe", "reopentab", "spanav", "duplicatetab", "pintab", "mutetab", "movetab", "movetabwindow", "searchtabs", "badgetab", "attachmeta", "focuswindow", "maximizewindow", "minimizewindow", "restorewindow", "incognitowindow", "asksubmit", "selectchain", "picktypeahead", "pickdate", "attachfile", "fillcode", "consentpassword"]);
|
|
746
|
+
var valueactions = /* @__PURE__ */ new Set(["presskey", "drag", "drop", "upload", "readattribute", "removeattribute", "waittext", "evaluate", "zoomset", "tabactivate", "tabclose", "tabreload", "windowclose", "windowresize", "tabcreate", "windowcreate", "downloadfile", "typetime", "appendtext", "setvalue", "typeedit", "keyhold", "keyrelease", "chooseradio", "setslider", "setdate", "setcolor", "followlink", "setfragment", "handleauth", "navintent", "openclipboard", "checksafe", "reopentab", "spanav", "duplicatetab", "pintab", "mutetab", "movetab", "movetabwindow", "searchtabs", "badgetab", "attachmeta", "focuswindow", "maximizewindow", "minimizewindow", "restorewindow", "incognitowindow", "asksubmit", "selectchain", "picktypeahead", "pickdate", "attachfile", "fillcode", "consentpassword", "pausedownload", "resumedownload", "verifydownload", "writeclipboard", "quarantinedownload", "scanvirus"]);
|
|
635
747
|
var tabscommandactions = /* @__PURE__ */ new Set(["querytabs", "duplicatetab", "closepattern", "pintab", "mutetab", "movetab", "movetabwindow", "grouptabs", "colorgroup", "collapsegroup", "discardtab", "reloadtabs", "zoomin", "zoomout", "watchtab", "switchtab", "maximizewindow", "minimizewindow", "restorewindow", "focuswindow", "scratchwindow", "incognitowindow", "restoretab", "savelayout", "restorelayout", "findclones", "searchtabs", "badgetab", "attachmeta", "listaudio", "reopenrun", "snapshotsession"]);
|
|
636
748
|
var formactions = /* @__PURE__ */ new Set(["fillform", "filllabel", "fillplaceholder", "detectfields", "generatevalues", "saveprofiles", "asksubmit", "submitform", "readerrors", "retryform", "runwizard", "selectchain", "picktypeahead", "pickdate", "attachfile", "handoffcaptcha", "fillcard", "fillcode", "consentpassword", "skiphoneypot", "detectlogin", "detecttemplate"]);
|
|
637
749
|
var datasetactions = /* @__PURE__ */ new Set(["scrapetable", "exportcsv", "exportjson", "exportexcel", "copytable", "pushsheets", "importcsv", "looprows", "transformvalues", "deduperows", "paginateextract", "mergepages", "stamplerows", "previewgrid", "streamdisk", "resumeextract", "logprovenance"]);
|
|
638
750
|
var exportactions = /* @__PURE__ */ new Set(["exportcsv", "exportjson", "exportexcel", "copytable", "pushsheets", "streamdisk"]);
|
|
751
|
+
var filesactions = /* @__PURE__ */ new Set(["batchdownload", "pausedownload", "resumedownload", "verifydownload", "interceptmime", "exportnetlog", "readclipboard", "writeclipboard", "copyscreen", "quarantinedownload", "scanvirus", "namecaptures", "cleanupartifacts"]);
|
|
639
752
|
var fieldkinds = ["text", "email", "phone", "date", "number", "select", "check", "radio", "file", "password", "card", "code"];
|
|
640
753
|
var layoutmutationactions = /* @__PURE__ */ new Set(["grouptabs", "colorgroup", "collapsegroup", "savelayout", "restorelayout"]);
|
|
641
754
|
var groupcolors = ["grey", "blue", "red", "yellow", "green", "pink", "purple", "cyan", "orange"];
|
|
@@ -689,6 +802,9 @@ function isdatasetkind(kind) {
|
|
|
689
802
|
function isexportkind(kind) {
|
|
690
803
|
return exportactions.has(kind);
|
|
691
804
|
}
|
|
805
|
+
function isfileskind(kind) {
|
|
806
|
+
return filesactions.has(kind);
|
|
807
|
+
}
|
|
692
808
|
function exportgranted(session, origin) {
|
|
693
809
|
if (!origingranted(session, origin)) return { allowed: false, reason: `The export of extracted data from ${origin} needs the session origin grants before it leaves local memory.` };
|
|
694
810
|
return { allowed: true };
|
|
@@ -873,6 +989,81 @@ function validatedatagrammar(step, options, origin) {
|
|
|
873
989
|
if (kind === "logprovenance" && !isnonempty(options.artifact)) return { allowed: false, reason: "A reviewed artifact id or name is required in options." };
|
|
874
990
|
return { allowed: true };
|
|
875
991
|
}
|
|
992
|
+
function validatedownloadspec(value) {
|
|
993
|
+
if (!value || typeof value !== "object" || Array.isArray(value)) return { allowed: false, reason: "A reviewed downloadspec with a url list is required in options." };
|
|
994
|
+
const spec = value;
|
|
995
|
+
if (!Array.isArray(spec.urls) || spec.urls.length === 0 || !spec.urls.every((url) => ishttpsurl(url))) return { allowed: false, reason: "The reviewed downloadspec needs a non-empty list of HTTPS urls." };
|
|
996
|
+
if (spec.filename !== void 0 && !isnonempty(spec.filename)) return { allowed: false, reason: "The reviewed downloadspec filename rule must be a non-empty string." };
|
|
997
|
+
if (spec.complete !== void 0 && spec.complete !== "size" && spec.complete !== "checksum") return { allowed: false, reason: "The reviewed downloadspec completion criterion must be size or checksum." };
|
|
998
|
+
return { allowed: true };
|
|
999
|
+
}
|
|
1000
|
+
function validatemimefilter(value) {
|
|
1001
|
+
if (!value || typeof value !== "object" || Array.isArray(value)) return { allowed: false, reason: "A reviewed mimefilter with include and exclude patterns is required in options." };
|
|
1002
|
+
const filter = value;
|
|
1003
|
+
if (!Array.isArray(filter.include) || filter.include.length === 0 || !filter.include.every((pattern) => isnonempty(pattern))) return { allowed: false, reason: "The reviewed mimefilter needs a non-empty list of include patterns." };
|
|
1004
|
+
if (filter.exclude !== void 0 && (!Array.isArray(filter.exclude) || !filter.exclude.every((pattern) => isnonempty(pattern)))) return { allowed: false, reason: "The reviewed mimefilter exclude patterns must be a list of non-empty strings." };
|
|
1005
|
+
if (filter.default !== "deny" && filter.default !== "allow") return { allowed: false, reason: "The reviewed mimefilter needs the deny or allow default for unlisted mime types." };
|
|
1006
|
+
return { allowed: true };
|
|
1007
|
+
}
|
|
1008
|
+
function validatecleanuprule(value) {
|
|
1009
|
+
if (!value || typeof value !== "object" || Array.isArray(value)) return { allowed: false, reason: "A reviewed cleanuprule with an age, a kind and a keep policy is required." };
|
|
1010
|
+
const rule = value;
|
|
1011
|
+
if (typeof rule.age !== "number" || !Number.isFinite(rule.age) || rule.age <= 0) return { allowed: false, reason: "The reviewed cleanup age window must be a positive number of milliseconds with no code ceiling." };
|
|
1012
|
+
if (!isnonempty(rule.kind)) return { allowed: false, reason: "The reviewed cleanup rule needs a non-empty artifact kind, or any to match every kind." };
|
|
1013
|
+
if (rule.keep !== "none" && rule.keep !== "latest" && rule.keep !== "all") return { allowed: false, reason: "The reviewed cleanup keep policy must be none, latest or all." };
|
|
1014
|
+
return { allowed: true };
|
|
1015
|
+
}
|
|
1016
|
+
function validatefilesgrammar(step, options) {
|
|
1017
|
+
const kind = step.kind;
|
|
1018
|
+
if (kind === "batchdownload") {
|
|
1019
|
+
const speccheck = validatedownloadspec(options.downloadspec);
|
|
1020
|
+
if (!speccheck.allowed) return speccheck;
|
|
1021
|
+
if (options.concurrent !== void 0 && (typeof options.concurrent !== "number" || !Number.isInteger(options.concurrent) || options.concurrent < 1)) return { allowed: false, reason: "The reviewed concurrent download window must be a positive integer with no code ceiling." };
|
|
1022
|
+
}
|
|
1023
|
+
if (kind === "pausedownload" || kind === "resumedownload" || kind === "verifydownload" || kind === "quarantinedownload" || kind === "scanvirus") {
|
|
1024
|
+
if (!isnonempty(step.value)) return { allowed: false, reason: "A reviewed download or quarantine reference is required." };
|
|
1025
|
+
if (kind === "verifydownload") {
|
|
1026
|
+
if (options.checksum !== void 0 && !isnonempty(options.checksum)) return { allowed: false, reason: "The reviewed expected checksum must be a non-empty string." };
|
|
1027
|
+
if (options.bytes !== void 0 && (typeof options.bytes !== "number" || !Number.isFinite(options.bytes) || options.bytes < 0)) return { allowed: false, reason: "The reviewed expected size must be zero or a positive number of bytes." };
|
|
1028
|
+
}
|
|
1029
|
+
if (kind === "scanvirus" && options.scanner !== void 0 && !isnonempty(options.scanner)) return { allowed: false, reason: "The reviewed scanner name must be a non-empty string." };
|
|
1030
|
+
if (kind === "quarantinedownload" && options.reason !== void 0 && !isnonempty(options.reason)) return { allowed: false, reason: "The reviewed quarantine reason must be a non-empty string." };
|
|
1031
|
+
}
|
|
1032
|
+
if (kind === "interceptmime") {
|
|
1033
|
+
const filtercheck = validatemimefilter(options.mimefilter);
|
|
1034
|
+
if (!filtercheck.allowed) return filtercheck;
|
|
1035
|
+
}
|
|
1036
|
+
if (kind === "readclipboard") {
|
|
1037
|
+
if (!isnonempty(options.consentref)) return { allowed: false, reason: "A clipboard read requires a reviewed consent ref of an approved consent prompt in options." };
|
|
1038
|
+
if (options.prompt !== void 0 && !isnonempty(options.prompt)) return { allowed: false, reason: "The reviewed clipboard consent prompt must be a non-empty string." };
|
|
1039
|
+
}
|
|
1040
|
+
if (kind === "exportnetlog" && options.stepid !== void 0 && !isnonempty(options.stepid)) return { allowed: false, reason: "The reviewed netlog step filter must be a non-empty step id." };
|
|
1041
|
+
if (kind === "namecaptures") {
|
|
1042
|
+
if (!isnonempty(options.task)) return { allowed: false, reason: "A reviewed task id is required in options for capture naming." };
|
|
1043
|
+
if (options.steps !== void 0 && (!Array.isArray(options.steps) || options.steps.length === 0 || !options.steps.every((item) => isnonempty(item)))) return { allowed: false, reason: "The reviewed capture steps must be a non-empty list of step ids when present." };
|
|
1044
|
+
if (options.extension !== void 0 && !isnonempty(options.extension)) return { allowed: false, reason: "The reviewed capture extension must be a non-empty string." };
|
|
1045
|
+
}
|
|
1046
|
+
if (kind === "cleanupartifacts" && options.rules !== void 0) {
|
|
1047
|
+
const rules = options.rules;
|
|
1048
|
+
if (!Array.isArray(rules) || rules.length === 0) return { allowed: false, reason: "The reviewed cleanup rules must be a non-empty list when present." };
|
|
1049
|
+
for (const item of rules) {
|
|
1050
|
+
const rulecheck = validatecleanuprule(item);
|
|
1051
|
+
if (!rulecheck.allowed) return rulecheck;
|
|
1052
|
+
}
|
|
1053
|
+
}
|
|
1054
|
+
return { allowed: true };
|
|
1055
|
+
}
|
|
1056
|
+
function clipboardconsentgranted(step) {
|
|
1057
|
+
let options = {};
|
|
1058
|
+
try {
|
|
1059
|
+
options = parseoptions(step);
|
|
1060
|
+
} catch {
|
|
1061
|
+
options = {};
|
|
1062
|
+
}
|
|
1063
|
+
const consentref = options.consentref;
|
|
1064
|
+
if (typeof consentref !== "string" || !consentref.trim()) return { allowed: false, reason: "A clipboard read requires a reviewed consent ref in options." };
|
|
1065
|
+
return { allowed: true };
|
|
1066
|
+
}
|
|
876
1067
|
function submitreviewgranted(steps, submitid) {
|
|
877
1068
|
const position = steps.findIndex((candidate) => candidate.id === submitid);
|
|
878
1069
|
const asked = steps.some((candidate, index) => candidate.kind === "asksubmit" && (position === -1 || index < position));
|
|
@@ -1395,6 +1586,10 @@ function validatestep(step, origin) {
|
|
|
1395
1586
|
const datacheck = validatedatagrammar(step, options, origin);
|
|
1396
1587
|
if (!datacheck.allowed) return datacheck;
|
|
1397
1588
|
}
|
|
1589
|
+
if (isfileskind(step.kind)) {
|
|
1590
|
+
const filescheck = validatefilesgrammar(step, options);
|
|
1591
|
+
if (!filescheck.allowed) return filescheck;
|
|
1592
|
+
}
|
|
1398
1593
|
if (step.kind === "tabcreate") {
|
|
1399
1594
|
if (options.background !== void 0 && typeof options.background !== "boolean") return { allowed: false, reason: "The reviewed background flag must be a boolean." };
|
|
1400
1595
|
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." };
|
|
@@ -1449,6 +1644,11 @@ function canexecute(input) {
|
|
|
1449
1644
|
const consentgate = passwordconsentgranted(input.step);
|
|
1450
1645
|
if (!consentgate.allowed) return consentgate;
|
|
1451
1646
|
}
|
|
1647
|
+
if (input.step.kind === "readclipboard") {
|
|
1648
|
+
const clipgate = clipboardconsentgranted(input.step);
|
|
1649
|
+
if (!clipgate.allowed) return clipgate;
|
|
1650
|
+
}
|
|
1651
|
+
if (input.step.kind === "interceptmime" && !origingranted(input.session, input.origin)) return { allowed: false, reason: "The download interception is outside the session origin grants." };
|
|
1452
1652
|
if (input.step.kind === "openlink" || input.step.kind === "openprivate" || input.step.kind === "batchopen" || input.step.kind === "prefetch" || input.step.kind === "deeplink" || input.step.kind === "reopentab") {
|
|
1453
1653
|
let options = {};
|
|
1454
1654
|
try {
|
|
@@ -1470,7 +1670,7 @@ function canexecute(input) {
|
|
|
1470
1670
|
}
|
|
1471
1671
|
|
|
1472
1672
|
// version.ts
|
|
1473
|
-
var packageversion = "1.1.
|
|
1673
|
+
var packageversion = "1.1.39";
|
|
1474
1674
|
|
|
1475
1675
|
// types.ts
|
|
1476
1676
|
var protocolversion = packageversion;
|
|
@@ -1602,11 +1802,21 @@ function provenancereport(input) {
|
|
|
1602
1802
|
function transformgrammar(rules) {
|
|
1603
1803
|
return JSON.stringify({ rules: rules.map((rule) => ({ expression: rule.expression, sources: rule.sources, target: rule.target })) });
|
|
1604
1804
|
}
|
|
1805
|
+
function downloadreport(input) {
|
|
1806
|
+
return JSON.stringify({ version: protocolversion, planid: input.plan.id, planstate: input.plan.state, downloads: input.downloads });
|
|
1807
|
+
}
|
|
1808
|
+
function netlogreport(input) {
|
|
1809
|
+
return { version: protocolversion, records: input.records };
|
|
1810
|
+
}
|
|
1811
|
+
function quarantinereport(input) {
|
|
1812
|
+
return { version: protocolversion, entries: input.entries };
|
|
1813
|
+
}
|
|
1605
1814
|
export {
|
|
1606
1815
|
canexecute,
|
|
1607
1816
|
datasetresponse,
|
|
1608
1817
|
actionrisk as deriveactionrisk,
|
|
1609
1818
|
diffresponse,
|
|
1819
|
+
downloadreport,
|
|
1610
1820
|
errorreportresponse,
|
|
1611
1821
|
eventresponse,
|
|
1612
1822
|
extractionreport,
|
|
@@ -1619,6 +1829,7 @@ export {
|
|
|
1619
1829
|
layoutreport,
|
|
1620
1830
|
mapresponse,
|
|
1621
1831
|
navstateresponse,
|
|
1832
|
+
netlogreport,
|
|
1622
1833
|
normalizeendpoint,
|
|
1623
1834
|
observationmodeof,
|
|
1624
1835
|
observationresponse,
|
|
@@ -1628,6 +1839,7 @@ export {
|
|
|
1628
1839
|
profilegrantgranted,
|
|
1629
1840
|
protocolversion,
|
|
1630
1841
|
provenancereport,
|
|
1842
|
+
quarantinereport,
|
|
1631
1843
|
randomid,
|
|
1632
1844
|
requestbody,
|
|
1633
1845
|
resolutionverdict,
|