vskill 1.2.4 → 1.2.7
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 +51 -3
- package/agents.json +6 -1
- package/dist/agents/agents-registry.d.ts +43 -16
- package/dist/agents/agents-registry.js +119 -33
- package/dist/agents/agents-registry.js.map +1 -1
- package/dist/agents/global-dirs.d.ts +19 -0
- package/dist/agents/global-dirs.js +53 -0
- package/dist/agents/global-dirs.js.map +1 -0
- package/dist/audit/fix-suggestions.js +6 -0
- package/dist/audit/fix-suggestions.js.map +1 -1
- package/dist/commands/add-github-bundle.d.ts +29 -0
- package/dist/commands/add-github-bundle.js +135 -0
- package/dist/commands/add-github-bundle.js.map +1 -0
- package/dist/commands/add-lockfile.d.ts +2 -0
- package/dist/commands/add-lockfile.js +1 -1
- package/dist/commands/add-lockfile.js.map +1 -1
- package/dist/commands/add.d.ts +5 -7
- package/dist/commands/add.js +207 -111
- package/dist/commands/add.js.map +1 -1
- package/dist/commands/audit-webmcp.d.ts +25 -0
- package/dist/commands/audit-webmcp.js +167 -0
- package/dist/commands/audit-webmcp.js.map +1 -0
- package/dist/commands/doctor.d.ts +69 -0
- package/dist/commands/doctor.js +760 -0
- package/dist/commands/doctor.js.map +1 -0
- package/dist/commands/remove.js +43 -8
- package/dist/commands/remove.js.map +1 -1
- package/dist/commands/scan.js +1 -1
- package/dist/commands/scan.js.map +1 -1
- package/dist/commands/update.js +12 -4
- package/dist/commands/update.js.map +1 -1
- package/dist/discovery/github-skill-bundle.d.ts +74 -0
- package/dist/discovery/github-skill-bundle.js +323 -0
- package/dist/discovery/github-skill-bundle.js.map +1 -0
- package/dist/eval/skill-scanner.js +7 -1
- package/dist/eval/skill-scanner.js.map +1 -1
- package/dist/eval-server/install-skill-routes.js +10 -3
- package/dist/eval-server/install-skill-routes.js.map +1 -1
- package/dist/eval-server/remove-skill-routes.js +262 -29
- package/dist/eval-server/remove-skill-routes.js.map +1 -1
- package/dist/eval-server/studio-privacy.js +2 -3
- package/dist/eval-server/studio-privacy.js.map +1 -1
- package/dist/eval-server/utils/scan-install-locations.js +22 -3
- package/dist/eval-server/utils/scan-install-locations.js.map +1 -1
- package/dist/eval-ui/assets/{CreateSkillPage-BUrgworx.js → CreateSkillPage-CXDd6gDN.js} +1 -1
- package/dist/eval-ui/assets/{FindSkillsPalette-BstJ22TI.js → FindSkillsPalette-DQ6uGhFP.js} +2 -2
- package/dist/eval-ui/assets/{SearchPaletteCore-Dagnc-E7.js → SearchPaletteCore-DpHCf0mf.js} +1 -1
- package/dist/eval-ui/assets/{SkillDetailPanel-DnujVk6g.js → SkillDetailPanel-BjHFjGxg.js} +1 -1
- package/dist/eval-ui/assets/{UpdateDropdown-B7D2vXrm.js → UpdateDropdown-Cn4Vsq5d.js} +1 -1
- package/dist/eval-ui/assets/main-BmB7Zj9I.js +86 -0
- package/dist/eval-ui/index.html +1 -1
- package/dist/index.js +34 -0
- package/dist/index.js.map +1 -1
- package/dist/installer/bundle-files.d.ts +39 -2
- package/dist/installer/bundle-files.js +80 -10
- package/dist/installer/bundle-files.js.map +1 -1
- package/dist/installer/canonical.d.ts +39 -4
- package/dist/installer/canonical.js +178 -24
- package/dist/installer/canonical.js.map +1 -1
- package/dist/installer/multi-install.d.ts +11 -2
- package/dist/installer/multi-install.js +41 -9
- package/dist/installer/multi-install.js.map +1 -1
- package/dist/installer/transformers/index.d.ts +8 -0
- package/dist/installer/yaml-safe-mutate.js +48 -2
- package/dist/installer/yaml-safe-mutate.js.map +1 -1
- package/dist/lib/github-fetch.js +2 -0
- package/dist/lib/github-fetch.js.map +1 -1
- package/dist/lib/private-source.d.ts +8 -0
- package/dist/lib/private-source.js +16 -2
- package/dist/lib/private-source.js.map +1 -1
- package/dist/scanner/hidden-content.d.ts +47 -0
- package/dist/scanner/hidden-content.js +904 -0
- package/dist/scanner/hidden-content.js.map +1 -0
- package/dist/scanner/installer-hosts.d.ts +26 -0
- package/dist/scanner/installer-hosts.js +92 -0
- package/dist/scanner/installer-hosts.js.map +1 -0
- package/dist/scanner/judge-guard.d.ts +119 -0
- package/dist/scanner/judge-guard.js +481 -0
- package/dist/scanner/judge-guard.js.map +1 -0
- package/dist/scanner/patterns.d.ts +12 -0
- package/dist/scanner/patterns.js +353 -113
- package/dist/scanner/patterns.js.map +1 -1
- package/dist/scanner/repo-scanner.d.ts +4 -0
- package/dist/scanner/repo-scanner.js +4 -1
- package/dist/scanner/repo-scanner.js.map +1 -1
- package/dist/scanner/tier1.js +37 -7
- package/dist/scanner/tier1.js.map +1 -1
- package/dist/scanner/tier2-llm.d.ts +22 -4
- package/dist/scanner/tier2-llm.js +163 -23
- package/dist/scanner/tier2-llm.js.map +1 -1
- package/dist/scanner/types.d.ts +8 -0
- package/dist/webmcp/args.d.ts +34 -0
- package/dist/webmcp/args.js +87 -0
- package/dist/webmcp/args.js.map +1 -0
- package/dist/webmcp/attribution.d.ts +38 -0
- package/dist/webmcp/attribution.js +141 -0
- package/dist/webmcp/attribution.js.map +1 -0
- package/dist/webmcp/enumerate.d.ts +81 -0
- package/dist/webmcp/enumerate.js +436 -0
- package/dist/webmcp/enumerate.js.map +1 -0
- package/dist/webmcp/format.d.ts +9 -0
- package/dist/webmcp/format.js +105 -0
- package/dist/webmcp/format.js.map +1 -0
- package/dist/webmcp/merge.d.ts +49 -0
- package/dist/webmcp/merge.js +167 -0
- package/dist/webmcp/merge.js.map +1 -0
- package/dist/webmcp/score.d.ts +70 -0
- package/dist/webmcp/score.js +586 -0
- package/dist/webmcp/score.js.map +1 -0
- package/dist/webmcp/types.d.ts +92 -0
- package/dist/webmcp/types.js +8 -0
- package/dist/webmcp/types.js.map +1 -0
- package/package.json +1 -1
- package/dist/eval-ui/assets/main-DjA5gpjV.js +0 -86
|
@@ -0,0 +1,436 @@
|
|
|
1
|
+
// ---------------------------------------------------------------------------
|
|
2
|
+
// vskill audit-webmcp -- headless Chromium enumeration of WebMCP tools.
|
|
3
|
+
//
|
|
4
|
+
// Playwright is an optional peer: we import 'playwright-core' or 'playwright'
|
|
5
|
+
// at runtime and never add it as a dependency. Each URL loads once in its own
|
|
6
|
+
// browser context. We read tool descriptors only: no tool is invoked or
|
|
7
|
+
// executed, no form is submitted, nothing is clicked, downloads are refused,
|
|
8
|
+
// dialogs dismissed, popups closed and service workers blocked.
|
|
9
|
+
// ---------------------------------------------------------------------------
|
|
10
|
+
import { existsSync, readdirSync } from "node:fs";
|
|
11
|
+
import { createRequire } from "node:module";
|
|
12
|
+
import { homedir } from "node:os";
|
|
13
|
+
import { join } from "node:path";
|
|
14
|
+
import { pathToFileURL } from "node:url";
|
|
15
|
+
import { mergeTools, scriptUrlFromStack } from "./merge.js";
|
|
16
|
+
/** Playwright always passes CDPScreenshotNewSurface; a second --enable-features would override it. */
|
|
17
|
+
export const CHROMIUM_ARGS = ["--enable-features=CDPScreenshotNewSurface,WebMCP"];
|
|
18
|
+
export const UA_SUFFIX = "vskill-audit-webmcp (+https://verified-skill.com)";
|
|
19
|
+
export const PROBE_NAME = "vskill-webmcp-probe";
|
|
20
|
+
/**
|
|
21
|
+
* Import playwright-core, then playwright: first from vskill's own install,
|
|
22
|
+
* then from the current project (so `npm i -D playwright-core` works with npx).
|
|
23
|
+
* Returns null when neither resolves.
|
|
24
|
+
*/
|
|
25
|
+
export async function loadChromium(cwd = process.cwd()) {
|
|
26
|
+
const projectRequire = createRequire(join(cwd, "noop.js"));
|
|
27
|
+
for (const specifier of ["playwright-core", "playwright"]) {
|
|
28
|
+
const attempts = [
|
|
29
|
+
() => import(specifier),
|
|
30
|
+
() => import(pathToFileURL(projectRequire.resolve(specifier)).href),
|
|
31
|
+
];
|
|
32
|
+
for (const attempt of attempts) {
|
|
33
|
+
try {
|
|
34
|
+
const mod = await attempt();
|
|
35
|
+
const chromium = mod.chromium ?? mod.default?.chromium;
|
|
36
|
+
if (chromium)
|
|
37
|
+
return chromium;
|
|
38
|
+
}
|
|
39
|
+
catch {
|
|
40
|
+
// try the next one
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
return null;
|
|
45
|
+
}
|
|
46
|
+
export const PLAYWRIGHT_INSTALL_HINT = [
|
|
47
|
+
"audit-webmcp needs Playwright and a Chromium build. Install them with:",
|
|
48
|
+
" npm i -D playwright-core (in the project you run vskill from; or npm i -g alongside a global vskill)",
|
|
49
|
+
" npx playwright install chromium-headless-shell",
|
|
50
|
+
"Or point at an existing build with --executable-path <path> or VSKILL_CHROMIUM=<path>.",
|
|
51
|
+
].join("\n");
|
|
52
|
+
// ---- Finding a Chromium build ----------------------------------------------
|
|
53
|
+
function browserCacheDirs() {
|
|
54
|
+
const dirs = [];
|
|
55
|
+
if (process.env.PLAYWRIGHT_BROWSERS_PATH && process.env.PLAYWRIGHT_BROWSERS_PATH !== "0") {
|
|
56
|
+
dirs.push(process.env.PLAYWRIGHT_BROWSERS_PATH);
|
|
57
|
+
}
|
|
58
|
+
const home = homedir();
|
|
59
|
+
dirs.push(join(home, "Library", "Caches", "ms-playwright"));
|
|
60
|
+
dirs.push(join(home, ".cache", "ms-playwright"));
|
|
61
|
+
if (process.env.LOCALAPPDATA)
|
|
62
|
+
dirs.push(join(process.env.LOCALAPPDATA, "ms-playwright"));
|
|
63
|
+
dirs.push("/opt/pw-browsers");
|
|
64
|
+
return dirs;
|
|
65
|
+
}
|
|
66
|
+
const BINARY_CANDIDATES = [
|
|
67
|
+
{
|
|
68
|
+
prefix: "chromium_headless_shell-",
|
|
69
|
+
paths: [
|
|
70
|
+
["chrome-headless-shell-mac-arm64", "chrome-headless-shell"],
|
|
71
|
+
["chrome-headless-shell-mac-x64", "chrome-headless-shell"],
|
|
72
|
+
["chrome-headless-shell-linux64", "chrome-headless-shell"],
|
|
73
|
+
["chrome-headless-shell-linux-arm64", "chrome-headless-shell"],
|
|
74
|
+
["chrome-linux", "headless_shell"],
|
|
75
|
+
["chrome-headless-shell-win64", "chrome-headless-shell.exe"],
|
|
76
|
+
],
|
|
77
|
+
},
|
|
78
|
+
{
|
|
79
|
+
prefix: "chromium-",
|
|
80
|
+
paths: [
|
|
81
|
+
["chrome-mac-arm64", "Google Chrome for Testing.app", "Contents", "MacOS", "Google Chrome for Testing"],
|
|
82
|
+
["chrome-mac", "Chromium.app", "Contents", "MacOS", "Chromium"],
|
|
83
|
+
["chrome-linux64", "chrome"],
|
|
84
|
+
["chrome-linux", "chrome"],
|
|
85
|
+
["chrome-win64", "chrome.exe"],
|
|
86
|
+
["chrome-win", "chrome.exe"],
|
|
87
|
+
],
|
|
88
|
+
},
|
|
89
|
+
];
|
|
90
|
+
/** Newest Chromium (headless shell preferred) in the usual Playwright cache dirs. */
|
|
91
|
+
export function findCachedChromium(dirs = browserCacheDirs()) {
|
|
92
|
+
for (const { prefix, paths } of BINARY_CANDIDATES) {
|
|
93
|
+
const found = [];
|
|
94
|
+
for (const dir of dirs) {
|
|
95
|
+
let entries;
|
|
96
|
+
try {
|
|
97
|
+
entries = readdirSync(dir);
|
|
98
|
+
}
|
|
99
|
+
catch {
|
|
100
|
+
continue;
|
|
101
|
+
}
|
|
102
|
+
for (const e of entries) {
|
|
103
|
+
if (!e.startsWith(prefix))
|
|
104
|
+
continue;
|
|
105
|
+
const rev = parseInt(e.slice(prefix.length), 10);
|
|
106
|
+
if (Number.isNaN(rev))
|
|
107
|
+
continue;
|
|
108
|
+
for (const segs of paths) {
|
|
109
|
+
const p = join(dir, e, ...segs);
|
|
110
|
+
if (existsSync(p))
|
|
111
|
+
found.push({ rev, path: p });
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
found.sort((a, b) => b.rev - a.rev);
|
|
116
|
+
if (found.length)
|
|
117
|
+
return found[0].path;
|
|
118
|
+
}
|
|
119
|
+
return null;
|
|
120
|
+
}
|
|
121
|
+
/**
|
|
122
|
+
* Resolve the executable: explicit flag, then VSKILL_CHROMIUM, then
|
|
123
|
+
* Playwright's own pinned build, then the newest cached build.
|
|
124
|
+
* Returns undefined when Playwright's default should be used.
|
|
125
|
+
*/
|
|
126
|
+
export function resolveExecutablePath(chromium, explicit) {
|
|
127
|
+
if (explicit)
|
|
128
|
+
return explicit;
|
|
129
|
+
if (process.env.VSKILL_CHROMIUM)
|
|
130
|
+
return process.env.VSKILL_CHROMIUM;
|
|
131
|
+
try {
|
|
132
|
+
const def = chromium.executablePath();
|
|
133
|
+
if (def && existsSync(def))
|
|
134
|
+
return undefined;
|
|
135
|
+
}
|
|
136
|
+
catch {
|
|
137
|
+
// fall through
|
|
138
|
+
}
|
|
139
|
+
return findCachedChromium() ?? undefined;
|
|
140
|
+
}
|
|
141
|
+
export async function launchBrowser(opts = {}) {
|
|
142
|
+
const chromium = await loadChromium();
|
|
143
|
+
if (!chromium) {
|
|
144
|
+
const err = new Error(PLAYWRIGHT_INSTALL_HINT);
|
|
145
|
+
err.code = "VSKILL_NO_PLAYWRIGHT";
|
|
146
|
+
throw err;
|
|
147
|
+
}
|
|
148
|
+
const executablePath = resolveExecutablePath(chromium, opts.executablePath);
|
|
149
|
+
return chromium.launch({
|
|
150
|
+
headless: true,
|
|
151
|
+
args: CHROMIUM_ARGS,
|
|
152
|
+
...(executablePath ? { executablePath } : {}),
|
|
153
|
+
});
|
|
154
|
+
}
|
|
155
|
+
// ---- In-page probe ---------------------------------------------------------
|
|
156
|
+
/**
|
|
157
|
+
* Runs before any page script in every frame. Wraps registerTool to record
|
|
158
|
+
* the descriptor (minus execute) and the caller's stack. The page's own
|
|
159
|
+
* registerTool still runs unchanged.
|
|
160
|
+
*/
|
|
161
|
+
export const INIT_SCRIPT = `(() => {
|
|
162
|
+
const KEY = Symbol.for("vskill.webmcp");
|
|
163
|
+
if (window[KEY]) return;
|
|
164
|
+
const log = [];
|
|
165
|
+
try { Object.defineProperty(window, KEY, { value: log, enumerable: false }); } catch (e) { return; }
|
|
166
|
+
// Crawl safety: the audit loads one page; popups (popunders, auto-opened tabs) never load.
|
|
167
|
+
try { window.open = function open() { return null; }; } catch (e) {}
|
|
168
|
+
let proto = null;
|
|
169
|
+
try {
|
|
170
|
+
proto = (typeof ModelContext !== "undefined" && ModelContext.prototype) ||
|
|
171
|
+
(document.modelContext && Object.getPrototypeOf(document.modelContext));
|
|
172
|
+
} catch (e) {}
|
|
173
|
+
if (!proto || typeof proto.registerTool !== "function") return;
|
|
174
|
+
const safe = (v) => { try { return v === undefined ? undefined : JSON.parse(JSON.stringify(v)); } catch (e) { return undefined; } };
|
|
175
|
+
const str = (v) => (typeof v === "string" ? v : undefined);
|
|
176
|
+
const orig = proto.registerTool;
|
|
177
|
+
const wrapped = function registerTool(tool, options) {
|
|
178
|
+
try {
|
|
179
|
+
const t = tool || {};
|
|
180
|
+
const rec = {
|
|
181
|
+
name: String(t.name == null ? "" : t.name),
|
|
182
|
+
title: str(t.title),
|
|
183
|
+
description: str(t.description),
|
|
184
|
+
inputSchema: typeof t.inputSchema === "string" ? t.inputSchema : safe(t.inputSchema),
|
|
185
|
+
annotations: safe(t.annotations),
|
|
186
|
+
exposedTo: safe((options && options.exposedTo) !== undefined ? options.exposedTo : t.exposedTo),
|
|
187
|
+
stack: String(new Error().stack || ""),
|
|
188
|
+
};
|
|
189
|
+
log.push(rec);
|
|
190
|
+
const signal = options && options.signal;
|
|
191
|
+
if (signal && typeof signal.addEventListener === "function") {
|
|
192
|
+
signal.addEventListener("abort", () => log.push({ name: rec.name, unregistered: true }), { once: true });
|
|
193
|
+
}
|
|
194
|
+
} catch (e) {}
|
|
195
|
+
return orig.apply(this, arguments);
|
|
196
|
+
};
|
|
197
|
+
try { Object.defineProperty(proto, "registerTool", { value: wrapped, writable: true, configurable: true }); } catch (e) {}
|
|
198
|
+
if (typeof proto.unregisterTool === "function") {
|
|
199
|
+
const origUn = proto.unregisterTool;
|
|
200
|
+
try {
|
|
201
|
+
Object.defineProperty(proto, "unregisterTool", {
|
|
202
|
+
value: function unregisterTool(name) {
|
|
203
|
+
try { log.push({ name: String(name), unregistered: true }); } catch (e) {}
|
|
204
|
+
return origUn.apply(this, arguments);
|
|
205
|
+
},
|
|
206
|
+
writable: true,
|
|
207
|
+
configurable: true,
|
|
208
|
+
});
|
|
209
|
+
} catch (e) {}
|
|
210
|
+
}
|
|
211
|
+
})();
|
|
212
|
+
//# sourceURL=${PROBE_NAME}.js`;
|
|
213
|
+
/** Evaluated in the page after it settles. Reads, never executes. */
|
|
214
|
+
function snapshotInPage() {
|
|
215
|
+
const w = window;
|
|
216
|
+
const d = document;
|
|
217
|
+
const mc = d.modelContext;
|
|
218
|
+
const out = {
|
|
219
|
+
documentModelContext: !!mc,
|
|
220
|
+
navigatorModelContext: "modelContext" in navigator,
|
|
221
|
+
captured: [],
|
|
222
|
+
listed: null,
|
|
223
|
+
platforms: [],
|
|
224
|
+
};
|
|
225
|
+
// Hosting-platform markers (attribution.ts PLATFORM_HOSTS). Shopify storefronts
|
|
226
|
+
// set window.Shopify.shop to the store's myshopify.com name and emit these metas.
|
|
227
|
+
try {
|
|
228
|
+
const shop = w.Shopify;
|
|
229
|
+
const shopifyMeta = d.querySelector('meta[name="shopify-checkout-api-token"], meta[name="shopify-digital-wallet"]');
|
|
230
|
+
if ((shop && typeof shop === "object" && typeof shop.shop === "string") || shopifyMeta || /\.myshopify\.com$/i.test(location.hostname)) {
|
|
231
|
+
out.platforms.push("shopify");
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
catch {
|
|
235
|
+
// markers are best effort
|
|
236
|
+
}
|
|
237
|
+
const log = w[Symbol.for("vskill.webmcp")];
|
|
238
|
+
if (Array.isArray(log))
|
|
239
|
+
out.captured = log.slice();
|
|
240
|
+
if (!mc || typeof mc.getTools !== "function")
|
|
241
|
+
return Promise.resolve(out);
|
|
242
|
+
const clone = (v) => {
|
|
243
|
+
try {
|
|
244
|
+
return v === undefined ? undefined : JSON.parse(JSON.stringify(v));
|
|
245
|
+
}
|
|
246
|
+
catch {
|
|
247
|
+
return undefined;
|
|
248
|
+
}
|
|
249
|
+
};
|
|
250
|
+
return Promise.race([
|
|
251
|
+
Promise.resolve(mc.getTools()),
|
|
252
|
+
new Promise((_, reject) => setTimeout(() => reject(new Error("getTools() timed out")), 3000)),
|
|
253
|
+
])
|
|
254
|
+
.then((tools) => {
|
|
255
|
+
out.listed = Array.from(tools || []).map((t) => ({
|
|
256
|
+
name: String(t.name),
|
|
257
|
+
title: typeof t.title === "string" ? t.title : undefined,
|
|
258
|
+
description: typeof t.description === "string" ? t.description : undefined,
|
|
259
|
+
inputSchema: typeof t.inputSchema === "string" ? t.inputSchema : clone(t.inputSchema),
|
|
260
|
+
annotations: clone(t.annotations),
|
|
261
|
+
origin: typeof t.origin === "string" ? t.origin : undefined,
|
|
262
|
+
exposedTo: clone(t.exposedTo),
|
|
263
|
+
}));
|
|
264
|
+
return out;
|
|
265
|
+
})
|
|
266
|
+
.catch((e) => {
|
|
267
|
+
out.getToolsError = String(e);
|
|
268
|
+
return out;
|
|
269
|
+
});
|
|
270
|
+
}
|
|
271
|
+
/** Reject when `p` takes longer than `ms` (a page stuck in a busy loop never answers evaluate). */
|
|
272
|
+
function withTimeout(p, ms, what) {
|
|
273
|
+
let timer;
|
|
274
|
+
return Promise.race([
|
|
275
|
+
p,
|
|
276
|
+
new Promise((_, reject) => {
|
|
277
|
+
timer = setTimeout(() => reject(new Error(`${what} timed out after ${ms}ms`)), ms);
|
|
278
|
+
}),
|
|
279
|
+
]).finally(() => clearTimeout(timer));
|
|
280
|
+
}
|
|
281
|
+
function firstLine(e) {
|
|
282
|
+
const msg = e instanceof Error ? e.message : String(e);
|
|
283
|
+
return msg.split("\n")[0].replace(/^page\.goto:\s*/, "").trim();
|
|
284
|
+
}
|
|
285
|
+
function cdpToolList(params) {
|
|
286
|
+
if (Array.isArray(params?.tools))
|
|
287
|
+
return params.tools;
|
|
288
|
+
if (params?.tool)
|
|
289
|
+
return [params.tool];
|
|
290
|
+
if (params?.name)
|
|
291
|
+
return [params];
|
|
292
|
+
return [];
|
|
293
|
+
}
|
|
294
|
+
/** Browser UA with our suffix, read once per browser. */
|
|
295
|
+
export async function userAgentFor(browser) {
|
|
296
|
+
const ctx = await browser.newContext();
|
|
297
|
+
try {
|
|
298
|
+
const page = await ctx.newPage();
|
|
299
|
+
const ua = await page.evaluate(() => navigator.userAgent);
|
|
300
|
+
return `${ua} ${UA_SUFFIX}`;
|
|
301
|
+
}
|
|
302
|
+
finally {
|
|
303
|
+
await ctx.close();
|
|
304
|
+
}
|
|
305
|
+
}
|
|
306
|
+
export async function enumerateSite(browser, url, opts) {
|
|
307
|
+
const settleMs = opts.settleMs ?? 5000;
|
|
308
|
+
const quietMs = opts.quietMs ?? 1500;
|
|
309
|
+
const result = {
|
|
310
|
+
url,
|
|
311
|
+
finalUrl: null,
|
|
312
|
+
documentModelContext: false,
|
|
313
|
+
navigatorModelContext: false,
|
|
314
|
+
permissionsPolicy: null,
|
|
315
|
+
platforms: [],
|
|
316
|
+
tools: [],
|
|
317
|
+
};
|
|
318
|
+
if (opts.signal?.aborted) {
|
|
319
|
+
result.error = "aborted";
|
|
320
|
+
return result;
|
|
321
|
+
}
|
|
322
|
+
const ctx = await browser.newContext({
|
|
323
|
+
acceptDownloads: false,
|
|
324
|
+
javaScriptEnabled: true,
|
|
325
|
+
serviceWorkers: "block",
|
|
326
|
+
...(opts.userAgent ? { userAgent: opts.userAgent } : {}),
|
|
327
|
+
});
|
|
328
|
+
const onAbort = () => {
|
|
329
|
+
ctx.close().catch(() => { });
|
|
330
|
+
};
|
|
331
|
+
opts.signal?.addEventListener("abort", onAbort, { once: true });
|
|
332
|
+
try {
|
|
333
|
+
await ctx.addInitScript({ content: INIT_SCRIPT });
|
|
334
|
+
const page = await ctx.newPage();
|
|
335
|
+
page.on("dialog", (d) => {
|
|
336
|
+
d.dismiss().catch(() => { });
|
|
337
|
+
});
|
|
338
|
+
// window.open popups would load more pages we never asked for: close them.
|
|
339
|
+
ctx.on("page", (p) => {
|
|
340
|
+
if (p !== page)
|
|
341
|
+
p.close().catch(() => { });
|
|
342
|
+
});
|
|
343
|
+
const cdpEvents = [];
|
|
344
|
+
try {
|
|
345
|
+
const cdp = await ctx.newCDPSession(page);
|
|
346
|
+
cdp.on("WebMCP.toolsAdded", (p) => {
|
|
347
|
+
for (const t of cdpToolList(p))
|
|
348
|
+
if (t?.name)
|
|
349
|
+
cdpEvents.push({ ...t, name: String(t.name) });
|
|
350
|
+
});
|
|
351
|
+
cdp.on("WebMCP.toolsRemoved", (p) => {
|
|
352
|
+
const names = Array.isArray(p?.names) ? p.names : cdpToolList(p).map((t) => t?.name ?? t);
|
|
353
|
+
for (const n of names)
|
|
354
|
+
if (typeof n === "string")
|
|
355
|
+
cdpEvents.push({ name: n, removed: true });
|
|
356
|
+
});
|
|
357
|
+
await cdp.send("WebMCP.enable");
|
|
358
|
+
}
|
|
359
|
+
catch {
|
|
360
|
+
// Older Chromium without the WebMCP domain: rely on the other sources.
|
|
361
|
+
}
|
|
362
|
+
try {
|
|
363
|
+
const response = await page.goto(url, { waitUntil: "load", timeout: opts.timeoutMs });
|
|
364
|
+
const headers = response?.headers() ?? {};
|
|
365
|
+
result.permissionsPolicy = headers["permissions-policy"] ?? null;
|
|
366
|
+
}
|
|
367
|
+
catch (e) {
|
|
368
|
+
const msg = firstLine(e);
|
|
369
|
+
if (!/timeout/i.test(msg) || page.url() === "about:blank") {
|
|
370
|
+
result.error = msg;
|
|
371
|
+
result.finalUrl = page.url() === "about:blank" ? null : page.url();
|
|
372
|
+
return result;
|
|
373
|
+
}
|
|
374
|
+
result.error = `${msg} (partial: tools registered before the timeout are included)`;
|
|
375
|
+
}
|
|
376
|
+
// Wait for registrations to stop: at most settleMs, done early after quietMs without change.
|
|
377
|
+
const countNow = async () => {
|
|
378
|
+
const captured = await withTimeout(page.evaluate(() => {
|
|
379
|
+
const log = window[Symbol.for("vskill.webmcp")];
|
|
380
|
+
return Array.isArray(log) ? log.length : 0;
|
|
381
|
+
}), 2000, "page.evaluate").catch(() => 0);
|
|
382
|
+
return captured + cdpEvents.length;
|
|
383
|
+
};
|
|
384
|
+
const start = Date.now();
|
|
385
|
+
let last = await countNow();
|
|
386
|
+
let lastChange = Date.now();
|
|
387
|
+
while (Date.now() - start < settleMs) {
|
|
388
|
+
await page.waitForTimeout(250);
|
|
389
|
+
const n = await countNow();
|
|
390
|
+
if (n !== last) {
|
|
391
|
+
last = n;
|
|
392
|
+
lastChange = Date.now();
|
|
393
|
+
}
|
|
394
|
+
else if (Date.now() - lastChange >= quietMs) {
|
|
395
|
+
break;
|
|
396
|
+
}
|
|
397
|
+
}
|
|
398
|
+
result.finalUrl = page.url();
|
|
399
|
+
const readSnapshot = () => withTimeout(page.evaluate(snapshotInPage), 10_000, "reading tools from the page");
|
|
400
|
+
let snap;
|
|
401
|
+
try {
|
|
402
|
+
snap = await readSnapshot();
|
|
403
|
+
}
|
|
404
|
+
catch (e) {
|
|
405
|
+
// The page navigated itself (client-side redirect) mid-read: read the new document once more.
|
|
406
|
+
if (!/context was destroyed|navigat/i.test(String(e)))
|
|
407
|
+
throw e;
|
|
408
|
+
await page.waitForTimeout(1000);
|
|
409
|
+
snap = await readSnapshot();
|
|
410
|
+
}
|
|
411
|
+
result.finalUrl = page.url();
|
|
412
|
+
result.documentModelContext = snap.documentModelContext;
|
|
413
|
+
result.navigatorModelContext = snap.navigatorModelContext;
|
|
414
|
+
result.platforms = snap.platforms;
|
|
415
|
+
const captured = snap.captured.map(({ stack, ...rest }) => ({
|
|
416
|
+
...rest,
|
|
417
|
+
scriptUrl: rest.unregistered ? undefined : scriptUrlFromStack(stack, PROBE_NAME),
|
|
418
|
+
}));
|
|
419
|
+
result.tools = mergeTools({
|
|
420
|
+
pageUrl: result.finalUrl,
|
|
421
|
+
captured,
|
|
422
|
+
cdp: cdpEvents,
|
|
423
|
+
listed: snap.listed,
|
|
424
|
+
platforms: snap.platforms,
|
|
425
|
+
});
|
|
426
|
+
}
|
|
427
|
+
catch (e) {
|
|
428
|
+
result.error = result.error ?? firstLine(e);
|
|
429
|
+
}
|
|
430
|
+
finally {
|
|
431
|
+
opts.signal?.removeEventListener("abort", onAbort);
|
|
432
|
+
await ctx.close().catch(() => { });
|
|
433
|
+
}
|
|
434
|
+
return result;
|
|
435
|
+
}
|
|
436
|
+
//# sourceMappingURL=enumerate.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"enumerate.js","sourceRoot":"","sources":["../../src/webmcp/enumerate.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { SiteReport } from "./types.js";
|
|
2
|
+
/**
|
|
3
|
+
* Page-supplied text (tool names, matched description excerpts, script URLs)
|
|
4
|
+
* goes to the auditor's terminal: show control and bidi-override characters
|
|
5
|
+
* as U+XXXX so a site cannot send escape sequences or reorder the output.
|
|
6
|
+
*/
|
|
7
|
+
export declare function clean(s: string): string;
|
|
8
|
+
export declare function formatSiteTerminal(r: SiteReport): string;
|
|
9
|
+
export declare function formatBatchFooter(reports: SiteReport[]): string;
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
// ---------------------------------------------------------------------------
|
|
2
|
+
// vskill audit-webmcp -- terminal output.
|
|
3
|
+
// ---------------------------------------------------------------------------
|
|
4
|
+
import { bold, cyan, dim, green, red, yellow } from "../utils/output.js";
|
|
5
|
+
function sevLabel(s) {
|
|
6
|
+
const label = s.toUpperCase().padEnd(8);
|
|
7
|
+
if (s === "critical" || s === "high")
|
|
8
|
+
return red(label);
|
|
9
|
+
if (s === "medium")
|
|
10
|
+
return yellow(label);
|
|
11
|
+
if (s === "low")
|
|
12
|
+
return cyan(label);
|
|
13
|
+
return dim(label);
|
|
14
|
+
}
|
|
15
|
+
function verdictLabel(r) {
|
|
16
|
+
const v = r.summary.verdict;
|
|
17
|
+
if (v === "ERROR")
|
|
18
|
+
return red(v);
|
|
19
|
+
return v === "PASS" ? green(v) : v === "CONCERNS" ? yellow(v) : red(v);
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Page-supplied text (tool names, matched description excerpts, script URLs)
|
|
23
|
+
* goes to the auditor's terminal: show control and bidi-override characters
|
|
24
|
+
* as U+XXXX so a site cannot send escape sequences or reorder the output.
|
|
25
|
+
*/
|
|
26
|
+
export function clean(s) {
|
|
27
|
+
return s.replace(/[\u0000-\u001F\u007F-\u009F\u202A-\u202E\u2066-\u2069]/g, (c) => `U+${c.charCodeAt(0).toString(16).toUpperCase().padStart(4, "0")}`);
|
|
28
|
+
}
|
|
29
|
+
function pad(s, n) {
|
|
30
|
+
return s.length >= n ? s : s + " ".repeat(n - s.length);
|
|
31
|
+
}
|
|
32
|
+
function shortScript(url) {
|
|
33
|
+
if (!url)
|
|
34
|
+
return "-";
|
|
35
|
+
try {
|
|
36
|
+
const u = new URL(url);
|
|
37
|
+
const path = u.pathname.length > 32 ? `${u.pathname.slice(0, 31)}…` : u.pathname;
|
|
38
|
+
return clean(`${u.host}${path}`);
|
|
39
|
+
}
|
|
40
|
+
catch {
|
|
41
|
+
return clean(url);
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
const yn = (b) => (b === true ? "yes" : b === false ? "no" : "-");
|
|
45
|
+
const SOURCE_LABELS = {
|
|
46
|
+
"first-party": "1st",
|
|
47
|
+
platform: "platform",
|
|
48
|
+
library: "library",
|
|
49
|
+
"third-party": "3rd",
|
|
50
|
+
};
|
|
51
|
+
function sourceLabel(t) {
|
|
52
|
+
if (t.registeredByKind)
|
|
53
|
+
return SOURCE_LABELS[t.registeredByKind];
|
|
54
|
+
return t.thirdParty ? "3rd" : "-";
|
|
55
|
+
}
|
|
56
|
+
export function formatSiteTerminal(r) {
|
|
57
|
+
const lines = [];
|
|
58
|
+
const s = r.summary;
|
|
59
|
+
const target = clean(r.finalUrl && r.finalUrl !== r.url ? `${r.url} -> ${r.finalUrl}` : r.url);
|
|
60
|
+
const failed = s.verdict === "ERROR";
|
|
61
|
+
lines.push(`${bold(target)} ${verdictLabel(r)}${failed ? "" : ` ${dim(`score ${s.score}`)}`}`);
|
|
62
|
+
if (r.error)
|
|
63
|
+
lines.push(` ${red("error:")} ${clean(r.error)}`);
|
|
64
|
+
if (failed)
|
|
65
|
+
return lines.join("\n");
|
|
66
|
+
if (!r.webmcp.documentModelContext && !r.error) {
|
|
67
|
+
lines.push(dim(" document.modelContext is not available in this browser; WebMCP was not enabled."));
|
|
68
|
+
}
|
|
69
|
+
if (r.webmcp.navigatorModelContext) {
|
|
70
|
+
lines.push(yellow(" navigator.modelContext exists (removed in Chrome 152; the page may polyfill it)."));
|
|
71
|
+
}
|
|
72
|
+
lines.push(` ${s.toolCount} tools: ${s.readOnlyCount} read-only, ${s.consequentialCount} consequential, ` +
|
|
73
|
+
`${s.writeShapedCount} write-shaped, ${s.thirdPartyCount} third-party` +
|
|
74
|
+
(s.platformCount ? `, ${s.platformCount} platform` : "") +
|
|
75
|
+
(s.libraryCount ? `, ${s.libraryCount} library` : ""));
|
|
76
|
+
if (r.tools.length > 0) {
|
|
77
|
+
const names = r.tools.map((t) => clean(t.name));
|
|
78
|
+
const nameW = Math.min(32, Math.max(4, ...names.map((n) => n.length)));
|
|
79
|
+
lines.push(dim(` ${pad("TOOL", nameW)} READONLY CONSEQ SOURCE REGISTERED BY`));
|
|
80
|
+
r.tools.forEach((t, i) => {
|
|
81
|
+
const full = names[i];
|
|
82
|
+
const name = full.length > nameW ? `${full.slice(0, nameW - 1)}…` : full;
|
|
83
|
+
lines.push(` ${pad(name, nameW)} ${pad(yn(t.annotations.readOnlyHint), 8)} ${pad(yn(t.annotations.consequentialHint), 6)} ` +
|
|
84
|
+
`${pad(sourceLabel(t), 8)} ${shortScript(t.registeredBy)}`);
|
|
85
|
+
});
|
|
86
|
+
}
|
|
87
|
+
if (r.findings.length > 0) {
|
|
88
|
+
lines.push("");
|
|
89
|
+
for (const f of r.findings) {
|
|
90
|
+
lines.push(` ${sevLabel(f.severity)} ${f.id} ${f.tool ? `${bold(clean(f.tool))}: ` : ""}${clean(f.message)}`);
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
else if (r.tools.length > 0) {
|
|
94
|
+
lines.push(green(" No findings."));
|
|
95
|
+
}
|
|
96
|
+
return lines.join("\n");
|
|
97
|
+
}
|
|
98
|
+
export function formatBatchFooter(reports) {
|
|
99
|
+
const withTools = reports.filter((r) => r.summary.toolCount > 0).length;
|
|
100
|
+
const count = (v) => reports.filter((r) => r.summary.verdict === v).length;
|
|
101
|
+
const errors = count("ERROR");
|
|
102
|
+
return bold(`${reports.length} sites: ${withTools} expose WebMCP tools | ` +
|
|
103
|
+
`${count("PASS")} PASS, ${count("CONCERNS")} CONCERNS, ${count("FAIL")} FAIL, ${errors} errors`);
|
|
104
|
+
}
|
|
105
|
+
//# sourceMappingURL=format.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"format.js","sourceRoot":"","sources":["../../src/webmcp/format.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import type { ToolAnnotations, WebmcpTool } from "./types.js";
|
|
2
|
+
export interface CapturedTool {
|
|
3
|
+
name: string;
|
|
4
|
+
title?: string;
|
|
5
|
+
description?: string;
|
|
6
|
+
inputSchema?: unknown;
|
|
7
|
+
annotations?: Record<string, unknown>;
|
|
8
|
+
exposedTo?: unknown;
|
|
9
|
+
scriptUrl?: string | null;
|
|
10
|
+
unregistered?: boolean;
|
|
11
|
+
}
|
|
12
|
+
export interface CdpTool {
|
|
13
|
+
name: string;
|
|
14
|
+
title?: string;
|
|
15
|
+
description?: string;
|
|
16
|
+
inputSchema?: unknown;
|
|
17
|
+
annotations?: Record<string, unknown>;
|
|
18
|
+
stackTrace?: {
|
|
19
|
+
callFrames?: Array<{
|
|
20
|
+
url?: string;
|
|
21
|
+
}>;
|
|
22
|
+
};
|
|
23
|
+
removed?: boolean;
|
|
24
|
+
}
|
|
25
|
+
export interface ListedTool {
|
|
26
|
+
name: string;
|
|
27
|
+
title?: string;
|
|
28
|
+
description?: string;
|
|
29
|
+
inputSchema?: unknown;
|
|
30
|
+
annotations?: Record<string, unknown>;
|
|
31
|
+
origin?: string;
|
|
32
|
+
exposedTo?: unknown;
|
|
33
|
+
}
|
|
34
|
+
export interface MergeInput {
|
|
35
|
+
pageUrl: string;
|
|
36
|
+
captured: CapturedTool[];
|
|
37
|
+
cdp: CdpTool[];
|
|
38
|
+
/** null when getTools() was unavailable or threw. */
|
|
39
|
+
listed: ListedTool[] | null;
|
|
40
|
+
/** Hosting platform markers found on the page (attribution.ts PlatformMarker). */
|
|
41
|
+
platforms?: string[];
|
|
42
|
+
}
|
|
43
|
+
/** Map readOnly/readOnlyHint, consequential/consequentialHint, untrustedContent/untrustedContentHint. */
|
|
44
|
+
export declare function normalizeAnnotations(raw: unknown): ToolAnnotations;
|
|
45
|
+
/** First http(s) frame in a CDP stack trace. */
|
|
46
|
+
export declare function cdpRegistrar(t: CdpTool): string | undefined;
|
|
47
|
+
/** First http(s) URL in a V8 Error().stack that is not our probe script. */
|
|
48
|
+
export declare function scriptUrlFromStack(stack: string | undefined, probeName?: string): string | null;
|
|
49
|
+
export declare function mergeTools(input: MergeInput): WebmcpTool[];
|