@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.
Files changed (107) hide show
  1. package/LICENSE +202 -0
  2. package/README.md +1047 -0
  3. package/cli.js +18 -0
  4. package/config.d.ts +124 -0
  5. package/index.d.ts +25 -0
  6. package/index.js +18 -0
  7. package/lib/actions.d.js +0 -0
  8. package/lib/batch/batch-executor.js +137 -0
  9. package/lib/browser-context-factory.js +252 -0
  10. package/lib/browser-server-backend.js +139 -0
  11. package/lib/config/constants.js +80 -0
  12. package/lib/config.js +405 -0
  13. package/lib/context.js +274 -0
  14. package/lib/diagnostics/common/diagnostic-base.js +63 -0
  15. package/lib/diagnostics/common/error-enrichment-utils.js +212 -0
  16. package/lib/diagnostics/common/index.js +56 -0
  17. package/lib/diagnostics/common/initialization-manager.js +210 -0
  18. package/lib/diagnostics/common/performance-tracker.js +132 -0
  19. package/lib/diagnostics/diagnostic-error.js +140 -0
  20. package/lib/diagnostics/diagnostic-level.js +123 -0
  21. package/lib/diagnostics/diagnostic-thresholds.js +347 -0
  22. package/lib/diagnostics/element-discovery.js +441 -0
  23. package/lib/diagnostics/enhanced-error-handler.js +376 -0
  24. package/lib/diagnostics/error-enrichment.js +157 -0
  25. package/lib/diagnostics/frame-reference-manager.js +179 -0
  26. package/lib/diagnostics/page-analyzer.js +639 -0
  27. package/lib/diagnostics/parallel-page-analyzer.js +129 -0
  28. package/lib/diagnostics/resource-manager.js +134 -0
  29. package/lib/diagnostics/smart-config.js +482 -0
  30. package/lib/diagnostics/smart-handle.js +118 -0
  31. package/lib/diagnostics/unified-system.js +717 -0
  32. package/lib/extension/cdp-relay.js +486 -0
  33. package/lib/extension/extension-context-factory.js +74 -0
  34. package/lib/extension/main.js +41 -0
  35. package/lib/file-utils.js +42 -0
  36. package/lib/generate-keys.js +75 -0
  37. package/lib/http-server.js +50 -0
  38. package/lib/in-process-client.js +64 -0
  39. package/lib/index.js +48 -0
  40. package/lib/javascript.js +90 -0
  41. package/lib/log.js +33 -0
  42. package/lib/loop/loop-claude.js +247 -0
  43. package/lib/loop/loop-open-ai.js +222 -0
  44. package/lib/loop/loop.js +174 -0
  45. package/lib/loop/main.js +46 -0
  46. package/lib/loopTools/context.js +76 -0
  47. package/lib/loopTools/main.js +65 -0
  48. package/lib/loopTools/perform.js +40 -0
  49. package/lib/loopTools/snapshot.js +37 -0
  50. package/lib/loopTools/tool.js +26 -0
  51. package/lib/manual-promise.js +125 -0
  52. package/lib/mcp/in-process-transport.js +91 -0
  53. package/lib/mcp/proxy-backend.js +127 -0
  54. package/lib/mcp/server.js +123 -0
  55. package/lib/mcp/transport.js +159 -0
  56. package/lib/package.js +28 -0
  57. package/lib/program.js +82 -0
  58. package/lib/response.js +493 -0
  59. package/lib/schemas/expectation.js +152 -0
  60. package/lib/session-log.js +210 -0
  61. package/lib/tab.js +417 -0
  62. package/lib/tools/base-tool-handler.js +141 -0
  63. package/lib/tools/batch-execute.js +150 -0
  64. package/lib/tools/common.js +65 -0
  65. package/lib/tools/console.js +60 -0
  66. package/lib/tools/diagnose/diagnose-analysis-runner.js +101 -0
  67. package/lib/tools/diagnose/diagnose-config-handler.js +130 -0
  68. package/lib/tools/diagnose/diagnose-report-builder.js +394 -0
  69. package/lib/tools/diagnose.js +147 -0
  70. package/lib/tools/dialogs.js +57 -0
  71. package/lib/tools/evaluate.js +67 -0
  72. package/lib/tools/files.js +53 -0
  73. package/lib/tools/find-elements.js +307 -0
  74. package/lib/tools/install.js +60 -0
  75. package/lib/tools/keyboard.js +93 -0
  76. package/lib/tools/mouse.js +110 -0
  77. package/lib/tools/navigate.js +82 -0
  78. package/lib/tools/network.js +50 -0
  79. package/lib/tools/pdf.js +46 -0
  80. package/lib/tools/screenshot.js +113 -0
  81. package/lib/tools/snapshot.js +158 -0
  82. package/lib/tools/tabs.js +97 -0
  83. package/lib/tools/tool.js +47 -0
  84. package/lib/tools/utils.js +131 -0
  85. package/lib/tools/wait.js +64 -0
  86. package/lib/tools.js +65 -0
  87. package/lib/types/batch.js +47 -0
  88. package/lib/types/diff.js +0 -0
  89. package/lib/types/performance.js +0 -0
  90. package/lib/types/threshold-base.js +0 -0
  91. package/lib/utils/array-utils.js +44 -0
  92. package/lib/utils/code-deduplication-utils.js +141 -0
  93. package/lib/utils/common-formatters.js +252 -0
  94. package/lib/utils/console-filter.js +64 -0
  95. package/lib/utils/diagnostic-report-utils.js +178 -0
  96. package/lib/utils/diff-formatter.js +126 -0
  97. package/lib/utils/disposable-manager.js +135 -0
  98. package/lib/utils/error-handler-middleware.js +77 -0
  99. package/lib/utils/image-processor.js +137 -0
  100. package/lib/utils/index.js +92 -0
  101. package/lib/utils/report-builder.js +189 -0
  102. package/lib/utils/request-logger.js +82 -0
  103. package/lib/utils/response-diff-detector.js +150 -0
  104. package/lib/utils/section-builder.js +62 -0
  105. package/lib/utils/tool-patterns.js +153 -0
  106. package/lib/utils.js +46 -0
  107. package/package.json +77 -0
