@tontoko/fast-playwright-mcp 0.0.4
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/LICENSE +202 -0
- package/README.md +1047 -0
- package/cli.js +18 -0
- package/config.d.ts +124 -0
- package/index.d.ts +25 -0
- package/index.js +18 -0
- package/lib/actions.d.js +0 -0
- package/lib/batch/batch-executor.js +137 -0
- package/lib/browser-context-factory.js +252 -0
- package/lib/browser-server-backend.js +139 -0
- package/lib/config/constants.js +80 -0
- package/lib/config.js +405 -0
- package/lib/context.js +274 -0
- package/lib/diagnostics/common/diagnostic-base.js +63 -0
- package/lib/diagnostics/common/error-enrichment-utils.js +212 -0
- package/lib/diagnostics/common/index.js +56 -0
- package/lib/diagnostics/common/initialization-manager.js +210 -0
- package/lib/diagnostics/common/performance-tracker.js +132 -0
- package/lib/diagnostics/diagnostic-error.js +140 -0
- package/lib/diagnostics/diagnostic-level.js +123 -0
- package/lib/diagnostics/diagnostic-thresholds.js +347 -0
- package/lib/diagnostics/element-discovery.js +441 -0
- package/lib/diagnostics/enhanced-error-handler.js +376 -0
- package/lib/diagnostics/error-enrichment.js +157 -0
- package/lib/diagnostics/frame-reference-manager.js +179 -0
- package/lib/diagnostics/page-analyzer.js +639 -0
- package/lib/diagnostics/parallel-page-analyzer.js +129 -0
- package/lib/diagnostics/resource-manager.js +134 -0
- package/lib/diagnostics/smart-config.js +482 -0
- package/lib/diagnostics/smart-handle.js +118 -0
- package/lib/diagnostics/unified-system.js +717 -0
- package/lib/extension/cdp-relay.js +486 -0
- package/lib/extension/extension-context-factory.js +74 -0
- package/lib/extension/main.js +41 -0
- package/lib/file-utils.js +42 -0
- package/lib/generate-keys.js +75 -0
- package/lib/http-server.js +50 -0
- package/lib/in-process-client.js +64 -0
- package/lib/index.js +48 -0
- package/lib/javascript.js +90 -0
- package/lib/log.js +33 -0
- package/lib/loop/loop-claude.js +247 -0
- package/lib/loop/loop-open-ai.js +222 -0
- package/lib/loop/loop.js +174 -0
- package/lib/loop/main.js +46 -0
- package/lib/loopTools/context.js +76 -0
- package/lib/loopTools/main.js +65 -0
- package/lib/loopTools/perform.js +40 -0
- package/lib/loopTools/snapshot.js +37 -0
- package/lib/loopTools/tool.js +26 -0
- package/lib/manual-promise.js +125 -0
- package/lib/mcp/in-process-transport.js +91 -0
- package/lib/mcp/proxy-backend.js +127 -0
- package/lib/mcp/server.js +123 -0
- package/lib/mcp/transport.js +159 -0
- package/lib/package.js +28 -0
- package/lib/program.js +82 -0
- package/lib/response.js +493 -0
- package/lib/schemas/expectation.js +152 -0
- package/lib/session-log.js +210 -0
- package/lib/tab.js +417 -0
- package/lib/tools/base-tool-handler.js +141 -0
- package/lib/tools/batch-execute.js +150 -0
- package/lib/tools/common.js +65 -0
- package/lib/tools/console.js +60 -0
- package/lib/tools/diagnose/diagnose-analysis-runner.js +101 -0
- package/lib/tools/diagnose/diagnose-config-handler.js +130 -0
- package/lib/tools/diagnose/diagnose-report-builder.js +394 -0
- package/lib/tools/diagnose.js +147 -0
- package/lib/tools/dialogs.js +57 -0
- package/lib/tools/evaluate.js +67 -0
- package/lib/tools/files.js +53 -0
- package/lib/tools/find-elements.js +307 -0
- package/lib/tools/install.js +60 -0
- package/lib/tools/keyboard.js +93 -0
- package/lib/tools/mouse.js +110 -0
- package/lib/tools/navigate.js +82 -0
- package/lib/tools/network.js +50 -0
- package/lib/tools/pdf.js +46 -0
- package/lib/tools/screenshot.js +113 -0
- package/lib/tools/snapshot.js +158 -0
- package/lib/tools/tabs.js +97 -0
- package/lib/tools/tool.js +47 -0
- package/lib/tools/utils.js +131 -0
- package/lib/tools/wait.js +64 -0
- package/lib/tools.js +65 -0
- package/lib/types/batch.js +47 -0
- package/lib/types/diff.js +0 -0
- package/lib/types/performance.js +0 -0
- package/lib/types/threshold-base.js +0 -0
- package/lib/utils/array-utils.js +44 -0
- package/lib/utils/code-deduplication-utils.js +141 -0
- package/lib/utils/common-formatters.js +252 -0
- package/lib/utils/console-filter.js +64 -0
- package/lib/utils/diagnostic-report-utils.js +178 -0
- package/lib/utils/diff-formatter.js +126 -0
- package/lib/utils/disposable-manager.js +135 -0
- package/lib/utils/error-handler-middleware.js +77 -0
- package/lib/utils/image-processor.js +137 -0
- package/lib/utils/index.js +92 -0
- package/lib/utils/report-builder.js +189 -0
- package/lib/utils/request-logger.js +82 -0
- package/lib/utils/response-diff-detector.js +150 -0
- package/lib/utils/section-builder.js +62 -0
- package/lib/utils/tool-patterns.js +153 -0
- package/lib/utils.js +46 -0
- package/package.json +77 -0
|
@@ -0,0 +1,150 @@
|
|
|
1
|
+
import { createRequire } from "node:module";
|
|
2
|
+
var __create = Object.create;
|
|
3
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
4
|
+
var __defProp = Object.defineProperty;
|
|
5
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
6
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
7
|
+
var __toESM = (mod, isNodeMode, target) => {
|
|
8
|
+
target = mod != null ? __create(__getProtoOf(mod)) : {};
|
|
9
|
+
const to = isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target;
|
|
10
|
+
for (let key of __getOwnPropNames(mod))
|
|
11
|
+
if (!__hasOwnProp.call(to, key))
|
|
12
|
+
__defProp(to, key, {
|
|
13
|
+
get: () => mod[key],
|
|
14
|
+
enumerable: true
|
|
15
|
+
});
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __require = /* @__PURE__ */ createRequire(import.meta.url);
|
|
19
|
+
|
|
20
|
+
// src/utils/response-diff-detector.ts
|
|
21
|
+
import { createHash } from "node:crypto";
|
|
22
|
+
import diff from "fast-diff";
|
|
23
|
+
import { DiffFormatter } from "./diff-formatter.js";
|
|
24
|
+
|
|
25
|
+
class ResponseDiffDetector {
|
|
26
|
+
storage = new Map;
|
|
27
|
+
formatter = new DiffFormatter;
|
|
28
|
+
detectDiff(current, toolName, options) {
|
|
29
|
+
const cacheKey = this.generateCacheKey(toolName);
|
|
30
|
+
const previous = this.storage.get(cacheKey);
|
|
31
|
+
if (!previous) {
|
|
32
|
+
this.storeResponse(current, toolName);
|
|
33
|
+
return {
|
|
34
|
+
hasDifference: false,
|
|
35
|
+
similarity: 1,
|
|
36
|
+
formattedDiff: "",
|
|
37
|
+
metadata: {
|
|
38
|
+
addedLines: 0,
|
|
39
|
+
removedLines: 0,
|
|
40
|
+
contextLines: 0,
|
|
41
|
+
totalLines: current.split(`
|
|
42
|
+
`).length
|
|
43
|
+
}
|
|
44
|
+
};
|
|
45
|
+
}
|
|
46
|
+
const diffSegments = this.calculateDiff(previous.content, current);
|
|
47
|
+
const similarity = this.calculateSimilarity(previous.content, current);
|
|
48
|
+
const hasDifference = similarity < 1 - options.threshold;
|
|
49
|
+
let formattedDiff = "";
|
|
50
|
+
const metadata = {
|
|
51
|
+
addedLines: 0,
|
|
52
|
+
removedLines: 0,
|
|
53
|
+
contextLines: 0,
|
|
54
|
+
totalLines: current.split(`
|
|
55
|
+
`).length
|
|
56
|
+
};
|
|
57
|
+
if (hasDifference) {
|
|
58
|
+
for (const segment of diffSegments) {
|
|
59
|
+
if (segment.type === "add") {
|
|
60
|
+
metadata.addedLines += segment.value.split(`
|
|
61
|
+
`).length - 1;
|
|
62
|
+
} else if (segment.type === "remove") {
|
|
63
|
+
metadata.removedLines += segment.value.split(`
|
|
64
|
+
`).length - 1;
|
|
65
|
+
} else {
|
|
66
|
+
metadata.contextLines += segment.value.split(`
|
|
67
|
+
`).length - 1;
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
switch (options.format) {
|
|
71
|
+
case "split":
|
|
72
|
+
formattedDiff = this.formatter.formatSplit(diffSegments);
|
|
73
|
+
break;
|
|
74
|
+
case "minimal":
|
|
75
|
+
formattedDiff = this.formatter.formatMinimal(diffSegments);
|
|
76
|
+
break;
|
|
77
|
+
default:
|
|
78
|
+
formattedDiff = this.formatter.formatUnified(diffSegments, options.context);
|
|
79
|
+
break;
|
|
80
|
+
}
|
|
81
|
+
if (formattedDiff.split(`
|
|
82
|
+
`).length > options.maxDiffLines) {
|
|
83
|
+
const lines = formattedDiff.split(`
|
|
84
|
+
`);
|
|
85
|
+
formattedDiff = lines.slice(0, options.maxDiffLines).join(`
|
|
86
|
+
`) + `
|
|
87
|
+
... (${lines.length - options.maxDiffLines} more lines truncated)`;
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
this.storeResponse(current, toolName);
|
|
91
|
+
return {
|
|
92
|
+
hasDifference,
|
|
93
|
+
similarity,
|
|
94
|
+
formattedDiff,
|
|
95
|
+
metadata
|
|
96
|
+
};
|
|
97
|
+
}
|
|
98
|
+
storeResponse(content, toolName) {
|
|
99
|
+
const cacheKey = this.generateCacheKey(toolName);
|
|
100
|
+
const hash = createHash("sha256").update(content).digest("hex");
|
|
101
|
+
this.storage.set(cacheKey, {
|
|
102
|
+
toolName,
|
|
103
|
+
timestamp: Date.now(),
|
|
104
|
+
content,
|
|
105
|
+
hash
|
|
106
|
+
});
|
|
107
|
+
}
|
|
108
|
+
generateCacheKey(toolName) {
|
|
109
|
+
return `diff_cache_${toolName}`;
|
|
110
|
+
}
|
|
111
|
+
calculateDiff(oldText, newText) {
|
|
112
|
+
const result = diff(oldText, newText);
|
|
113
|
+
return result.map(([type, value]) => {
|
|
114
|
+
let diffType = "equal";
|
|
115
|
+
if (type === -1) {
|
|
116
|
+
diffType = "remove";
|
|
117
|
+
} else if (type === 1) {
|
|
118
|
+
diffType = "add";
|
|
119
|
+
}
|
|
120
|
+
return {
|
|
121
|
+
type: diffType,
|
|
122
|
+
value
|
|
123
|
+
};
|
|
124
|
+
});
|
|
125
|
+
}
|
|
126
|
+
calculateSimilarity(text1, text2) {
|
|
127
|
+
if (text1 === text2) {
|
|
128
|
+
return 1;
|
|
129
|
+
}
|
|
130
|
+
if (text1.length === 0 && text2.length === 0) {
|
|
131
|
+
return 1;
|
|
132
|
+
}
|
|
133
|
+
if (text1.length === 0 || text2.length === 0) {
|
|
134
|
+
return 0;
|
|
135
|
+
}
|
|
136
|
+
const diffSegments = this.calculateDiff(text1, text2);
|
|
137
|
+
let equalChars = 0;
|
|
138
|
+
let totalChars = 0;
|
|
139
|
+
for (const segment of diffSegments) {
|
|
140
|
+
totalChars += segment.value.length;
|
|
141
|
+
if (segment.type === "equal") {
|
|
142
|
+
equalChars += segment.value.length;
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
return totalChars > 0 ? equalChars / totalChars : 0;
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
export {
|
|
149
|
+
ResponseDiffDetector
|
|
150
|
+
};
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import { createRequire } from "node:module";
|
|
2
|
+
var __create = Object.create;
|
|
3
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
4
|
+
var __defProp = Object.defineProperty;
|
|
5
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
6
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
7
|
+
var __toESM = (mod, isNodeMode, target) => {
|
|
8
|
+
target = mod != null ? __create(__getProtoOf(mod)) : {};
|
|
9
|
+
const to = isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target;
|
|
10
|
+
for (let key of __getOwnPropNames(mod))
|
|
11
|
+
if (!__hasOwnProp.call(to, key))
|
|
12
|
+
__defProp(to, key, {
|
|
13
|
+
get: () => mod[key],
|
|
14
|
+
enumerable: true
|
|
15
|
+
});
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __require = /* @__PURE__ */ createRequire(import.meta.url);
|
|
19
|
+
|
|
20
|
+
// src/utils/section-builder.ts
|
|
21
|
+
function buildDiagnosticSection(sections, title, content, level = 2) {
|
|
22
|
+
sections.push("");
|
|
23
|
+
sections.push(`${"#".repeat(level)} ${title}`);
|
|
24
|
+
if (typeof content === "function") {
|
|
25
|
+
content();
|
|
26
|
+
} else {
|
|
27
|
+
sections.push(...content);
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
function addKeyValuePairs(sections, pairs) {
|
|
31
|
+
for (const [key, value] of Object.entries(pairs)) {
|
|
32
|
+
sections.push(`- **${key}:** ${value}`);
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
function addListItems(sections, items, prefix = "-") {
|
|
36
|
+
for (const item of items) {
|
|
37
|
+
sections.push(`${prefix} ${item}`);
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
function addIfNotEmpty(sections, items, formatter) {
|
|
41
|
+
if (items.length > 0) {
|
|
42
|
+
for (const item of items) {
|
|
43
|
+
sections.push(formatter(item));
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
function buildPerformanceSection(sections, metrics) {
|
|
48
|
+
if (metrics.executionTime !== undefined) {
|
|
49
|
+
const icon = metrics.threshold && metrics.executionTime > metrics.threshold ? "⚠️" : "✅";
|
|
50
|
+
sections.push(`${icon} Execution time: ${metrics.executionTime}ms`);
|
|
51
|
+
if (metrics.threshold && metrics.executionTime > metrics.threshold) {
|
|
52
|
+
sections.push(`⚠️ Exceeded threshold (${metrics.threshold}ms)`);
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
export {
|
|
57
|
+
buildPerformanceSection,
|
|
58
|
+
buildDiagnosticSection,
|
|
59
|
+
addListItems,
|
|
60
|
+
addKeyValuePairs,
|
|
61
|
+
addIfNotEmpty
|
|
62
|
+
};
|
|
@@ -0,0 +1,153 @@
|
|
|
1
|
+
import { createRequire } from "node:module";
|
|
2
|
+
var __create = Object.create;
|
|
3
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
4
|
+
var __defProp = Object.defineProperty;
|
|
5
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
6
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
7
|
+
var __toESM = (mod, isNodeMode, target) => {
|
|
8
|
+
target = mod != null ? __create(__getProtoOf(mod)) : {};
|
|
9
|
+
const to = isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target;
|
|
10
|
+
for (let key of __getOwnPropNames(mod))
|
|
11
|
+
if (!__hasOwnProp.call(to, key))
|
|
12
|
+
__defProp(to, key, {
|
|
13
|
+
get: () => mod[key],
|
|
14
|
+
enumerable: true
|
|
15
|
+
});
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __require = /* @__PURE__ */ createRequire(import.meta.url);
|
|
19
|
+
|
|
20
|
+
// src/utils/tool-patterns.ts
|
|
21
|
+
import { BaseElementToolHandler } from "../tools/base-tool-handler.js";
|
|
22
|
+
import { getErrorMessage } from "./common-formatters.js";
|
|
23
|
+
var resolveElementLocator = async (tab, params) => {
|
|
24
|
+
|
|
25
|
+
class TempHandler extends BaseElementToolHandler {
|
|
26
|
+
constructor() {
|
|
27
|
+
super("temp");
|
|
28
|
+
}
|
|
29
|
+
executeToolLogic() {
|
|
30
|
+
return Promise.resolve();
|
|
31
|
+
}
|
|
32
|
+
resolveLocator(tabInstance, locatorParams) {
|
|
33
|
+
return this.resolveElementLocator(tabInstance, locatorParams);
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
return await new TempHandler().resolveLocator(tab, params);
|
|
37
|
+
};
|
|
38
|
+
var validateElementParams = (params) => {
|
|
39
|
+
|
|
40
|
+
class TempHandler extends BaseElementToolHandler {
|
|
41
|
+
constructor() {
|
|
42
|
+
super("temp");
|
|
43
|
+
}
|
|
44
|
+
executeToolLogic() {
|
|
45
|
+
return Promise.resolve();
|
|
46
|
+
}
|
|
47
|
+
validateParams(validationParams) {
|
|
48
|
+
this.validateElementParams(validationParams);
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
new TempHandler().validateParams(params);
|
|
52
|
+
};
|
|
53
|
+
function addToolErrorContext(response, error, toolName, params) {
|
|
54
|
+
const errorMessage = getErrorMessage(error);
|
|
55
|
+
response.addError(`Error in ${toolName}: ${errorMessage}`);
|
|
56
|
+
if (params?.element) {
|
|
57
|
+
response.addResult(`Element context: ${params.element}`);
|
|
58
|
+
}
|
|
59
|
+
if (params?.ref) {
|
|
60
|
+
response.addResult(`Reference: ${params.ref}`);
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
function applyCommonExpectations(response, expectation) {
|
|
64
|
+
if (expectation?.includeSnapshot !== false) {
|
|
65
|
+
response.setIncludeSnapshot();
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
async function waitForToolCompletion(tab, operation, toolName, operationName) {
|
|
69
|
+
try {
|
|
70
|
+
await tab.waitForCompletion(operation);
|
|
71
|
+
} catch (error) {
|
|
72
|
+
const opName = operationName ?? "operation";
|
|
73
|
+
throw new Error(`${toolName} ${opName} failed: ${getErrorMessage(error)}`);
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
function addOperationComment(response, operation, context) {
|
|
77
|
+
const comment = context ? `// ${operation} - ${context}` : `// ${operation}`;
|
|
78
|
+
response.addCode(comment);
|
|
79
|
+
}
|
|
80
|
+
function addMouseOperationComment(response, operation, params) {
|
|
81
|
+
if (params.element) {
|
|
82
|
+
addOperationComment(response, operation, `on ${params.element}`);
|
|
83
|
+
} else {
|
|
84
|
+
addOperationComment(response, operation, `at (${params.x}, ${params.y})`);
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
function addNavigationComment(response, operation, url) {
|
|
88
|
+
if (url) {
|
|
89
|
+
addOperationComment(response, operation, `to ${url}`);
|
|
90
|
+
} else {
|
|
91
|
+
addOperationComment(response, operation);
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
async function executeToolOperation(operation, toolName, response, params) {
|
|
95
|
+
try {
|
|
96
|
+
return await operation();
|
|
97
|
+
} catch (error) {
|
|
98
|
+
addToolErrorContext(response, error, toolName, params);
|
|
99
|
+
throw error;
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
function setupToolResponse(response, params) {
|
|
103
|
+
applyCommonExpectations(response, params.expectation);
|
|
104
|
+
}
|
|
105
|
+
async function validateAndResolveElement(tab, params) {
|
|
106
|
+
validateElementParams(params);
|
|
107
|
+
return await resolveElementLocator(tab, params);
|
|
108
|
+
}
|
|
109
|
+
var ToolPatterns = {
|
|
110
|
+
Mouse: {
|
|
111
|
+
addComment: addMouseOperationComment,
|
|
112
|
+
validate: (params) => {
|
|
113
|
+
if (params.x < 0 || params.y < 0) {
|
|
114
|
+
throw new Error("Mouse coordinates must be non-negative");
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
},
|
|
118
|
+
Navigation: {
|
|
119
|
+
addComment: addNavigationComment,
|
|
120
|
+
validateUrl: (url) => {
|
|
121
|
+
try {
|
|
122
|
+
new URL(url);
|
|
123
|
+
} catch {
|
|
124
|
+
throw new Error(`Invalid URL: ${url}`);
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
},
|
|
128
|
+
Element: {
|
|
129
|
+
validateAndResolve: validateAndResolveElement,
|
|
130
|
+
addErrorContext: (response, error, toolName, element) => {
|
|
131
|
+
const errorMsg = getErrorMessage(error);
|
|
132
|
+
response.addResult(`${toolName} failed: ${errorMsg}`);
|
|
133
|
+
if (element) {
|
|
134
|
+
response.addResult(`Target element: ${element}`);
|
|
135
|
+
response.addResult("Suggestion: Verify element is visible and interactable");
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
};
|
|
140
|
+
export {
|
|
141
|
+
waitForToolCompletion,
|
|
142
|
+
validateElementParams,
|
|
143
|
+
validateAndResolveElement,
|
|
144
|
+
setupToolResponse,
|
|
145
|
+
resolveElementLocator,
|
|
146
|
+
executeToolOperation,
|
|
147
|
+
applyCommonExpectations,
|
|
148
|
+
addToolErrorContext,
|
|
149
|
+
addOperationComment,
|
|
150
|
+
addNavigationComment,
|
|
151
|
+
addMouseOperationComment,
|
|
152
|
+
ToolPatterns
|
|
153
|
+
};
|
package/lib/utils.js
ADDED
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import { createRequire } from "node:module";
|
|
2
|
+
var __create = Object.create;
|
|
3
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
4
|
+
var __defProp = Object.defineProperty;
|
|
5
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
6
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
7
|
+
var __toESM = (mod, isNodeMode, target) => {
|
|
8
|
+
target = mod != null ? __create(__getProtoOf(mod)) : {};
|
|
9
|
+
const to = isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target;
|
|
10
|
+
for (let key of __getOwnPropNames(mod))
|
|
11
|
+
if (!__hasOwnProp.call(to, key))
|
|
12
|
+
__defProp(to, key, {
|
|
13
|
+
get: () => mod[key],
|
|
14
|
+
enumerable: true
|
|
15
|
+
});
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __require = /* @__PURE__ */ createRequire(import.meta.url);
|
|
19
|
+
|
|
20
|
+
// src/utils.ts
|
|
21
|
+
import { createHash as cryptoCreateHash } from "node:crypto";
|
|
22
|
+
function createHash(data) {
|
|
23
|
+
return cryptoCreateHash("sha256").update(data).digest("hex").slice(0, 7);
|
|
24
|
+
}
|
|
25
|
+
var UNSAFE_FILENAME_CHARS = /[<>:"/\\|?*]+/g;
|
|
26
|
+
function removeControlCharacters(str) {
|
|
27
|
+
return str.split("").map((char) => {
|
|
28
|
+
const code = char.charCodeAt(0);
|
|
29
|
+
return code >= 0 && code <= 31 || code === 127 ? "-" : char;
|
|
30
|
+
}).join("");
|
|
31
|
+
}
|
|
32
|
+
function sanitizeForFilePath(input) {
|
|
33
|
+
const sanitize = (str) => {
|
|
34
|
+
const cleanStr = removeControlCharacters(str);
|
|
35
|
+
return cleanStr.replace(UNSAFE_FILENAME_CHARS, "-");
|
|
36
|
+
};
|
|
37
|
+
const separator = input.lastIndexOf(".");
|
|
38
|
+
if (separator === -1) {
|
|
39
|
+
return sanitize(input);
|
|
40
|
+
}
|
|
41
|
+
return sanitize(input.substring(0, separator)) + "." + sanitize(input.substring(separator + 1));
|
|
42
|
+
}
|
|
43
|
+
export {
|
|
44
|
+
sanitizeForFilePath,
|
|
45
|
+
createHash
|
|
46
|
+
};
|
package/package.json
ADDED
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@tontoko/fast-playwright-mcp",
|
|
3
|
+
"version": "0.0.4",
|
|
4
|
+
"publishConfig": {
|
|
5
|
+
"access": "public"
|
|
6
|
+
},
|
|
7
|
+
"description": "Fast Playwright Tools for MCP",
|
|
8
|
+
"type": "module",
|
|
9
|
+
"repository": {
|
|
10
|
+
"type": "git",
|
|
11
|
+
"url": "https://github.com/tontoko/fast-playwright-mcp"
|
|
12
|
+
},
|
|
13
|
+
"homepage": "https://playwright.dev",
|
|
14
|
+
"engines": {
|
|
15
|
+
"node": ">=18"
|
|
16
|
+
},
|
|
17
|
+
"author": {
|
|
18
|
+
"name": "Microsoft Corporation"
|
|
19
|
+
},
|
|
20
|
+
"license": "Apache-2.0",
|
|
21
|
+
"scripts": {
|
|
22
|
+
"build": "bun build ./src/**/**/*.ts ./src/**/*.ts ./src/*.ts --outdir ./lib --root ./src --target node --format esm --external '*'",
|
|
23
|
+
"build:publish": "bun build ./src/**/**/*.ts ./src/**/*.ts ./src/*.ts --outdir ./lib --root ./src --target node --format esm --external '*'",
|
|
24
|
+
"benchmark": "bun benchmark/src/index.ts",
|
|
25
|
+
"benchmark:verbose": "bun benchmark/src/index.ts --verbose",
|
|
26
|
+
"benchmark:quiet": "bun benchmark/src/index.ts --quiet",
|
|
27
|
+
"lint": "ultracite lint",
|
|
28
|
+
"lint-fix": "ultracite format",
|
|
29
|
+
"update-readme": "bun utils/update-readme.js",
|
|
30
|
+
"watch": "tsc --watch",
|
|
31
|
+
"test": "playwright test",
|
|
32
|
+
"ctest": "playwright test --project=chrome",
|
|
33
|
+
"ftest": "playwright test --project=firefox",
|
|
34
|
+
"wtest": "playwright test --project=webkit",
|
|
35
|
+
"run-server": "bun lib/browserServer.js",
|
|
36
|
+
"clean": "rm -rf lib benchmark/lib",
|
|
37
|
+
"npm-publish": "npm run clean && npm run build:publish && npm run test && npm publish"
|
|
38
|
+
},
|
|
39
|
+
"exports": {
|
|
40
|
+
"./package.json": "./package.json",
|
|
41
|
+
".": {
|
|
42
|
+
"types": "./index.d.ts",
|
|
43
|
+
"default": "./index.js"
|
|
44
|
+
}
|
|
45
|
+
},
|
|
46
|
+
"dependencies": {
|
|
47
|
+
"@modelcontextprotocol/sdk": "^1.16.0",
|
|
48
|
+
"@types/sharp": "^0.31.1",
|
|
49
|
+
"commander": "^13.1.0",
|
|
50
|
+
"debug": "^4.4.1",
|
|
51
|
+
"dotenv": "^17.2.0",
|
|
52
|
+
"fast-diff": "^1.3.0",
|
|
53
|
+
"mime": "^4.0.7",
|
|
54
|
+
"playwright": "1.55.0-alpha-2025-08-07",
|
|
55
|
+
"playwright-core": "1.55.0-alpha-2025-08-07",
|
|
56
|
+
"sharp": "^0.34.3",
|
|
57
|
+
"ws": "^8.18.1",
|
|
58
|
+
"zod": "^3.24.1",
|
|
59
|
+
"zod-to-json-schema": "^3.24.4"
|
|
60
|
+
},
|
|
61
|
+
"devDependencies": {
|
|
62
|
+
"@anthropic-ai/sdk": "^0.57.0",
|
|
63
|
+
"@biomejs/biome": "2.1.2",
|
|
64
|
+
"@playwright/test": "1.55.0-alpha-2025-08-07",
|
|
65
|
+
"@types/debug": "^4.1.12",
|
|
66
|
+
"@types/node": "^22.13.10",
|
|
67
|
+
"@types/ws": "^8.18.1",
|
|
68
|
+
"@typescript/native-preview": "^7.0.0-dev.20250808.1",
|
|
69
|
+
"esbuild": "^0.20.1",
|
|
70
|
+
"lefthook": "^1.12.2",
|
|
71
|
+
"openai": "^5.10.2",
|
|
72
|
+
"ultracite": "5.1.2"
|
|
73
|
+
},
|
|
74
|
+
"bin": {
|
|
75
|
+
"mcp-server-playwright": "cli.js"
|
|
76
|
+
}
|
|
77
|
+
}
|