cdp-toolkit 2.6.0 → 3.0.0
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/CHANGELOG.md +44 -0
- package/CONTRACT.md +1 -1
- package/README.md +81 -46
- package/dist/bidi/mux-daemon.js +47 -0
- package/dist/cli.js +78 -5
- package/dist/index.js +73 -4
- package/dist/mcp.js +236 -50
- package/package.json +5 -3
- package/src/bidi/driver.ts +8 -0
- package/src/cdp/driver.ts +69 -4
- package/src/client.ts +22 -0
- package/src/driver.ts +2 -1
- package/src/frames.ts +169 -0
- package/src/manifest.ts +1 -1
- package/src/mcp.ts +177 -55
- package/src/shared-tools.ts +13 -0
- package/src/toolDocs.ts +3 -3
- package/src/toolGroups.ts +41 -10
- package/src/types.ts +13 -0
- package/src/version.ts +1 -1
package/src/toolGroups.ts
CHANGED
|
@@ -42,41 +42,72 @@ for (const group of TOOL_GROUPS) {
|
|
|
42
42
|
}
|
|
43
43
|
}
|
|
44
44
|
|
|
45
|
+
/**
|
|
46
|
+
* The 3.0 default listing: the five tools nearly every browser task touches. Everything
|
|
47
|
+
* else is reached through the search_tools / call_tool meta-tools (src/mcp.ts), so an
|
|
48
|
+
* eagerly-loading host pays for 7 schemas instead of 49. evaluate_script is the escape
|
|
49
|
+
* hatch that covers most of what the other 43 do.
|
|
50
|
+
*/
|
|
51
|
+
export const GATEWAY_TOOLS = ["navigate_page", "take_snapshot", "click", "fill", "evaluate_script"] as const;
|
|
52
|
+
|
|
45
53
|
export const PROFILES = {
|
|
54
|
+
gateway: [],
|
|
46
55
|
core: ["core"],
|
|
47
56
|
full: [...TOOL_GROUPS],
|
|
48
57
|
} as const;
|
|
49
58
|
|
|
50
59
|
export type ProfileName = keyof typeof PROFILES;
|
|
51
60
|
|
|
61
|
+
/** What tools/list advertises: every tool in `groups`, plus the individual `tools`. */
|
|
62
|
+
export interface ResolvedProfile {
|
|
63
|
+
groups: ReadonlySet<ToolGroup>;
|
|
64
|
+
tools: ReadonlySet<string>;
|
|
65
|
+
label: string;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
/** True when a profile advertises `name` in tools/list. */
|
|
69
|
+
export function isListed(profile: ResolvedProfile, name: string): boolean {
|
|
70
|
+
const group = TOOL_GROUP[name];
|
|
71
|
+
return profile.tools.has(name) || (group !== undefined && profile.groups.has(group));
|
|
72
|
+
}
|
|
73
|
+
|
|
52
74
|
/**
|
|
53
|
-
* Resolve CDP_TOOL_PROFILE into
|
|
75
|
+
* Resolve CDP_TOOL_PROFILE into what tools/list advertises.
|
|
54
76
|
*
|
|
55
77
|
* The profile is a STARTUP filter, read once: the listing it selects is fixed for the
|
|
56
78
|
* life of the process (2.1 dropped the runtime `browser_tools` toggle, so the tool set
|
|
57
79
|
* can never change as a side effect of another request — a spec MUST). Accepted
|
|
58
|
-
* spellings: unset/empty or "
|
|
59
|
-
*
|
|
60
|
-
*
|
|
80
|
+
* spellings: unset/empty or "gateway" (the 5 GATEWAY_TOOLS; the 3.0 default), "full"
|
|
81
|
+
* (everything), "core" (the 12-tool everyday group), or a comma-separated list of group
|
|
82
|
+
* names, optionally including "gateway". A group list without "gateway" always includes
|
|
83
|
+
* `core`, so it can never strand the basics.
|
|
61
84
|
*/
|
|
62
|
-
export function resolveProfile(spec: string | undefined):
|
|
63
|
-
const all = ():
|
|
85
|
+
export function resolveProfile(spec: string | undefined): ResolvedProfile {
|
|
86
|
+
const all = (): ResolvedProfile => ({ groups: new Set(TOOL_GROUPS), tools: new Set(), label: "full" });
|
|
64
87
|
const raw = (spec ?? "").trim();
|
|
65
|
-
if (raw === ""
|
|
88
|
+
if (raw === "") return { groups: new Set(), tools: new Set(GATEWAY_TOOLS), label: "gateway" };
|
|
89
|
+
if (raw.toLowerCase() === "full") return all();
|
|
66
90
|
|
|
67
91
|
const tokens = raw.split(",").map((t) => t.trim().toLowerCase()).filter((t) => t !== "");
|
|
68
92
|
if (tokens.includes("full")) return all();
|
|
69
93
|
|
|
94
|
+
const gateway = tokens.includes("gateway");
|
|
70
95
|
const known = new Set<string>(TOOL_GROUPS);
|
|
71
|
-
const picked = new Set<ToolGroup>(["core"]);
|
|
96
|
+
const picked = new Set<ToolGroup>(gateway ? [] : ["core"]);
|
|
72
97
|
for (const token of tokens) {
|
|
98
|
+
if (token === "gateway") continue;
|
|
73
99
|
if (!known.has(token)) {
|
|
74
|
-
throw new Error(`CDP_TOOL_PROFILE: unknown tool group '${token}'. Known: full, core, ${TOOL_GROUPS.filter((g) => g !== "core").join(", ")}`);
|
|
100
|
+
throw new Error(`CDP_TOOL_PROFILE: unknown tool group '${token}'. Known: gateway, full, core, ${TOOL_GROUPS.filter((g) => g !== "core").join(", ")}`);
|
|
75
101
|
}
|
|
76
102
|
picked.add(token as ToolGroup);
|
|
77
103
|
}
|
|
78
104
|
if (picked.size === TOOL_GROUPS.length) return all();
|
|
79
105
|
// Canonical label: TOOL_GROUPS order, not the order the caller typed, so the ready
|
|
80
106
|
// line and the catalog header read the same for every equivalent spelling.
|
|
81
|
-
|
|
107
|
+
const groupLabel = TOOL_GROUPS.filter((g) => picked.has(g));
|
|
108
|
+
return {
|
|
109
|
+
groups: picked,
|
|
110
|
+
tools: new Set(gateway ? GATEWAY_TOOLS : []),
|
|
111
|
+
label: (gateway ? ["gateway", ...groupLabel] : groupLabel).join(","),
|
|
112
|
+
};
|
|
82
113
|
}
|
package/src/types.ts
CHANGED
|
@@ -63,6 +63,19 @@ export interface CdpEvent<P = Record<string, unknown>> {
|
|
|
63
63
|
* listing, because a worker is not a page target — and a worker that is
|
|
64
64
|
* idle-evicted is in no listing at all, which is what `wake` exists for.
|
|
65
65
|
* See src/workers.ts and src/cdp/workers.ts.
|
|
66
|
+
* - "frame:<substring>" -> the out-of-process (cross-origin) IFRAME target
|
|
67
|
+
* whose url contains the substring (site isolation gives an OOPIF its own
|
|
68
|
+
* process and its own target, type "iframe"). Chrome-only, like "worker:",
|
|
69
|
+
* but accepted by EVERY target-taking tool except the four page-only ones
|
|
70
|
+
* (close/select/release/claim act on the embedder tab): the arm lives in
|
|
71
|
+
* pickTarget itself, the one resolver every Chrome tool's target flows
|
|
72
|
+
* through, so no per-tool wiring was needed or added. Reads the UNFILTERED
|
|
73
|
+
* listing; a SAME-ORIGIN iframe is not a target at all (it runs inside its
|
|
74
|
+
* parent page) and can only be reached through the parent. Refused with a
|
|
75
|
+
* capability error on Firefox (no iframe targets exist in BiDi's context
|
|
76
|
+
* model) and by the page-only resolvers. See src/frames.ts. A bare iframe
|
|
77
|
+
* targetId from list_pages{all:true} also still resolves via the bare-id
|
|
78
|
+
* arm below.
|
|
66
79
|
*/
|
|
67
80
|
export type TargetSelector = string | undefined;
|
|
68
81
|
|
package/src/version.ts
CHANGED