agentic-qe 3.7.6 → 3.7.8
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/.claude/helpers/statusline-v3.cjs +13 -1
- package/.claude/skills/skills-manifest.json +1 -1
- package/CHANGELOG.md +39 -0
- package/README.md +36 -0
- package/dist/cli/bundle.js +2052 -183
- package/dist/coordination/complexity-composition/index.d.ts +2 -0
- package/dist/coordination/complexity-composition/index.d.ts.map +1 -0
- package/dist/coordination/complexity-composition/index.js +2 -0
- package/dist/coordination/complexity-composition/index.js.map +1 -0
- package/dist/coordination/complexity-composition/team-composer.d.ts +72 -0
- package/dist/coordination/complexity-composition/team-composer.d.ts.map +1 -0
- package/dist/coordination/complexity-composition/team-composer.js +221 -0
- package/dist/coordination/complexity-composition/team-composer.js.map +1 -0
- package/dist/coordination/consensus/consensus-engine.d.ts +10 -1
- package/dist/coordination/consensus/consensus-engine.d.ts.map +1 -1
- package/dist/coordination/consensus/consensus-engine.js +31 -1
- package/dist/coordination/consensus/consensus-engine.js.map +1 -1
- package/dist/coordination/consensus/index.d.ts +1 -0
- package/dist/coordination/consensus/index.d.ts.map +1 -1
- package/dist/coordination/consensus/index.js +4 -0
- package/dist/coordination/consensus/index.js.map +1 -1
- package/dist/coordination/consensus/interfaces.d.ts +5 -0
- package/dist/coordination/consensus/interfaces.d.ts.map +1 -1
- package/dist/coordination/consensus/interfaces.js +1 -0
- package/dist/coordination/consensus/interfaces.js.map +1 -1
- package/dist/coordination/consensus/sycophancy-scorer.d.ts +62 -0
- package/dist/coordination/consensus/sycophancy-scorer.d.ts.map +1 -0
- package/dist/coordination/consensus/sycophancy-scorer.js +200 -0
- package/dist/coordination/consensus/sycophancy-scorer.js.map +1 -0
- package/dist/coordination/fleet-tiers/tier-selector.d.ts +20 -0
- package/dist/coordination/fleet-tiers/tier-selector.d.ts.map +1 -1
- package/dist/coordination/fleet-tiers/tier-selector.js +31 -0
- package/dist/coordination/fleet-tiers/tier-selector.js.map +1 -1
- package/dist/coordination/fleet-tiers/types.d.ts +2 -0
- package/dist/coordination/fleet-tiers/types.d.ts.map +1 -1
- package/dist/domains/test-execution/services/e2e/adaptive-locator-service.d.ts +71 -0
- package/dist/domains/test-execution/services/e2e/adaptive-locator-service.d.ts.map +1 -0
- package/dist/domains/test-execution/services/e2e/adaptive-locator-service.js +456 -0
- package/dist/domains/test-execution/services/e2e/adaptive-locator-service.js.map +1 -0
- package/dist/domains/test-execution/services/e2e/adaptive-locator-types.d.ts +81 -0
- package/dist/domains/test-execution/services/e2e/adaptive-locator-types.d.ts.map +1 -0
- package/dist/domains/test-execution/services/e2e/adaptive-locator-types.js +20 -0
- package/dist/domains/test-execution/services/e2e/adaptive-locator-types.js.map +1 -0
- package/dist/domains/test-execution/services/e2e/browser-orchestrator.d.ts +19 -0
- package/dist/domains/test-execution/services/e2e/browser-orchestrator.d.ts.map +1 -1
- package/dist/domains/test-execution/services/e2e/browser-orchestrator.js +82 -0
- package/dist/domains/test-execution/services/e2e/browser-orchestrator.js.map +1 -1
- package/dist/domains/test-execution/services/e2e/index.d.ts +2 -0
- package/dist/domains/test-execution/services/e2e/index.d.ts.map +1 -1
- package/dist/domains/test-execution/services/e2e/index.js +5 -0
- package/dist/domains/test-execution/services/e2e/index.js.map +1 -1
- package/dist/domains/test-execution/services/e2e/step-executors.d.ts +6 -0
- package/dist/domains/test-execution/services/e2e/step-executors.d.ts.map +1 -1
- package/dist/domains/test-execution/services/e2e/step-executors.js +17 -2
- package/dist/domains/test-execution/services/e2e/step-executors.js.map +1 -1
- package/dist/domains/test-execution/services/e2e/types.d.ts +18 -1
- package/dist/domains/test-execution/services/e2e/types.d.ts.map +1 -1
- package/dist/domains/test-execution/services/e2e/types.js.map +1 -1
- package/dist/domains/test-generation/blind-review/blind-review-orchestrator.d.ts +65 -0
- package/dist/domains/test-generation/blind-review/blind-review-orchestrator.d.ts.map +1 -0
- package/dist/domains/test-generation/blind-review/blind-review-orchestrator.js +189 -0
- package/dist/domains/test-generation/blind-review/blind-review-orchestrator.js.map +1 -0
- package/dist/domains/test-generation/blind-review/index.d.ts +2 -0
- package/dist/domains/test-generation/blind-review/index.d.ts.map +1 -0
- package/dist/domains/test-generation/blind-review/index.js +2 -0
- package/dist/domains/test-generation/blind-review/index.js.map +1 -0
- package/dist/domains/test-generation/gates/index.d.ts +2 -0
- package/dist/domains/test-generation/gates/index.d.ts.map +1 -0
- package/dist/domains/test-generation/gates/index.js +2 -0
- package/dist/domains/test-generation/gates/index.js.map +1 -0
- package/dist/domains/test-generation/gates/test-quality-gate.d.ts +85 -0
- package/dist/domains/test-generation/gates/test-quality-gate.d.ts.map +1 -0
- package/dist/domains/test-generation/gates/test-quality-gate.js +320 -0
- package/dist/domains/test-generation/gates/test-quality-gate.js.map +1 -0
- package/dist/domains/test-generation/interfaces.d.ts +3 -0
- package/dist/domains/test-generation/interfaces.d.ts.map +1 -1
- package/dist/domains/test-generation/pattern-injection/edge-case-injector.d.ts +68 -0
- package/dist/domains/test-generation/pattern-injection/edge-case-injector.d.ts.map +1 -0
- package/dist/domains/test-generation/pattern-injection/edge-case-injector.js +225 -0
- package/dist/domains/test-generation/pattern-injection/edge-case-injector.js.map +1 -0
- package/dist/domains/test-generation/pattern-injection/index.d.ts +2 -0
- package/dist/domains/test-generation/pattern-injection/index.d.ts.map +1 -0
- package/dist/domains/test-generation/pattern-injection/index.js +2 -0
- package/dist/domains/test-generation/pattern-injection/index.js.map +1 -0
- package/dist/domains/test-generation/services/test-generator.d.ts +6 -0
- package/dist/domains/test-generation/services/test-generator.d.ts.map +1 -1
- package/dist/domains/test-generation/services/test-generator.js +29 -0
- package/dist/domains/test-generation/services/test-generator.js.map +1 -1
- package/dist/integrations/agentic-flow/reasoning-bank/experience-replay.d.ts +8 -2
- package/dist/integrations/agentic-flow/reasoning-bank/experience-replay.d.ts.map +1 -1
- package/dist/integrations/agentic-flow/reasoning-bank/experience-replay.js +62 -38
- package/dist/integrations/agentic-flow/reasoning-bank/experience-replay.js.map +1 -1
- package/dist/integrations/browser/client-factory.d.ts +6 -1
- package/dist/integrations/browser/client-factory.d.ts.map +1 -1
- package/dist/integrations/browser/client-factory.js +37 -2
- package/dist/integrations/browser/client-factory.js.map +1 -1
- package/dist/integrations/browser/index.d.ts +5 -1
- package/dist/integrations/browser/index.d.ts.map +1 -1
- package/dist/integrations/browser/index.js +8 -1
- package/dist/integrations/browser/index.js.map +1 -1
- package/dist/integrations/browser/page-pool-types.d.ts +70 -0
- package/dist/integrations/browser/page-pool-types.d.ts.map +1 -0
- package/dist/integrations/browser/page-pool-types.js +19 -0
- package/dist/integrations/browser/page-pool-types.js.map +1 -0
- package/dist/integrations/browser/page-pool.d.ts +79 -0
- package/dist/integrations/browser/page-pool.d.ts.map +1 -0
- package/dist/integrations/browser/page-pool.js +288 -0
- package/dist/integrations/browser/page-pool.js.map +1 -0
- package/dist/integrations/browser/resource-blocking.d.ts +47 -0
- package/dist/integrations/browser/resource-blocking.d.ts.map +1 -0
- package/dist/integrations/browser/resource-blocking.js +195 -0
- package/dist/integrations/browser/resource-blocking.js.map +1 -0
- package/dist/integrations/browser/stealth/index.d.ts +8 -0
- package/dist/integrations/browser/stealth/index.d.ts.map +1 -0
- package/dist/integrations/browser/stealth/index.js +7 -0
- package/dist/integrations/browser/stealth/index.js.map +1 -0
- package/dist/integrations/browser/stealth/stealth-client.d.ts +51 -0
- package/dist/integrations/browser/stealth/stealth-client.d.ts.map +1 -0
- package/dist/integrations/browser/stealth/stealth-client.js +359 -0
- package/dist/integrations/browser/stealth/stealth-client.js.map +1 -0
- package/dist/integrations/browser/stealth/stealth-types.d.ts +35 -0
- package/dist/integrations/browser/stealth/stealth-types.d.ts.map +1 -0
- package/dist/integrations/browser/stealth/stealth-types.js +17 -0
- package/dist/integrations/browser/stealth/stealth-types.js.map +1 -0
- package/dist/integrations/browser/types.d.ts +13 -10
- package/dist/integrations/browser/types.d.ts.map +1 -1
- package/dist/integrations/browser/types.js.map +1 -1
- package/dist/learning/experience-capture.d.ts +12 -2
- package/dist/learning/experience-capture.d.ts.map +1 -1
- package/dist/learning/experience-capture.js +28 -35
- package/dist/learning/experience-capture.js.map +1 -1
- package/dist/learning/experience-consolidation.d.ts +74 -0
- package/dist/learning/experience-consolidation.d.ts.map +1 -0
- package/dist/learning/experience-consolidation.js +403 -0
- package/dist/learning/experience-consolidation.js.map +1 -0
- package/dist/mcp/bundle.js +3050 -341
- package/dist/routing/calibration/ema-calibrator.d.ts +93 -0
- package/dist/routing/calibration/ema-calibrator.d.ts.map +1 -0
- package/dist/routing/calibration/ema-calibrator.js +140 -0
- package/dist/routing/calibration/ema-calibrator.js.map +1 -0
- package/dist/routing/calibration/index.d.ts +2 -0
- package/dist/routing/calibration/index.d.ts.map +1 -0
- package/dist/routing/calibration/index.js +2 -0
- package/dist/routing/calibration/index.js.map +1 -0
- package/dist/routing/escalation/auto-escalation-tracker.d.ts +62 -0
- package/dist/routing/escalation/auto-escalation-tracker.d.ts.map +1 -0
- package/dist/routing/escalation/auto-escalation-tracker.js +116 -0
- package/dist/routing/escalation/auto-escalation-tracker.js.map +1 -0
- package/dist/routing/escalation/index.d.ts +2 -0
- package/dist/routing/escalation/index.d.ts.map +1 -0
- package/dist/routing/escalation/index.js +2 -0
- package/dist/routing/escalation/index.js.map +1 -0
- package/dist/routing/index.d.ts +4 -0
- package/dist/routing/index.d.ts.map +1 -1
- package/dist/routing/index.js +4 -0
- package/dist/routing/index.js.map +1 -1
- package/dist/routing/routing-config.d.ts +4 -0
- package/dist/routing/routing-config.d.ts.map +1 -1
- package/dist/routing/routing-config.js +2 -0
- package/dist/routing/routing-config.js.map +1 -1
- package/dist/routing/routing-feedback.d.ts +35 -2
- package/dist/routing/routing-feedback.d.ts.map +1 -1
- package/dist/routing/routing-feedback.js +97 -3
- package/dist/routing/routing-feedback.js.map +1 -1
- package/dist/routing/types.d.ts +2 -0
- package/dist/routing/types.d.ts.map +1 -1
- package/dist/routing/types.js.map +1 -1
- package/dist/workers/workers/learning-consolidation.d.ts.map +1 -1
- package/dist/workers/workers/learning-consolidation.js +32 -0
- package/dist/workers/workers/learning-consolidation.js.map +1 -1
- package/package.json +1 -1
|
@@ -0,0 +1,195 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Resource Blocking for Browser Automation
|
|
3
|
+
*
|
|
4
|
+
* Inspired by Scrapling's resource filtering patterns.
|
|
5
|
+
* Blocks non-essential resources (images, fonts, tracking) during E2E tests
|
|
6
|
+
* to improve page load speed and reduce flakiness.
|
|
7
|
+
*
|
|
8
|
+
* @module integrations/browser/resource-blocking
|
|
9
|
+
*/
|
|
10
|
+
// ============================================================================
|
|
11
|
+
// Known Tracker / Ad Domains
|
|
12
|
+
// ============================================================================
|
|
13
|
+
const TRACKING_DOMAINS = new Set([
|
|
14
|
+
'google-analytics.com',
|
|
15
|
+
'googletagmanager.com',
|
|
16
|
+
'analytics.google.com',
|
|
17
|
+
'hotjar.com',
|
|
18
|
+
'fullstory.com',
|
|
19
|
+
'segment.io',
|
|
20
|
+
'segment.com',
|
|
21
|
+
'mixpanel.com',
|
|
22
|
+
'heap.io',
|
|
23
|
+
'heapanalytics.com',
|
|
24
|
+
'amplitude.com',
|
|
25
|
+
'mouseflow.com',
|
|
26
|
+
'crazyegg.com',
|
|
27
|
+
'optimizely.com',
|
|
28
|
+
'newrelic.com',
|
|
29
|
+
'nr-data.net',
|
|
30
|
+
'sentry.io',
|
|
31
|
+
'bugsnag.com',
|
|
32
|
+
'logrocket.com',
|
|
33
|
+
'clarity.ms',
|
|
34
|
+
'facebook.net',
|
|
35
|
+
'connect.facebook.net',
|
|
36
|
+
]);
|
|
37
|
+
const ADVERTISING_DOMAINS = new Set([
|
|
38
|
+
'doubleclick.net',
|
|
39
|
+
'googlesyndication.com',
|
|
40
|
+
'googleadservices.com',
|
|
41
|
+
'google-analytics.com',
|
|
42
|
+
'adservice.google.com',
|
|
43
|
+
'pagead2.googlesyndication.com',
|
|
44
|
+
'ads.twitter.com',
|
|
45
|
+
'ads-api.twitter.com',
|
|
46
|
+
'adsserver.com',
|
|
47
|
+
'adnxs.com',
|
|
48
|
+
'amazon-adsystem.com',
|
|
49
|
+
'criteo.com',
|
|
50
|
+
'moatads.com',
|
|
51
|
+
'outbrain.com',
|
|
52
|
+
'taboola.com',
|
|
53
|
+
'bidswitch.net',
|
|
54
|
+
'rubiconproject.com',
|
|
55
|
+
]);
|
|
56
|
+
// ============================================================================
|
|
57
|
+
// Resource Type Mapping
|
|
58
|
+
// ============================================================================
|
|
59
|
+
/**
|
|
60
|
+
* Maps Playwright/CDP resource types to our categories
|
|
61
|
+
*/
|
|
62
|
+
const RESOURCE_TYPE_TO_CATEGORY = {
|
|
63
|
+
image: 'image',
|
|
64
|
+
font: 'font',
|
|
65
|
+
media: 'media',
|
|
66
|
+
stylesheet: 'stylesheet',
|
|
67
|
+
websocket: 'websocket',
|
|
68
|
+
};
|
|
69
|
+
// ============================================================================
|
|
70
|
+
// Presets
|
|
71
|
+
// ============================================================================
|
|
72
|
+
const PRESETS = {
|
|
73
|
+
/**
|
|
74
|
+
* Functional preset: block everything non-essential for functional testing.
|
|
75
|
+
* Fastest page loads — only HTML, JS, and XHR/fetch are allowed.
|
|
76
|
+
*/
|
|
77
|
+
functional: {
|
|
78
|
+
enabled: true,
|
|
79
|
+
blockedCategories: ['image', 'font', 'media', 'stylesheet', 'tracking', 'advertising'],
|
|
80
|
+
},
|
|
81
|
+
/**
|
|
82
|
+
* Visual preset: block nothing — needed for visual regression testing.
|
|
83
|
+
*/
|
|
84
|
+
visual: {
|
|
85
|
+
enabled: false,
|
|
86
|
+
blockedCategories: [],
|
|
87
|
+
},
|
|
88
|
+
/**
|
|
89
|
+
* Performance preset: block heavy resources and tracking only.
|
|
90
|
+
* Keeps stylesheets for layout accuracy but drops images/fonts/media.
|
|
91
|
+
*/
|
|
92
|
+
performance: {
|
|
93
|
+
enabled: true,
|
|
94
|
+
blockedCategories: ['image', 'font', 'media', 'tracking', 'advertising'],
|
|
95
|
+
},
|
|
96
|
+
};
|
|
97
|
+
// ============================================================================
|
|
98
|
+
// Core Logic
|
|
99
|
+
// ============================================================================
|
|
100
|
+
/**
|
|
101
|
+
* Determine if a request should be blocked based on URL, resource type, and config.
|
|
102
|
+
*
|
|
103
|
+
* @param url - The request URL
|
|
104
|
+
* @param resourceType - The CDP/Playwright resource type string (e.g., 'image', 'script', 'font')
|
|
105
|
+
* @param config - The resource blocking configuration
|
|
106
|
+
* @returns true if the request should be blocked
|
|
107
|
+
*/
|
|
108
|
+
export function shouldBlockRequest(url, resourceType, config) {
|
|
109
|
+
if (!config.enabled) {
|
|
110
|
+
return false;
|
|
111
|
+
}
|
|
112
|
+
// Check allow patterns first (highest priority)
|
|
113
|
+
if (config.allowPatterns?.length) {
|
|
114
|
+
for (const pattern of config.allowPatterns) {
|
|
115
|
+
if (urlMatchesPattern(url, pattern)) {
|
|
116
|
+
return false;
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
// Check explicit block patterns
|
|
121
|
+
if (config.blockPatterns?.length) {
|
|
122
|
+
for (const pattern of config.blockPatterns) {
|
|
123
|
+
if (urlMatchesPattern(url, pattern)) {
|
|
124
|
+
return true;
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
// Check resource type against blocked categories
|
|
129
|
+
const category = RESOURCE_TYPE_TO_CATEGORY[resourceType];
|
|
130
|
+
if (category && config.blockedCategories.includes(category)) {
|
|
131
|
+
return true;
|
|
132
|
+
}
|
|
133
|
+
// Check domain-based categories (tracking & advertising)
|
|
134
|
+
if (config.blockedCategories.includes('tracking') && isDomainInSet(url, TRACKING_DOMAINS)) {
|
|
135
|
+
return true;
|
|
136
|
+
}
|
|
137
|
+
if (config.blockedCategories.includes('advertising') && isDomainInSet(url, ADVERTISING_DOMAINS)) {
|
|
138
|
+
return true;
|
|
139
|
+
}
|
|
140
|
+
return false;
|
|
141
|
+
}
|
|
142
|
+
/**
|
|
143
|
+
* Get a resource blocking preset by name.
|
|
144
|
+
*
|
|
145
|
+
* @param name - Preset name or a ResourceBlockingConfig object (passed through)
|
|
146
|
+
* @returns A ResourceBlockingConfig
|
|
147
|
+
*/
|
|
148
|
+
export function getResourceBlockingPreset(name) {
|
|
149
|
+
if (typeof name === 'object') {
|
|
150
|
+
return name;
|
|
151
|
+
}
|
|
152
|
+
const preset = PRESETS[name];
|
|
153
|
+
if (!preset) {
|
|
154
|
+
return PRESETS.visual; // safe default: block nothing
|
|
155
|
+
}
|
|
156
|
+
// Return a copy to prevent mutation
|
|
157
|
+
return { ...preset, blockedCategories: [...preset.blockedCategories] };
|
|
158
|
+
}
|
|
159
|
+
// ============================================================================
|
|
160
|
+
// Helpers
|
|
161
|
+
// ============================================================================
|
|
162
|
+
/**
|
|
163
|
+
* Cache of compiled glob patterns to avoid RegExp creation on every request
|
|
164
|
+
*/
|
|
165
|
+
const patternCache = new Map();
|
|
166
|
+
/**
|
|
167
|
+
* Check if a URL matches a simple glob pattern (supports * wildcard)
|
|
168
|
+
*/
|
|
169
|
+
function urlMatchesPattern(url, pattern) {
|
|
170
|
+
let regex = patternCache.get(pattern);
|
|
171
|
+
if (!regex) {
|
|
172
|
+
const escaped = pattern.replace(/[.+^${}()|[\]\\]/g, '\\$&').replace(/\*/g, '.*');
|
|
173
|
+
regex = new RegExp(escaped, 'i');
|
|
174
|
+
patternCache.set(pattern, regex);
|
|
175
|
+
}
|
|
176
|
+
return regex.test(url);
|
|
177
|
+
}
|
|
178
|
+
/**
|
|
179
|
+
* Check if a URL's hostname matches any domain in a set
|
|
180
|
+
*/
|
|
181
|
+
function isDomainInSet(url, domains) {
|
|
182
|
+
try {
|
|
183
|
+
const hostname = new URL(url).hostname;
|
|
184
|
+
for (const domain of domains) {
|
|
185
|
+
if (hostname === domain || hostname.endsWith(`.${domain}`)) {
|
|
186
|
+
return true;
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
catch {
|
|
191
|
+
// Invalid URL — don't block
|
|
192
|
+
}
|
|
193
|
+
return false;
|
|
194
|
+
}
|
|
195
|
+
//# sourceMappingURL=resource-blocking.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"resource-blocking.js","sourceRoot":"","sources":["../../../src/integrations/browser/resource-blocking.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Stealth Browser Module
|
|
3
|
+
* @module integrations/browser/stealth
|
|
4
|
+
*/
|
|
5
|
+
export { StealthBrowserClient } from './stealth-client';
|
|
6
|
+
export type { StealthBrowserConfig } from './stealth-types';
|
|
7
|
+
export { DEFAULT_STEALTH_CONFIG } from './stealth-types';
|
|
8
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/integrations/browser/stealth/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,oBAAoB,EAAE,MAAM,kBAAkB,CAAC;AACxD,YAAY,EAAE,oBAAoB,EAAE,MAAM,iBAAiB,CAAC;AAC5D,OAAO,EAAE,sBAAsB,EAAE,MAAM,iBAAiB,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../src/integrations/browser/stealth/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,oBAAoB,EAAE,MAAM,kBAAkB,CAAC;AAExD,OAAO,EAAE,sBAAsB,EAAE,MAAM,iBAAiB,CAAC"}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Stealth Browser Client via Patchright
|
|
3
|
+
*
|
|
4
|
+
* Implements IBrowserClient using Patchright — a drop-in Playwright replacement
|
|
5
|
+
* that avoids CDP detection for bot-protected test environments.
|
|
6
|
+
*
|
|
7
|
+
* Uses lazy require pattern (like ruvector wrappers) so the module works
|
|
8
|
+
* even if patchright is not installed.
|
|
9
|
+
*
|
|
10
|
+
* @module integrations/browser/stealth/stealth-client
|
|
11
|
+
*/
|
|
12
|
+
import type { IBrowserClient, BrowserLaunchOptions, BrowserSessionInfo, BrowserNavigateResult, BrowserScreenshotResult, ElementTarget } from '../types';
|
|
13
|
+
import { BrowserError } from '../types';
|
|
14
|
+
import type { Result } from '../../../shared/types';
|
|
15
|
+
import type { StealthBrowserConfig } from './stealth-types';
|
|
16
|
+
/**
|
|
17
|
+
* Stealth browser client using Patchright for bot-protected environments.
|
|
18
|
+
* Implements IBrowserClient with `tool = 'stealth'`.
|
|
19
|
+
*/
|
|
20
|
+
export declare class StealthBrowserClient implements IBrowserClient {
|
|
21
|
+
readonly tool: "stealth";
|
|
22
|
+
private readonly stealthConfig;
|
|
23
|
+
private page;
|
|
24
|
+
private context;
|
|
25
|
+
private browser;
|
|
26
|
+
private sessionId;
|
|
27
|
+
constructor(config?: Partial<StealthBrowserConfig>);
|
|
28
|
+
isAvailable(): Promise<boolean>;
|
|
29
|
+
launch(options?: BrowserLaunchOptions): Promise<Result<BrowserSessionInfo, BrowserError>>;
|
|
30
|
+
quit(): Promise<Result<void, BrowserError>>;
|
|
31
|
+
navigate(url: string): Promise<Result<BrowserNavigateResult, BrowserError>>;
|
|
32
|
+
reload(): Promise<Result<void, BrowserError>>;
|
|
33
|
+
goBack(): Promise<Result<void, BrowserError>>;
|
|
34
|
+
goForward(): Promise<Result<void, BrowserError>>;
|
|
35
|
+
click(target: ElementTarget | string): Promise<Result<void, BrowserError>>;
|
|
36
|
+
fill(target: ElementTarget | string, text: string): Promise<Result<void, BrowserError>>;
|
|
37
|
+
getText(target: ElementTarget | string): Promise<Result<string, BrowserError>>;
|
|
38
|
+
isVisible(target: ElementTarget | string): Promise<Result<boolean, BrowserError>>;
|
|
39
|
+
screenshot(options?: {
|
|
40
|
+
path?: string;
|
|
41
|
+
fullPage?: boolean;
|
|
42
|
+
}): Promise<Result<BrowserScreenshotResult, BrowserError>>;
|
|
43
|
+
evaluate<T = unknown>(script: string): Promise<Result<T, BrowserError>>;
|
|
44
|
+
dispose(): Promise<void>;
|
|
45
|
+
private resolveSelector;
|
|
46
|
+
private applyResourceBlocking;
|
|
47
|
+
private waitForCloudflare;
|
|
48
|
+
private notLaunched;
|
|
49
|
+
private wrapError;
|
|
50
|
+
}
|
|
51
|
+
//# sourceMappingURL=stealth-client.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"stealth-client.d.ts","sourceRoot":"","sources":["../../../../src/integrations/browser/stealth/stealth-client.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAGH,OAAO,KAAK,EACV,cAAc,EACd,oBAAoB,EACpB,kBAAkB,EAClB,qBAAqB,EACrB,uBAAuB,EACvB,aAAa,EACd,MAAM,UAAU,CAAC;AAClB,OAAO,EAAE,YAAY,EAA2B,MAAM,UAAU,CAAC;AACjE,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,uBAAuB,CAAC;AACpD,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,iBAAiB,CAAC;AA2E5D;;;GAGG;AACH,qBAAa,oBAAqB,YAAW,cAAc;IACzD,QAAQ,CAAC,IAAI,EAAG,SAAS,CAAU;IAEnC,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAuB;IACrD,OAAO,CAAC,IAAI,CAA+B;IAC3C,OAAO,CAAC,OAAO,CAAkC;IACjD,OAAO,CAAC,OAAO,CAAkC;IACjD,OAAO,CAAC,SAAS,CAAuB;gBAE5B,MAAM,CAAC,EAAE,OAAO,CAAC,oBAAoB,CAAC;IAQ5C,WAAW,IAAI,OAAO,CAAC,OAAO,CAAC;IAI/B,MAAM,CACV,OAAO,CAAC,EAAE,oBAAoB,GAC7B,OAAO,CAAC,MAAM,CAAC,kBAAkB,EAAE,YAAY,CAAC,CAAC;IAoE9C,IAAI,IAAI,OAAO,CAAC,MAAM,CAAC,IAAI,EAAE,YAAY,CAAC,CAAC;IA8B3C,QAAQ,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,qBAAqB,EAAE,YAAY,CAAC,CAAC;IA8B3E,MAAM,IAAI,OAAO,CAAC,MAAM,CAAC,IAAI,EAAE,YAAY,CAAC,CAAC;IAU7C,MAAM,IAAI,OAAO,CAAC,MAAM,CAAC,IAAI,EAAE,YAAY,CAAC,CAAC;IAU7C,SAAS,IAAI,OAAO,CAAC,MAAM,CAAC,IAAI,EAAE,YAAY,CAAC,CAAC;IAchD,KAAK,CAAC,MAAM,EAAE,aAAa,GAAG,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,IAAI,EAAE,YAAY,CAAC,CAAC;IAW1E,IAAI,CAAC,MAAM,EAAE,aAAa,GAAG,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,IAAI,EAAE,YAAY,CAAC,CAAC;IAWvF,OAAO,CAAC,MAAM,EAAE,aAAa,GAAG,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,YAAY,CAAC,CAAC;IAW9E,SAAS,CAAC,MAAM,EAAE,aAAa,GAAG,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,OAAO,EAAE,YAAY,CAAC,CAAC;IAejF,UAAU,CACd,OAAO,CAAC,EAAE;QAAE,IAAI,CAAC,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,EAAE,OAAO,CAAA;KAAE,GAC9C,OAAO,CAAC,MAAM,CAAC,uBAAuB,EAAE,YAAY,CAAC,CAAC;IA2BnD,QAAQ,CAAC,CAAC,GAAG,OAAO,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC,EAAE,YAAY,CAAC,CAAC;IAcvE,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;IAQ9B,OAAO,CAAC,eAAe;YAgBT,qBAAqB;YAsBrB,iBAAiB;IAoB/B,OAAO,CAAC,WAAW;IAWnB,OAAO,CAAC,SAAS;CAWlB"}
|
|
@@ -0,0 +1,359 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Stealth Browser Client via Patchright
|
|
3
|
+
*
|
|
4
|
+
* Implements IBrowserClient using Patchright — a drop-in Playwright replacement
|
|
5
|
+
* that avoids CDP detection for bot-protected test environments.
|
|
6
|
+
*
|
|
7
|
+
* Uses lazy require pattern (like ruvector wrappers) so the module works
|
|
8
|
+
* even if patchright is not installed.
|
|
9
|
+
*
|
|
10
|
+
* @module integrations/browser/stealth/stealth-client
|
|
11
|
+
*/
|
|
12
|
+
import { randomUUID } from 'crypto';
|
|
13
|
+
import { BrowserError, BrowserUnavailableError } from '../types';
|
|
14
|
+
import { DEFAULT_STEALTH_CONFIG } from './stealth-types';
|
|
15
|
+
import { shouldBlockRequest, getResourceBlockingPreset, } from '../resource-blocking';
|
|
16
|
+
let patchrightModule = null;
|
|
17
|
+
let patchrightChecked = false;
|
|
18
|
+
function getPatchright() {
|
|
19
|
+
if (patchrightChecked)
|
|
20
|
+
return patchrightModule;
|
|
21
|
+
patchrightChecked = true;
|
|
22
|
+
try {
|
|
23
|
+
// eslint-disable-next-line @typescript-eslint/no-require-imports
|
|
24
|
+
patchrightModule = require('patchright');
|
|
25
|
+
}
|
|
26
|
+
catch {
|
|
27
|
+
patchrightModule = null;
|
|
28
|
+
}
|
|
29
|
+
return patchrightModule;
|
|
30
|
+
}
|
|
31
|
+
// ============================================================================
|
|
32
|
+
// Stealth Browser Client
|
|
33
|
+
// ============================================================================
|
|
34
|
+
/**
|
|
35
|
+
* Stealth browser client using Patchright for bot-protected environments.
|
|
36
|
+
* Implements IBrowserClient with `tool = 'stealth'`.
|
|
37
|
+
*/
|
|
38
|
+
export class StealthBrowserClient {
|
|
39
|
+
tool = 'stealth';
|
|
40
|
+
stealthConfig;
|
|
41
|
+
page = null;
|
|
42
|
+
context = null;
|
|
43
|
+
browser = null;
|
|
44
|
+
sessionId = null;
|
|
45
|
+
constructor(config) {
|
|
46
|
+
this.stealthConfig = { ...DEFAULT_STEALTH_CONFIG, ...config };
|
|
47
|
+
}
|
|
48
|
+
// ========================================================================
|
|
49
|
+
// Lifecycle
|
|
50
|
+
// ========================================================================
|
|
51
|
+
async isAvailable() {
|
|
52
|
+
return getPatchright() !== null;
|
|
53
|
+
}
|
|
54
|
+
async launch(options) {
|
|
55
|
+
const pr = getPatchright();
|
|
56
|
+
if (!pr) {
|
|
57
|
+
return {
|
|
58
|
+
success: false,
|
|
59
|
+
error: new BrowserUnavailableError('stealth', 'Patchright is not installed. Install with: npm install patchright'),
|
|
60
|
+
};
|
|
61
|
+
}
|
|
62
|
+
try {
|
|
63
|
+
const launchOptions = {
|
|
64
|
+
headless: options?.headless ?? true,
|
|
65
|
+
};
|
|
66
|
+
if (options?.viewport) {
|
|
67
|
+
launchOptions.viewport = options.viewport;
|
|
68
|
+
}
|
|
69
|
+
if (options?.args) {
|
|
70
|
+
launchOptions.args = options.args;
|
|
71
|
+
}
|
|
72
|
+
if (this.stealthConfig.userAgent) {
|
|
73
|
+
launchOptions.userAgent = this.stealthConfig.userAgent;
|
|
74
|
+
}
|
|
75
|
+
if (this.stealthConfig.proxy) {
|
|
76
|
+
launchOptions.proxy = this.stealthConfig.proxy;
|
|
77
|
+
}
|
|
78
|
+
if (this.stealthConfig.persistentContext) {
|
|
79
|
+
const userDataDir = this.stealthConfig.userDataDir || `/tmp/stealth-browser-${randomUUID()}`;
|
|
80
|
+
this.context = await pr.chromium.launchPersistentContext(userDataDir, launchOptions);
|
|
81
|
+
const pages = this.context.pages();
|
|
82
|
+
this.page = pages.length > 0 ? pages[0] : await this.context.newPage();
|
|
83
|
+
}
|
|
84
|
+
else {
|
|
85
|
+
this.browser = await pr.chromium.launch(launchOptions);
|
|
86
|
+
this.page = await this.browser.newPage();
|
|
87
|
+
}
|
|
88
|
+
// Apply resource blocking
|
|
89
|
+
await this.applyResourceBlocking();
|
|
90
|
+
this.sessionId = randomUUID();
|
|
91
|
+
return {
|
|
92
|
+
success: true,
|
|
93
|
+
value: {
|
|
94
|
+
id: this.sessionId,
|
|
95
|
+
tool: 'stealth',
|
|
96
|
+
status: 'active',
|
|
97
|
+
createdAt: new Date(),
|
|
98
|
+
},
|
|
99
|
+
};
|
|
100
|
+
}
|
|
101
|
+
catch (err) {
|
|
102
|
+
return {
|
|
103
|
+
success: false,
|
|
104
|
+
error: new BrowserError(`Failed to launch stealth browser: ${err instanceof Error ? err.message : String(err)}`, 'LAUNCH_FAILED', 'stealth', err instanceof Error ? err : undefined),
|
|
105
|
+
};
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
async quit() {
|
|
109
|
+
try {
|
|
110
|
+
if (this.context) {
|
|
111
|
+
await this.context.close();
|
|
112
|
+
this.context = null;
|
|
113
|
+
}
|
|
114
|
+
if (this.browser) {
|
|
115
|
+
await this.browser.close();
|
|
116
|
+
this.browser = null;
|
|
117
|
+
}
|
|
118
|
+
this.page = null;
|
|
119
|
+
this.sessionId = null;
|
|
120
|
+
return { success: true, value: undefined };
|
|
121
|
+
}
|
|
122
|
+
catch (err) {
|
|
123
|
+
return {
|
|
124
|
+
success: false,
|
|
125
|
+
error: new BrowserError('Failed to quit stealth browser', 'QUIT_FAILED', 'stealth', err instanceof Error ? err : undefined),
|
|
126
|
+
};
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
// ========================================================================
|
|
130
|
+
// Navigation
|
|
131
|
+
// ========================================================================
|
|
132
|
+
async navigate(url) {
|
|
133
|
+
if (!this.page)
|
|
134
|
+
return this.notLaunched();
|
|
135
|
+
try {
|
|
136
|
+
const start = Date.now();
|
|
137
|
+
const response = await this.page.goto(url, { waitUntil: 'domcontentloaded' });
|
|
138
|
+
const statusCode = response?.status() ?? undefined;
|
|
139
|
+
// Optional Cloudflare challenge wait
|
|
140
|
+
if (this.stealthConfig.cloudflareWaitSeconds > 0) {
|
|
141
|
+
await this.waitForCloudflare();
|
|
142
|
+
}
|
|
143
|
+
const title = await this.page.title();
|
|
144
|
+
return {
|
|
145
|
+
success: true,
|
|
146
|
+
value: {
|
|
147
|
+
url: this.page.url(),
|
|
148
|
+
title,
|
|
149
|
+
success: true,
|
|
150
|
+
durationMs: Date.now() - start,
|
|
151
|
+
statusCode: statusCode ?? undefined,
|
|
152
|
+
},
|
|
153
|
+
};
|
|
154
|
+
}
|
|
155
|
+
catch (err) {
|
|
156
|
+
return this.wrapError('navigate', err);
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
async reload() {
|
|
160
|
+
if (!this.page)
|
|
161
|
+
return this.notLaunched();
|
|
162
|
+
try {
|
|
163
|
+
await this.page.reload();
|
|
164
|
+
return { success: true, value: undefined };
|
|
165
|
+
}
|
|
166
|
+
catch (err) {
|
|
167
|
+
return this.wrapError('reload', err);
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
async goBack() {
|
|
171
|
+
if (!this.page)
|
|
172
|
+
return this.notLaunched();
|
|
173
|
+
try {
|
|
174
|
+
await this.page.goBack();
|
|
175
|
+
return { success: true, value: undefined };
|
|
176
|
+
}
|
|
177
|
+
catch (err) {
|
|
178
|
+
return this.wrapError('goBack', err);
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
async goForward() {
|
|
182
|
+
if (!this.page)
|
|
183
|
+
return this.notLaunched();
|
|
184
|
+
try {
|
|
185
|
+
await this.page.goForward();
|
|
186
|
+
return { success: true, value: undefined };
|
|
187
|
+
}
|
|
188
|
+
catch (err) {
|
|
189
|
+
return this.wrapError('goForward', err);
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
// ========================================================================
|
|
193
|
+
// Element Interaction
|
|
194
|
+
// ========================================================================
|
|
195
|
+
async click(target) {
|
|
196
|
+
if (!this.page)
|
|
197
|
+
return this.notLaunched();
|
|
198
|
+
try {
|
|
199
|
+
const selector = this.resolveSelector(target);
|
|
200
|
+
await this.page.click(selector);
|
|
201
|
+
return { success: true, value: undefined };
|
|
202
|
+
}
|
|
203
|
+
catch (err) {
|
|
204
|
+
return this.wrapError('click', err);
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
async fill(target, text) {
|
|
208
|
+
if (!this.page)
|
|
209
|
+
return this.notLaunched();
|
|
210
|
+
try {
|
|
211
|
+
const selector = this.resolveSelector(target);
|
|
212
|
+
await this.page.fill(selector, text);
|
|
213
|
+
return { success: true, value: undefined };
|
|
214
|
+
}
|
|
215
|
+
catch (err) {
|
|
216
|
+
return this.wrapError('fill', err);
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
async getText(target) {
|
|
220
|
+
if (!this.page)
|
|
221
|
+
return this.notLaunched();
|
|
222
|
+
try {
|
|
223
|
+
const selector = this.resolveSelector(target);
|
|
224
|
+
const text = await this.page.textContent(selector);
|
|
225
|
+
return { success: true, value: text ?? '' };
|
|
226
|
+
}
|
|
227
|
+
catch (err) {
|
|
228
|
+
return this.wrapError('getText', err);
|
|
229
|
+
}
|
|
230
|
+
}
|
|
231
|
+
async isVisible(target) {
|
|
232
|
+
if (!this.page)
|
|
233
|
+
return this.notLaunched();
|
|
234
|
+
try {
|
|
235
|
+
const selector = this.resolveSelector(target);
|
|
236
|
+
const visible = await this.page.isVisible(selector);
|
|
237
|
+
return { success: true, value: visible };
|
|
238
|
+
}
|
|
239
|
+
catch (err) {
|
|
240
|
+
return this.wrapError('isVisible', err);
|
|
241
|
+
}
|
|
242
|
+
}
|
|
243
|
+
// ========================================================================
|
|
244
|
+
// Screenshots
|
|
245
|
+
// ========================================================================
|
|
246
|
+
async screenshot(options) {
|
|
247
|
+
if (!this.page)
|
|
248
|
+
return this.notLaunched();
|
|
249
|
+
try {
|
|
250
|
+
const buffer = await this.page.screenshot({
|
|
251
|
+
path: options?.path,
|
|
252
|
+
fullPage: options?.fullPage,
|
|
253
|
+
type: 'png',
|
|
254
|
+
});
|
|
255
|
+
return {
|
|
256
|
+
success: true,
|
|
257
|
+
value: {
|
|
258
|
+
base64: buffer.toString('base64'),
|
|
259
|
+
path: options?.path,
|
|
260
|
+
format: 'png',
|
|
261
|
+
dimensions: { width: 0, height: 0 }, // Patchright doesn't expose dimensions directly
|
|
262
|
+
},
|
|
263
|
+
};
|
|
264
|
+
}
|
|
265
|
+
catch (err) {
|
|
266
|
+
return this.wrapError('screenshot', err);
|
|
267
|
+
}
|
|
268
|
+
}
|
|
269
|
+
// ========================================================================
|
|
270
|
+
// Evaluate
|
|
271
|
+
// ========================================================================
|
|
272
|
+
async evaluate(script) {
|
|
273
|
+
if (!this.page)
|
|
274
|
+
return this.notLaunched();
|
|
275
|
+
try {
|
|
276
|
+
const result = await this.page.evaluate(script);
|
|
277
|
+
return { success: true, value: result };
|
|
278
|
+
}
|
|
279
|
+
catch (err) {
|
|
280
|
+
return this.wrapError('evaluate', err);
|
|
281
|
+
}
|
|
282
|
+
}
|
|
283
|
+
// ========================================================================
|
|
284
|
+
// Cleanup
|
|
285
|
+
// ========================================================================
|
|
286
|
+
async dispose() {
|
|
287
|
+
await this.quit();
|
|
288
|
+
}
|
|
289
|
+
// ========================================================================
|
|
290
|
+
// Private Helpers
|
|
291
|
+
// ========================================================================
|
|
292
|
+
resolveSelector(target) {
|
|
293
|
+
if (typeof target === 'string')
|
|
294
|
+
return target;
|
|
295
|
+
switch (target.type) {
|
|
296
|
+
case 'css':
|
|
297
|
+
return target.value;
|
|
298
|
+
case 'xpath':
|
|
299
|
+
return `xpath=${target.value}`;
|
|
300
|
+
case 'text':
|
|
301
|
+
return `text=${target.value}`;
|
|
302
|
+
case 'ref':
|
|
303
|
+
return target.value;
|
|
304
|
+
default:
|
|
305
|
+
return target.value;
|
|
306
|
+
}
|
|
307
|
+
}
|
|
308
|
+
async applyResourceBlocking() {
|
|
309
|
+
if (!this.page || !this.stealthConfig.resourceBlocking)
|
|
310
|
+
return;
|
|
311
|
+
const config = typeof this.stealthConfig.resourceBlocking === 'string'
|
|
312
|
+
? getResourceBlockingPreset(this.stealthConfig.resourceBlocking)
|
|
313
|
+
: this.stealthConfig.resourceBlocking;
|
|
314
|
+
if (!config.enabled)
|
|
315
|
+
return;
|
|
316
|
+
await this.page.route('**/*', (route) => {
|
|
317
|
+
const url = route.request().url();
|
|
318
|
+
const resourceType = route.request().resourceType();
|
|
319
|
+
if (shouldBlockRequest(url, resourceType, config)) {
|
|
320
|
+
route.abort().catch(() => { });
|
|
321
|
+
}
|
|
322
|
+
else {
|
|
323
|
+
route.continue().catch(() => { });
|
|
324
|
+
}
|
|
325
|
+
});
|
|
326
|
+
}
|
|
327
|
+
async waitForCloudflare() {
|
|
328
|
+
if (!this.page || this.stealthConfig.cloudflareWaitSeconds <= 0)
|
|
329
|
+
return;
|
|
330
|
+
const ms = this.stealthConfig.cloudflareWaitSeconds * 1000;
|
|
331
|
+
const start = Date.now();
|
|
332
|
+
while (Date.now() - start < ms) {
|
|
333
|
+
try {
|
|
334
|
+
const title = await this.page.title();
|
|
335
|
+
// Cloudflare challenge pages typically have these in the title
|
|
336
|
+
if (!title.includes('Just a moment') && !title.includes('Checking your browser')) {
|
|
337
|
+
return;
|
|
338
|
+
}
|
|
339
|
+
}
|
|
340
|
+
catch {
|
|
341
|
+
// page might not be ready
|
|
342
|
+
}
|
|
343
|
+
await new Promise((resolve) => setTimeout(resolve, 500));
|
|
344
|
+
}
|
|
345
|
+
}
|
|
346
|
+
notLaunched() {
|
|
347
|
+
return {
|
|
348
|
+
success: false,
|
|
349
|
+
error: new BrowserError('Stealth browser not launched. Call launch() first.', 'NOT_LAUNCHED', 'stealth'),
|
|
350
|
+
};
|
|
351
|
+
}
|
|
352
|
+
wrapError(operation, err) {
|
|
353
|
+
return {
|
|
354
|
+
success: false,
|
|
355
|
+
error: new BrowserError(`Stealth ${operation} failed: ${err instanceof Error ? err.message : String(err)}`, 'OPERATION_FAILED', 'stealth', err instanceof Error ? err : undefined),
|
|
356
|
+
};
|
|
357
|
+
}
|
|
358
|
+
}
|
|
359
|
+
//# sourceMappingURL=stealth-client.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"stealth-client.js","sourceRoot":"","sources":["../../../../src/integrations/browser/stealth/stealth-client.ts"],"names":[],"mappings":"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"}
|