@@ -0,0 +1,394 @@
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/tools/diagnose/diagnose-report-builder.ts
21
+ import { ElementDiscovery } from "../../diagnostics/element-discovery.js";
22
+ import { ArrayBuilder } from "../../utils/code-deduplication-utils.js";
23
+ import {
24
+ formatPerformanceComparison,
25
+ formatStatusString,
26
+ getErrorMessage,
27
+ processBrowserMetrics
28
+ } from "../../utils/common-formatters.js";
29
+ import {
30
+ addDomComplexityMetrics,
31
+ addElementList as addElementListUtil,
32
+ addErrorSection,
33
+ addInteractionMetrics,
34
+ addKeyValuePairs as addKeyValuePairsUtil,
35
+ addModalStatesIfPresent,
36
+ addOptionalListSection as addOptionalListSectionUtil,
37
+ addResourceMetrics,
38
+ addSystemHealthSection
39
+ } from "../../utils/diagnostic-report-utils.js";
40
+ import { DiagnosticReportBuilder } from "../../utils/report-builder.js";
41
+
42
+ class DiagnoseReportBuilder {
43
+ reportBuilder;
44
+ tab;
45
+ constructor(tab) {
46
+ this.tab = tab;
47
+ this.reportBuilder = new DiagnosticReportBuilder;
48
+ }
49
+ addKeyValuePairs(pairs, headerText, subHeaderText, headerLevel = 2) {
50
+ if (headerText) {
51
+ this.reportBuilder.addHeader(headerText, 1).addEmptyLine();
52
+ }
53
+ if (subHeaderText) {
54
+ this.reportBuilder.addHeader(subHeaderText, headerLevel);
55
+ }
56
+ addKeyValuePairsUtil(this.reportBuilder, pairs.map(([key, value]) => ({ key, value })));
57
+ this.reportBuilder.addEmptyLine();
58
+ }
59
+ addOptionalListSection(title, items, formatter, headerLevel = 2) {
60
+ addOptionalListSectionUtil(this.reportBuilder, title, items, formatter, headerLevel);
61
+ }
62
+ shouldIncludeSection(options, section) {
63
+ const sectionConfig = {
64
+ accessibility: options.includeAccessibilityInfo || options.diagnosticLevel === "full",
65
+ performance: options.includePerformanceMetrics || options.diagnosticLevel === "detailed" || options.diagnosticLevel === "full",
66
+ troubleshooting: options.includeTroubleshootingSuggestions || ["standard", "detailed", "full"].includes(options.diagnosticLevel)
67
+ };
68
+ return sectionConfig[section] && options.diagnosticLevel !== "basic";
69
+ }
70
+ addElementList(title, elements, formatter, maxItems = 5) {
71
+ addElementListUtil(this.reportBuilder, title, elements, formatter, maxItems);
72
+ }
73
+ async buildReport(analysisResult, unifiedSystem, pageAnalyzer, options) {
74
+ this.reportBuilder.clear();
75
+ if (options.diagnosticLevel === "none") {
76
+ return "Diagnostics disabled (level: none)";
77
+ }
78
+ this.addReportHeader(analysisResult, unifiedSystem, options);
79
+ await this.addPageStructureSection(analysisResult.diagnosticInfo, options);
80
+ this.addModalStatesSection(analysisResult.diagnosticInfo);
81
+ await this.addElementSearchSection(options);
82
+ await this.addPerformanceSection(analysisResult, unifiedSystem, pageAnalyzer, options);
83
+ await this.addAccessibilitySection(analysisResult.diagnosticInfo, options);
84
+ this.addTroubleshootingSection(analysisResult.diagnosticInfo, options);
85
+ return this.reportBuilder.build();
86
+ }
87
+ addReportHeader(analysisResult, unifiedSystem, options) {
88
+ if (unifiedSystem) {
89
+ this.addKeyValuePairs([
90
+ [
91
+ "Unified System Status",
92
+ "Active with enhanced error handling and monitoring"
93
+ ],
94
+ [
95
+ "Configuration",
96
+ options.appliedOverrides?.length ? "Custom overrides applied" : "Default settings"
97
+ ],
98
+ ["Analysis Type", analysisResult.analysisType],
99
+ ["Analysis Status", analysisResult.analysisStatus]
100
+ ], "Unified Diagnostic System Report");
101
+ this.addOptionalListSection("Applied Configuration Overrides", options.appliedOverrides, (item) => `**${item}**`);
102
+ this.addOptionalListSection("Analysis Warnings", analysisResult.errors, (item) => `**${item}**`);
103
+ this.addSystemHealthSection(analysisResult, unifiedSystem, options);
104
+ }
105
+ }
106
+ addSystemHealthSection(analysisResult, unifiedSystem, options) {
107
+ if (!(options.includeSystemStats && analysisResult.systemHealthInfo)) {
108
+ return;
109
+ }
110
+ const systemHealthInfo = analysisResult.systemHealthInfo;
111
+ const systemStats = unifiedSystem.getSystemStats();
112
+ addSystemHealthSection(this.reportBuilder, {
113
+ status: systemHealthInfo.status,
114
+ totalOperations: systemStats.performanceMetrics.totalOperations,
115
+ successRate: systemStats.performanceMetrics.successRate,
116
+ activeHandles: systemStats.resourceUsage.currentHandles,
117
+ totalErrors: Object.values(systemStats.errorCount).reduce((sum, count) => sum + count, 0)
118
+ });
119
+ this.addConfigurationImpactSection(unifiedSystem, options);
120
+ this.addSystemIssuesAndRecommendations(systemHealthInfo);
121
+ }
122
+ addConfigurationImpactSection(unifiedSystem, options) {
123
+ if (!options.appliedOverrides?.length) {
124
+ return;
125
+ }
126
+ const configReport = unifiedSystem.getConfigurationReport();
127
+ this.reportBuilder.addSection("Configuration Impact Analysis", (builder) => {
128
+ builder.addKeyValue("Configuration Status", configReport.configurationStatus.replace("-", " ").replace(/\b\w/g, (l) => l.toUpperCase()));
129
+ }, 3);
130
+ this.addPerformanceBaselineComparison(configReport);
131
+ this.addAppliedOverridesDetails(configReport);
132
+ this.addHighPriorityRecommendations(configReport);
133
+ }
134
+ addPerformanceBaselineComparison(configReport) {
135
+ const { expectedExecutionTimes, actualAverages, deviations } = configReport.performanceBaseline;
136
+ const hasActualData = Object.values(actualAverages).some((val) => val > 0);
137
+ if (!hasActualData) {
138
+ return;
139
+ }
140
+ this.reportBuilder.addEmptyLine().addLine("**Performance Baseline Comparison:**");
141
+ for (const component of Object.keys(expectedExecutionTimes)) {
142
+ const expected = expectedExecutionTimes[component];
143
+ const actual = actualAverages[component];
144
+ const deviation = deviations[component];
145
+ if (actual > 0) {
146
+ this.reportBuilder.addLine(formatPerformanceComparison(component, expected, actual, deviation));
147
+ }
148
+ }
149
+ }
150
+ addAppliedOverridesDetails(configReport) {
151
+ if (configReport.appliedOverrides.length === 0) {
152
+ return;
153
+ }
154
+ this.reportBuilder.addEmptyLine().addLine("**Applied Configuration Changes:**");
155
+ for (const override of configReport.appliedOverrides) {
156
+ this.reportBuilder.addLine(formatStatusString(`**${override.category}**`, override.impact, "impact", `(${override.impact} impact):`));
157
+ for (const change of override.changes) {
158
+ this.reportBuilder.addLine(` - ${change}`);
159
+ }
160
+ }
161
+ }
162
+ addHighPriorityRecommendations(configReport) {
163
+ const highPriorityRecs = configReport.recommendations.filter((r) => r.priority === "high");
164
+ if (highPriorityRecs.length === 0) {
165
+ return;
166
+ }
167
+ this.reportBuilder.addEmptyLine().addLine("**High Priority Recommendations:**");
168
+ for (const rec of highPriorityRecs) {
169
+ this.reportBuilder.addLine(formatStatusString(rec.message, rec.type, "recommendation"));
170
+ }
171
+ }
172
+ addSystemIssuesAndRecommendations(systemHealthInfo) {
173
+ this.addOptionalListSection("System Issues", systemHealthInfo.issues, (item) => `⚠️ ${item}`, 3);
174
+ this.addOptionalListSection("System Recommendations", systemHealthInfo.recommendations, (item) => `\uD83D\uDCA1 ${item}`, 3);
175
+ this.reportBuilder.addEmptyLine();
176
+ }
177
+ async addPageStructureSection(diagnosticInfo, options) {
178
+ const isBasic = options.diagnosticLevel === "basic";
179
+ const title = isBasic ? "Basic Diagnostic Report" : "Page Diagnostic Report";
180
+ const url = this.tab.page.url();
181
+ const basicKeyValues = [["URL", url]];
182
+ if (!isBasic) {
183
+ basicKeyValues.push(["Title", await this.tab.page.title()]);
184
+ }
185
+ this.addKeyValuePairs(basicKeyValues, title);
186
+ if (isBasic) {
187
+ this.addBasicDiagnosticInfo(diagnosticInfo);
188
+ } else {
189
+ this.addDetailedPageStructure(diagnosticInfo);
190
+ }
191
+ }
192
+ addBasicDiagnosticInfo(diagnosticInfo) {
193
+ this.reportBuilder.addHeader("Critical Information", 2);
194
+ const criticalInfo = [
195
+ [
196
+ "IFrames detected",
197
+ diagnosticInfo.iframes.count,
198
+ diagnosticInfo.iframes.detected
199
+ ],
200
+ [
201
+ "Active modals",
202
+ diagnosticInfo.modalStates.blockedBy.join(", "),
203
+ diagnosticInfo.modalStates.blockedBy.length > 0
204
+ ],
205
+ [
206
+ "Interactable elements",
207
+ diagnosticInfo.elements.totalInteractable,
208
+ true
209
+ ]
210
+ ];
211
+ for (const [key, value, condition] of criticalInfo) {
212
+ if (condition) {
213
+ this.reportBuilder.addKeyValue(key, value);
214
+ }
215
+ }
216
+ this.reportBuilder.addEmptyLine();
217
+ }
218
+ addDetailedPageStructure(diagnosticInfo) {
219
+ this.reportBuilder.addHeader("Page Structure Analysis", 2);
220
+ const structureData = [
221
+ [
222
+ "IFrames",
223
+ `${diagnosticInfo.iframes.count} iframes detected: ${diagnosticInfo.iframes.detected}`
224
+ ],
225
+ ["Accessible iframes", diagnosticInfo.iframes.accessible.length],
226
+ ["Inaccessible iframes", diagnosticInfo.iframes.inaccessible.length]
227
+ ];
228
+ this.addKeyValuePairs(structureData);
229
+ const elementData = [
230
+ ["Total visible elements", diagnosticInfo.elements.totalVisible],
231
+ [
232
+ "Total interactable elements",
233
+ diagnosticInfo.elements.totalInteractable
234
+ ],
235
+ ["Elements missing ARIA", diagnosticInfo.elements.missingAria]
236
+ ];
237
+ this.addKeyValuePairs(elementData);
238
+ }
239
+ addModalStatesSection(diagnosticInfo) {
240
+ addModalStatesIfPresent(this.reportBuilder, diagnosticInfo.modalStates);
241
+ }
242
+ async addElementSearchSection(options) {
243
+ if (!options.searchForElements || options.diagnosticLevel === "basic") {
244
+ return;
245
+ }
246
+ const elementDiscovery = new ElementDiscovery(this.tab.page);
247
+ const foundElements = await elementDiscovery.findAlternativeElements({
248
+ originalSelector: "",
249
+ searchCriteria: options.searchForElements,
250
+ maxResults: 10
251
+ });
252
+ this.reportBuilder.addHeader("Element Search Results", 2);
253
+ if (foundElements.length === 0) {
254
+ this.reportBuilder.addListItem("No elements found matching the search criteria");
255
+ } else {
256
+ this.reportBuilder.addLine(`Found ${foundElements.length} matching elements:`);
257
+ for (let index = 0;index < foundElements.length; index++) {
258
+ const element = foundElements[index];
259
+ this.reportBuilder.addLine(`${index + 1}. **${element.selector}** (${(element.confidence * 100).toFixed(0)}% confidence)`);
260
+ this.reportBuilder.addLine(` - ${element.reason}`);
261
+ }
262
+ }
263
+ this.reportBuilder.addEmptyLine();
264
+ }
265
+ async addPerformanceSection(analysisResult, unifiedSystem, pageAnalyzer, options) {
266
+ const shouldIncludeMetrics = (options.includePerformanceMetrics || options.diagnosticLevel === "detailed" || options.diagnosticLevel === "full") && options.diagnosticLevel !== "basic";
267
+ if (!shouldIncludeMetrics) {
268
+ return;
269
+ }
270
+ const diagnosisTime = Date.now() - options.startTime;
271
+ this.reportBuilder.addHeader("Performance Metrics", 2).addKeyValue("Diagnosis execution time", `${diagnosisTime}ms`);
272
+ try {
273
+ const comprehensiveMetrics = await this.getComprehensiveMetrics(analysisResult, unifiedSystem, pageAnalyzer);
274
+ addDomComplexityMetrics(this.reportBuilder, comprehensiveMetrics);
275
+ addInteractionMetrics(this.reportBuilder, comprehensiveMetrics);
276
+ addResourceMetrics(this.reportBuilder, comprehensiveMetrics);
277
+ if (options.diagnosticLevel === "full") {
278
+ this.addLayoutMetrics(comprehensiveMetrics);
279
+ }
280
+ this.addPerformanceWarnings(comprehensiveMetrics);
281
+ } catch (error) {
282
+ addErrorSection(this.reportBuilder, error, "analyzing performance metrics");
283
+ }
284
+ await this.addBrowserPerformanceMetrics();
285
+ this.reportBuilder.addEmptyLine();
286
+ }
287
+ async getComprehensiveMetrics(analysisResult, unifiedSystem, pageAnalyzer) {
288
+ if (analysisResult.performanceMetrics) {
289
+ return analysisResult.performanceMetrics;
290
+ }
291
+ if (pageAnalyzer) {
292
+ return await pageAnalyzer.analyzePerformanceMetrics();
293
+ }
294
+ if (unifiedSystem) {
295
+ const perfResult = await unifiedSystem.analyzePerformanceMetrics();
296
+ if (perfResult.success) {
297
+ return perfResult.data;
298
+ }
299
+ throw new Error(`Performance metrics analysis failed: ${getErrorMessage(perfResult.error)}`);
300
+ }
301
+ throw new Error("No performance analyzer available");
302
+ }
303
+ addLayoutMetrics(metrics) {
304
+ const layoutData = [
305
+ [
306
+ "Fixed position elements",
307
+ metrics?.layoutMetrics?.fixedElements?.length ?? 0
308
+ ],
309
+ [
310
+ "High z-index elements",
311
+ metrics?.layoutMetrics?.highZIndexElements?.length ?? 0
312
+ ],
313
+ [
314
+ "Overflow hidden elements",
315
+ metrics?.layoutMetrics?.overflowHiddenElements ?? 0
316
+ ]
317
+ ];
318
+ this.addKeyValuePairs(layoutData, undefined, "Layout Analysis", 3);
319
+ this.addElementList("Fixed Elements", metrics?.layoutMetrics?.fixedElements, (element, index) => `${index + 1}. **${element.selector}**: ${element.purpose} (z-index: ${element.zIndex})`);
320
+ this.addElementList("High Z-Index Elements", metrics?.layoutMetrics?.highZIndexElements, (element, index) => `${index + 1}. **${element.selector}**: z-index ${element.zIndex} (${element.description})`);
321
+ }
322
+ addPerformanceWarnings(metrics) {
323
+ if (metrics?.warnings?.length && metrics.warnings.length > 0) {
324
+ this.reportBuilder.addEmptyLine().addHeader("Performance Warnings", 3);
325
+ for (const warning of metrics.warnings) {
326
+ const icon = warning.level === "danger" ? "\uD83D\uDEA8" : "⚠️";
327
+ this.reportBuilder.addListItem(`${icon} **${warning.type}**: ${warning.message}`);
328
+ }
329
+ }
330
+ }
331
+ async addBrowserPerformanceMetrics() {
332
+ try {
333
+ const browserMetrics = await this.tab.page.evaluate(() => {
334
+ const navigationEntries = performance.getEntriesByType("navigation");
335
+ const navigation = navigationEntries[0];
336
+ const paint = performance.getEntriesByType("paint");
337
+ return {
338
+ domContentLoaded: navigation?.domContentLoadedEventEnd != null && navigation?.domContentLoadedEventStart != null ? navigation.domContentLoadedEventEnd - navigation.domContentLoadedEventStart : undefined,
339
+ loadComplete: navigation?.loadEventEnd != null && navigation?.loadEventStart != null ? navigation.loadEventEnd - navigation.loadEventStart : undefined,
340
+ firstPaint: paint.find((p) => p.name === "first-paint")?.startTime,
341
+ firstContentfulPaint: paint.find((p) => p.name === "first-contentful-paint")?.startTime
342
+ };
343
+ });
344
+ const metricsWithValues = processBrowserMetrics(browserMetrics);
345
+ if (metricsWithValues.length > 0) {
346
+ this.addKeyValuePairs(metricsWithValues, undefined, "Browser Performance Timing", 3);
347
+ }
348
+ } catch (error) {
349
+ addErrorSection(this.reportBuilder, error, "retrieving browser timing metrics");
350
+ }
351
+ }
352
+ async addAccessibilitySection(diagnosticInfo, options) {
353
+ if (!this.shouldIncludeSection(options, "accessibility")) {
354
+ return;
355
+ }
356
+ const a11yMetrics = await this.tab.page.evaluate(() => {
357
+ const headings = document.querySelectorAll("h1, h2, h3, h4, h5, h6").length;
358
+ const landmarks = document.querySelectorAll('[role="main"], [role="navigation"], [role="banner"], [role="contentinfo"], main, nav, header, footer').length;
359
+ const altTexts = document.querySelectorAll("img[alt]").length;
360
+ const totalImages = document.querySelectorAll("img").length;
361
+ return { headings, landmarks, imagesWithAlt: altTexts, totalImages };
362
+ });
363
+ const a11yData = [
364
+ [
365
+ "Elements with missing ARIA labels",
366
+ diagnosticInfo.elements.missingAria
367
+ ],
368
+ ["Heading elements", a11yMetrics.headings],
369
+ ["Landmark elements", a11yMetrics.landmarks],
370
+ [
371
+ "Images with alt text",
372
+ `${a11yMetrics.imagesWithAlt}/${a11yMetrics.totalImages}`
373
+ ]
374
+ ];
375
+ this.addKeyValuePairs(a11yData, "Accessibility Information");
376
+ }
377
+ addTroubleshootingSection(diagnosticInfo, options) {
378
+ if (!this.shouldIncludeSection(options, "troubleshooting")) {
379
+ return;
380
+ }
381
+ this.reportBuilder.addHeader("Troubleshooting Suggestions", 2);
382
+ const suggestions = new ArrayBuilder().addIf(diagnosticInfo.iframes.detected, "Elements might be inside iframes - use frameLocator() for iframe interactions").addIf(diagnosticInfo.modalStates.blockedBy.length > 0, `Active modal states (${diagnosticInfo.modalStates.blockedBy.join(", ")}) may block interactions`).addIf(diagnosticInfo.elements.missingAria > 0, `${diagnosticInfo.elements.missingAria} elements lack proper ARIA attributes - consider using text-based selectors`).addIf(diagnosticInfo.elements.totalInteractable < diagnosticInfo.elements.totalVisible * 0.1, "Low ratio of interactable elements - page might still be loading or have CSS issues").build();
383
+ const finalSuggestions = suggestions.length === 0 ? [
384
+ "No obvious issues detected - page appears to be in good state for automation"
385
+ ] : suggestions;
386
+ for (const suggestion of finalSuggestions) {
387
+ this.reportBuilder.addListItem(suggestion);
388
+ }
389
+ this.reportBuilder.addEmptyLine();
390
+ }
391
+ }
392
+ export {
393
+ DiagnoseReportBuilder
394
+ };
@@ -0,0 +1,147 @@
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/tools/diagnose.ts
21
+ import { z } from "zod";
22
+ import { expectationSchema } from "../schemas/expectation.js";
23
+ import { createErrorReporter } from "../utils/error-handler-middleware.js";
24
+ import { DiagnoseAnalysisRunner } from "./diagnose/diagnose-analysis-runner.js";
25
+ import { DiagnoseConfigHandler } from "./diagnose/diagnose-config-handler.js";
26
+ import { DiagnoseReportBuilder } from "./diagnose/diagnose-report-builder.js";
27
+ import { defineTabTool } from "./tool.js";
28
+ var diagnoseSchema = z.object({
29
+ searchForElements: z.object({
30
+ text: z.string().optional(),
31
+ role: z.string().optional(),
32
+ tagName: z.string().optional(),
33
+ attributes: z.record(z.string()).optional()
34
+ }).optional().describe("Search for specific elements and include them in the report"),
35
+ includePerformanceMetrics: z.boolean().optional().default(false).describe("Include performance metrics in the report"),
36
+ includeAccessibilityInfo: z.boolean().optional().default(false).describe("Include accessibility information"),
37
+ includeTroubleshootingSuggestions: z.boolean().optional().default(false).describe("Include troubleshooting suggestions"),
38
+ diagnosticLevel: z.enum(["none", "basic", "standard", "detailed", "full"]).optional().default("standard").describe("Level of diagnostic detail: none (no diagnostics), basic (critical only), standard (default), detailed (with metrics), full (all info)"),
39
+ useParallelAnalysis: z.boolean().optional().default(false).describe("Use Phase 2 parallel analysis for improved performance and resource monitoring"),
40
+ useUnifiedSystem: z.boolean().optional().default(true).describe("Use Phase 3 unified diagnostic system with enhanced error handling and monitoring"),
41
+ configOverrides: z.object({
42
+ enableResourceMonitoring: z.boolean().optional(),
43
+ enableErrorEnrichment: z.boolean().optional(),
44
+ enableAdaptiveThresholds: z.boolean().optional(),
45
+ performanceThresholds: z.object({
46
+ pageAnalysis: z.number().optional(),
47
+ elementDiscovery: z.number().optional(),
48
+ resourceMonitoring: z.number().optional()
49
+ }).optional()
50
+ }).optional().describe("Runtime configuration overrides for diagnostic system"),
51
+ includeSystemStats: z.boolean().optional().default(false).describe("Include unified system statistics and health information"),
52
+ expectation: expectationSchema.optional()
53
+ }).describe("Generate a comprehensive diagnostic report of the current page");
54
+ var browserDiagnose = defineTabTool({
55
+ capability: "core",
56
+ schema: {
57
+ name: "browser_diagnose",
58
+ title: "Diagnose page",
59
+ type: "readOnly",
60
+ description: "Analyze page complexity and performance characteristics. Reports on: iframe count, DOM size, modal states, element statistics. Use for: debugging slow pages, understanding page structure, or monitoring page complexity.",
61
+ inputSchema: diagnoseSchema
62
+ },
63
+ handle: async (tab, params, response) => {
64
+ const config = extractDiagnoseConfig(params);
65
+ try {
66
+ if (config.diagnosticLevel === "none") {
67
+ response.addResult("Diagnostics disabled (level: none)");
68
+ return;
69
+ }
70
+ const startTime = Date.now();
71
+ await executeDiagnoseProcess(tab, config, response, startTime);
72
+ } catch (error) {
73
+ handleDiagnoseError(error, response);
74
+ }
75
+ }
76
+ });
77
+ function extractDiagnoseConfig(params) {
78
+ return {
79
+ searchForElements: params.searchForElements,
80
+ includePerformanceMetrics: Boolean(params.includePerformanceMetrics ?? false),
81
+ includeAccessibilityInfo: Boolean(params.includeAccessibilityInfo ?? false),
82
+ includeTroubleshootingSuggestions: Boolean(params.includeTroubleshootingSuggestions ?? false),
83
+ diagnosticLevel: params.diagnosticLevel ?? "standard",
84
+ useParallelAnalysis: Boolean(params.useParallelAnalysis ?? false),
85
+ useUnifiedSystem: Boolean(params.useUnifiedSystem ?? true),
86
+ configOverrides: params.configOverrides,
87
+ includeSystemStats: Boolean(params.includeSystemStats ?? false)
88
+ };
89
+ }
90
+ async function executeDiagnoseProcess(tab, config, response, startTime) {
91
+ const configHandler = new DiagnoseConfigHandler;
92
+ const _configDiagnostics = validateAndSetupConfig(configHandler, config, response);
93
+ const systemConfig = configHandler.initializeSystems(tab, config.useUnifiedSystem, config.useParallelAnalysis, config.configOverrides || {});
94
+ try {
95
+ const report = await runAnalysisAndBuildReport(tab, systemConfig, config, startTime);
96
+ response.addResult(report);
97
+ } finally {
98
+ await cleanupSystems(systemConfig);
99
+ }
100
+ }
101
+ function validateAndSetupConfig(configHandler, config, response) {
102
+ const configDiagnostics = configHandler.validateConfiguration();
103
+ if (config.diagnosticLevel === "full" && config.includeSystemStats) {
104
+ response.addResult(`## Configuration Status
105
+ - **Thresholds Status**: ${configDiagnostics.status}
106
+ - **Customizations**: ${configDiagnostics.customizations.length} active
107
+ - **Warnings**: ${configDiagnostics.warnings.length} items
108
+
109
+ `);
110
+ }
111
+ if (configDiagnostics.status === "failed") {
112
+ response.addError("Configuration system validation failed - using fallback settings");
113
+ }
114
+ return configDiagnostics;
115
+ }
116
+ async function runAnalysisAndBuildReport(tab, systemConfig, config, startTime) {
117
+ const analysisRunner = new DiagnoseAnalysisRunner;
118
+ const analysisResult = await analysisRunner.runAnalysis(systemConfig.unifiedSystem ?? null, systemConfig.pageAnalyzer ?? null, config.useParallelAnalysis, config.includeSystemStats);
119
+ const reportBuilder = new DiagnoseReportBuilder(tab);
120
+ const reportOptions = {
121
+ diagnosticLevel: config.diagnosticLevel,
122
+ includePerformanceMetrics: config.includePerformanceMetrics,
123
+ includeAccessibilityInfo: config.includeAccessibilityInfo,
124
+ includeTroubleshootingSuggestions: config.includeTroubleshootingSuggestions,
125
+ includeSystemStats: config.includeSystemStats,
126
+ searchForElements: config.searchForElements,
127
+ appliedOverrides: systemConfig.appliedOverrides,
128
+ startTime
129
+ };
130
+ return await reportBuilder.buildReport(analysisResult, systemConfig.unifiedSystem ?? null, systemConfig.pageAnalyzer ?? null, reportOptions);
131
+ }
132
+ async function cleanupSystems(systemConfig) {
133
+ if (!systemConfig.unifiedSystem && systemConfig.pageAnalyzer) {
134
+ await systemConfig.pageAnalyzer.dispose();
135
+ }
136
+ }
137
+ function handleDiagnoseError(error, response) {
138
+ const errorReporter = createErrorReporter("Diagnose");
139
+ try {
140
+ errorReporter.reportAndThrow(error, "generateDiagnosticReport");
141
+ } catch (enrichedError) {
142
+ response.addError(enrichedError instanceof Error ? enrichedError.message : String(enrichedError));
143
+ }
144
+ }
145
+ export {
146
+ browserDiagnose
147
+ };
@@ -0,0 +1,57 @@
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/tools/dialogs.ts
21
+ import { z } from "zod";
22
+ import { expectationSchema } from "../schemas/expectation.js";
23
+ import { defineTabTool } from "./tool.js";
24
+ var handleDialog = defineTabTool({
25
+ capability: "core",
26
+ schema: {
27
+ name: "browser_handle_dialog",
28
+ title: "Handle a dialog",
29
+ description: `Handle a dialog(alert,confirm,prompt).accept:true to accept,false to dismiss.promptText:"answer" for prompt dialogs.expectation:{includeSnapshot:true} to see page after dialog handling.USE batch_execute if dialog appears during workflow.`,
30
+ inputSchema: z.object({
31
+ accept: z.boolean().describe("Whether to accept the dialog."),
32
+ promptText: z.string().optional().describe("The text of the prompt in case of a prompt dialog."),
33
+ expectation: expectationSchema
34
+ }),
35
+ type: "destructive"
36
+ },
37
+ handle: async (tab, params, response) => {
38
+ response.setIncludeSnapshot();
39
+ const dialogState = tab.modalStates().find((state) => state.type === "dialog");
40
+ if (!dialogState) {
41
+ throw new Error("No dialog visible");
42
+ }
43
+ tab.clearModalState(dialogState);
44
+ await tab.waitForCompletion(async () => {
45
+ if (params.accept) {
46
+ await dialogState.dialog.accept(params.promptText);
47
+ } else {
48
+ await dialogState.dialog.dismiss();
49
+ }
50
+ });
51
+ },
52
+ clearsModalState: "dialog"
53
+ });
54
+ var dialogs_default = [handleDialog];
55
+ export {
56
+ dialogs_default as default
57
+ };
@@ -0,0 +1,67 @@
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/tools/evaluate.ts
21
+ import { z } from "zod";
22
+ import { quote } from "../javascript.js";
23
+ import { expectationSchema } from "../schemas/expectation.js";
24
+ import { defineTabTool } from "./tool.js";
25
+ import { generateLocator } from "./utils.js";
26
+ var evaluateSchema = z.object({
27
+ function: z.string().describe("() => { /* code */ } or (element) => { /* code */ } when element is provided"),
28
+ element: z.string().optional().describe("Human-readable element description used to obtain permission to interact with the element"),
29
+ ref: z.string().optional().describe("Exact target element reference from the page snapshot"),
30
+ expectation: expectationSchema
31
+ });
32
+ var evaluate = defineTabTool({
33
+ capability: "core",
34
+ schema: {
35
+ name: "browser_evaluate",
36
+ title: "Evaluate JavaScript",
37
+ description: "Evaluate JavaScript expression on page or element.Returns evaluation result.USE CASES:extract data,modify DOM,trigger events.expectation:{includeSnapshot:false} for data extraction,true if modifying page.element+ref to run on specific element.CONSIDER batch_execute for multiple evaluations.",
38
+ inputSchema: evaluateSchema,
39
+ type: "destructive"
40
+ },
41
+ handle: async (tab, params, response) => {
42
+ let locator;
43
+ if (params.ref && params.element) {
44
+ locator = await tab.refLocator({
45
+ ref: params.ref,
46
+ element: params.element
47
+ });
48
+ response.addCode(`await page.${await generateLocator(locator)}.evaluate(${quote(params.function)});`);
49
+ } else {
50
+ response.addCode(`await page.evaluate(${quote(params.function)});`);
51
+ }
52
+ await tab.waitForCompletion(async () => {
53
+ try {
54
+ const receiver = locator ?? tab.page;
55
+ const result = await receiver._evaluateFunction(params.function);
56
+ const stringifiedResult = JSON.stringify(result, null, 2);
57
+ response.addResult(stringifiedResult ?? "undefined");
58
+ } catch (error) {
59
+ response.addError(`JavaScript evaluation failed: ${error instanceof Error ? error.message : String(error)}`);
60
+ }
61
+ });
62
+ }
63
+ });
64
+ var evaluate_default = [evaluate];
65
+ export {
66
+ evaluate_default as default
67
+ };