@wenathlan/extension 1.1.53 → 1.1.54
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 +3 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +999 -543
- package/dist/index.js.map +4 -4
- package/dist/mcpserver.d.ts +167 -0
- package/dist/mcpserver.d.ts.map +1 -0
- package/dist/memory.d.ts +27 -1
- package/dist/memory.d.ts.map +1 -1
- package/dist/policy.d.ts +25 -1
- package/dist/policy.d.ts.map +1 -1
- package/dist/protocol.d.ts +24 -1
- package/dist/protocol.d.ts.map +1 -1
- package/dist/toolcatalog.d.ts +31 -0
- package/dist/toolcatalog.d.ts.map +1 -0
- package/dist/types.d.ts +164 -3
- package/dist/types.d.ts.map +1 -1
- package/dist/version.d.ts +1 -1
- package/extension/dist/background.js +534 -4
- package/extension/dist/background.js.map +3 -3
- package/extension/dist/manifest.json +1 -1
- package/extension/dist/pagebridge.js +1 -1
- package/extension/dist/pagebridge.js.map +2 -2
- package/extension/dist/popup.html +1 -1
- package/extension/dist/popup.js +12 -1
- package/extension/dist/popup.js.map +2 -2
- package/extension/dist/sidepanel.html +1 -1
- package/extension/dist/sidepanel.js +136 -1
- package/extension/dist/sidepanel.js.map +2 -2
- package/extension/manifest.json +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -4587,6 +4587,61 @@ var sessionmemory = class {
|
|
|
4587
4587
|
async removeworkflowversion(id, version) {
|
|
4588
4588
|
await this.adapter.set("workflowrecords", (await this.getworkflowrecordversions()).filter((entry) => !(entry.id === id && entry.version === version)));
|
|
4589
4589
|
}
|
|
4590
|
+
/** Returns every stored mcp client record, newest first. */
|
|
4591
|
+
async getclients() {
|
|
4592
|
+
return await this.adapter.get("mcpclients") ?? [];
|
|
4593
|
+
}
|
|
4594
|
+
/** Upserts one mcp client record by its id so one clientrecord stays per connected transport. */
|
|
4595
|
+
async setclient(client) {
|
|
4596
|
+
const records = (await this.getclients()).filter((entry) => entry.id !== client.id);
|
|
4597
|
+
await this.adapter.set("mcpclients", [client, ...records]);
|
|
4598
|
+
}
|
|
4599
|
+
/** Returns the connected client records — every client whose disconnect time is absent. */
|
|
4600
|
+
async listclients() {
|
|
4601
|
+
return (await this.getclients()).filter((client) => client.disconnectedat === void 0);
|
|
4602
|
+
}
|
|
4603
|
+
/** Stores the negotiated capability set of one client on its record. */
|
|
4604
|
+
async setclientcapabilities(id, capabilities) {
|
|
4605
|
+
await this.adapter.set("mcpclients", (await this.getclients()).map((client) => client.id === id ? { ...client, capabilities } : client));
|
|
4606
|
+
}
|
|
4607
|
+
/** Drops every stored client record when the server stops. */
|
|
4608
|
+
async clearclients() {
|
|
4609
|
+
await this.adapter.set("mcpclients", []);
|
|
4610
|
+
}
|
|
4611
|
+
/** Records one stdio bridge launch event with its process id; a restart marker distinguishes the relaunch of a dead client process. */
|
|
4612
|
+
async addbridgelaunch(launch) {
|
|
4613
|
+
await this.adapter.set("mcbridgelaunches", [launch, ...await this.adapter.get("mcbridgelaunches") ?? []]);
|
|
4614
|
+
}
|
|
4615
|
+
/** Returns every stdio bridge launch event, newest first. */
|
|
4616
|
+
async listbridgelaunches() {
|
|
4617
|
+
return await this.adapter.get("mcbridgelaunches") ?? [];
|
|
4618
|
+
}
|
|
4619
|
+
/** Returns the user configured mcp server config; an absent record keeps the documented localhost default. */
|
|
4620
|
+
async getmcpconfig() {
|
|
4621
|
+
return this.adapter.get("mcpconfig");
|
|
4622
|
+
}
|
|
4623
|
+
/** Stores the user configured mcp server config: bind address, port, transports, frame size, queue depth and enablement all stay user choices. */
|
|
4624
|
+
async setmcpconfig(config) {
|
|
4625
|
+
return this.adapter.set("mcpconfig", config);
|
|
4626
|
+
}
|
|
4627
|
+
/** Returns the persisted mcp server runtime state. */
|
|
4628
|
+
async getmcpstate() {
|
|
4629
|
+
return this.adapter.get("mcpstate");
|
|
4630
|
+
}
|
|
4631
|
+
/** Stores the mcp server runtime state with the stdio bridge status. */
|
|
4632
|
+
async setmcpstate(state) {
|
|
4633
|
+
return this.adapter.set("mcpstate", state);
|
|
4634
|
+
}
|
|
4635
|
+
/** Records one mcp tool call — the client, the tool, the origin and the outcome without any payload — under the user configured call retention with no code ceiling. */
|
|
4636
|
+
async addtoolcall(record2) {
|
|
4637
|
+
const records = await this.listtoolcalls();
|
|
4638
|
+
const retention = (await this.getmcpconfig())?.callretention;
|
|
4639
|
+
await this.adapter.set("mcptoolcalls", retention === void 0 ? [record2, ...records] : [record2, ...records].slice(0, retention));
|
|
4640
|
+
}
|
|
4641
|
+
/** Returns every stored mcp tool call record, newest first. */
|
|
4642
|
+
async listtoolcalls() {
|
|
4643
|
+
return await this.adapter.get("mcptoolcalls") ?? [];
|
|
4644
|
+
}
|
|
4590
4645
|
};
|
|
4591
4646
|
function mediakindof(record2) {
|
|
4592
4647
|
if ("pages" in record2) return "pdf";
|
|
@@ -4630,313 +4685,333 @@ function randomid() {
|
|
|
4630
4685
|
return crypto.randomUUID();
|
|
4631
4686
|
}
|
|
4632
4687
|
|
|
4633
|
-
//
|
|
4634
|
-
|
|
4635
|
-
|
|
4636
|
-
|
|
4637
|
-
|
|
4638
|
-
|
|
4639
|
-
|
|
4640
|
-
|
|
4641
|
-
|
|
4642
|
-
|
|
4688
|
+
// version.ts
|
|
4689
|
+
var packageversion = "1.1.54";
|
|
4690
|
+
|
|
4691
|
+
// types.ts
|
|
4692
|
+
var protocolversion = packageversion;
|
|
4693
|
+
|
|
4694
|
+
// toolcatalog.ts
|
|
4695
|
+
var toolcatalogversion = 1;
|
|
4696
|
+
var toolnamespaces = ["browser", "workflow", "memory", "system"];
|
|
4697
|
+
var domainkinds = {
|
|
4698
|
+
browser: ["observe", "extract", "readtext", "readtable", "readlinks", "a11ytree", "tablist", "windowlist", "click", "type", "presskey", "navigate", "back", "forward", "reload", "tabcreate", "tabactivate", "tabclose", "windowcreate", "windowclose", "windowresize"],
|
|
4699
|
+
workflow: ["composeworkflow", "runworkflow", "dryrun", "eventrule"],
|
|
4700
|
+
memory: ["listruns", "extractvars", "trailaudit"],
|
|
4701
|
+
system: ["observe", "readmeta"]
|
|
4702
|
+
};
|
|
4703
|
+
function toolschemaof(properties) {
|
|
4704
|
+
return { type: "object", properties, required: Object.entries(properties).filter(([, property]) => property.required === true).map(([name]) => name) };
|
|
4643
4705
|
}
|
|
4644
|
-
function
|
|
4645
|
-
|
|
4646
|
-
url.searchParams.set("response_type", "code");
|
|
4647
|
-
url.searchParams.set("redirect_uri", flow.redirectorigin);
|
|
4648
|
-
url.searchParams.set("scope", flow.scopes.join(" "));
|
|
4649
|
-
url.searchParams.set("state", state);
|
|
4650
|
-
return url.toString();
|
|
4706
|
+
function readtool(name, kind, description, inputs = {}) {
|
|
4707
|
+
return { name, version: toolcatalogversion, description, inputschema: toolschemaof({ target: { type: "string", description: "Reviewed css selector the tool addresses." }, value: { type: "string", description: "Reviewed literal value the tool carries." }, options: { type: "object", description: "Reviewed json options of the wrapped action kind with the empty default.", default: {} }, ...inputs }), kind, risk: "read" };
|
|
4651
4708
|
}
|
|
4652
|
-
function
|
|
4653
|
-
|
|
4654
|
-
try {
|
|
4655
|
-
parsed = new URL(url);
|
|
4656
|
-
} catch {
|
|
4657
|
-
return { error: "The redirect url does not parse for the code capture." };
|
|
4658
|
-
}
|
|
4659
|
-
const granted = redirectorigin.includes("/", redirectorigin.indexOf("://") + 3) ? `${parsed.origin}${parsed.pathname}`.startsWith(redirectorigin) : parsed.origin === redirectorigin;
|
|
4660
|
-
if (!granted) return { error: `The redirect landed on ${parsed.origin} outside the granted redirect origin ${redirectorigin}.` };
|
|
4661
|
-
const returned = parsed.searchParams.get("state");
|
|
4662
|
-
if (returned !== state) return { error: "The redirect state token does not match the reviewed flow." };
|
|
4663
|
-
const error = parsed.searchParams.get("error");
|
|
4664
|
-
if (error) return { error: `The provider refused the flow: ${error}.` };
|
|
4665
|
-
const code = parsed.searchParams.get("code");
|
|
4666
|
-
if (!code) return { error: "The redirect carries no authorization code." };
|
|
4667
|
-
return { code };
|
|
4709
|
+
function gatedtool(name, kind, risk, description, review) {
|
|
4710
|
+
return { name, version: toolcatalogversion, description, inputschema: toolschemaof({ stepid: { type: "string", description: "Id of the approved plan step this tool executes.", required: true } }), kind, risk, consentmeta: { review } };
|
|
4668
4711
|
}
|
|
4669
|
-
function
|
|
4670
|
-
|
|
4671
|
-
|
|
4672
|
-
|
|
4673
|
-
|
|
4674
|
-
|
|
4675
|
-
|
|
4676
|
-
|
|
4677
|
-
|
|
4678
|
-
|
|
4679
|
-
|
|
4680
|
-
|
|
4681
|
-
|
|
4682
|
-
|
|
4683
|
-
|
|
4684
|
-
|
|
4712
|
+
function browserdomain() {
|
|
4713
|
+
return {
|
|
4714
|
+
namespace: "browser",
|
|
4715
|
+
version: toolcatalogversion,
|
|
4716
|
+
tools: [
|
|
4717
|
+
readtool("browser.snapshot", "observe", "Captures the semantic snapshot of the active tab: url, title, text preview, forms and interactive elements. Read only with no side effects; runs under the dryrun risk class once the session is approved."),
|
|
4718
|
+
readtool("browser.extract", "extract", "Extracts the reviewed structured data of the page. Read only with no side effects."),
|
|
4719
|
+
readtool("browser.readtext", "readtext", "Reads the text of the addressed element. Read only with no side effects.", { target: { type: "string", description: "Reviewed css selector of the element to read.", required: true } }),
|
|
4720
|
+
readtool("browser.readtable", "readtable", "Reads the rows of the addressed data table. Read only with no side effects.", { target: { type: "string", description: "Reviewed css selector of the table to read.", required: true } }),
|
|
4721
|
+
readtool("browser.readlinks", "readlinks", "Reads the link inventory of the page. Read only with no side effects."),
|
|
4722
|
+
readtool("browser.a11ytree", "a11ytree", "Reads the accessibility tree of the page. Read only with no side effects."),
|
|
4723
|
+
readtool("browser.tablist", "tablist", "Lists the open tabs. Read only with no side effects."),
|
|
4724
|
+
readtool("browser.windowlist", "windowlist", "Lists the open windows. Read only with no side effects."),
|
|
4725
|
+
gatedtool("browser.click", "click", "sensitive", "Clicks the addressed element. Sensitive: it changes page state, so it executes exactly one approved plan step.", "The click runs only as the approved plan step it names; a paired client can never widen the reviewed target or options."),
|
|
4726
|
+
gatedtool("browser.type", "type", "sensitive", "Types the reviewed text into the addressed element. Sensitive: it changes page state, so it executes exactly one approved plan step.", "The typing runs only as the approved plan step it names; the reviewed target, text and options stay fixed."),
|
|
4727
|
+
gatedtool("browser.presskey", "presskey", "sensitive", "Presses the reviewed key. Sensitive: it changes page state, so it executes exactly one approved plan step.", "The key press runs only as the approved plan step it names."),
|
|
4728
|
+
gatedtool("browser.navigate", "navigate", "sensitive", "Navigates the active tab to the reviewed url. Sensitive: it changes browser state, so it executes exactly one approved plan step.", "The navigation runs only as the approved plan step it names and stays inside the session origin grants."),
|
|
4729
|
+
gatedtool("browser.back", "back", "sensitive", "Navigates back in the history of the active tab. Sensitive: it changes browser state, so it executes exactly one approved plan step.", "The history navigation runs only as the approved plan step it names."),
|
|
4730
|
+
gatedtool("browser.forward", "forward", "sensitive", "Navigates forward in the history of the active tab. Sensitive: it changes browser state, so it executes exactly one approved plan step.", "The history navigation runs only as the approved plan step it names."),
|
|
4731
|
+
gatedtool("browser.reload", "reload", "sensitive", "Reloads the active tab. Sensitive: it changes browser state, so it executes exactly one approved plan step.", "The reload runs only as the approved plan step it names."),
|
|
4732
|
+
gatedtool("browser.tabcreate", "tabcreate", "sensitive", "Opens a new tab. Sensitive: it changes browser state, so it executes exactly one approved plan step.", "The tab creation runs only as the approved plan step it names."),
|
|
4733
|
+
gatedtool("browser.tabactivate", "tabactivate", "sensitive", "Activates the reviewed tab. Sensitive: it moves focus, so it executes exactly one approved plan step.", "The tab activation runs only as the approved plan step it names."),
|
|
4734
|
+
gatedtool("browser.tabclose", "tabclose", "sensitive", "Closes the reviewed tab. Sensitive: it destroys browser state, so it executes exactly one approved plan step.", "The tab close runs only as the approved plan step it names."),
|
|
4735
|
+
gatedtool("browser.windowcreate", "windowcreate", "sensitive", "Opens a new window. Sensitive: it changes browser state, so it executes exactly one approved plan step.", "The window creation runs only as the approved plan step it names."),
|
|
4736
|
+
gatedtool("browser.windowclose", "windowclose", "sensitive", "Closes the reviewed window. Sensitive: it destroys browser state, so it executes exactly one approved plan step.", "The window close runs only as the approved plan step it names."),
|
|
4737
|
+
gatedtool("browser.windowresize", "windowresize", "sensitive", "Resizes the reviewed window. Sensitive: it changes browser state, so it executes exactly one approved plan step.", "The window resize runs only as the approved plan step it names.")
|
|
4738
|
+
]
|
|
4739
|
+
};
|
|
4685
4740
|
}
|
|
4686
|
-
function
|
|
4687
|
-
|
|
4688
|
-
|
|
4741
|
+
function workflowdomain() {
|
|
4742
|
+
return {
|
|
4743
|
+
namespace: "workflow",
|
|
4744
|
+
version: toolcatalogversion,
|
|
4745
|
+
tools: [
|
|
4746
|
+
readtool("workflow.list", "composeworkflow", "Lists the composed workflows with their names, versions, origins and step counts. Read only with no side effects."),
|
|
4747
|
+
readtool("workflow.dryrun", "dryrun", "Runs a composed workflow as a dry run: read steps project their would be outcome and every step with side effects is refused. Read only with no side effects."),
|
|
4748
|
+
gatedtool("workflow.run", "runworkflow", "sensitive", "Runs a composed workflow for real. Sensitive: it executes every step of the workflow, so it executes exactly one approved runworkflow plan step with its explicit run review.", "The workflow run needs the explicit run review: the approved runworkflow plan step with its expanded step list shown before the first step executes."),
|
|
4749
|
+
gatedtool("workflow.triggers", "eventrule", "sensitive", "Lists the armed trigger rules with their schedules, cooldowns and fire counters so a client can inspect what launches runs automatically. Sensitive by its trigger family: automatic launchers stay behind the arm review class.", "The trigger listing runs behind the approved plan review because trigger rules launch runs automatically.")
|
|
4750
|
+
]
|
|
4751
|
+
};
|
|
4689
4752
|
}
|
|
4690
|
-
function
|
|
4691
|
-
|
|
4692
|
-
|
|
4693
|
-
|
|
4694
|
-
|
|
4695
|
-
|
|
4753
|
+
function memorydomain() {
|
|
4754
|
+
return {
|
|
4755
|
+
namespace: "memory",
|
|
4756
|
+
version: toolcatalogversion,
|
|
4757
|
+
tools: [
|
|
4758
|
+
readtool("memory.list", "listruns", "Lists the stored workflow run records with their states and step cursors from local memory. Read only with no page access.", { target: { type: "string", description: "Unused by the memory read; kept for schema uniformity." }, value: { type: "string", description: "Unused by the memory read; kept for schema uniformity." }, state: { type: "string", description: "Optional reviewed run state filter of the listing.", default: "" } }),
|
|
4759
|
+
readtool("memory.variables", "extractvars", "Reads the stored variable scopes of a run from local memory. Read only with no page access."),
|
|
4760
|
+
readtool("memory.audit", "trailaudit", "Reads the audit summary of the session trail from local memory. Read only with no page access.")
|
|
4761
|
+
]
|
|
4762
|
+
};
|
|
4696
4763
|
}
|
|
4697
|
-
function
|
|
4698
|
-
|
|
4699
|
-
|
|
4700
|
-
|
|
4701
|
-
|
|
4702
|
-
|
|
4703
|
-
|
|
4704
|
-
|
|
4705
|
-
|
|
4706
|
-
|
|
4707
|
-
if (typeof field.value !== "string") return void 0;
|
|
4708
|
-
fields.push({ name: field.name.trim(), value: field.value });
|
|
4709
|
-
}
|
|
4710
|
-
return { url: options.url.trim(), fields };
|
|
4764
|
+
function systemdomain() {
|
|
4765
|
+
return {
|
|
4766
|
+
namespace: "system",
|
|
4767
|
+
version: toolcatalogversion,
|
|
4768
|
+
tools: [
|
|
4769
|
+
readtool("system.status", "observe", "Reports the mcp server status, the session state and the connected clients. Read only with no side effects."),
|
|
4770
|
+
readtool("system.version", "readmeta", "Reports the protocol version, the catalog version and the extension version. Read only with no side effects."),
|
|
4771
|
+
readtool("system.capabilities", "observe", "Reports the optional browser capabilities the user has granted. Read only with no side effects.")
|
|
4772
|
+
]
|
|
4773
|
+
};
|
|
4711
4774
|
}
|
|
4712
|
-
function
|
|
4713
|
-
return
|
|
4775
|
+
function buildtoolcatalog() {
|
|
4776
|
+
return { version: toolcatalogversion, domains: [browserdomain(), workflowdomain(), memorydomain(), systemdomain()] };
|
|
4714
4777
|
}
|
|
4715
|
-
function
|
|
4716
|
-
|
|
4717
|
-
return bytes.map((byte) => byte >= 65 && byte <= 90 || byte >= 97 && byte <= 122 || byte >= 48 && byte <= 57 || byte === 45 || byte === 95 || byte === 46 || byte === 126 ? String.fromCharCode(byte) : `%${byte.toString(16).toUpperCase().padStart(2, "0")}`).join("");
|
|
4778
|
+
function alltools(catalog) {
|
|
4779
|
+
return catalog.domains.flatMap((domain) => domain.tools);
|
|
4718
4780
|
}
|
|
4719
|
-
function
|
|
4720
|
-
|
|
4721
|
-
const options = value;
|
|
4722
|
-
if (typeof options.url !== "string" || !options.url.trim()) return void 0;
|
|
4723
|
-
if (!Array.isArray(options.files) || options.files.length === 0) return void 0;
|
|
4724
|
-
const fields = [];
|
|
4725
|
-
for (const item of Array.isArray(options.fields) ? options.fields : []) {
|
|
4726
|
-
if (!item || typeof item !== "object" || Array.isArray(item)) return void 0;
|
|
4727
|
-
const field = item;
|
|
4728
|
-
if (typeof field.name !== "string" || !field.name.trim()) return void 0;
|
|
4729
|
-
if (typeof field.value !== "string") return void 0;
|
|
4730
|
-
fields.push({ name: field.name.trim(), value: field.value });
|
|
4731
|
-
}
|
|
4732
|
-
const files = [];
|
|
4733
|
-
for (const item of options.files) {
|
|
4734
|
-
if (!item || typeof item !== "object" || Array.isArray(item)) return void 0;
|
|
4735
|
-
const file = item;
|
|
4736
|
-
if (typeof file.name !== "string" || !file.name.trim()) return void 0;
|
|
4737
|
-
if (typeof file.filename !== "string" || !file.filename.trim()) return void 0;
|
|
4738
|
-
if (typeof file.mime !== "string" || !file.mime.trim()) return void 0;
|
|
4739
|
-
if (typeof file.content !== "string") return void 0;
|
|
4740
|
-
if (file.reviewed !== true) return void 0;
|
|
4741
|
-
files.push({ name: file.name.trim(), filename: file.filename.trim(), mime: file.mime.trim(), content: file.content, reviewed: true });
|
|
4742
|
-
}
|
|
4743
|
-
const payload = { url: options.url.trim(), fields, files, ...typeof options.boundary === "string" && options.boundary.trim() ? { boundary: options.boundary.trim() } : {} };
|
|
4744
|
-
return payload;
|
|
4781
|
+
function toolname(namespace, base) {
|
|
4782
|
+
return `${namespace}.${base}`;
|
|
4745
4783
|
}
|
|
4746
|
-
function
|
|
4747
|
-
|
|
4784
|
+
function resolvetool(catalog, name) {
|
|
4785
|
+
if (name.includes(".")) return alltools(catalog).find((tool) => tool.name === name);
|
|
4786
|
+
const matches = alltools(catalog).filter((tool) => tool.name.split(".")[1] === name);
|
|
4787
|
+
return matches.length === 1 ? matches[0] : void 0;
|
|
4748
4788
|
}
|
|
4749
|
-
function
|
|
4750
|
-
const
|
|
4751
|
-
|
|
4752
|
-
for (const field of payload.fields) chunks.push(`--${boundary}\r
|
|
4753
|
-
content-disposition: form-data; name="${field.name}"\r
|
|
4754
|
-
\r
|
|
4755
|
-
${field.value}\r
|
|
4756
|
-
`);
|
|
4757
|
-
for (const file of payload.files) chunks.push(`--${boundary}\r
|
|
4758
|
-
content-disposition: form-data; name="${file.name}"; filename="${file.filename}"\r
|
|
4759
|
-
content-type: ${file.mime}\r
|
|
4760
|
-
\r
|
|
4761
|
-
${file.content}\r
|
|
4762
|
-
`);
|
|
4763
|
-
chunks.push(`--${boundary}--\r
|
|
4764
|
-
`);
|
|
4765
|
-
return { chunks, boundary, bytes: chunks.reduce((total, chunk) => total + chunk.length, 0) };
|
|
4789
|
+
function namespaceof(name) {
|
|
4790
|
+
const head = name.split(".")[0];
|
|
4791
|
+
return toolnamespaces.includes(head) ? head : void 0;
|
|
4766
4792
|
}
|
|
4767
|
-
|
|
4768
|
-
|
|
4769
|
-
var controlkinds = ["blockrequest", "mockresponse", "rewriteheaders", "setcookies", "readcookies", "clearcookies", "authflow", "saveapikey", "routeproxy", "postform", "postfiles"];
|
|
4770
|
-
function patternorigin(pattern) {
|
|
4771
|
-
const trimmed = pattern.trim();
|
|
4772
|
-
if (!trimmed.startsWith("https://")) return void 0;
|
|
4773
|
-
const rest = trimmed.slice("https://".length);
|
|
4774
|
-
const host = rest.split("/")[0] ?? "";
|
|
4775
|
-
if (!host.trim()) return void 0;
|
|
4776
|
-
return `https://${host.toLowerCase()}`;
|
|
4793
|
+
function toolsbynamespace(catalog) {
|
|
4794
|
+
return catalog.domains.map((domain) => ({ namespace: domain.namespace, version: domain.version, tools: domain.tools }));
|
|
4777
4795
|
}
|
|
4778
|
-
|
|
4779
|
-
|
|
4780
|
-
|
|
4781
|
-
|
|
4796
|
+
|
|
4797
|
+
// socketbus.ts
|
|
4798
|
+
var socketkinds = ["opensocket", "sendmessage", "waitmessage", "subscribesse", "longpoll"];
|
|
4799
|
+
function channelorigin(url) {
|
|
4782
4800
|
try {
|
|
4783
|
-
parsed = new URL(url);
|
|
4801
|
+
const parsed = new URL(url);
|
|
4802
|
+
const protocol = parsed.protocol === "wss:" ? "https:" : parsed.protocol === "ws:" ? "http:" : parsed.protocol;
|
|
4803
|
+
return `${protocol}//${parsed.host}`;
|
|
4784
4804
|
} catch {
|
|
4785
|
-
return
|
|
4805
|
+
return "";
|
|
4786
4806
|
}
|
|
4787
|
-
if (parsed.origin !== origin) return false;
|
|
4788
|
-
const patternpath = pattern.trim().slice(origin.length);
|
|
4789
|
-
if (patternpath === "" || patternpath === "/") return true;
|
|
4790
|
-
const segments = patternpath.split("/").filter((segment) => segment !== "");
|
|
4791
|
-
if (segments.includes("**")) return true;
|
|
4792
|
-
const pathsegments = parsed.pathname.split("/").filter((segment) => segment !== "");
|
|
4793
|
-
if (segments.length !== pathsegments.length) return false;
|
|
4794
|
-
return segments.every((segment, index) => segment === pathsegments[index] || segment.includes("*") && new RegExp(`^${segment.split("*").map((part) => part.replace(/[.*+?^${}()|[\]\\]/g, "\\$&")).join(".*")}$`).test(pathsegments[index] ?? ""));
|
|
4795
4807
|
}
|
|
4796
|
-
function
|
|
4808
|
+
function channeloptionsof(value) {
|
|
4797
4809
|
if (!value || typeof value !== "object" || Array.isArray(value)) return void 0;
|
|
4798
|
-
const
|
|
4799
|
-
if (typeof
|
|
4800
|
-
const
|
|
4801
|
-
if (Array.isArray(options.
|
|
4802
|
-
|
|
4803
|
-
|
|
4804
|
-
|
|
4810
|
+
const entry = value;
|
|
4811
|
+
if (typeof entry.url !== "string" || !entry.url.trim()) return void 0;
|
|
4812
|
+
const options = {};
|
|
4813
|
+
if (Array.isArray(entry.protocols)) options.protocols = entry.protocols.filter((item) => typeof item === "string" && item.trim().length > 0);
|
|
4814
|
+
if (typeof entry.reconnect === "number" && Number.isFinite(entry.reconnect)) options.reconnect = entry.reconnect;
|
|
4815
|
+
if (typeof entry.backoff === "number" && Number.isFinite(entry.backoff)) options.backoff = entry.backoff;
|
|
4816
|
+
if (typeof entry.backoffceiling === "number" && Number.isFinite(entry.backoffceiling)) options.backoffceiling = entry.backoffceiling;
|
|
4817
|
+
if (typeof entry.lifetime === "number" && Number.isFinite(entry.lifetime)) options.lifetime = entry.lifetime;
|
|
4818
|
+
return { url: entry.url.trim(), options };
|
|
4819
|
+
}
|
|
4820
|
+
function newchannel(input) {
|
|
4821
|
+
return { id: input.id, runid: input.runid, stepid: input.stepid, kind: input.kind, url: input.url, origin: channelorigin(input.url), state: "connecting", openedat: input.at, sent: 0, received: 0, reconnects: 0, ...input.protocols !== void 0 && input.protocols.length > 0 ? { protocols: [...input.protocols] } : {} };
|
|
4822
|
+
}
|
|
4823
|
+
function reconnectwaits(attempts, base, ceiling) {
|
|
4824
|
+
const count = Math.max(0, Math.floor(attempts));
|
|
4825
|
+
const waits = [];
|
|
4826
|
+
let wait = Math.max(0, base);
|
|
4827
|
+
for (let index = 0; index < count; index += 1) {
|
|
4828
|
+
waits.push(wait);
|
|
4829
|
+
const next = wait * 2;
|
|
4830
|
+
wait = ceiling !== void 0 && Number.isFinite(ceiling) && ceiling >= 0 ? Math.min(next, ceiling) : next;
|
|
4805
4831
|
}
|
|
4806
|
-
return
|
|
4832
|
+
return waits;
|
|
4807
4833
|
}
|
|
4808
|
-
function
|
|
4809
|
-
|
|
4834
|
+
async function openchannel(input) {
|
|
4835
|
+
const sleep = input.sleep ?? ((milliseconds) => new Promise((resolve) => setTimeout(resolve, Math.max(0, milliseconds))));
|
|
4836
|
+
const now = input.now ?? Date.now;
|
|
4837
|
+
const attempts = Math.max(1, Math.floor(input.options.reconnect ?? 0) + 1);
|
|
4838
|
+
const waits = reconnectwaits(attempts - 1, input.options.backoff ?? 0, input.options.backoffceiling);
|
|
4839
|
+
let record2 = { ...input.record, state: "connecting" };
|
|
4840
|
+
let lasterror = "";
|
|
4841
|
+
for (let attempt = 0; attempt < attempts; attempt += 1) {
|
|
4842
|
+
try {
|
|
4843
|
+
const result = await input.connect(record2.url, record2.protocols ?? []);
|
|
4844
|
+
if (result.open) return { ...record2, state: "open", openedat: now() };
|
|
4845
|
+
lasterror = result.error ?? `closed with code ${result.code ?? 0}`;
|
|
4846
|
+
} catch (error) {
|
|
4847
|
+
lasterror = error instanceof Error ? error.message : String(error);
|
|
4848
|
+
}
|
|
4849
|
+
if (attempt < attempts - 1) {
|
|
4850
|
+
const wait = waits[attempt] ?? 0;
|
|
4851
|
+
if (wait > 0) await sleep(wait);
|
|
4852
|
+
record2 = { ...record2, reconnects: record2.reconnects + 1 };
|
|
4853
|
+
}
|
|
4854
|
+
}
|
|
4855
|
+
return { ...record2, state: "failed", error: lasterror };
|
|
4810
4856
|
}
|
|
4811
|
-
function
|
|
4812
|
-
|
|
4813
|
-
|
|
4814
|
-
if (typeof options.urlpattern !== "string" || !options.urlpattern.trim()) return void 0;
|
|
4815
|
-
if (typeof options.status !== "number" || !Number.isInteger(options.status) || options.status < 100 || options.status > 599) return void 0;
|
|
4816
|
-
const hasbody = typeof options.body === "string";
|
|
4817
|
-
const bodyref = typeof options.bodyref === "string" ? options.bodyref.trim() : "";
|
|
4818
|
-
if (!hasbody && bodyref === "") return void 0;
|
|
4819
|
-
const spec = { urlpattern: options.urlpattern.trim(), status: options.status };
|
|
4820
|
-
if (hasbody) spec.body = options.body;
|
|
4821
|
-
if (bodyref !== "") spec.bodyref = bodyref;
|
|
4822
|
-
if (options.headers && typeof options.headers === "object" && !Array.isArray(options.headers)) spec.headers = options.headers;
|
|
4823
|
-
if (options.reviewed === true) spec.reviewed = true;
|
|
4824
|
-
return spec;
|
|
4857
|
+
function closechannel(record2, at, error) {
|
|
4858
|
+
const state = error !== void 0 ? "failed" : "closed";
|
|
4859
|
+
return { ...record2, state, closedat: at, ...error !== void 0 ? { error } : {} };
|
|
4825
4860
|
}
|
|
4826
|
-
function
|
|
4827
|
-
|
|
4861
|
+
function tagmessage(state, channelid, stream, payload, at) {
|
|
4862
|
+
const sequence = (state.sequences[channelid] ?? 0) + 1;
|
|
4863
|
+
const envelope = { channelid, stream, payload, sequence, at };
|
|
4864
|
+
return { state: { sequences: { ...state.sequences, [channelid]: sequence }, queue: state.queue }, envelope };
|
|
4828
4865
|
}
|
|
4829
|
-
function
|
|
4830
|
-
return
|
|
4866
|
+
function publishmessage(state, channelid, stream, payload, at) {
|
|
4867
|
+
return tagmessage(state, channelid, stream, payload, at);
|
|
4831
4868
|
}
|
|
4832
|
-
function
|
|
4833
|
-
|
|
4834
|
-
|
|
4835
|
-
if (typeof options.urlpattern !== "string" || !options.urlpattern.trim()) return void 0;
|
|
4836
|
-
if (typeof options.name !== "string" || !options.name.trim()) return void 0;
|
|
4837
|
-
if (options.operation !== "set" && options.operation !== "append" && options.operation !== "remove") return void 0;
|
|
4838
|
-
if (options.operation === "remove" && options.value !== void 0) return void 0;
|
|
4839
|
-
if (options.operation !== "remove" && typeof options.value !== "string") return void 0;
|
|
4840
|
-
const rule = { urlpattern: options.urlpattern.trim(), name: options.name.trim(), operation: options.operation };
|
|
4841
|
-
if (options.operation !== "remove") rule.value = typeof options.value === "string" ? options.value : "";
|
|
4842
|
-
return rule;
|
|
4869
|
+
function receivemessage(state, channelid, stream, payload, at) {
|
|
4870
|
+
const tagged = tagmessage(state, channelid, stream, payload, at);
|
|
4871
|
+
return { state: { ...tagged.state, queue: [...state.queue, tagged.envelope] }, envelope: tagged.envelope };
|
|
4843
4872
|
}
|
|
4844
|
-
function
|
|
4845
|
-
|
|
4873
|
+
function pathstep2(current, segment) {
|
|
4874
|
+
if (Array.isArray(current) && /^\d+$/.test(segment)) return current[Number.parseInt(segment, 10)];
|
|
4875
|
+
if (current && typeof current === "object" && !Array.isArray(current)) return current[segment];
|
|
4876
|
+
return void 0;
|
|
4846
4877
|
}
|
|
4847
|
-
function
|
|
4848
|
-
|
|
4849
|
-
|
|
4850
|
-
|
|
4851
|
-
|
|
4852
|
-
|
|
4853
|
-
|
|
4854
|
-
|
|
4855
|
-
|
|
4856
|
-
|
|
4857
|
-
|
|
4878
|
+
function matchmessage(filter, envelope) {
|
|
4879
|
+
if (!filter) return true;
|
|
4880
|
+
if (filter.stream !== void 0 && filter.stream !== envelope.stream) return false;
|
|
4881
|
+
if (filter.path !== void 0) {
|
|
4882
|
+
try {
|
|
4883
|
+
const parsed = JSON.parse(envelope.payload);
|
|
4884
|
+
let current = parsed;
|
|
4885
|
+
let missing = false;
|
|
4886
|
+
for (const segment of filter.path.split(".")) {
|
|
4887
|
+
const next = pathstep2(current, segment);
|
|
4888
|
+
if (next === void 0) {
|
|
4889
|
+
missing = true;
|
|
4890
|
+
break;
|
|
4891
|
+
}
|
|
4892
|
+
current = next;
|
|
4893
|
+
}
|
|
4894
|
+
if (missing) return false;
|
|
4895
|
+
} catch {
|
|
4896
|
+
return false;
|
|
4858
4897
|
}
|
|
4859
|
-
const value = rule.value ?? "";
|
|
4860
|
-
if (rule.operation === "set") rewritten[name] = value;
|
|
4861
|
-
else rewritten[name] = rewritten[name] !== void 0 ? `${rewritten[name]}, ${value}` : value;
|
|
4862
|
-
applied.push(rule);
|
|
4863
4898
|
}
|
|
4864
|
-
return
|
|
4899
|
+
return true;
|
|
4865
4900
|
}
|
|
4866
|
-
function
|
|
4867
|
-
|
|
4868
|
-
|
|
4901
|
+
function collectmessages(state, channelid, filter) {
|
|
4902
|
+
const limit = filter?.limit !== void 0 && Number.isFinite(filter.limit) && filter.limit >= 1 ? Math.floor(filter.limit) : Number.POSITIVE_INFINITY;
|
|
4903
|
+
const matched = [];
|
|
4904
|
+
const queue = [];
|
|
4905
|
+
for (const envelope of state.queue) {
|
|
4906
|
+
if (envelope.channelid === channelid && matched.length < limit && matchmessage(filter, envelope)) matched.push(envelope);
|
|
4907
|
+
else queue.push(envelope);
|
|
4908
|
+
}
|
|
4909
|
+
return { state: { sequences: state.sequences, queue }, matched };
|
|
4869
4910
|
}
|
|
4870
|
-
function
|
|
4871
|
-
|
|
4872
|
-
const
|
|
4873
|
-
|
|
4874
|
-
|
|
4875
|
-
|
|
4876
|
-
|
|
4877
|
-
|
|
4878
|
-
|
|
4879
|
-
return record2;
|
|
4911
|
+
function sequenceintegrity(envelopes) {
|
|
4912
|
+
const last = /* @__PURE__ */ new Map();
|
|
4913
|
+
const gaps = [];
|
|
4914
|
+
for (const envelope of envelopes) {
|
|
4915
|
+
const expected = (last.get(envelope.channelid) ?? 0) + 1;
|
|
4916
|
+
if (envelope.sequence !== expected) gaps.push({ channelid: envelope.channelid, expected, found: envelope.sequence });
|
|
4917
|
+
last.set(envelope.channelid, Math.max(envelope.sequence, expected));
|
|
4918
|
+
}
|
|
4919
|
+
return { ok: gaps.length === 0, gaps };
|
|
4880
4920
|
}
|
|
4881
|
-
function
|
|
4882
|
-
|
|
4883
|
-
|
|
4884
|
-
|
|
4885
|
-
|
|
4886
|
-
|
|
4887
|
-
|
|
4888
|
-
|
|
4921
|
+
function messagefilterof(value) {
|
|
4922
|
+
if (!value || typeof value !== "object" || Array.isArray(value)) return {};
|
|
4923
|
+
const entry = value;
|
|
4924
|
+
const filter = {};
|
|
4925
|
+
if (typeof entry.stream === "string" && entry.stream.trim()) filter.stream = entry.stream.trim();
|
|
4926
|
+
if (typeof entry.path === "string" && entry.path.trim()) filter.path = entry.path.trim();
|
|
4927
|
+
if (typeof entry.limit === "number" && Number.isFinite(entry.limit) && entry.limit >= 1) filter.limit = Math.floor(entry.limit);
|
|
4928
|
+
return filter;
|
|
4929
|
+
}
|
|
4930
|
+
function parsessetext(text2) {
|
|
4931
|
+
const separator = text2.lastIndexOf("\n\n");
|
|
4932
|
+
const complete = separator === -1 ? "" : text2.slice(0, separator + 2);
|
|
4933
|
+
const rest = separator === -1 ? text2 : text2.slice(separator + 2);
|
|
4934
|
+
const events = [];
|
|
4935
|
+
for (const block of complete.split(/\n\n/)) {
|
|
4936
|
+
const id = [];
|
|
4937
|
+
const names = [];
|
|
4938
|
+
const data = [];
|
|
4939
|
+
let retry;
|
|
4940
|
+
for (const line of block.split("\n")) {
|
|
4941
|
+
if (line === "" || line.startsWith(":")) continue;
|
|
4942
|
+
const colon = line.indexOf(":");
|
|
4943
|
+
const field = colon === -1 ? line : line.slice(0, colon);
|
|
4944
|
+
let value = colon === -1 ? "" : line.slice(colon + 1);
|
|
4945
|
+
if (value.startsWith(" ")) value = value.slice(1);
|
|
4946
|
+
if (field === "id" && value !== "") id.push(value);
|
|
4947
|
+
if (field === "event" && value !== "") names.push(value);
|
|
4948
|
+
if (field === "data") data.push(value);
|
|
4949
|
+
if (field === "retry" && /^\d+$/.test(value)) retry = Number.parseInt(value, 10);
|
|
4889
4950
|
}
|
|
4890
|
-
|
|
4891
|
-
|
|
4951
|
+
if (id.length === 0 && names.length === 0 && data.length === 0) continue;
|
|
4952
|
+
events.push({ ...id.length > 0 ? { id: id[id.length - 1] } : {}, ...names.length > 0 ? { event: names[names.length - 1] } : {}, data: data.join("\n"), ...retry !== void 0 ? { retry } : {} });
|
|
4953
|
+
}
|
|
4954
|
+
return { events, rest };
|
|
4892
4955
|
}
|
|
4893
|
-
function
|
|
4894
|
-
return
|
|
4956
|
+
function sserequestheaders(record2) {
|
|
4957
|
+
return { accept: "text/event-stream", ...record2.lasteventid !== void 0 && record2.lasteventid !== "" ? { "last-event-id": record2.lasteventid } : {} };
|
|
4958
|
+
}
|
|
4959
|
+
function subscriptionoptionsof(value) {
|
|
4960
|
+
if (!value || typeof value !== "object" || Array.isArray(value)) return void 0;
|
|
4961
|
+
const entry = value;
|
|
4962
|
+
if (typeof entry.url !== "string" || !entry.url.trim()) return void 0;
|
|
4963
|
+
const cancel = entry.cancel;
|
|
4964
|
+
if (!cancel || typeof cancel !== "object" || Array.isArray(cancel)) return void 0;
|
|
4965
|
+
const cancelrecord = cancel;
|
|
4966
|
+
if (cancelrecord.kind !== "stop" && cancelrecord.kind !== "lifetime") return void 0;
|
|
4967
|
+
if (typeof cancelrecord.value !== "string" && typeof cancelrecord.value !== "number") return void 0;
|
|
4968
|
+
const result = { url: entry.url.trim(), cancel: { kind: cancelrecord.kind, value: cancelrecord.value } };
|
|
4969
|
+
if (typeof entry.lifetime === "number" && Number.isFinite(entry.lifetime) && entry.lifetime > 0) result.lifetime = entry.lifetime;
|
|
4970
|
+
if (typeof entry.lasteventid === "string" && entry.lasteventid.trim()) result.lasteventid = entry.lasteventid.trim();
|
|
4971
|
+
return result;
|
|
4895
4972
|
}
|
|
4896
|
-
function
|
|
4973
|
+
function pollcursorof(value) {
|
|
4897
4974
|
if (!value || typeof value !== "object" || Array.isArray(value)) return void 0;
|
|
4898
|
-
const
|
|
4899
|
-
if (
|
|
4900
|
-
if (typeof
|
|
4901
|
-
if (typeof
|
|
4902
|
-
|
|
4903
|
-
|
|
4975
|
+
const entry = value;
|
|
4976
|
+
if (typeof entry.url !== "string" || !entry.url.trim()) return void 0;
|
|
4977
|
+
if (typeof entry.cursorfield !== "string" || !entry.cursorfield.trim()) return void 0;
|
|
4978
|
+
if (typeof entry.interval !== "number" || !Number.isFinite(entry.interval) || entry.interval <= 0) return void 0;
|
|
4979
|
+
const stop = entry.stop;
|
|
4980
|
+
if (!stop || typeof stop !== "object" || Array.isArray(stop)) return void 0;
|
|
4981
|
+
const stoprecord = stop;
|
|
4982
|
+
if (typeof stoprecord.field !== "string" || !stoprecord.field.trim()) return void 0;
|
|
4983
|
+
if (typeof stoprecord.equals !== "string") return void 0;
|
|
4984
|
+
const cursor = { url: entry.url.trim(), cursorfield: entry.cursorfield.trim(), interval: entry.interval, stop: { field: stoprecord.field.trim(), equals: stoprecord.equals } };
|
|
4985
|
+
if (typeof entry.maxpolls === "number" && Number.isFinite(entry.maxpolls) && entry.maxpolls >= 1) cursor.maxpolls = Math.floor(entry.maxpolls);
|
|
4986
|
+
if (typeof entry.param === "string" && entry.param.trim()) cursor.param = entry.param.trim();
|
|
4987
|
+
return cursor;
|
|
4904
4988
|
}
|
|
4905
|
-
function
|
|
4906
|
-
|
|
4907
|
-
|
|
4908
|
-
|
|
4909
|
-
|
|
4910
|
-
|
|
4911
|
-
|
|
4912
|
-
|
|
4913
|
-
};
|
|
4914
|
-
const remaining = pick("x-ratelimit-remaining");
|
|
4915
|
-
const limit = pick("x-ratelimit-limit");
|
|
4916
|
-
const reset = pick("x-ratelimit-reset");
|
|
4917
|
-
if (remaining === void 0 && limit === void 0 && reset === void 0) return void 0;
|
|
4918
|
-
const read = { origin, ...remaining !== void 0 ? { remaining } : {}, ...limit !== void 0 ? { limit } : {}, resetat: now, at: now };
|
|
4919
|
-
if (reset !== void 0) read.resetat = reset > Math.floor(now / 1e3) ? reset * 1e3 : now + reset * 1e3;
|
|
4920
|
-
return read;
|
|
4989
|
+
function cursorfrom(response, field) {
|
|
4990
|
+
let current = response;
|
|
4991
|
+
for (const segment of field.split(".")) {
|
|
4992
|
+
const next = pathstep2(current, segment);
|
|
4993
|
+
if (next === void 0) return void 0;
|
|
4994
|
+
current = next;
|
|
4995
|
+
}
|
|
4996
|
+
return current === void 0 || current === null ? void 0 : String(current);
|
|
4921
4997
|
}
|
|
4922
|
-
function
|
|
4923
|
-
if (
|
|
4924
|
-
|
|
4925
|
-
if (key.toLowerCase() !== "retry-after") continue;
|
|
4926
|
-
const raw = headers[key];
|
|
4927
|
-
if (raw === void 0) continue;
|
|
4928
|
-
const value = raw.trim();
|
|
4929
|
-
const seconds = Number(value);
|
|
4930
|
-
if (Number.isFinite(seconds) && seconds >= 0) return seconds * 1e3;
|
|
4931
|
-
const date = Date.parse(value);
|
|
4932
|
-
if (Number.isFinite(date)) return Math.max(0, date - Date.now());
|
|
4933
|
-
return void 0;
|
|
4998
|
+
function pollurl(cursor, value) {
|
|
4999
|
+
if (cursor.param === void 0 || value === void 0) {
|
|
5000
|
+
return { url: cursor.url, ...value !== void 0 ? { body: JSON.stringify({ [cursor.cursorfield]: value }) } : {} };
|
|
4934
5001
|
}
|
|
4935
|
-
|
|
5002
|
+
const url = new URL(cursor.url);
|
|
5003
|
+
url.searchParams.set(cursor.param, value);
|
|
5004
|
+
return { url: url.toString() };
|
|
4936
5005
|
}
|
|
4937
|
-
function
|
|
4938
|
-
if (
|
|
4939
|
-
|
|
5006
|
+
function polldecision(input) {
|
|
5007
|
+
if (input.cancelled?.() === true) return { continue: false, reason: "The long poll loop was cancelled." };
|
|
5008
|
+
if (input.expiresat !== void 0 && input.now >= input.expiresat) return { continue: false, reason: "The long poll loop stopped at the reviewed plan expiry." };
|
|
5009
|
+
const stopvalue = cursorfrom(input.response, input.cursor.stop.field);
|
|
5010
|
+
if (stopvalue !== void 0 && stopvalue === input.cursor.stop.equals) return { continue: false, reason: `The stop condition matched ${input.cursor.stop.field} ${stopvalue}.` };
|
|
5011
|
+
if (input.cursor.maxpolls !== void 0 && input.polls + 1 >= input.cursor.maxpolls) return { continue: false, reason: `The long poll loop reached the reviewed poll ceiling of ${input.cursor.maxpolls}.` };
|
|
5012
|
+
const value = cursorfrom(input.response, input.cursor.cursorfield);
|
|
5013
|
+
const next = pollurl(input.cursor, value);
|
|
5014
|
+
return { continue: true, reason: "The long poll loop continues.", ...value !== void 0 ? { cursor: value } : {}, next: { ...next, wait: input.cursor.interval } };
|
|
4940
5015
|
}
|
|
4941
5016
|
|
|
4942
5017
|
// netwatch.ts
|
|
@@ -5043,84 +5118,258 @@ function payloadshapeof(body) {
|
|
|
5043
5118
|
return [];
|
|
5044
5119
|
}
|
|
5045
5120
|
}
|
|
5046
|
-
function isapicandidate(exchange) {
|
|
5047
|
-
if (exchange.initiator === "fetch" || exchange.initiator === "xmlhttprequest") return true;
|
|
5048
|
-
if (exchange.bodyref !== void 0) return true;
|
|
5049
|
-
try {
|
|
5050
|
-
return /\/api\/|\/graphql|\.json($|\?)|\/v\d+\//i.test(new URL(exchange.url).pathname);
|
|
5051
|
-
} catch {
|
|
5052
|
-
return false;
|
|
5053
|
-
}
|
|
5121
|
+
function isapicandidate(exchange) {
|
|
5122
|
+
if (exchange.initiator === "fetch" || exchange.initiator === "xmlhttprequest") return true;
|
|
5123
|
+
if (exchange.bodyref !== void 0) return true;
|
|
5124
|
+
try {
|
|
5125
|
+
return /\/api\/|\/graphql|\.json($|\?)|\/v\d+\//i.test(new URL(exchange.url).pathname);
|
|
5126
|
+
} catch {
|
|
5127
|
+
return false;
|
|
5128
|
+
}
|
|
5129
|
+
}
|
|
5130
|
+
function apientries(exchanges, bodies) {
|
|
5131
|
+
const bodybyref = new Map(bodies.map((body) => [body.correlationid, body]));
|
|
5132
|
+
const groups = /* @__PURE__ */ new Map();
|
|
5133
|
+
for (const exchange of exchanges) {
|
|
5134
|
+
if (!isapicandidate(exchange)) continue;
|
|
5135
|
+
let endpoint = exchange.url;
|
|
5136
|
+
let origin = exchange.origin;
|
|
5137
|
+
try {
|
|
5138
|
+
const parsed = new URL(exchange.url);
|
|
5139
|
+
endpoint = `${parsed.origin}${parsed.pathname}`;
|
|
5140
|
+
origin = parsed.origin;
|
|
5141
|
+
} catch {
|
|
5142
|
+
}
|
|
5143
|
+
const key = `${exchange.method} ${endpoint}`;
|
|
5144
|
+
const group = groups.get(key) ?? { endpoint, method: exchange.method, origin, mimes: /* @__PURE__ */ new Map(), frequency: 0, json: 0, captured: 0, shapes: /* @__PURE__ */ new Map(), correlationids: [] };
|
|
5145
|
+
group.frequency += 1;
|
|
5146
|
+
group.correlationids.push(exchange.correlationid);
|
|
5147
|
+
const body = exchange.bodyref !== void 0 ? bodybyref.get(exchange.correlationid) : void 0;
|
|
5148
|
+
const mime = body?.mime ?? exchange.mime ?? "";
|
|
5149
|
+
group.mimes.set(mime, (group.mimes.get(mime) ?? 0) + 1);
|
|
5150
|
+
if (body !== void 0) {
|
|
5151
|
+
group.captured += 1;
|
|
5152
|
+
const shape = payloadshapeof(body.body);
|
|
5153
|
+
if (shape.length > 0) group.json += 1;
|
|
5154
|
+
const shapekey = shape.join(",");
|
|
5155
|
+
group.shapes.set(shapekey, (group.shapes.get(shapekey) ?? 0) + 1);
|
|
5156
|
+
}
|
|
5157
|
+
groups.set(key, group);
|
|
5158
|
+
}
|
|
5159
|
+
return [...groups.values()].map((group) => {
|
|
5160
|
+
const mime = [...group.mimes.entries()].sort((left, right) => right[1] - left[1])[0]?.[0] ?? "";
|
|
5161
|
+
const modalshape = [...group.shapes.entries()].sort((left, right) => right[1] - left[1])[0];
|
|
5162
|
+
return { endpoint: group.endpoint, method: group.method, mime, frequency: group.frequency, payloadshape: (modalshape?.[0] ?? "").split(",").filter(Boolean), jsonshare: group.captured > 0 ? group.json / group.captured : 0, stability: group.captured > 0 ? (modalshape?.[1] ?? 0) / group.captured : 0, origin: group.origin, correlationids: group.correlationids };
|
|
5163
|
+
});
|
|
5164
|
+
}
|
|
5165
|
+
function rankapis(entries) {
|
|
5166
|
+
const score = (entry) => entry.frequency * (1 + entry.jsonshare + entry.stability);
|
|
5167
|
+
return [...entries].sort((left, right) => score(right) - score(left) || right.frequency - left.frequency);
|
|
5168
|
+
}
|
|
5169
|
+
function apireplayspecof(value) {
|
|
5170
|
+
if (!value || typeof value !== "object" || Array.isArray(value)) return void 0;
|
|
5171
|
+
const entry = value;
|
|
5172
|
+
if (typeof entry.endpoint !== "string" || !entry.endpoint.trim()) return void 0;
|
|
5173
|
+
const spec = { endpoint: entry.endpoint.trim() };
|
|
5174
|
+
if (typeof entry.verb === "string" && entry.verb.trim()) spec.verb = entry.verb.trim().toUpperCase();
|
|
5175
|
+
if (entry.overrides !== void 0 && entry.overrides !== null && typeof entry.overrides === "object" && !Array.isArray(entry.overrides)) {
|
|
5176
|
+
const overrides = {};
|
|
5177
|
+
for (const [name, override] of Object.entries(entry.overrides)) {
|
|
5178
|
+
if (typeof override === "string") overrides[name] = override;
|
|
5179
|
+
}
|
|
5180
|
+
spec.overrides = overrides;
|
|
5181
|
+
}
|
|
5182
|
+
if (Array.isArray(entry.paths)) spec.paths = entry.paths.filter((path) => typeof path === "string" && path.trim().length > 0);
|
|
5183
|
+
return spec;
|
|
5184
|
+
}
|
|
5185
|
+
function replayurl(spec) {
|
|
5186
|
+
const url = new URL(spec.endpoint);
|
|
5187
|
+
for (const [name, value] of Object.entries(spec.overrides ?? {})) url.searchParams.set(name, value);
|
|
5188
|
+
return url.toString();
|
|
5189
|
+
}
|
|
5190
|
+
function extractvalues(body, paths) {
|
|
5191
|
+
let parsed;
|
|
5192
|
+
try {
|
|
5193
|
+
parsed = JSON.parse(body);
|
|
5194
|
+
} catch {
|
|
5195
|
+
return paths.map((path) => ({ path, missing: true }));
|
|
5196
|
+
}
|
|
5197
|
+
const fields = readpath(parsed, paths.map((path) => ({ name: path, path, kind: "json" })));
|
|
5198
|
+
return fields.map((field) => ({ path: field.path, ...field.value !== void 0 ? { value: field.value } : {}, ...field.missing ? { missing: true } : {} }));
|
|
5199
|
+
}
|
|
5200
|
+
|
|
5201
|
+
// netcontrol.ts
|
|
5202
|
+
var controlkinds = ["blockrequest", "mockresponse", "rewriteheaders", "setcookies", "readcookies", "clearcookies", "authflow", "saveapikey", "routeproxy", "postform", "postfiles"];
|
|
5203
|
+
function patternorigin(pattern) {
|
|
5204
|
+
const trimmed = pattern.trim();
|
|
5205
|
+
if (!trimmed.startsWith("https://")) return void 0;
|
|
5206
|
+
const rest = trimmed.slice("https://".length);
|
|
5207
|
+
const host = rest.split("/")[0] ?? "";
|
|
5208
|
+
if (!host.trim()) return void 0;
|
|
5209
|
+
return `https://${host.toLowerCase()}`;
|
|
5210
|
+
}
|
|
5211
|
+
function matchurlpattern(pattern, url) {
|
|
5212
|
+
const origin = patternorigin(pattern);
|
|
5213
|
+
if (!origin) return false;
|
|
5214
|
+
let parsed;
|
|
5215
|
+
try {
|
|
5216
|
+
parsed = new URL(url);
|
|
5217
|
+
} catch {
|
|
5218
|
+
return false;
|
|
5219
|
+
}
|
|
5220
|
+
if (parsed.origin !== origin) return false;
|
|
5221
|
+
const patternpath = pattern.trim().slice(origin.length);
|
|
5222
|
+
if (patternpath === "" || patternpath === "/") return true;
|
|
5223
|
+
const segments = patternpath.split("/").filter((segment) => segment !== "");
|
|
5224
|
+
if (segments.includes("**")) return true;
|
|
5225
|
+
const pathsegments = parsed.pathname.split("/").filter((segment) => segment !== "");
|
|
5226
|
+
if (segments.length !== pathsegments.length) return false;
|
|
5227
|
+
return segments.every((segment, index) => segment === pathsegments[index] || segment.includes("*") && new RegExp(`^${segment.split("*").map((part) => part.replace(/[.*+?^${}()|[\]\\]/g, "\\$&")).join(".*")}$`).test(pathsegments[index] ?? ""));
|
|
5228
|
+
}
|
|
5229
|
+
function blockruleof(value) {
|
|
5230
|
+
if (!value || typeof value !== "object" || Array.isArray(value)) return void 0;
|
|
5231
|
+
const options = value;
|
|
5232
|
+
if (typeof options.urlpattern !== "string" || !options.urlpattern.trim()) return void 0;
|
|
5233
|
+
const rule = { urlpattern: options.urlpattern.trim() };
|
|
5234
|
+
if (Array.isArray(options.resourcetypes)) {
|
|
5235
|
+
const types = options.resourcetypes.filter((item) => typeof item === "string" && item.trim().length > 0);
|
|
5236
|
+
if (types.length === 0) return void 0;
|
|
5237
|
+
rule.resourcetypes = types;
|
|
5238
|
+
}
|
|
5239
|
+
return rule;
|
|
5240
|
+
}
|
|
5241
|
+
function newblockrule(input) {
|
|
5242
|
+
return { id: input.id, runid: input.runid, stepid: input.stepid, urlpattern: input.urlpattern, ...input.resourcetypes !== void 0 ? { resourcetypes: input.resourcetypes } : {}, hits: 0, registeredat: input.at };
|
|
5243
|
+
}
|
|
5244
|
+
function mockspecof(value) {
|
|
5245
|
+
if (!value || typeof value !== "object" || Array.isArray(value)) return void 0;
|
|
5246
|
+
const options = value;
|
|
5247
|
+
if (typeof options.urlpattern !== "string" || !options.urlpattern.trim()) return void 0;
|
|
5248
|
+
if (typeof options.status !== "number" || !Number.isInteger(options.status) || options.status < 100 || options.status > 599) return void 0;
|
|
5249
|
+
const hasbody = typeof options.body === "string";
|
|
5250
|
+
const bodyref = typeof options.bodyref === "string" ? options.bodyref.trim() : "";
|
|
5251
|
+
if (!hasbody && bodyref === "") return void 0;
|
|
5252
|
+
const spec = { urlpattern: options.urlpattern.trim(), status: options.status };
|
|
5253
|
+
if (hasbody) spec.body = options.body;
|
|
5254
|
+
if (bodyref !== "") spec.bodyref = bodyref;
|
|
5255
|
+
if (options.headers && typeof options.headers === "object" && !Array.isArray(options.headers)) spec.headers = options.headers;
|
|
5256
|
+
if (options.reviewed === true) spec.reviewed = true;
|
|
5257
|
+
return spec;
|
|
5258
|
+
}
|
|
5259
|
+
function newmockspec(input) {
|
|
5260
|
+
return { id: input.id, runid: input.runid, stepid: input.stepid, urlpattern: input.urlpattern, status: input.status, ...input.headers !== void 0 ? { headers: input.headers } : {}, ...input.body !== void 0 ? { body: input.body } : {}, ...input.bodyref !== void 0 ? { bodyref: input.bodyref } : {}, reviewed: input.reviewed, hits: 0, registeredat: input.at };
|
|
5261
|
+
}
|
|
5262
|
+
function mockfor(url, specs) {
|
|
5263
|
+
return specs.find((spec) => spec.revertedat === void 0 && matchurlpattern(spec.urlpattern, url));
|
|
5264
|
+
}
|
|
5265
|
+
function headeruleof(value) {
|
|
5266
|
+
if (!value || typeof value !== "object" || Array.isArray(value)) return void 0;
|
|
5267
|
+
const options = value;
|
|
5268
|
+
if (typeof options.urlpattern !== "string" || !options.urlpattern.trim()) return void 0;
|
|
5269
|
+
if (typeof options.name !== "string" || !options.name.trim()) return void 0;
|
|
5270
|
+
if (options.operation !== "set" && options.operation !== "append" && options.operation !== "remove") return void 0;
|
|
5271
|
+
if (options.operation === "remove" && options.value !== void 0) return void 0;
|
|
5272
|
+
if (options.operation !== "remove" && typeof options.value !== "string") return void 0;
|
|
5273
|
+
const rule = { urlpattern: options.urlpattern.trim(), name: options.name.trim(), operation: options.operation };
|
|
5274
|
+
if (options.operation !== "remove") rule.value = typeof options.value === "string" ? options.value : "";
|
|
5275
|
+
return rule;
|
|
5276
|
+
}
|
|
5277
|
+
function newheaderule(input) {
|
|
5278
|
+
return { id: input.id, runid: input.runid, stepid: input.stepid, urlpattern: input.urlpattern, name: input.name, operation: input.operation, ...input.value !== void 0 ? { value: input.value } : {}, hits: 0, registeredat: input.at };
|
|
5279
|
+
}
|
|
5280
|
+
function applyheaderules(url, headers, rules) {
|
|
5281
|
+
const rewritten = { ...headers };
|
|
5282
|
+
const applied = [];
|
|
5283
|
+
for (const rule of rules) {
|
|
5284
|
+
if (rule.revertedat !== void 0) continue;
|
|
5285
|
+
if (!matchurlpattern(rule.urlpattern, url)) continue;
|
|
5286
|
+
const name = rule.name;
|
|
5287
|
+
if (rule.operation === "remove") {
|
|
5288
|
+
delete rewritten[name];
|
|
5289
|
+
applied.push(rule);
|
|
5290
|
+
continue;
|
|
5291
|
+
}
|
|
5292
|
+
const value = rule.value ?? "";
|
|
5293
|
+
if (rule.operation === "set") rewritten[name] = value;
|
|
5294
|
+
else rewritten[name] = rewritten[name] !== void 0 ? `${rewritten[name]}, ${value}` : value;
|
|
5295
|
+
applied.push(rule);
|
|
5296
|
+
}
|
|
5297
|
+
return { headers: rewritten, applied };
|
|
5298
|
+
}
|
|
5299
|
+
function revertrule(rule, at) {
|
|
5300
|
+
if (rule.revertedat !== void 0) return rule;
|
|
5301
|
+
return { ...rule, revertedat: at };
|
|
5054
5302
|
}
|
|
5055
|
-
function
|
|
5056
|
-
|
|
5057
|
-
const
|
|
5058
|
-
|
|
5059
|
-
|
|
5060
|
-
|
|
5061
|
-
|
|
5303
|
+
function cookierecordof(value) {
|
|
5304
|
+
if (!value || typeof value !== "object" || Array.isArray(value)) return void 0;
|
|
5305
|
+
const options = value;
|
|
5306
|
+
if (typeof options.name !== "string" || !options.name.trim()) return void 0;
|
|
5307
|
+
if (typeof options.domain !== "string" || !options.domain.trim()) return void 0;
|
|
5308
|
+
if (typeof options.path !== "string" || !options.path.trim()) return void 0;
|
|
5309
|
+
if (typeof options.value !== "string") return void 0;
|
|
5310
|
+
const record2 = { name: options.name.trim(), domain: options.domain.trim().toLowerCase(), path: options.path.trim(), value: options.value };
|
|
5311
|
+
if (typeof options.expiresat === "number" && Number.isFinite(options.expiresat)) record2.expiresat = options.expiresat;
|
|
5312
|
+
return record2;
|
|
5313
|
+
}
|
|
5314
|
+
function cookiedomaingranted(domain, grants) {
|
|
5315
|
+
const host = domain.trim().toLowerCase().replace(/^\./, "");
|
|
5316
|
+
return grants.some((grant) => {
|
|
5317
|
+
let granthost = "";
|
|
5062
5318
|
try {
|
|
5063
|
-
|
|
5064
|
-
endpoint = `${parsed.origin}${parsed.pathname}`;
|
|
5065
|
-
origin = parsed.origin;
|
|
5319
|
+
granthost = new URL(grant).hostname.toLowerCase();
|
|
5066
5320
|
} catch {
|
|
5321
|
+
return false;
|
|
5067
5322
|
}
|
|
5068
|
-
|
|
5069
|
-
const group = groups.get(key) ?? { endpoint, method: exchange.method, origin, mimes: /* @__PURE__ */ new Map(), frequency: 0, json: 0, captured: 0, shapes: /* @__PURE__ */ new Map(), correlationids: [] };
|
|
5070
|
-
group.frequency += 1;
|
|
5071
|
-
group.correlationids.push(exchange.correlationid);
|
|
5072
|
-
const body = exchange.bodyref !== void 0 ? bodybyref.get(exchange.correlationid) : void 0;
|
|
5073
|
-
const mime = body?.mime ?? exchange.mime ?? "";
|
|
5074
|
-
group.mimes.set(mime, (group.mimes.get(mime) ?? 0) + 1);
|
|
5075
|
-
if (body !== void 0) {
|
|
5076
|
-
group.captured += 1;
|
|
5077
|
-
const shape = payloadshapeof(body.body);
|
|
5078
|
-
if (shape.length > 0) group.json += 1;
|
|
5079
|
-
const shapekey = shape.join(",");
|
|
5080
|
-
group.shapes.set(shapekey, (group.shapes.get(shapekey) ?? 0) + 1);
|
|
5081
|
-
}
|
|
5082
|
-
groups.set(key, group);
|
|
5083
|
-
}
|
|
5084
|
-
return [...groups.values()].map((group) => {
|
|
5085
|
-
const mime = [...group.mimes.entries()].sort((left, right) => right[1] - left[1])[0]?.[0] ?? "";
|
|
5086
|
-
const modalshape = [...group.shapes.entries()].sort((left, right) => right[1] - left[1])[0];
|
|
5087
|
-
return { endpoint: group.endpoint, method: group.method, mime, frequency: group.frequency, payloadshape: (modalshape?.[0] ?? "").split(",").filter(Boolean), jsonshare: group.captured > 0 ? group.json / group.captured : 0, stability: group.captured > 0 ? (modalshape?.[1] ?? 0) / group.captured : 0, origin: group.origin, correlationids: group.correlationids };
|
|
5323
|
+
return host === granthost || host.endsWith(`.${granthost}`);
|
|
5088
5324
|
});
|
|
5089
5325
|
}
|
|
5090
|
-
function
|
|
5091
|
-
|
|
5092
|
-
return [...entries].sort((left, right) => score(right) - score(left) || right.frequency - left.frequency);
|
|
5326
|
+
function redactedcookies(records) {
|
|
5327
|
+
return records.map((record2) => ({ name: record2.name, domain: record2.domain, path: record2.path, ...record2.expiresat !== void 0 ? { expiresat: record2.expiresat } : {} }));
|
|
5093
5328
|
}
|
|
5094
|
-
function
|
|
5329
|
+
function proxyrouteof(value) {
|
|
5095
5330
|
if (!value || typeof value !== "object" || Array.isArray(value)) return void 0;
|
|
5096
|
-
const
|
|
5097
|
-
if (
|
|
5098
|
-
|
|
5099
|
-
if (typeof
|
|
5100
|
-
if (
|
|
5101
|
-
|
|
5102
|
-
for (const [name, override] of Object.entries(entry.overrides)) {
|
|
5103
|
-
if (typeof override === "string") overrides[name] = override;
|
|
5104
|
-
}
|
|
5105
|
-
spec.overrides = overrides;
|
|
5106
|
-
}
|
|
5107
|
-
if (Array.isArray(entry.paths)) spec.paths = entry.paths.filter((path) => typeof path === "string" && path.trim().length > 0);
|
|
5108
|
-
return spec;
|
|
5331
|
+
const options = value;
|
|
5332
|
+
if (options.scheme !== "http" && options.scheme !== "https" && options.scheme !== "socks4" && options.scheme !== "socks5") return void 0;
|
|
5333
|
+
if (typeof options.host !== "string" || !options.host.trim()) return void 0;
|
|
5334
|
+
if (typeof options.port !== "number" || !Number.isInteger(options.port) || options.port < 1 || options.port > 65535) return void 0;
|
|
5335
|
+
if (!Array.isArray(options.bypass) || options.bypass.length === 0 || !options.bypass.every((item) => typeof item === "string" && item.trim().length > 0)) return void 0;
|
|
5336
|
+
return { scheme: options.scheme, host: options.host.trim(), port: options.port, bypass: options.bypass.map((item) => item.trim()) };
|
|
5109
5337
|
}
|
|
5110
|
-
function
|
|
5111
|
-
const
|
|
5112
|
-
|
|
5113
|
-
|
|
5338
|
+
function ratelimitreadof(headers, origin, now) {
|
|
5339
|
+
const pick = (name) => {
|
|
5340
|
+
for (const key of Object.keys(headers)) {
|
|
5341
|
+
if (key.toLowerCase() !== name) continue;
|
|
5342
|
+
const value = Number(headers[key]);
|
|
5343
|
+
return Number.isFinite(value) && value >= 0 ? value : void 0;
|
|
5344
|
+
}
|
|
5345
|
+
return void 0;
|
|
5346
|
+
};
|
|
5347
|
+
const remaining = pick("x-ratelimit-remaining");
|
|
5348
|
+
const limit = pick("x-ratelimit-limit");
|
|
5349
|
+
const reset = pick("x-ratelimit-reset");
|
|
5350
|
+
if (remaining === void 0 && limit === void 0 && reset === void 0) return void 0;
|
|
5351
|
+
const read = { origin, ...remaining !== void 0 ? { remaining } : {}, ...limit !== void 0 ? { limit } : {}, resetat: now, at: now };
|
|
5352
|
+
if (reset !== void 0) read.resetat = reset > Math.floor(now / 1e3) ? reset * 1e3 : now + reset * 1e3;
|
|
5353
|
+
return read;
|
|
5114
5354
|
}
|
|
5115
|
-
function
|
|
5116
|
-
|
|
5117
|
-
|
|
5118
|
-
|
|
5119
|
-
|
|
5120
|
-
|
|
5355
|
+
function retryafterof(status, headers) {
|
|
5356
|
+
if (status !== 429 && status !== 503) return void 0;
|
|
5357
|
+
for (const key of Object.keys(headers)) {
|
|
5358
|
+
if (key.toLowerCase() !== "retry-after") continue;
|
|
5359
|
+
const raw = headers[key];
|
|
5360
|
+
if (raw === void 0) continue;
|
|
5361
|
+
const value = raw.trim();
|
|
5362
|
+
const seconds = Number(value);
|
|
5363
|
+
if (Number.isFinite(seconds) && seconds >= 0) return seconds * 1e3;
|
|
5364
|
+
const date = Date.parse(value);
|
|
5365
|
+
if (Number.isFinite(date)) return Math.max(0, date - Date.now());
|
|
5366
|
+
return void 0;
|
|
5121
5367
|
}
|
|
5122
|
-
|
|
5123
|
-
|
|
5368
|
+
return void 0;
|
|
5369
|
+
}
|
|
5370
|
+
function ratelimitwait(state, now) {
|
|
5371
|
+
if (!state) return 0;
|
|
5372
|
+
return Math.max(0, state.resetat - now);
|
|
5124
5373
|
}
|
|
5125
5374
|
|
|
5126
5375
|
// trigger.ts
|
|
@@ -5518,224 +5767,139 @@ function ruleoriginsgranted(rule, workfloworigins) {
|
|
|
5518
5767
|
return ruleorigins(rule).every((origin) => granted.has(origin));
|
|
5519
5768
|
}
|
|
5520
5769
|
|
|
5521
|
-
//
|
|
5522
|
-
|
|
5523
|
-
function channelorigin(url) {
|
|
5524
|
-
try {
|
|
5525
|
-
const parsed = new URL(url);
|
|
5526
|
-
const protocol = parsed.protocol === "wss:" ? "https:" : parsed.protocol === "ws:" ? "http:" : parsed.protocol;
|
|
5527
|
-
return `${protocol}//${parsed.host}`;
|
|
5528
|
-
} catch {
|
|
5529
|
-
return "";
|
|
5530
|
-
}
|
|
5531
|
-
}
|
|
5532
|
-
function channeloptionsof(value) {
|
|
5770
|
+
// netauth.ts
|
|
5771
|
+
function oauthflowof(value) {
|
|
5533
5772
|
if (!value || typeof value !== "object" || Array.isArray(value)) return void 0;
|
|
5534
|
-
const
|
|
5535
|
-
if (typeof
|
|
5536
|
-
|
|
5537
|
-
if (
|
|
5538
|
-
if (
|
|
5539
|
-
if (typeof
|
|
5540
|
-
|
|
5541
|
-
if (typeof entry.lifetime === "number" && Number.isFinite(entry.lifetime)) options.lifetime = entry.lifetime;
|
|
5542
|
-
return { url: entry.url.trim(), options };
|
|
5543
|
-
}
|
|
5544
|
-
function newchannel(input) {
|
|
5545
|
-
return { id: input.id, runid: input.runid, stepid: input.stepid, kind: input.kind, url: input.url, origin: channelorigin(input.url), state: "connecting", openedat: input.at, sent: 0, received: 0, reconnects: 0, ...input.protocols !== void 0 && input.protocols.length > 0 ? { protocols: [...input.protocols] } : {} };
|
|
5546
|
-
}
|
|
5547
|
-
function reconnectwaits(attempts, base, ceiling) {
|
|
5548
|
-
const count = Math.max(0, Math.floor(attempts));
|
|
5549
|
-
const waits = [];
|
|
5550
|
-
let wait = Math.max(0, base);
|
|
5551
|
-
for (let index = 0; index < count; index += 1) {
|
|
5552
|
-
waits.push(wait);
|
|
5553
|
-
const next = wait * 2;
|
|
5554
|
-
wait = ceiling !== void 0 && Number.isFinite(ceiling) && ceiling >= 0 ? Math.min(next, ceiling) : next;
|
|
5555
|
-
}
|
|
5556
|
-
return waits;
|
|
5557
|
-
}
|
|
5558
|
-
async function openchannel(input) {
|
|
5559
|
-
const sleep = input.sleep ?? ((milliseconds) => new Promise((resolve) => setTimeout(resolve, Math.max(0, milliseconds))));
|
|
5560
|
-
const now = input.now ?? Date.now;
|
|
5561
|
-
const attempts = Math.max(1, Math.floor(input.options.reconnect ?? 0) + 1);
|
|
5562
|
-
const waits = reconnectwaits(attempts - 1, input.options.backoff ?? 0, input.options.backoffceiling);
|
|
5563
|
-
let record2 = { ...input.record, state: "connecting" };
|
|
5564
|
-
let lasterror = "";
|
|
5565
|
-
for (let attempt = 0; attempt < attempts; attempt += 1) {
|
|
5566
|
-
try {
|
|
5567
|
-
const result = await input.connect(record2.url, record2.protocols ?? []);
|
|
5568
|
-
if (result.open) return { ...record2, state: "open", openedat: now() };
|
|
5569
|
-
lasterror = result.error ?? `closed with code ${result.code ?? 0}`;
|
|
5570
|
-
} catch (error) {
|
|
5571
|
-
lasterror = error instanceof Error ? error.message : String(error);
|
|
5572
|
-
}
|
|
5573
|
-
if (attempt < attempts - 1) {
|
|
5574
|
-
const wait = waits[attempt] ?? 0;
|
|
5575
|
-
if (wait > 0) await sleep(wait);
|
|
5576
|
-
record2 = { ...record2, reconnects: record2.reconnects + 1 };
|
|
5577
|
-
}
|
|
5578
|
-
}
|
|
5579
|
-
return { ...record2, state: "failed", error: lasterror };
|
|
5580
|
-
}
|
|
5581
|
-
function closechannel(record2, at, error) {
|
|
5582
|
-
const state = error !== void 0 ? "failed" : "closed";
|
|
5583
|
-
return { ...record2, state, closedat: at, ...error !== void 0 ? { error } : {} };
|
|
5584
|
-
}
|
|
5585
|
-
function tagmessage(state, channelid, stream, payload, at) {
|
|
5586
|
-
const sequence = (state.sequences[channelid] ?? 0) + 1;
|
|
5587
|
-
const envelope = { channelid, stream, payload, sequence, at };
|
|
5588
|
-
return { state: { sequences: { ...state.sequences, [channelid]: sequence }, queue: state.queue }, envelope };
|
|
5589
|
-
}
|
|
5590
|
-
function publishmessage(state, channelid, stream, payload, at) {
|
|
5591
|
-
return tagmessage(state, channelid, stream, payload, at);
|
|
5592
|
-
}
|
|
5593
|
-
function receivemessage(state, channelid, stream, payload, at) {
|
|
5594
|
-
const tagged = tagmessage(state, channelid, stream, payload, at);
|
|
5595
|
-
return { state: { ...tagged.state, queue: [...state.queue, tagged.envelope] }, envelope: tagged.envelope };
|
|
5773
|
+
const options = value;
|
|
5774
|
+
if (typeof options.provider !== "string" || !options.provider.trim()) return void 0;
|
|
5775
|
+
if (typeof options.authorizeurl !== "string" || !options.authorizeurl.trim()) return void 0;
|
|
5776
|
+
if (typeof options.tokenurl !== "string" || !options.tokenurl.trim()) return void 0;
|
|
5777
|
+
if (!Array.isArray(options.scopes) || options.scopes.length === 0 || !options.scopes.every((item) => typeof item === "string" && item.trim().length > 0)) return void 0;
|
|
5778
|
+
if (typeof options.redirectorigin !== "string" || !options.redirectorigin.trim()) return void 0;
|
|
5779
|
+
return { provider: options.provider.trim(), authorizeurl: options.authorizeurl.trim(), tokenurl: options.tokenurl.trim(), scopes: options.scopes.map((item) => item.trim()), redirectorigin: options.redirectorigin.trim() };
|
|
5596
5780
|
}
|
|
5597
|
-
function
|
|
5598
|
-
|
|
5599
|
-
|
|
5600
|
-
|
|
5781
|
+
function authorizeurl(flow, state) {
|
|
5782
|
+
const url = new URL(flow.authorizeurl);
|
|
5783
|
+
url.searchParams.set("response_type", "code");
|
|
5784
|
+
url.searchParams.set("redirect_uri", flow.redirectorigin);
|
|
5785
|
+
url.searchParams.set("scope", flow.scopes.join(" "));
|
|
5786
|
+
url.searchParams.set("state", state);
|
|
5787
|
+
return url.toString();
|
|
5601
5788
|
}
|
|
5602
|
-
function
|
|
5603
|
-
|
|
5604
|
-
|
|
5605
|
-
|
|
5606
|
-
|
|
5607
|
-
|
|
5608
|
-
let current = parsed;
|
|
5609
|
-
let missing = false;
|
|
5610
|
-
for (const segment of filter.path.split(".")) {
|
|
5611
|
-
const next = pathstep2(current, segment);
|
|
5612
|
-
if (next === void 0) {
|
|
5613
|
-
missing = true;
|
|
5614
|
-
break;
|
|
5615
|
-
}
|
|
5616
|
-
current = next;
|
|
5617
|
-
}
|
|
5618
|
-
if (missing) return false;
|
|
5619
|
-
} catch {
|
|
5620
|
-
return false;
|
|
5621
|
-
}
|
|
5789
|
+
function capturecode(url, redirectorigin, state) {
|
|
5790
|
+
let parsed;
|
|
5791
|
+
try {
|
|
5792
|
+
parsed = new URL(url);
|
|
5793
|
+
} catch {
|
|
5794
|
+
return { error: "The redirect url does not parse for the code capture." };
|
|
5622
5795
|
}
|
|
5623
|
-
|
|
5796
|
+
const granted = redirectorigin.includes("/", redirectorigin.indexOf("://") + 3) ? `${parsed.origin}${parsed.pathname}`.startsWith(redirectorigin) : parsed.origin === redirectorigin;
|
|
5797
|
+
if (!granted) return { error: `The redirect landed on ${parsed.origin} outside the granted redirect origin ${redirectorigin}.` };
|
|
5798
|
+
const returned = parsed.searchParams.get("state");
|
|
5799
|
+
if (returned !== state) return { error: "The redirect state token does not match the reviewed flow." };
|
|
5800
|
+
const error = parsed.searchParams.get("error");
|
|
5801
|
+
if (error) return { error: `The provider refused the flow: ${error}.` };
|
|
5802
|
+
const code = parsed.searchParams.get("code");
|
|
5803
|
+
if (!code) return { error: "The redirect carries no authorization code." };
|
|
5804
|
+
return { code };
|
|
5624
5805
|
}
|
|
5625
|
-
function
|
|
5626
|
-
|
|
5627
|
-
|
|
5628
|
-
|
|
5629
|
-
|
|
5630
|
-
|
|
5631
|
-
else queue.push(envelope);
|
|
5806
|
+
function parsetokens(body) {
|
|
5807
|
+
let parsed;
|
|
5808
|
+
try {
|
|
5809
|
+
parsed = JSON.parse(body);
|
|
5810
|
+
} catch {
|
|
5811
|
+
return void 0;
|
|
5632
5812
|
}
|
|
5633
|
-
|
|
5813
|
+
if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) return void 0;
|
|
5814
|
+
const record2 = parsed;
|
|
5815
|
+
const tokens = {};
|
|
5816
|
+
if (typeof record2.access_token === "string" && record2.access_token) tokens.accesstoken = record2.access_token;
|
|
5817
|
+
if (typeof record2.refresh_token === "string" && record2.refresh_token) tokens.refreshtoken = record2.refresh_token;
|
|
5818
|
+
if (typeof record2.expires_in === "number" && Number.isFinite(record2.expires_in) && record2.expires_in >= 0) tokens.expiresin = record2.expires_in;
|
|
5819
|
+
if (typeof record2.scope === "string" && record2.scope.trim()) tokens.scopes = record2.scope.trim().split(/\s+/);
|
|
5820
|
+
if (tokens.accesstoken === void 0 && tokens.refreshtoken === void 0) return void 0;
|
|
5821
|
+
return tokens;
|
|
5634
5822
|
}
|
|
5635
|
-
function
|
|
5636
|
-
|
|
5637
|
-
|
|
5638
|
-
for (const envelope of envelopes) {
|
|
5639
|
-
const expected = (last.get(envelope.channelid) ?? 0) + 1;
|
|
5640
|
-
if (envelope.sequence !== expected) gaps.push({ channelid: envelope.channelid, expected, found: envelope.sequence });
|
|
5641
|
-
last.set(envelope.channelid, Math.max(envelope.sequence, expected));
|
|
5642
|
-
}
|
|
5643
|
-
return { ok: gaps.length === 0, gaps };
|
|
5823
|
+
function tokenrequest(flow, input) {
|
|
5824
|
+
if (input.refreshtoken !== void 0) return { url: flow.tokenurl, body: urlencodeform([{ name: "grant_type", value: "refresh_token" }, { name: "refresh_token", value: input.refreshtoken }]) };
|
|
5825
|
+
return { url: flow.tokenurl, body: urlencodeform([{ name: "grant_type", value: "authorization_code" }, { name: "code", value: input.code ?? "" }, { name: "redirect_uri", value: flow.redirectorigin }]) };
|
|
5644
5826
|
}
|
|
5645
|
-
function
|
|
5646
|
-
if (!value || typeof value !== "object" || Array.isArray(value)) return
|
|
5647
|
-
const
|
|
5648
|
-
|
|
5649
|
-
if (typeof
|
|
5650
|
-
|
|
5651
|
-
if (typeof entry.limit === "number" && Number.isFinite(entry.limit) && entry.limit >= 1) filter.limit = Math.floor(entry.limit);
|
|
5652
|
-
return filter;
|
|
5827
|
+
function revocationruleof(value) {
|
|
5828
|
+
if (!value || typeof value !== "object" || Array.isArray(value)) return void 0;
|
|
5829
|
+
const options = value;
|
|
5830
|
+
if (!Array.isArray(options.tokenids) || options.tokenids.length === 0 || !options.tokenids.every((item) => typeof item === "string" && item.trim().length > 0)) return void 0;
|
|
5831
|
+
if (typeof options.reason !== "string" || !options.reason.trim()) return void 0;
|
|
5832
|
+
return { tokenids: options.tokenids.map((item) => item.trim()), reason: options.reason.trim(), revokedat: Date.now() };
|
|
5653
5833
|
}
|
|
5654
|
-
function
|
|
5655
|
-
|
|
5656
|
-
const
|
|
5657
|
-
|
|
5658
|
-
|
|
5659
|
-
|
|
5660
|
-
|
|
5661
|
-
|
|
5662
|
-
const
|
|
5663
|
-
|
|
5664
|
-
|
|
5665
|
-
|
|
5666
|
-
const colon = line.indexOf(":");
|
|
5667
|
-
const field = colon === -1 ? line : line.slice(0, colon);
|
|
5668
|
-
let value = colon === -1 ? "" : line.slice(colon + 1);
|
|
5669
|
-
if (value.startsWith(" ")) value = value.slice(1);
|
|
5670
|
-
if (field === "id" && value !== "") id.push(value);
|
|
5671
|
-
if (field === "event" && value !== "") names.push(value);
|
|
5672
|
-
if (field === "data") data.push(value);
|
|
5673
|
-
if (field === "retry" && /^\d+$/.test(value)) retry = Number.parseInt(value, 10);
|
|
5674
|
-
}
|
|
5675
|
-
if (id.length === 0 && names.length === 0 && data.length === 0) continue;
|
|
5676
|
-
events.push({ ...id.length > 0 ? { id: id[id.length - 1] } : {}, ...names.length > 0 ? { event: names[names.length - 1] } : {}, data: data.join("\n"), ...retry !== void 0 ? { retry } : {} });
|
|
5834
|
+
function formpayloadof(value) {
|
|
5835
|
+
if (!value || typeof value !== "object" || Array.isArray(value)) return void 0;
|
|
5836
|
+
const options = value;
|
|
5837
|
+
if (typeof options.url !== "string" || !options.url.trim()) return void 0;
|
|
5838
|
+
if (!Array.isArray(options.fields) || options.fields.length === 0) return void 0;
|
|
5839
|
+
const fields = [];
|
|
5840
|
+
for (const item of options.fields) {
|
|
5841
|
+
if (!item || typeof item !== "object" || Array.isArray(item)) return void 0;
|
|
5842
|
+
const field = item;
|
|
5843
|
+
if (typeof field.name !== "string" || !field.name.trim()) return void 0;
|
|
5844
|
+
if (typeof field.value !== "string") return void 0;
|
|
5845
|
+
fields.push({ name: field.name.trim(), value: field.value });
|
|
5677
5846
|
}
|
|
5678
|
-
return {
|
|
5847
|
+
return { url: options.url.trim(), fields };
|
|
5679
5848
|
}
|
|
5680
|
-
function
|
|
5681
|
-
return
|
|
5849
|
+
function urlencodeform(fields) {
|
|
5850
|
+
return fields.map((field) => `${formencode(field.name)}=${formencode(field.value)}`).join("&");
|
|
5682
5851
|
}
|
|
5683
|
-
function
|
|
5684
|
-
|
|
5685
|
-
|
|
5686
|
-
if (typeof entry.url !== "string" || !entry.url.trim()) return void 0;
|
|
5687
|
-
const cancel = entry.cancel;
|
|
5688
|
-
if (!cancel || typeof cancel !== "object" || Array.isArray(cancel)) return void 0;
|
|
5689
|
-
const cancelrecord = cancel;
|
|
5690
|
-
if (cancelrecord.kind !== "stop" && cancelrecord.kind !== "lifetime") return void 0;
|
|
5691
|
-
if (typeof cancelrecord.value !== "string" && typeof cancelrecord.value !== "number") return void 0;
|
|
5692
|
-
const result = { url: entry.url.trim(), cancel: { kind: cancelrecord.kind, value: cancelrecord.value } };
|
|
5693
|
-
if (typeof entry.lifetime === "number" && Number.isFinite(entry.lifetime) && entry.lifetime > 0) result.lifetime = entry.lifetime;
|
|
5694
|
-
if (typeof entry.lasteventid === "string" && entry.lasteventid.trim()) result.lasteventid = entry.lasteventid.trim();
|
|
5695
|
-
return result;
|
|
5852
|
+
function formencode(value) {
|
|
5853
|
+
const bytes = [...new TextEncoder().encode(value)];
|
|
5854
|
+
return bytes.map((byte) => byte >= 65 && byte <= 90 || byte >= 97 && byte <= 122 || byte >= 48 && byte <= 57 || byte === 45 || byte === 95 || byte === 46 || byte === 126 ? String.fromCharCode(byte) : `%${byte.toString(16).toUpperCase().padStart(2, "0")}`).join("");
|
|
5696
5855
|
}
|
|
5697
|
-
function
|
|
5856
|
+
function multipartpayloadof(value) {
|
|
5698
5857
|
if (!value || typeof value !== "object" || Array.isArray(value)) return void 0;
|
|
5699
|
-
const
|
|
5700
|
-
if (typeof
|
|
5701
|
-
if (
|
|
5702
|
-
|
|
5703
|
-
const
|
|
5704
|
-
|
|
5705
|
-
|
|
5706
|
-
|
|
5707
|
-
|
|
5708
|
-
|
|
5709
|
-
if (typeof entry.maxpolls === "number" && Number.isFinite(entry.maxpolls) && entry.maxpolls >= 1) cursor.maxpolls = Math.floor(entry.maxpolls);
|
|
5710
|
-
if (typeof entry.param === "string" && entry.param.trim()) cursor.param = entry.param.trim();
|
|
5711
|
-
return cursor;
|
|
5712
|
-
}
|
|
5713
|
-
function cursorfrom(response, field) {
|
|
5714
|
-
let current = response;
|
|
5715
|
-
for (const segment of field.split(".")) {
|
|
5716
|
-
const next = pathstep2(current, segment);
|
|
5717
|
-
if (next === void 0) return void 0;
|
|
5718
|
-
current = next;
|
|
5858
|
+
const options = value;
|
|
5859
|
+
if (typeof options.url !== "string" || !options.url.trim()) return void 0;
|
|
5860
|
+
if (!Array.isArray(options.files) || options.files.length === 0) return void 0;
|
|
5861
|
+
const fields = [];
|
|
5862
|
+
for (const item of Array.isArray(options.fields) ? options.fields : []) {
|
|
5863
|
+
if (!item || typeof item !== "object" || Array.isArray(item)) return void 0;
|
|
5864
|
+
const field = item;
|
|
5865
|
+
if (typeof field.name !== "string" || !field.name.trim()) return void 0;
|
|
5866
|
+
if (typeof field.value !== "string") return void 0;
|
|
5867
|
+
fields.push({ name: field.name.trim(), value: field.value });
|
|
5719
5868
|
}
|
|
5720
|
-
|
|
5721
|
-
|
|
5722
|
-
|
|
5723
|
-
|
|
5724
|
-
|
|
5869
|
+
const files = [];
|
|
5870
|
+
for (const item of options.files) {
|
|
5871
|
+
if (!item || typeof item !== "object" || Array.isArray(item)) return void 0;
|
|
5872
|
+
const file = item;
|
|
5873
|
+
if (typeof file.name !== "string" || !file.name.trim()) return void 0;
|
|
5874
|
+
if (typeof file.filename !== "string" || !file.filename.trim()) return void 0;
|
|
5875
|
+
if (typeof file.mime !== "string" || !file.mime.trim()) return void 0;
|
|
5876
|
+
if (typeof file.content !== "string") return void 0;
|
|
5877
|
+
if (file.reviewed !== true) return void 0;
|
|
5878
|
+
files.push({ name: file.name.trim(), filename: file.filename.trim(), mime: file.mime.trim(), content: file.content, reviewed: true });
|
|
5725
5879
|
}
|
|
5726
|
-
const
|
|
5727
|
-
|
|
5728
|
-
return { url: url.toString() };
|
|
5880
|
+
const payload = { url: options.url.trim(), fields, files, ...typeof options.boundary === "string" && options.boundary.trim() ? { boundary: options.boundary.trim() } : {} };
|
|
5881
|
+
return payload;
|
|
5729
5882
|
}
|
|
5730
|
-
function
|
|
5731
|
-
|
|
5732
|
-
|
|
5733
|
-
|
|
5734
|
-
|
|
5735
|
-
|
|
5736
|
-
const
|
|
5737
|
-
|
|
5738
|
-
|
|
5883
|
+
function newboundary() {
|
|
5884
|
+
return `----devthink${Math.random().toString(16).slice(2)}${Date.now().toString(16)}`;
|
|
5885
|
+
}
|
|
5886
|
+
function multipartchunks(payload) {
|
|
5887
|
+
const boundary = payload.boundary ?? newboundary();
|
|
5888
|
+
const chunks = [];
|
|
5889
|
+
for (const field of payload.fields) chunks.push(`--${boundary}\r
|
|
5890
|
+
content-disposition: form-data; name="${field.name}"\r
|
|
5891
|
+
\r
|
|
5892
|
+
${field.value}\r
|
|
5893
|
+
`);
|
|
5894
|
+
for (const file of payload.files) chunks.push(`--${boundary}\r
|
|
5895
|
+
content-disposition: form-data; name="${file.name}"; filename="${file.filename}"\r
|
|
5896
|
+
content-type: ${file.mime}\r
|
|
5897
|
+
\r
|
|
5898
|
+
${file.content}\r
|
|
5899
|
+
`);
|
|
5900
|
+
chunks.push(`--${boundary}--\r
|
|
5901
|
+
`);
|
|
5902
|
+
return { chunks, boundary, bytes: chunks.reduce((total, chunk) => total + chunk.length, 0) };
|
|
5739
5903
|
}
|
|
5740
5904
|
|
|
5741
5905
|
// runtimeline.ts
|
|
@@ -5930,7 +6094,7 @@ function consolediff(input) {
|
|
|
5930
6094
|
// policy.ts
|
|
5931
6095
|
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", "visitrule", "urlrule", "menurule", "keyrule", "buttonrule", "cronrule", "intervalrule", "urllistrule", "webhookrule", "eventrule"]);
|
|
5932
6096
|
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", "loop", "repeatuntil", "whileloop", "foreach", "parallel", "trycatch"]);
|
|
5933
|
-
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", "condition", "branch"]);
|
|
6097
|
+
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", "listruns", "condition", "branch"]);
|
|
5934
6098
|
var allowedactions = /* @__PURE__ */ new Set([...sensitiveactions, ...interactionactions, ...readactions]);
|
|
5935
6099
|
var watchactions = /* @__PURE__ */ new Set(["watchmutate", "watchbanner", "watchfocus", "watchtab"]);
|
|
5936
6100
|
var targetactions = /* @__PURE__ */ new Set(["inspect", "focus", "click", "type", "scroll", "select", "hover", "clickdeep", "rightclick", "doubleclick", "drag", "drop", "upload", "clear", "check", "uncheck", "toggle", "submit", "readattribute", "readstyle", "readgeometry", "readvalue", "readtext", "readhtml", "countelements", "readtable", "highlight", "setattribute", "removeattribute", "waitfor", "shiftclick", "typetime", "appendtext", "setvalue", "typeedit", "submitsearch", "selectmulti", "chooseradio", "setslider", "setdate", "setcolor", "expanddetails", "verifyvisible", "verifyenabled", "pierceshadow", "deriveselector", "fingerprintsection", "submitform", "retryform", "selectchain", "picktypeahead", "pickdate", "attachfile", "fillcode", "consentpassword", "scrapetable", "paginateextract", "shotelement", "captureframe", "shotcanvas"]);
|
|
@@ -8731,12 +8895,247 @@ function watchdogconfigvalid(config) {
|
|
|
8731
8895
|
if (config.zombiewindow !== void 0 && (typeof config.zombiewindow !== "number" || !Number.isFinite(config.zombiewindow) || config.zombiewindow <= 0)) return { allowed: false, reason: "The watchdog zombie window, when configured, must be a positive number of milliseconds with no code ceiling." };
|
|
8732
8896
|
return { allowed: true };
|
|
8733
8897
|
}
|
|
8898
|
+
function validatetoolcatalog(catalog) {
|
|
8899
|
+
if (!Array.isArray(catalog.domains) || catalog.domains.length === 0) return { allowed: false, reason: "The tool catalog needs its tool domains." };
|
|
8900
|
+
const seen = /* @__PURE__ */ new Set();
|
|
8901
|
+
for (const domain of catalog.domains) {
|
|
8902
|
+
if (!toolnamespaces.includes(domain.namespace)) return { allowed: false, reason: `The tool domain ${String(domain.namespace)} is not a reviewed namespace.` };
|
|
8903
|
+
if (!Array.isArray(domain.tools) || domain.tools.length === 0) return { allowed: false, reason: `The ${domain.namespace} domain exposes no tools.` };
|
|
8904
|
+
for (const tool of domain.tools) {
|
|
8905
|
+
if (typeof tool.name !== "string" || !tool.name.startsWith(`${domain.namespace}.`)) return { allowed: false, reason: `The tool ${String(tool.name)} does not carry its ${domain.namespace} namespace prefix.` };
|
|
8906
|
+
if (seen.has(tool.name)) return { allowed: false, reason: `The tool name ${tool.name} is not unique across the catalog.` };
|
|
8907
|
+
seen.add(tool.name);
|
|
8908
|
+
if (!allowedactions.has(tool.kind)) return { allowed: false, reason: `The tool ${tool.name} wraps ${String(tool.kind)} which is outside the reviewed action kind grammar.` };
|
|
8909
|
+
if (!domainkinds[domain.namespace].includes(tool.kind)) return { allowed: false, reason: `The tool ${tool.name} wraps ${String(tool.kind)} which does not belong to the ${domain.namespace} domain.` };
|
|
8910
|
+
if (typeof tool.description !== "string" || tool.description.trim() === "") return { allowed: false, reason: `The tool ${tool.name} needs its plain language description.` };
|
|
8911
|
+
const schema = tool.inputschema;
|
|
8912
|
+
if (!schema || schema.type !== "object" || schema.properties === void 0 || schema.properties === null || typeof schema.properties !== "object" || Array.isArray(schema.properties) || Object.keys(schema.properties).length === 0) return { allowed: false, reason: `The tool ${tool.name} needs its json schema inputs of at least one typed property.` };
|
|
8913
|
+
for (const [name, property] of Object.entries(schema.properties)) {
|
|
8914
|
+
if (!["string", "number", "boolean", "object", "array"].includes(property.type)) return { allowed: false, reason: `The ${tool.name} input ${name} carries an untyped property.` };
|
|
8915
|
+
if (typeof property.description !== "string" || property.description.trim() === "") return { allowed: false, reason: `The ${tool.name} input ${name} needs its plain language description.` };
|
|
8916
|
+
}
|
|
8917
|
+
for (const name of schema.required) {
|
|
8918
|
+
if (!(name in schema.properties)) return { allowed: false, reason: `The tool ${tool.name} marks ${name} required outside its properties.` };
|
|
8919
|
+
}
|
|
8920
|
+
}
|
|
8921
|
+
}
|
|
8922
|
+
return { allowed: true };
|
|
8923
|
+
}
|
|
8924
|
+
function toolriskgrade(tool) {
|
|
8925
|
+
const grade = actionrisk(tool.kind);
|
|
8926
|
+
if (grade !== tool.risk) return { allowed: false, reason: `The tool ${tool.name} declares the ${tool.risk} grade while its kind ${String(tool.kind)} grades ${grade}.` };
|
|
8927
|
+
return { allowed: true };
|
|
8928
|
+
}
|
|
8929
|
+
function toolconsentrequired(tool) {
|
|
8930
|
+
if (tool.risk === "read") return { allowed: true };
|
|
8931
|
+
if (tool.consentmeta === void 0 || typeof tool.consentmeta.review !== "string" || tool.consentmeta.review.trim() === "") return { allowed: false, reason: `The tool ${tool.name} has side effects and needs its consent metadata with the review requirement.` };
|
|
8932
|
+
return { allowed: true };
|
|
8933
|
+
}
|
|
8934
|
+
function serverbindgate(config) {
|
|
8935
|
+
const bind = config.bind !== void 0 && config.bind.trim() !== "" ? config.bind.trim() : "127.0.0.1";
|
|
8936
|
+
const local = bind === "127.0.0.1" || bind === "localhost" || bind === "::1";
|
|
8937
|
+
if (!local && config.remote !== true) return { allowed: false, reason: `The bind ${bind} leaves localhost and grades sensitive: the explicit remote review must approve it first.` };
|
|
8938
|
+
return { allowed: true };
|
|
8939
|
+
}
|
|
8940
|
+
function toolversionfloor(tool, floor) {
|
|
8941
|
+
if (typeof floor === "number" && Number.isFinite(floor) && tool.version < floor) return { allowed: false, reason: `The tool ${tool.name} of version ${tool.version} stays below the negotiated compatibility floor of ${floor}.` };
|
|
8942
|
+
return { allowed: true };
|
|
8943
|
+
}
|
|
8944
|
+
function serverenablementgate(config) {
|
|
8945
|
+
if (config.enabled !== true) return { allowed: false, reason: "The mcp server starts only after the user enables it; the protocol surface stays closed by default." };
|
|
8946
|
+
const bind = serverbindgate(config);
|
|
8947
|
+
if (!bind.allowed) return bind;
|
|
8948
|
+
if (!Array.isArray(config.transports) || config.transports.length === 0) return { allowed: false, reason: "The mcp server needs at least one allowed transport of stdio or http." };
|
|
8949
|
+
if (!config.transports.every((transport) => transport === "stdio" || transport === "http")) return { allowed: false, reason: "The allowed transports of the mcp server are stdio and http." };
|
|
8950
|
+
if (typeof config.port !== "number" || !Number.isFinite(config.port) || config.port <= 0 || config.port > 65535) return { allowed: false, reason: "The http listener port must be a valid port number." };
|
|
8951
|
+
if (config.framesize !== void 0 && (typeof config.framesize !== "number" || !Number.isFinite(config.framesize) || config.framesize <= 0)) return { allowed: false, reason: "The user configured frame size must stay a positive number with no code ceiling." };
|
|
8952
|
+
if (config.queuedepth !== void 0 && (typeof config.queuedepth !== "number" || !Number.isFinite(config.queuedepth) || config.queuedepth <= 0)) return { allowed: false, reason: "The user configured queue depth must stay a positive number with no code ceiling." };
|
|
8953
|
+
return { allowed: true };
|
|
8954
|
+
}
|
|
8955
|
+
function toolnamespacegate(tool) {
|
|
8956
|
+
const namespace = tool.name.split(".")[0];
|
|
8957
|
+
if (!toolnamespaces.includes(namespace)) return { allowed: false, reason: `The tool ${tool.name} carries no reviewed namespace prefix.` };
|
|
8958
|
+
if (!domainkinds[namespace].includes(tool.kind)) return { allowed: false, reason: `The tool ${tool.name} wraps ${String(tool.kind)} which does not belong to the ${namespace} domain.` };
|
|
8959
|
+
return { allowed: true };
|
|
8960
|
+
}
|
|
8961
|
+
function tooldispatchgate(input) {
|
|
8962
|
+
if (input.client.disconnectedat !== void 0) return { allowed: false, reason: "The mcp client is disconnected and its tool calls are refused." };
|
|
8963
|
+
if (!input.client.paired) return { allowed: false, reason: "The mcp client waits for the user pairing approval; unpaired clients never dispatch tools." };
|
|
8964
|
+
if (!input.session || input.session.stoppedat || input.session.pausedat) return { allowed: false, reason: "Tool dispatch needs the live browser session behind the consent gates." };
|
|
8965
|
+
if (input.session.expiresat <= input.now) return { allowed: false, reason: "The browser session has expired and tool dispatch is refused." };
|
|
8966
|
+
if (!input.plan || input.plan.state !== "approved") return { allowed: false, reason: "Tool dispatch needs the approved plan review before any tool runs." };
|
|
8967
|
+
if (!origingranted(input.session, input.origin)) return { allowed: false, reason: `The tool call origin ${input.origin} stays outside the session grants and is refused.` };
|
|
8968
|
+
if (input.tool.risk === "read") return { allowed: true };
|
|
8969
|
+
if (input.stepid === void 0 || input.stepid.trim() === "") return { allowed: false, reason: `The ${input.tool.name} tool has side effects and needs the id of the approved plan step it executes.` };
|
|
8970
|
+
const step = input.plan.steps.find((candidate) => candidate.id === input.stepid);
|
|
8971
|
+
if (step === void 0) return { allowed: false, reason: `The tool call names the step ${input.stepid} which the approved plan does not carry.` };
|
|
8972
|
+
if (step.kind !== input.tool.kind) return { allowed: false, reason: `The tool call names the step ${input.stepid} whose kind ${String(step.kind)} does not match the ${input.tool.name} tool.` };
|
|
8973
|
+
return { allowed: true };
|
|
8974
|
+
}
|
|
8734
8975
|
|
|
8735
|
-
//
|
|
8736
|
-
var
|
|
8737
|
-
|
|
8738
|
-
|
|
8739
|
-
|
|
8976
|
+
// mcpserver.ts
|
|
8977
|
+
var localhostbind = "127.0.0.1";
|
|
8978
|
+
var defaultmcpport = 7436;
|
|
8979
|
+
var rpcerrornumbers = { parse: -32700, method: -32601, params: -32602, internal: -32603, consentrefused: -32001 };
|
|
8980
|
+
function rpcerrorof(code, message, data) {
|
|
8981
|
+
return { code, message, ...data !== void 0 ? { data } : {} };
|
|
8982
|
+
}
|
|
8983
|
+
function rpcerrorcodeof(number) {
|
|
8984
|
+
const entry = Object.entries(rpcerrornumbers).find(([, value]) => value === number);
|
|
8985
|
+
return entry?.[0];
|
|
8986
|
+
}
|
|
8987
|
+
function defaultmcpconfig() {
|
|
8988
|
+
return { port: defaultmcpport, transports: ["stdio", "http"], enabled: false };
|
|
8989
|
+
}
|
|
8990
|
+
function unwraphttppost(value) {
|
|
8991
|
+
if (value && typeof value === "object" && !Array.isArray(value)) {
|
|
8992
|
+
const candidate = value;
|
|
8993
|
+
if (candidate.transport === "http" && candidate.frame && typeof candidate.frame === "object" && !Array.isArray(candidate.frame)) return candidate.frame;
|
|
8994
|
+
}
|
|
8995
|
+
return value;
|
|
8996
|
+
}
|
|
8997
|
+
function parseframe(raw) {
|
|
8998
|
+
const parsed = unwraphttppost(JSON.parse(raw));
|
|
8999
|
+
if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) throw new Error("A json rpc frame must be an object.");
|
|
9000
|
+
return parsed;
|
|
9001
|
+
}
|
|
9002
|
+
function parsewire(raw) {
|
|
9003
|
+
return raw.split("\n").map((line) => line.trim()).filter((line) => line.length > 0).map((line) => parseframe(line));
|
|
9004
|
+
}
|
|
9005
|
+
function serializeframe(frame) {
|
|
9006
|
+
return JSON.stringify(frame);
|
|
9007
|
+
}
|
|
9008
|
+
function wireformat(frame, format) {
|
|
9009
|
+
return format === "newline" ? `${serializeframe(frame)}
|
|
9010
|
+
` : JSON.stringify({ transport: "http", frame });
|
|
9011
|
+
}
|
|
9012
|
+
function validateframe(frame, methods, config) {
|
|
9013
|
+
if (frame.jsonrpc !== "2.0") return rpcerrorof("parse", "The frame must carry the jsonrpc 2.0 tag.");
|
|
9014
|
+
if (frame.id !== void 0 && typeof frame.id !== "number" && typeof frame.id !== "string" && frame.id !== null) return rpcerrorof("parse", "The frame id must be a number, a string or null.");
|
|
9015
|
+
if (frame.method === void 0 || frame.method.trim() === "") return rpcerrorof("method", "The frame carries no method to route.");
|
|
9016
|
+
if (!methods.some((entry) => entry.method === frame.method)) return rpcerrorof("method", `The server routes no method named ${frame.method}.`);
|
|
9017
|
+
if (frame.params !== void 0 && (typeof frame.params !== "object" || Array.isArray(frame.params))) return rpcerrorof("params", "The frame params must be an object.");
|
|
9018
|
+
if (config?.framesize !== void 0 && serializeframe(frame).length > config.framesize) return rpcerrorof("params", `The serialized frame exceeds the user configured frame size of ${config.framesize} characters.`);
|
|
9019
|
+
return void 0;
|
|
9020
|
+
}
|
|
9021
|
+
function respond(input) {
|
|
9022
|
+
return { jsonrpc: "2.0", ...input.id === void 0 ? input.error !== void 0 ? { id: null } : {} : { id: input.id }, ...input.error !== void 0 ? { error: input.error } : { result: input.result } };
|
|
9023
|
+
}
|
|
9024
|
+
function servermethods() {
|
|
9025
|
+
return [
|
|
9026
|
+
{ method: "initialize", handler: "initialize", description: "Completes the mcp handshake and returns the server info." },
|
|
9027
|
+
{ method: "ping", handler: "ping", description: "Answers keepalive frames with pong." },
|
|
9028
|
+
{ method: "tools/list", handler: "listtools", description: "Returns every tool with its version and json schema inputs." },
|
|
9029
|
+
{ method: "negotiate", handler: "negotiate", description: "Exchanges capability sets with the client." },
|
|
9030
|
+
{ method: "tools/call", handler: "dispatch", description: "Invokes one tool behind the consent gates." }
|
|
9031
|
+
];
|
|
9032
|
+
}
|
|
9033
|
+
function servercapabilities(input) {
|
|
9034
|
+
return { protocolversion, name: "devthink", version: protocolversion, toolversion: input.catalog.version, tools: alltools(input.catalog).length, namespaces: toolnamespaces, transports: input.config.transports };
|
|
9035
|
+
}
|
|
9036
|
+
function initialize(input) {
|
|
9037
|
+
void input.params;
|
|
9038
|
+
return { serverinfo: servercapabilities({ config: input.config, catalog: input.catalog }), protocolversion, instructions: "Devthink serves browser tools behind the human review gates: read only tools run once a session is approved while every tool with side effects executes exactly the approved plan step it names. No endpoint, provider or key is hardcoded; the user pairs every client." };
|
|
9039
|
+
}
|
|
9040
|
+
function ping(input) {
|
|
9041
|
+
return { pong: true, at: input.now };
|
|
9042
|
+
}
|
|
9043
|
+
function listtools(catalog) {
|
|
9044
|
+
return { tools: alltools(catalog).map((tool) => ({ name: tool.name, version: tool.version, description: tool.description, inputschema: tool.inputschema, risk: tool.risk, ...tool.consentmeta !== void 0 ? { consentmeta: tool.consentmeta.review } : {} })) };
|
|
9045
|
+
}
|
|
9046
|
+
function negotiate(input) {
|
|
9047
|
+
const client = input.client;
|
|
9048
|
+
if (client?.protocolversion !== void 0 && client.protocolversion !== input.server.protocolversion) return { agreed: false, mismatch: `The client speaks protocol version ${String(client.protocolversion)} while the server offers ${input.server.protocolversion}.` };
|
|
9049
|
+
if (client?.toolversion !== void 0 && client.toolversion > input.server.toolversion) return { agreed: false, mismatch: `The client requires tool version ${String(client.toolversion)} while the server offers ${String(input.server.toolversion)}.` };
|
|
9050
|
+
if (client?.transports !== void 0 && client.transports.some((transport) => !input.server.transports.includes(transport))) return { agreed: false, mismatch: "The client requires a transport the server configuration does not allow." };
|
|
9051
|
+
return { agreed: true, capabilities: input.server };
|
|
9052
|
+
}
|
|
9053
|
+
function connectclient(input) {
|
|
9054
|
+
return { id: input.id ?? `client-${input.now}`, transport: input.transport, paired: false, connectedat: input.now };
|
|
9055
|
+
}
|
|
9056
|
+
function pairclient(clients, id, approved, now) {
|
|
9057
|
+
return clients.map((client) => client.id !== id || client.disconnectedat !== void 0 ? client : approved ? { ...client, paired: true, pairedat: now } : { ...client, paired: false, disconnectedat: now });
|
|
9058
|
+
}
|
|
9059
|
+
function disconnectclient(clients, id, now) {
|
|
9060
|
+
return clients.map((client) => client.id === id && client.disconnectedat === void 0 ? { ...client, disconnectedat: now } : client);
|
|
9061
|
+
}
|
|
9062
|
+
function enqueuerequest(input) {
|
|
9063
|
+
if (input.depth !== void 0 && input.queue.length + 1 > input.depth) return void 0;
|
|
9064
|
+
return [...input.queue, input.frame];
|
|
9065
|
+
}
|
|
9066
|
+
function nextrequest(queue) {
|
|
9067
|
+
return queue.length === 0 ? void 0 : { frame: queue[0], remaining: queue.slice(1) };
|
|
9068
|
+
}
|
|
9069
|
+
async function dispatchtool(input) {
|
|
9070
|
+
const params = input.params;
|
|
9071
|
+
if (!params || typeof params !== "object" || Array.isArray(params)) return { error: rpcerrorof("params", "The tool call needs its params object.") };
|
|
9072
|
+
if (typeof params.name !== "string" || !params.name.trim()) return { error: rpcerrorof("params", "The tool call needs the namespaced name of the tool it invokes.") };
|
|
9073
|
+
const tool = resolvetool(input.catalog, params.name.trim());
|
|
9074
|
+
if (tool === void 0) return { error: rpcerrorof("params", `The catalog holds no unambiguous tool named ${params.name.trim()}.`) };
|
|
9075
|
+
const floor = input.client.capabilities?.toolversion ?? input.catalog.version;
|
|
9076
|
+
if (tool.version < floor) return { error: rpcerrorof("params", `The tool ${tool.name} of version ${tool.version} stays below the negotiated compatibility floor of ${floor}.`) };
|
|
9077
|
+
const stepid = typeof params.stepid === "string" ? params.stepid : void 0;
|
|
9078
|
+
const gate = tooldispatchgate({ client: input.client, tool, session: input.session, plan: input.plan, origin: input.origin, ...stepid !== void 0 ? { stepid } : {}, now: input.now });
|
|
9079
|
+
if (!gate.allowed) return { error: rpcerrorof("consentrefused", gate.reason ?? "The consent gates refused the tool call.") };
|
|
9080
|
+
const step = tool.risk === "read" ? { id: `mcp-${input.client.id}-${input.now}`, kind: tool.kind, summary: tool.description.split(".")[0] ?? tool.description, risk: "read", ...typeof params.target === "string" ? { target: params.target } : {}, ...typeof params.value === "string" ? { value: params.value } : {}, ...params.options !== void 0 && typeof params.options === "object" && !Array.isArray(params.options) ? { options: JSON.stringify(params.options) } : {} } : input.plan?.steps.find((candidate) => candidate.id === stepid);
|
|
9081
|
+
if (step === void 0) return { error: rpcerrorof("consentrefused", "The tool call names a step the approved plan does not carry.") };
|
|
9082
|
+
try {
|
|
9083
|
+
const result = await input.execute(step);
|
|
9084
|
+
return { result, step };
|
|
9085
|
+
} catch (error) {
|
|
9086
|
+
return { error: rpcerrorof("internal", error instanceof Error ? error.message : String(error)) };
|
|
9087
|
+
}
|
|
9088
|
+
}
|
|
9089
|
+
async function handleframe(input) {
|
|
9090
|
+
if (input.raw !== void 0 && input.config.framesize !== void 0 && input.raw.length > input.config.framesize) return respond({ id: null, error: rpcerrorof("params", `The wire frame exceeds the user configured frame size of ${input.config.framesize} characters.`) });
|
|
9091
|
+
let frame;
|
|
9092
|
+
if (input.raw !== void 0) {
|
|
9093
|
+
try {
|
|
9094
|
+
frame = parseframe(input.raw);
|
|
9095
|
+
} catch {
|
|
9096
|
+
return respond({ id: null, error: rpcerrorof("parse", "The wire frame does not parse as json.") });
|
|
9097
|
+
}
|
|
9098
|
+
} else if (input.frame !== void 0) {
|
|
9099
|
+
frame = input.frame;
|
|
9100
|
+
} else {
|
|
9101
|
+
return respond({ id: null, error: rpcerrorof("parse", "The server received no frame to route.") });
|
|
9102
|
+
}
|
|
9103
|
+
const invalid = validateframe(frame, servermethods(), input.config);
|
|
9104
|
+
if (invalid !== void 0) return respond({ ...frame.id !== void 0 ? { id: frame.id } : {}, error: invalid });
|
|
9105
|
+
const entry = servermethods().find((candidate) => candidate.method === frame.method);
|
|
9106
|
+
if (entry === void 0) return respond({ ...frame.id !== void 0 ? { id: frame.id } : {}, error: rpcerrorof("method", `The server routes no method named ${String(frame.method)}.`) });
|
|
9107
|
+
const params = frame.params;
|
|
9108
|
+
if (entry.handler === "initialize") return respond({ ...frame.id !== void 0 ? { id: frame.id } : {}, result: initialize({ ...params !== void 0 ? { params } : {}, config: input.config, catalog: input.catalog }) });
|
|
9109
|
+
if (entry.handler === "ping") return respond({ ...frame.id !== void 0 ? { id: frame.id } : {}, result: ping({ now: input.now }) });
|
|
9110
|
+
if (entry.handler === "listtools") return respond({ ...frame.id !== void 0 ? { id: frame.id } : {}, result: listtools(input.catalog) });
|
|
9111
|
+
if (entry.handler === "negotiate") {
|
|
9112
|
+
const server = servercapabilities({ config: input.config, catalog: input.catalog });
|
|
9113
|
+
const clientcaps = params?.capabilities && typeof params.capabilities === "object" && !Array.isArray(params.capabilities) ? params.capabilities : void 0;
|
|
9114
|
+
const outcome = negotiate({ ...clientcaps !== void 0 ? { client: clientcaps } : {}, server });
|
|
9115
|
+
return respond({ ...frame.id !== void 0 ? { id: frame.id } : {}, ...outcome.agreed ? { result: outcome.capabilities } : { error: rpcerrorof("params", outcome.mismatch ?? "The capability negotiation did not agree.") } });
|
|
9116
|
+
}
|
|
9117
|
+
const dispatched = await dispatchtool({ ...params !== void 0 ? { params } : {}, client: input.client, catalog: input.catalog, ...input.session !== void 0 ? { session: input.session } : {}, ...input.plan !== void 0 ? { plan: input.plan } : {}, origin: input.origin, now: input.now, execute: input.execute });
|
|
9118
|
+
return respond({ ...frame.id !== void 0 ? { id: frame.id } : {}, ...dispatched.error !== void 0 ? { error: dispatched.error } : { result: dispatched.result } });
|
|
9119
|
+
}
|
|
9120
|
+
function bindlocalhost(config) {
|
|
9121
|
+
const bind = config.bind !== void 0 && config.bind.trim() !== "" ? config.bind.trim() : localhostbind;
|
|
9122
|
+
return { bind, port: config.port, localhost: bind === localhostbind || bind === "localhost" || bind === "::1" };
|
|
9123
|
+
}
|
|
9124
|
+
function launchbridge(input) {
|
|
9125
|
+
return { id: input.id ?? `bridge-${input.now}`, host: input.host, connected: true, ...input.pid !== void 0 ? { pid: input.pid } : {}, startedat: input.now, restarts: 0, received: 0, sent: 0 };
|
|
9126
|
+
}
|
|
9127
|
+
function relayframe(input) {
|
|
9128
|
+
return { ...input.bridge, connected: true, received: input.bridge.received + (input.direction === "inbound" ? 1 : 0), sent: input.bridge.sent + (input.direction === "outbound" ? 1 : 0), lastframeat: input.now };
|
|
9129
|
+
}
|
|
9130
|
+
function restartbridge(input) {
|
|
9131
|
+
return { ...input.bridge, connected: true, pid: input.pid, restarts: input.bridge.restarts + 1, startedat: input.now };
|
|
9132
|
+
}
|
|
9133
|
+
function framedlog(event, at, fields) {
|
|
9134
|
+
return JSON.stringify({ at, event, ...fields ?? {} });
|
|
9135
|
+
}
|
|
9136
|
+
function toolcallevent(input) {
|
|
9137
|
+
return { id: input.id, clientid: input.clientid, tool: input.tool, origin: input.origin, ok: input.ok, ...input.code !== void 0 ? { code: input.code } : {}, at: input.now };
|
|
9138
|
+
}
|
|
8740
9139
|
|
|
8741
9140
|
// protocol.ts
|
|
8742
9141
|
function record(value) {
|
|
@@ -9133,7 +9532,7 @@ function requestbody(input) {
|
|
|
9133
9532
|
return JSON.stringify({ version: protocolversion, objective: input.objective, session: input.session, observation: input.observation, capabilities: input.capabilities });
|
|
9134
9533
|
}
|
|
9135
9534
|
function outcomeresponse(input) {
|
|
9136
|
-
return JSON.stringify({ version: protocolversion, planid: input.plan.id, planstate: input.plan.state, outcome: input.outcome, ...input.resolvedtarget ? { resolvedtarget: input.resolvedtarget } : {}, ...input.capture ? { capture: input.capture } : {}, ...input.media ? { media: input.media } : {}, ...input.transport ? { transport: input.transport } : {}, ...input.network ? { network: input.network } : {}, ...input.control ? { control: input.control } : {}, ...input.timeline ? { timeline: input.timeline } : {}, ...input.cdp ? { cdp: input.cdp } : {}, ...input.profile ? { profile: input.profile } : {}, ...input.emulation ? { emulation: input.emulation } : {}, ...input.session ? { session: input.session } : {}, ...input.workflow ? { workflow: { runid: input.workflow.runid, state: input.workflow.state, ...input.workflow.dryrun === true ? { dryrun: true } : {}, produced: input.workflow.produced, consumed: input.workflow.consumed, ...input.workflow.timeout !== void 0 ? { timeout: input.workflow.timeout } : {}, ...input.workflow.retry !== void 0 ? { retry: input.workflow.retry } : {} } } : {}, ...input.trigger ? { trigger: { ruleid: input.trigger.ruleid, kind: input.trigger.kind, enabled: input.trigger.enabled, ...input.trigger.nextfireat !== void 0 ? { nextfireat: input.trigger.nextfireat } : {} } } : {} });
|
|
9535
|
+
return JSON.stringify({ version: protocolversion, planid: input.plan.id, planstate: input.plan.state, outcome: input.outcome, ...input.resolvedtarget ? { resolvedtarget: input.resolvedtarget } : {}, ...input.capture ? { capture: input.capture } : {}, ...input.media ? { media: input.media } : {}, ...input.transport ? { transport: input.transport } : {}, ...input.network ? { network: input.network } : {}, ...input.control ? { control: input.control } : {}, ...input.timeline ? { timeline: input.timeline } : {}, ...input.cdp ? { cdp: input.cdp } : {}, ...input.profile ? { profile: input.profile } : {}, ...input.emulation ? { emulation: input.emulation } : {}, ...input.session ? { session: input.session } : {}, ...input.workflow ? { workflow: { runid: input.workflow.runid, state: input.workflow.state, ...input.workflow.dryrun === true ? { dryrun: true } : {}, produced: input.workflow.produced, consumed: input.workflow.consumed, ...input.workflow.timeout !== void 0 ? { timeout: input.workflow.timeout } : {}, ...input.workflow.retry !== void 0 ? { retry: input.workflow.retry } : {} } } : {}, ...input.trigger ? { trigger: { ruleid: input.trigger.ruleid, kind: input.trigger.kind, enabled: input.trigger.enabled, ...input.trigger.nextfireat !== void 0 ? { nextfireat: input.trigger.nextfireat } : {} } } : {}, ...input.tool ? { tool: { clientid: input.tool.clientid, tool: input.tool.tool, origin: input.tool.origin, ok: input.tool.ok, ...input.tool.code !== void 0 ? { code: input.tool.code } : {} } } : {} });
|
|
9137
9536
|
}
|
|
9138
9537
|
function mapresponse(input) {
|
|
9139
9538
|
return JSON.stringify({ version: protocolversion, planid: input.plan.id, planstate: input.plan.state, map: input.map });
|
|
@@ -9330,6 +9729,12 @@ function triggerfired(input) {
|
|
|
9330
9729
|
function manualrunpreview(input) {
|
|
9331
9730
|
return { version: protocolversion, manualrun: input.preview, ...input.workflowname !== void 0 ? { workflowname: input.workflowname } : {} };
|
|
9332
9731
|
}
|
|
9732
|
+
function toolcallframe(input) {
|
|
9733
|
+
return { jsonrpc: "2.0", id: input.id, method: "tools/call", params: { ...input.params ?? {}, name: input.name } };
|
|
9734
|
+
}
|
|
9735
|
+
function toolresultframe(input) {
|
|
9736
|
+
return { jsonrpc: "2.0", id: input.id, ...input.error !== void 0 ? { error: input.error } : { result: input.result } };
|
|
9737
|
+
}
|
|
9333
9738
|
var workflowfileversion = 1;
|
|
9334
9739
|
function editorstate(input) {
|
|
9335
9740
|
const editor = { versions: input.versions, diffs: input.diffs ?? [], history: input.history, breakpoints: input.breakpoints ?? [], overrides: input.overrides, imports: input.imports, backgroundruns: input.backgroundruns ?? {}, watchdog: { ...input.watchdog.config !== void 0 ? { config: input.watchdog.config } : {}, events: input.watchdog.events } };
|
|
@@ -10071,6 +10476,7 @@ export {
|
|
|
10071
10476
|
agentgrammarvalid,
|
|
10072
10477
|
agentpresetof,
|
|
10073
10478
|
allowlistcovers,
|
|
10479
|
+
alltools,
|
|
10074
10480
|
annotatetrace,
|
|
10075
10481
|
annotationof,
|
|
10076
10482
|
annotationplanof,
|
|
@@ -10095,6 +10501,7 @@ export {
|
|
|
10095
10501
|
authreport,
|
|
10096
10502
|
autointervalof,
|
|
10097
10503
|
backoffdelay,
|
|
10504
|
+
bindlocalhost,
|
|
10098
10505
|
bindparam,
|
|
10099
10506
|
bindvariables,
|
|
10100
10507
|
blackboxedurls,
|
|
@@ -10117,6 +10524,7 @@ export {
|
|
|
10117
10524
|
buildsheet,
|
|
10118
10525
|
buildsteplibrary,
|
|
10119
10526
|
buildstitchplan,
|
|
10527
|
+
buildtoolcatalog,
|
|
10120
10528
|
callgraphql,
|
|
10121
10529
|
callrest,
|
|
10122
10530
|
callsreport,
|
|
@@ -10151,6 +10559,7 @@ export {
|
|
|
10151
10559
|
composeworkflow,
|
|
10152
10560
|
conditionof,
|
|
10153
10561
|
confirmmanualrun,
|
|
10562
|
+
connectclient,
|
|
10154
10563
|
consolecapture,
|
|
10155
10564
|
consoleconsentcovers,
|
|
10156
10565
|
consolediff,
|
|
@@ -10180,6 +10589,8 @@ export {
|
|
|
10180
10589
|
debugwaitbudgetallowed,
|
|
10181
10590
|
dedupeimages,
|
|
10182
10591
|
defaultloopbound,
|
|
10592
|
+
defaultmcpconfig,
|
|
10593
|
+
defaultmcpport,
|
|
10183
10594
|
defaulttriggercooldown,
|
|
10184
10595
|
delayjitter,
|
|
10185
10596
|
actionrisk as deriveactionrisk,
|
|
@@ -10189,6 +10600,9 @@ export {
|
|
|
10189
10600
|
diffreviewgrade,
|
|
10190
10601
|
diffsessionrecords,
|
|
10191
10602
|
diffversions,
|
|
10603
|
+
disconnectclient,
|
|
10604
|
+
dispatchtool,
|
|
10605
|
+
domainkinds,
|
|
10192
10606
|
downloadreport,
|
|
10193
10607
|
drainqueue,
|
|
10194
10608
|
dryrunprojection,
|
|
@@ -10202,6 +10616,7 @@ export {
|
|
|
10202
10616
|
emulationretentionwindow,
|
|
10203
10617
|
emulationstackallowed,
|
|
10204
10618
|
emulationstateof,
|
|
10619
|
+
enqueuerequest,
|
|
10205
10620
|
errorcapture,
|
|
10206
10621
|
errorreportresponse,
|
|
10207
10622
|
evaluatecondition,
|
|
@@ -10237,6 +10652,7 @@ export {
|
|
|
10237
10652
|
foreachof,
|
|
10238
10653
|
formpayloadof,
|
|
10239
10654
|
formreportresponse,
|
|
10655
|
+
framedlog,
|
|
10240
10656
|
frameinterval,
|
|
10241
10657
|
generatedvalueallowed,
|
|
10242
10658
|
graphqlopenvelope,
|
|
@@ -10244,6 +10660,7 @@ export {
|
|
|
10244
10660
|
groupselect,
|
|
10245
10661
|
growsampleof,
|
|
10246
10662
|
growthtrend,
|
|
10663
|
+
handleframe,
|
|
10247
10664
|
headerfilterof,
|
|
10248
10665
|
headeruleof,
|
|
10249
10666
|
heapintervalallowed,
|
|
@@ -10259,6 +10676,7 @@ export {
|
|
|
10259
10676
|
importpresetlibrary,
|
|
10260
10677
|
importsessionfile,
|
|
10261
10678
|
importworkflow,
|
|
10679
|
+
initialize,
|
|
10262
10680
|
iscdpkind,
|
|
10263
10681
|
iscontrolflowkind,
|
|
10264
10682
|
iscontrolkind,
|
|
@@ -10277,11 +10695,14 @@ export {
|
|
|
10277
10695
|
jsonpathrulesof,
|
|
10278
10696
|
lapseframes,
|
|
10279
10697
|
lapseplanof,
|
|
10698
|
+
launchbridge,
|
|
10280
10699
|
layernames,
|
|
10281
10700
|
layoutreport,
|
|
10282
10701
|
levelrank,
|
|
10283
10702
|
listdue,
|
|
10703
|
+
listtools,
|
|
10284
10704
|
loadworkflow,
|
|
10705
|
+
localhostbind,
|
|
10285
10706
|
locationconsentcovers,
|
|
10286
10707
|
locationconsentgate,
|
|
10287
10708
|
locationpresetof,
|
|
@@ -10308,7 +10729,9 @@ export {
|
|
|
10308
10729
|
mockspecof,
|
|
10309
10730
|
multipartchunks,
|
|
10310
10731
|
multipartpayloadof,
|
|
10732
|
+
namespaceof,
|
|
10311
10733
|
navstateresponse,
|
|
10734
|
+
negotiate,
|
|
10312
10735
|
netfailureentryof,
|
|
10313
10736
|
netlogreport,
|
|
10314
10737
|
netwatchkinds,
|
|
@@ -10323,6 +10746,7 @@ export {
|
|
|
10323
10746
|
newsessiondiff,
|
|
10324
10747
|
newsessionrecord,
|
|
10325
10748
|
newworkflowrun,
|
|
10749
|
+
nextrequest,
|
|
10326
10750
|
normalizeendpoint,
|
|
10327
10751
|
oauthflowof,
|
|
10328
10752
|
observationmodeof,
|
|
@@ -10332,15 +10756,18 @@ export {
|
|
|
10332
10756
|
outcomeresponse,
|
|
10333
10757
|
overrideinputof,
|
|
10334
10758
|
overridematches,
|
|
10759
|
+
pairclient,
|
|
10335
10760
|
pairexchange,
|
|
10336
10761
|
pairstates,
|
|
10337
10762
|
palettecategories,
|
|
10338
10763
|
palettenodes,
|
|
10339
10764
|
parallelof,
|
|
10765
|
+
parseframe,
|
|
10340
10766
|
parsehtmlbody,
|
|
10341
10767
|
parseproposal,
|
|
10342
10768
|
parsessetext,
|
|
10343
10769
|
parsetokens,
|
|
10770
|
+
parsewire,
|
|
10344
10771
|
parseworkflowproposal,
|
|
10345
10772
|
passwordconsentgranted,
|
|
10346
10773
|
patternorigin,
|
|
@@ -10359,6 +10786,7 @@ export {
|
|
|
10359
10786
|
permissionnamevalid,
|
|
10360
10787
|
permissionstates,
|
|
10361
10788
|
permissionstatevalid,
|
|
10789
|
+
ping,
|
|
10362
10790
|
planallowlist,
|
|
10363
10791
|
pollcursorof,
|
|
10364
10792
|
polldecision,
|
|
@@ -10395,6 +10823,7 @@ export {
|
|
|
10395
10823
|
regexruleof,
|
|
10396
10824
|
regionsteps,
|
|
10397
10825
|
rejectioncapture,
|
|
10826
|
+
relayframe,
|
|
10398
10827
|
removeedge,
|
|
10399
10828
|
removenode,
|
|
10400
10829
|
renderminimap,
|
|
@@ -10405,8 +10834,11 @@ export {
|
|
|
10405
10834
|
requestbody,
|
|
10406
10835
|
resolutionverdict,
|
|
10407
10836
|
resolvedrisk,
|
|
10837
|
+
resolvetool,
|
|
10408
10838
|
resolvevariable,
|
|
10409
10839
|
resourcefacts,
|
|
10840
|
+
respond,
|
|
10841
|
+
restartbridge,
|
|
10410
10842
|
restoreoriginsgranted,
|
|
10411
10843
|
restoreplanof,
|
|
10412
10844
|
restorereviewgranted,
|
|
@@ -10421,6 +10853,9 @@ export {
|
|
|
10421
10853
|
rewritesourcelocation,
|
|
10422
10854
|
rotatelogs,
|
|
10423
10855
|
rotationruleof,
|
|
10856
|
+
rpcerrorcodeof,
|
|
10857
|
+
rpcerrornumbers,
|
|
10858
|
+
rpcerrorof,
|
|
10424
10859
|
ruleorigins,
|
|
10425
10860
|
ruleoriginsgranted,
|
|
10426
10861
|
runcatch,
|
|
@@ -10455,6 +10890,11 @@ export {
|
|
|
10455
10890
|
sequenceintegrity,
|
|
10456
10891
|
serializearg,
|
|
10457
10892
|
serializecdpcommand,
|
|
10893
|
+
serializeframe,
|
|
10894
|
+
serverbindgate,
|
|
10895
|
+
servercapabilities,
|
|
10896
|
+
serverenablementgate,
|
|
10897
|
+
servermethods,
|
|
10458
10898
|
sessionfileversion,
|
|
10459
10899
|
sessionfolderof,
|
|
10460
10900
|
sessionfolderunique,
|
|
@@ -10507,6 +10947,19 @@ export {
|
|
|
10507
10947
|
timelinesources,
|
|
10508
10948
|
timezonevalid,
|
|
10509
10949
|
tokenrequest,
|
|
10950
|
+
toolcallevent,
|
|
10951
|
+
toolcallframe,
|
|
10952
|
+
toolcatalogversion,
|
|
10953
|
+
toolconsentrequired,
|
|
10954
|
+
tooldispatchgate,
|
|
10955
|
+
toolname,
|
|
10956
|
+
toolnamespacegate,
|
|
10957
|
+
toolnamespaces,
|
|
10958
|
+
toolresultframe,
|
|
10959
|
+
toolriskgrade,
|
|
10960
|
+
toolsbynamespace,
|
|
10961
|
+
toolschemaof,
|
|
10962
|
+
toolversionfloor,
|
|
10510
10963
|
tracecategories,
|
|
10511
10964
|
traceceilingof,
|
|
10512
10965
|
tracestart,
|
|
@@ -10532,10 +10985,12 @@ export {
|
|
|
10532
10985
|
validatecontrolpayload,
|
|
10533
10986
|
validatefieldmatch,
|
|
10534
10987
|
validateformrecord,
|
|
10988
|
+
validateframe,
|
|
10535
10989
|
validateregexrule,
|
|
10536
10990
|
validatesiteoverride,
|
|
10537
10991
|
validatestep,
|
|
10538
10992
|
validatetargetref,
|
|
10993
|
+
validatetoolcatalog,
|
|
10539
10994
|
validatevaluegen,
|
|
10540
10995
|
validateworkflow,
|
|
10541
10996
|
verifywebhook,
|
|
@@ -10549,6 +11004,7 @@ export {
|
|
|
10549
11004
|
watchgate,
|
|
10550
11005
|
webhooksecretok,
|
|
10551
11006
|
whileof,
|
|
11007
|
+
wireformat,
|
|
10552
11008
|
wizardreport,
|
|
10553
11009
|
workflowblockof,
|
|
10554
11010
|
workflowfileversion,
|