@keak/webmcp-core 0.1.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.
Files changed (111) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +165 -0
  3. package/dist/config.d.ts +103 -0
  4. package/dist/config.d.ts.map +1 -0
  5. package/dist/config.js +54 -0
  6. package/dist/config.js.map +1 -0
  7. package/dist/exporter/manifest.d.ts +6 -0
  8. package/dist/exporter/manifest.d.ts.map +1 -0
  9. package/dist/exporter/manifest.js +36 -0
  10. package/dist/exporter/manifest.js.map +1 -0
  11. package/dist/exporter/snippet.d.ts +7 -0
  12. package/dist/exporter/snippet.d.ts.map +1 -0
  13. package/dist/exporter/snippet.js +197 -0
  14. package/dist/exporter/snippet.js.map +1 -0
  15. package/dist/exporter/userscript.d.ts +6 -0
  16. package/dist/exporter/userscript.d.ts.map +1 -0
  17. package/dist/exporter/userscript.js +53 -0
  18. package/dist/exporter/userscript.js.map +1 -0
  19. package/dist/exporter/yaml.d.ts +6 -0
  20. package/dist/exporter/yaml.d.ts.map +1 -0
  21. package/dist/exporter/yaml.js +90 -0
  22. package/dist/exporter/yaml.js.map +1 -0
  23. package/dist/extractor/api-extractor.d.ts +3 -0
  24. package/dist/extractor/api-extractor.d.ts.map +1 -0
  25. package/dist/extractor/api-extractor.js +274 -0
  26. package/dist/extractor/api-extractor.js.map +1 -0
  27. package/dist/extractor/click-extractor.d.ts +3 -0
  28. package/dist/extractor/click-extractor.d.ts.map +1 -0
  29. package/dist/extractor/click-extractor.js +52 -0
  30. package/dist/extractor/click-extractor.js.map +1 -0
  31. package/dist/extractor/form-extractor.d.ts +3 -0
  32. package/dist/extractor/form-extractor.d.ts.map +1 -0
  33. package/dist/extractor/form-extractor.js +27 -0
  34. package/dist/extractor/form-extractor.js.map +1 -0
  35. package/dist/extractor/route-extractor.d.ts +3 -0
  36. package/dist/extractor/route-extractor.d.ts.map +1 -0
  37. package/dist/extractor/route-extractor.js +84 -0
  38. package/dist/extractor/route-extractor.js.map +1 -0
  39. package/dist/extractor/schema-inferrer.d.ts +4 -0
  40. package/dist/extractor/schema-inferrer.d.ts.map +1 -0
  41. package/dist/extractor/schema-inferrer.js +128 -0
  42. package/dist/extractor/schema-inferrer.js.map +1 -0
  43. package/dist/index.d.ts +88 -0
  44. package/dist/index.d.ts.map +1 -0
  45. package/dist/index.js +170 -0
  46. package/dist/index.js.map +1 -0
  47. package/dist/linter/linter.d.ts +10 -0
  48. package/dist/linter/linter.d.ts.map +1 -0
  49. package/dist/linter/linter.js +39 -0
  50. package/dist/linter/linter.js.map +1 -0
  51. package/dist/linter/rules.d.ts +4 -0
  52. package/dist/linter/rules.d.ts.map +1 -0
  53. package/dist/linter/rules.js +111 -0
  54. package/dist/linter/rules.js.map +1 -0
  55. package/dist/scanner/browser.d.ts +14 -0
  56. package/dist/scanner/browser.d.ts.map +1 -0
  57. package/dist/scanner/browser.js +42 -0
  58. package/dist/scanner/browser.js.map +1 -0
  59. package/dist/scanner/crawler.d.ts +12 -0
  60. package/dist/scanner/crawler.d.ts.map +1 -0
  61. package/dist/scanner/crawler.js +80 -0
  62. package/dist/scanner/crawler.js.map +1 -0
  63. package/dist/scanner/dom-capture.d.ts +4 -0
  64. package/dist/scanner/dom-capture.d.ts.map +1 -0
  65. package/dist/scanner/dom-capture.js +148 -0
  66. package/dist/scanner/dom-capture.js.map +1 -0
  67. package/dist/scanner/network-capture.d.ts +8 -0
  68. package/dist/scanner/network-capture.d.ts.map +1 -0
  69. package/dist/scanner/network-capture.js +112 -0
  70. package/dist/scanner/network-capture.js.map +1 -0
  71. package/dist/scanner/screenshot.d.ts +3 -0
  72. package/dist/scanner/screenshot.d.ts.map +1 -0
  73. package/dist/scanner/screenshot.js +10 -0
  74. package/dist/scanner/screenshot.js.map +1 -0
  75. package/dist/synthesizer/clusterer.d.ts +7 -0
  76. package/dist/synthesizer/clusterer.d.ts.map +1 -0
  77. package/dist/synthesizer/clusterer.js +310 -0
  78. package/dist/synthesizer/clusterer.js.map +1 -0
  79. package/dist/synthesizer/describer.d.ts +3 -0
  80. package/dist/synthesizer/describer.d.ts.map +1 -0
  81. package/dist/synthesizer/describer.js +92 -0
  82. package/dist/synthesizer/describer.js.map +1 -0
  83. package/dist/synthesizer/llm-client.d.ts +7 -0
  84. package/dist/synthesizer/llm-client.d.ts.map +1 -0
  85. package/dist/synthesizer/llm-client.js +7 -0
  86. package/dist/synthesizer/llm-client.js.map +1 -0
  87. package/dist/synthesizer/namer.d.ts +3 -0
  88. package/dist/synthesizer/namer.d.ts.map +1 -0
  89. package/dist/synthesizer/namer.js +154 -0
  90. package/dist/synthesizer/namer.js.map +1 -0
  91. package/dist/synthesizer/safety-classifier.d.ts +3 -0
  92. package/dist/synthesizer/safety-classifier.d.ts.map +1 -0
  93. package/dist/synthesizer/safety-classifier.js +68 -0
  94. package/dist/synthesizer/safety-classifier.js.map +1 -0
  95. package/dist/synthesizer/schema-builder.d.ts +3 -0
  96. package/dist/synthesizer/schema-builder.d.ts.map +1 -0
  97. package/dist/synthesizer/schema-builder.js +99 -0
  98. package/dist/synthesizer/schema-builder.js.map +1 -0
  99. package/dist/types.d.ts +271 -0
  100. package/dist/types.d.ts.map +1 -0
  101. package/dist/types.js +3 -0
  102. package/dist/types.js.map +1 -0
  103. package/dist/utils/redact.d.ts +3 -0
  104. package/dist/utils/redact.d.ts.map +1 -0
  105. package/dist/utils/redact.js +42 -0
  106. package/dist/utils/redact.js.map +1 -0
  107. package/dist/utils/validation.d.ts +876 -0
  108. package/dist/utils/validation.d.ts.map +1 -0
  109. package/dist/utils/validation.js +108 -0
  110. package/dist/utils/validation.js.map +1 -0
  111. package/package.json +69 -0
@@ -0,0 +1,53 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.generateUserscript = generateUserscript;
4
+ function generateUserscript(tools, options) {
5
+ const lines = [];
6
+ lines.push("// ==UserScript==");
7
+ lines.push(`// @name WebMCP Tools for ${options.domain}`);
8
+ lines.push("// @namespace https://webmcp.dev/userscripts");
9
+ lines.push("// @version 1.0.0");
10
+ lines.push(`// @description WebMCP tool definitions for ${options.domain} — auto-generated by webmcp-autogen`);
11
+ lines.push(`// @match https://${options.domain}/*`);
12
+ lines.push(`// @match https://www.${options.domain}/*`);
13
+ lines.push("// @grant none");
14
+ lines.push("// @run-at document-idle");
15
+ lines.push("// ==/UserScript==");
16
+ lines.push("");
17
+ lines.push("(function() {");
18
+ lines.push(' "use strict";');
19
+ lines.push("");
20
+ lines.push(" if (!navigator.modelContext) {");
21
+ lines.push(' console.warn("[WebMCP Userscript] navigator.modelContext not available.");');
22
+ lines.push(" return;");
23
+ lines.push(" }");
24
+ lines.push("");
25
+ for (const tool of tools) {
26
+ lines.push(` // Tool: ${tool.name} (${tool.safety.level})`);
27
+ lines.push(" navigator.modelContext.registerTool({");
28
+ lines.push(` name: ${JSON.stringify(tool.name)},`);
29
+ lines.push(` description: ${JSON.stringify(tool.description)},`);
30
+ lines.push(` inputSchema: ${JSON.stringify(tool.inputSchema)},`);
31
+ lines.push(" handler: async (params) => {");
32
+ lines.push(` // TODO: Implement ${tool.name} handler`);
33
+ lines.push(" return { success: true };");
34
+ lines.push(" },");
35
+ lines.push(" });");
36
+ lines.push("");
37
+ }
38
+ lines.push(` console.log("[WebMCP Userscript] Registered ${tools.length} tools for ${options.domain}");`);
39
+ lines.push("})();");
40
+ lines.push("");
41
+ const files = [
42
+ {
43
+ name: `webmcp.${sanitize(options.domain)}.user.js`,
44
+ content: lines.join("\n"),
45
+ language: "javascript",
46
+ },
47
+ ];
48
+ return { files, target: "userscript" };
49
+ }
50
+ function sanitize(domain) {
51
+ return domain.replace(/[^a-z0-9.-]/gi, "_").toLowerCase();
52
+ }
53
+ //# sourceMappingURL=userscript.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"userscript.js","sourceRoot":"","sources":["../../src/exporter/userscript.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,6 @@
1
+ import type { ToolSpec, ExportResult } from "../types.js";
2
+ export interface YamlOptions {
3
+ domain: string;
4
+ }
5
+ export declare function generateYaml(tools: ToolSpec[], options: YamlOptions): ExportResult;
6
+ //# sourceMappingURL=yaml.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"yaml.d.ts","sourceRoot":"","sources":["../../src/exporter/yaml.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,YAAY,EAAc,MAAM,aAAa,CAAC;AAEtE,MAAM,WAAW,WAAW;IAC1B,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,wBAAgB,YAAY,CAC1B,KAAK,EAAE,QAAQ,EAAE,EACjB,OAAO,EAAE,WAAW,GACnB,YAAY,CA8Cd"}
@@ -0,0 +1,90 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.generateYaml = generateYaml;
4
+ function generateYaml(tools, options) {
5
+ const lines = [];
6
+ lines.push("# WebMCP Tool Definitions");
7
+ lines.push(`# Domain: ${options.domain}`);
8
+ lines.push(`# Generated by webmcp-autogen on ${new Date().toISOString()}`);
9
+ lines.push(`# Tools: ${tools.length}`);
10
+ lines.push("");
11
+ lines.push(`version: "1.0"`);
12
+ lines.push(`domain: ${quote(options.domain)}`);
13
+ lines.push("");
14
+ lines.push("tools:");
15
+ for (const tool of tools) {
16
+ lines.push(` - name: ${quote(tool.name)}`);
17
+ lines.push(` description: ${quote(tool.description)}`);
18
+ lines.push(` safety:`);
19
+ lines.push(` level: ${tool.safety.level}`);
20
+ lines.push(` requiresConfirm: ${tool.safety.requiresConfirm}`);
21
+ lines.push(` availability:`);
22
+ lines.push(` urlPatterns:`);
23
+ for (const pattern of tool.availability.urlPatterns) {
24
+ lines.push(` - ${quote(pattern)}`);
25
+ }
26
+ lines.push(` requiresAuth: ${tool.availability.requiresAuth}`);
27
+ lines.push(` inputSchema:`);
28
+ lines.push(objectToYaml(tool.inputSchema, 6));
29
+ lines.push(` implementation:`);
30
+ lines.push(` kind: ${tool.implementation.kind}`);
31
+ if (tool.implementation.form) {
32
+ lines.push(` form:`);
33
+ lines.push(` formSelector: ${quote(tool.implementation.form.formSelector)}`);
34
+ lines.push(` toolautosubmit: ${tool.implementation.form.toolautosubmit ?? false}`);
35
+ }
36
+ lines.push("");
37
+ }
38
+ const files = [
39
+ {
40
+ name: "webmcp.tools.yaml",
41
+ content: lines.join("\n") + "\n",
42
+ language: "yaml",
43
+ },
44
+ ];
45
+ return { files, target: "yaml" };
46
+ }
47
+ function quote(value) {
48
+ if (value.includes(":") ||
49
+ value.includes("#") ||
50
+ value.includes("'") ||
51
+ value.includes('"') ||
52
+ value.includes("\n") ||
53
+ value.startsWith(" ") ||
54
+ value.endsWith(" ")) {
55
+ return JSON.stringify(value);
56
+ }
57
+ return value;
58
+ }
59
+ function objectToYaml(obj, indent) {
60
+ const lines = [];
61
+ const pad = " ".repeat(indent);
62
+ for (const [key, value] of Object.entries(obj)) {
63
+ if (value === null || value === undefined)
64
+ continue;
65
+ if (typeof value === "object" && !Array.isArray(value)) {
66
+ lines.push(`${pad}${key}:`);
67
+ lines.push(objectToYaml(value, indent + 2));
68
+ }
69
+ else if (Array.isArray(value)) {
70
+ lines.push(`${pad}${key}:`);
71
+ for (const item of value) {
72
+ if (typeof item === "object") {
73
+ lines.push(`${pad} -`);
74
+ lines.push(objectToYaml(item, indent + 4));
75
+ }
76
+ else {
77
+ lines.push(`${pad} - ${quote(String(item))}`);
78
+ }
79
+ }
80
+ }
81
+ else if (typeof value === "string") {
82
+ lines.push(`${pad}${key}: ${quote(value)}`);
83
+ }
84
+ else {
85
+ lines.push(`${pad}${key}: ${value}`);
86
+ }
87
+ }
88
+ return lines.join("\n");
89
+ }
90
+ //# sourceMappingURL=yaml.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"yaml.js","sourceRoot":"","sources":["../../src/exporter/yaml.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ import type { ApiCallAction, DomSnapshot, NetworkCall } from "../types.js";
2
+ export declare function extractApiCalls(networkCalls: NetworkCall[], pages: DomSnapshot[], baseUrl: string): ApiCallAction[];
3
+ //# sourceMappingURL=api-extractor.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"api-extractor.d.ts","sourceRoot":"","sources":["../../src/extractor/api-extractor.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,aAAa,EAAE,WAAW,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAwI3E,wBAAgB,eAAe,CAC7B,YAAY,EAAE,WAAW,EAAE,EAC3B,KAAK,EAAE,WAAW,EAAE,EACpB,OAAO,EAAE,MAAM,GACd,aAAa,EAAE,CA+BjB"}
@@ -0,0 +1,274 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.extractApiCalls = extractApiCalls;
4
+ const uuid_1 = require("uuid");
5
+ const BLOCKED_DOMAINS = [
6
+ "accounts.google.com",
7
+ "adnxs.com",
8
+ "adsrvr.org",
9
+ "akamai.net",
10
+ "akamaihd.net",
11
+ "akamaized.net",
12
+ "algolia.io",
13
+ "algolia.net",
14
+ "algolianet.com",
15
+ "amplitude.com",
16
+ "analytics.google.com",
17
+ "auth0.com",
18
+ "bugsnag.com",
19
+ "calendly.com",
20
+ "cdnjs.cloudflare.com",
21
+ "clarity.ms",
22
+ "clerk.com",
23
+ "clerk.dev",
24
+ "cloudflare-dns.com",
25
+ "cloudflare.com",
26
+ "cloudfront.net",
27
+ "crisp.chat",
28
+ "criteo.com",
29
+ "criteo.net",
30
+ "datadog-agent",
31
+ "datadoghq.com",
32
+ "doubleclick.net",
33
+ "drift.com",
34
+ "driftt.com",
35
+ "facebook.com",
36
+ "facebook.net",
37
+ "fastly.net",
38
+ "fbcdn.net",
39
+ "firebase.googleapis.com",
40
+ "firebaseapp.com",
41
+ "fontawesome.com",
42
+ "fonts.googleapis.com",
43
+ "fonts.gstatic.com",
44
+ "fullstory.com",
45
+ "google-analytics.com",
46
+ "googleapis.com",
47
+ "googleadservices.com",
48
+ "googlesyndication.com",
49
+ "googletagmanager.com",
50
+ "googlevideo.com",
51
+ "gotolstoy.com",
52
+ "gtag",
53
+ "gtm.js",
54
+ "heap.io",
55
+ "heapanalytics.com",
56
+ "hotjar.com",
57
+ "hotjar.io",
58
+ "hsforms.com",
59
+ "hubspot.com",
60
+ "hubspot.net",
61
+ "intercom.com",
62
+ "intercom.io",
63
+ "intercomcdn.com",
64
+ "jsdelivr.net",
65
+ "linkedin.com",
66
+ "logrocket.com",
67
+ "logrocket.io",
68
+ "mapbox.com",
69
+ "maps.google.com",
70
+ "maps.googleapis.com",
71
+ "meilisearch.com",
72
+ "mixpanel.com",
73
+ "newrelic.com",
74
+ "nr-data.net",
75
+ "outbrain.com",
76
+ "pinterest.com",
77
+ "posthog.com",
78
+ "raygun.com",
79
+ "rollbar.com",
80
+ "salesforce.com",
81
+ "segment.com",
82
+ "segment.io",
83
+ "cdn.segment.com",
84
+ "sentry-cdn.com",
85
+ "sentry.io",
86
+ "supabase.co",
87
+ "taboola.com",
88
+ "trackjs.com",
89
+ "twitter.com",
90
+ "typeform.com",
91
+ "typekit.com",
92
+ "typesense.org",
93
+ "unpkg.com",
94
+ "use.typekit.net",
95
+ "vidyard.com",
96
+ "vimeo.com",
97
+ "vimeocdn.com",
98
+ "wistia.com",
99
+ "wistia.net",
100
+ "x.com",
101
+ "youtu.be",
102
+ "youtube-nocookie.com",
103
+ "youtube.com",
104
+ "ytimg.com",
105
+ "zdassets.com",
106
+ "zendesk.com",
107
+ ];
108
+ const BLOCKED_URL_PATTERNS = [
109
+ /\/analytics/i,
110
+ /\/tracking/i,
111
+ /\/pixel/i,
112
+ /\/beacon/i,
113
+ /\/telemetry/i,
114
+ /\/collect\b/i,
115
+ /\/events?\//i,
116
+ /\/__analytics/i,
117
+ /\/log\b/i,
118
+ ];
119
+ const STATIC_PATHS = [
120
+ "/favicon.ico",
121
+ "/robots.txt",
122
+ "/sitemap.xml",
123
+ "/manifest.json",
124
+ "/sw.js",
125
+ "/service-worker.js",
126
+ ];
127
+ const FRAMEWORK_PREFIXES = [
128
+ "/_next/",
129
+ "/__nextjs_",
130
+ "/_nuxt/",
131
+ "/__webpack_",
132
+ "/hot-update",
133
+ "/.well-known/",
134
+ ];
135
+ function extractApiCalls(networkCalls, pages, baseUrl) {
136
+ const actions = [];
137
+ const baseHost = getHostname(baseUrl);
138
+ const relevantCalls = networkCalls.filter((call) => {
139
+ if (!isSameSite(call.url, baseHost))
140
+ return false;
141
+ if (isNoiseCall(call))
142
+ return false;
143
+ if (isStaticPath(call.url))
144
+ return false;
145
+ if (isRedirectOrEmpty(call))
146
+ return false;
147
+ return true;
148
+ });
149
+ const grouped = groupByEndpoint(relevantCalls);
150
+ for (const [key, calls] of grouped) {
151
+ const representative = calls[0];
152
+ if (isPageNavigation(representative, pages))
153
+ continue;
154
+ const pageUrl = findPageContext(representative, pages);
155
+ actions.push({
156
+ kind: "api_call",
157
+ id: (0, uuid_1.v4)(),
158
+ pageUrl: pageUrl || representative.url,
159
+ request: representative,
160
+ labels: buildLabels(representative),
161
+ });
162
+ }
163
+ return actions;
164
+ }
165
+ function getHostname(url) {
166
+ try {
167
+ return new URL(url).hostname;
168
+ }
169
+ catch {
170
+ return url;
171
+ }
172
+ }
173
+ function isSameSite(requestUrl, baseHost) {
174
+ try {
175
+ const callHost = new URL(requestUrl).hostname;
176
+ return (callHost === baseHost ||
177
+ callHost.endsWith("." + baseHost) ||
178
+ baseHost.endsWith("." + callHost));
179
+ }
180
+ catch {
181
+ return false;
182
+ }
183
+ }
184
+ function isNoiseCall(call) {
185
+ const url = call.url.toLowerCase();
186
+ if (BLOCKED_DOMAINS.some((d) => url.includes(d)))
187
+ return true;
188
+ if (BLOCKED_URL_PATTERNS.some((p) => p.test(url)))
189
+ return true;
190
+ return false;
191
+ }
192
+ function isStaticPath(url) {
193
+ try {
194
+ const path = new URL(url).pathname.toLowerCase();
195
+ if (STATIC_PATHS.includes(path))
196
+ return true;
197
+ if (FRAMEWORK_PREFIXES.some((p) => path.startsWith(p)))
198
+ return true;
199
+ return false;
200
+ }
201
+ catch {
202
+ return false;
203
+ }
204
+ }
205
+ function isRedirectOrEmpty(call) {
206
+ if (!call.status)
207
+ return false;
208
+ if (call.status >= 300 && call.status < 400)
209
+ return true;
210
+ if (call.status === 204)
211
+ return true;
212
+ return false;
213
+ }
214
+ function groupByEndpoint(calls) {
215
+ const map = new Map();
216
+ for (const call of calls) {
217
+ try {
218
+ const parsed = new URL(call.url);
219
+ const key = `${call.method}:${parsed.pathname}`;
220
+ if (!map.has(key)) {
221
+ map.set(key, []);
222
+ }
223
+ map.get(key).push(call);
224
+ }
225
+ catch {
226
+ // Invalid URL, skip
227
+ }
228
+ }
229
+ return map;
230
+ }
231
+ function isPageNavigation(call, pages) {
232
+ if (call.method !== "GET")
233
+ return false;
234
+ return pages.some((p) => {
235
+ try {
236
+ return new URL(p.url).pathname === new URL(call.url).pathname;
237
+ }
238
+ catch {
239
+ return false;
240
+ }
241
+ });
242
+ }
243
+ function findPageContext(call, pages) {
244
+ try {
245
+ const callOrigin = new URL(call.url).origin;
246
+ const matchingPage = pages.find((p) => {
247
+ try {
248
+ return new URL(p.url).origin === callOrigin;
249
+ }
250
+ catch {
251
+ return false;
252
+ }
253
+ });
254
+ return matchingPage?.url;
255
+ }
256
+ catch {
257
+ return undefined;
258
+ }
259
+ }
260
+ function buildLabels(call) {
261
+ const labels = [];
262
+ try {
263
+ const parsed = new URL(call.url);
264
+ labels.push(`${call.method} ${parsed.pathname}`);
265
+ }
266
+ catch {
267
+ labels.push(`${call.method} ${call.url}`);
268
+ }
269
+ if (call.operationName) {
270
+ labels.push(call.operationName);
271
+ }
272
+ return labels;
273
+ }
274
+ //# sourceMappingURL=api-extractor.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"api-extractor.js","sourceRoot":"","sources":["../../src/extractor/api-extractor.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ import type { ClickFlowAction, DomSnapshot } from "../types.js";
2
+ export declare function extractClickFlows(pages: DomSnapshot[]): ClickFlowAction[];
3
+ //# sourceMappingURL=click-extractor.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"click-extractor.d.ts","sourceRoot":"","sources":["../../src/extractor/click-extractor.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,eAAe,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAahE,wBAAgB,iBAAiB,CAC/B,KAAK,EAAE,WAAW,EAAE,GACnB,eAAe,EAAE,CAgCnB"}
@@ -0,0 +1,52 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.extractClickFlows = extractClickFlows;
4
+ const uuid_1 = require("uuid");
5
+ const NOISE_BUTTONS = [
6
+ "close", "dismiss", "cancel", "\u00d7", "\u2715", "\u2716",
7
+ "menu", "toggle", "hamburger", "sidebar",
8
+ "expand", "collapse", "more", "less", "show more", "show less",
9
+ "cookie", "accept", "reject", "consent", "got it", "i agree",
10
+ "ok", "okay", "yes", "no", "confirm",
11
+ "share", "tweet", "like", "follow",
12
+ "play", "pause", "mute", "unmute", "fullscreen",
13
+ "scroll", "back to top", "top",
14
+ ];
15
+ function extractClickFlows(pages) {
16
+ const actions = [];
17
+ for (const page of pages) {
18
+ const seenText = new Set();
19
+ for (const button of page.buttons) {
20
+ if (button.isInsideForm)
21
+ continue;
22
+ const label = button.text || button.ariaLabel || "";
23
+ if (!label || label.length < 2)
24
+ continue;
25
+ if (isNoiseButton(label))
26
+ continue;
27
+ const normalizedText = label.toLowerCase().trim();
28
+ if (seenText.has(normalizedText))
29
+ continue;
30
+ seenText.add(normalizedText);
31
+ actions.push({
32
+ kind: "click_flow",
33
+ id: (0, uuid_1.v4)(),
34
+ pageUrl: page.url,
35
+ startSelector: button.selector,
36
+ labels: [button.text, button.ariaLabel].filter((s) => !!s && s.trim().length > 0),
37
+ networkCalls: [],
38
+ });
39
+ }
40
+ }
41
+ return actions;
42
+ }
43
+ function isNoiseButton(text) {
44
+ const normalized = text.toLowerCase().trim();
45
+ if (NOISE_BUTTONS.includes(normalized))
46
+ return true;
47
+ // Single character buttons (x, arrows, etc.)
48
+ if (normalized.length === 1)
49
+ return true;
50
+ return false;
51
+ }
52
+ //# sourceMappingURL=click-extractor.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"click-extractor.js","sourceRoot":"","sources":["../../src/extractor/click-extractor.ts"],"names":[],"mappings":";;AAcA,8CAkCC;AAhDD,+BAAkC;AAGlC,MAAM,aAAa,GAAG;IACpB,OAAO,EAAE,SAAS,EAAE,QAAQ,EAAE,QAAQ,EAAE,QAAQ,EAAE,QAAQ;IAC1D,MAAM,EAAE,QAAQ,EAAE,WAAW,EAAE,SAAS;IACxC,QAAQ,EAAE,UAAU,EAAE,MAAM,EAAE,MAAM,EAAE,WAAW,EAAE,WAAW;IAC9D,QAAQ,EAAE,QAAQ,EAAE,QAAQ,EAAE,SAAS,EAAE,QAAQ,EAAE,SAAS;IAC5D,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,IAAI,EAAE,SAAS;IACpC,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,QAAQ;IAClC,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,YAAY;IAC/C,QAAQ,EAAE,aAAa,EAAE,KAAK;CAC/B,CAAC;AAEF,SAAgB,iBAAiB,CAC/B,KAAoB;IAEpB,MAAM,OAAO,GAAsB,EAAE,CAAC;IAEtC,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzB,MAAM,QAAQ,GAAG,IAAI,GAAG,EAAU,CAAC;QAEnC,KAAK,MAAM,MAAM,IAAI,IAAI,CAAC,OAAO,EAAE,CAAC;YAClC,IAAI,MAAM,CAAC,YAAY;gBAAE,SAAS;YAElC,MAAM,KAAK,GAAG,MAAM,CAAC,IAAI,IAAI,MAAM,CAAC,SAAS,IAAI,EAAE,CAAC;YACpD,IAAI,CAAC,KAAK,IAAI,KAAK,CAAC,MAAM,GAAG,CAAC;gBAAE,SAAS;YAEzC,IAAI,aAAa,CAAC,KAAK,CAAC;gBAAE,SAAS;YAEnC,MAAM,cAAc,GAAG,KAAK,CAAC,WAAW,EAAE,CAAC,IAAI,EAAE,CAAC;YAClD,IAAI,QAAQ,CAAC,GAAG,CAAC,cAAc,CAAC;gBAAE,SAAS;YAC3C,QAAQ,CAAC,GAAG,CAAC,cAAc,CAAC,CAAC;YAE7B,OAAO,CAAC,IAAI,CAAC;gBACX,IAAI,EAAE,YAAY;gBAClB,EAAE,EAAE,IAAA,SAAI,GAAE;gBACV,OAAO,EAAE,IAAI,CAAC,GAAG;gBACjB,aAAa,EAAE,MAAM,CAAC,QAAQ;gBAC9B,MAAM,EAAE,CAAC,MAAM,CAAC,IAAI,EAAE,MAAM,CAAC,SAAS,CAAC,CAAC,MAAM,CAC5C,CAAC,CAAC,EAAe,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,CAAC,MAAM,GAAG,CAAC,CAC/C;gBACD,YAAY,EAAE,EAAE;aACjB,CAAC,CAAC;QACL,CAAC;IACH,CAAC;IAED,OAAO,OAAO,CAAC;AACjB,CAAC;AAED,SAAS,aAAa,CAAC,IAAY;IACjC,MAAM,UAAU,GAAG,IAAI,CAAC,WAAW,EAAE,CAAC,IAAI,EAAE,CAAC;IAE7C,IAAI,aAAa,CAAC,QAAQ,CAAC,UAAU,CAAC;QAAE,OAAO,IAAI,CAAC;IAEpD,6CAA6C;IAC7C,IAAI,UAAU,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,IAAI,CAAC;IAEzC,OAAO,KAAK,CAAC;AACf,CAAC"}
@@ -0,0 +1,3 @@
1
+ import type { FormSubmitAction, DomSnapshot } from "../types.js";
2
+ export declare function extractForms(pages: DomSnapshot[]): FormSubmitAction[];
3
+ //# sourceMappingURL=form-extractor.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"form-extractor.d.ts","sourceRoot":"","sources":["../../src/extractor/form-extractor.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAU,gBAAgB,EAAE,WAAW,EAAW,MAAM,aAAa,CAAC;AAElF,wBAAgB,YAAY,CAAC,KAAK,EAAE,WAAW,EAAE,GAAG,gBAAgB,EAAE,CAuBrE"}
@@ -0,0 +1,27 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.extractForms = extractForms;
4
+ const uuid_1 = require("uuid");
5
+ function extractForms(pages) {
6
+ const actions = [];
7
+ for (const page of pages) {
8
+ for (const form of page.forms) {
9
+ if (form.fields.length === 0)
10
+ continue;
11
+ actions.push({
12
+ kind: "form_submit",
13
+ id: (0, uuid_1.v4)(),
14
+ pageUrl: page.url,
15
+ formSelector: form.selector,
16
+ fields: form.fields,
17
+ submitSelector: form.submitSelector || `${form.selector} button`,
18
+ labels: form.labels,
19
+ method: form.method || "POST",
20
+ action: form.action,
21
+ networkCalls: [],
22
+ });
23
+ }
24
+ }
25
+ return actions;
26
+ }
27
+ //# sourceMappingURL=form-extractor.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"form-extractor.js","sourceRoot":"","sources":["../../src/extractor/form-extractor.ts"],"names":[],"mappings":";;AAGA,oCAuBC;AA1BD,+BAAkC;AAGlC,SAAgB,YAAY,CAAC,KAAoB;IAC/C,MAAM,OAAO,GAAuB,EAAE,CAAC;IAEvC,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzB,KAAK,MAAM,IAAI,IAAI,IAAI,CAAC,KAAK,EAAE,CAAC;YAC9B,IAAI,IAAI,CAAC,MAAM,CAAC,MAAM,KAAK,CAAC;gBAAE,SAAS;YAEvC,OAAO,CAAC,IAAI,CAAC;gBACX,IAAI,EAAE,aAAa;gBACnB,EAAE,EAAE,IAAA,SAAI,GAAE;gBACV,OAAO,EAAE,IAAI,CAAC,GAAG;gBACjB,YAAY,EAAE,IAAI,CAAC,QAAQ;gBAC3B,MAAM,EAAE,IAAI,CAAC,MAAM;gBACnB,cAAc,EAAE,IAAI,CAAC,cAAc,IAAI,GAAG,IAAI,CAAC,QAAQ,SAAS;gBAChE,MAAM,EAAE,IAAI,CAAC,MAAM;gBACnB,MAAM,EAAG,IAAI,CAAC,MAAyB,IAAI,MAAM;gBACjD,MAAM,EAAE,IAAI,CAAC,MAAM;gBACnB,YAAY,EAAE,EAAE;aACjB,CAAC,CAAC;QACL,CAAC;IACH,CAAC;IAED,OAAO,OAAO,CAAC;AACjB,CAAC"}
@@ -0,0 +1,3 @@
1
+ import type { RouteChangeAction, DomSnapshot } from "../types.js";
2
+ export declare function extractRouteChanges(pages: DomSnapshot[]): RouteChangeAction[];
3
+ //# sourceMappingURL=route-extractor.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"route-extractor.d.ts","sourceRoot":"","sources":["../../src/extractor/route-extractor.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,iBAAiB,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AA0BlE,wBAAgB,mBAAmB,CACjC,KAAK,EAAE,WAAW,EAAE,GACnB,iBAAiB,EAAE,CAoCrB"}
@@ -0,0 +1,84 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.extractRouteChanges = extractRouteChanges;
4
+ const uuid_1 = require("uuid");
5
+ const NOISE_LINK_TEXTS = [
6
+ "login", "log in", "logout", "log out",
7
+ "signin", "sign in", "signout", "sign out",
8
+ "signup", "sign up", "register",
9
+ "terms", "terms of service", "terms of use", "terms & conditions",
10
+ "privacy", "privacy policy",
11
+ "cookie", "cookie policy", "cookie settings",
12
+ "legal", "disclaimer",
13
+ "sitemap", "site map",
14
+ "rss", "feed", "atom",
15
+ "skip to content", "skip navigation", "skip to main",
16
+ "back", "go back", "return",
17
+ ];
18
+ const NOISE_HREF_PATTERNS = [
19
+ "mailto:", "tel:", "javascript:",
20
+ "/login", "/logout", "/signin", "/signout",
21
+ "/signup", "/register",
22
+ "/terms", "/privacy", "/legal",
23
+ "/cookie", "/sitemap",
24
+ "/rss", "/feed",
25
+ "/cdn-cgi/",
26
+ ];
27
+ function extractRouteChanges(pages) {
28
+ const actions = [];
29
+ const seenTargets = new Set();
30
+ for (const page of pages) {
31
+ for (const link of page.links) {
32
+ if (!link.isInternal)
33
+ continue;
34
+ if (link.href.includes("#") && new URL(link.href).pathname === new URL(page.url).pathname)
35
+ continue;
36
+ const label = link.text || link.ariaLabel || "";
37
+ if (!label || label.length < 2)
38
+ continue;
39
+ if (isNoiseLink(label, link.href))
40
+ continue;
41
+ const normalizedTarget = normalizeUrl(link.href);
42
+ if (seenTargets.has(normalizedTarget))
43
+ continue;
44
+ if (normalizedTarget === normalizeUrl(page.url))
45
+ continue;
46
+ seenTargets.add(normalizedTarget);
47
+ actions.push({
48
+ kind: "route_change",
49
+ id: (0, uuid_1.v4)(),
50
+ from: page.url,
51
+ to: link.href,
52
+ trigger: link.selector,
53
+ labels: [link.text, link.ariaLabel].filter((s) => !!s && s.trim().length > 0),
54
+ });
55
+ }
56
+ }
57
+ return actions;
58
+ }
59
+ function isNoiseLink(text, href) {
60
+ const normalizedText = text.toLowerCase().trim();
61
+ const normalizedHref = href.toLowerCase();
62
+ if (NOISE_LINK_TEXTS.includes(normalizedText))
63
+ return true;
64
+ if (NOISE_HREF_PATTERNS.some((p) => normalizedHref.includes(p)))
65
+ return true;
66
+ return false;
67
+ }
68
+ function normalizeUrl(url) {
69
+ try {
70
+ const parsed = new URL(url);
71
+ parsed.hash = "";
72
+ parsed.search = "";
73
+ let path = parsed.pathname;
74
+ if (path.endsWith("/") && path !== "/") {
75
+ path = path.slice(0, -1);
76
+ }
77
+ parsed.pathname = path;
78
+ return parsed.toString();
79
+ }
80
+ catch {
81
+ return url;
82
+ }
83
+ }
84
+ //# sourceMappingURL=route-extractor.js.map