@eddym06/custom-chrome-mcp 1.0.8 → 1.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (62) hide show
  1. package/CONDITIONAL_DESCRIPTIONS.md +174 -0
  2. package/FUTURE_FEATURES.txt +1503 -0
  3. package/README.md +300 -3
  4. package/TEST_WORKFLOW.md +311 -0
  5. package/USAGE_GUIDE.md +393 -0
  6. package/demo_features.ts +115 -0
  7. package/dist/chrome-connector.d.ts +10 -0
  8. package/dist/chrome-connector.d.ts.map +1 -1
  9. package/dist/chrome-connector.js +44 -0
  10. package/dist/chrome-connector.js.map +1 -1
  11. package/dist/index.js +22 -1
  12. package/dist/index.js.map +1 -1
  13. package/dist/tests/execute-script-tests.d.ts +62 -0
  14. package/dist/tests/execute-script-tests.d.ts.map +1 -0
  15. package/dist/tests/execute-script-tests.js +280 -0
  16. package/dist/tests/execute-script-tests.js.map +1 -0
  17. package/dist/tests/run-execute-tests.d.ts +7 -0
  18. package/dist/tests/run-execute-tests.d.ts.map +1 -0
  19. package/dist/tests/run-execute-tests.js +88 -0
  20. package/dist/tests/run-execute-tests.js.map +1 -0
  21. package/dist/tools/advanced-network.backup.d.ts +245 -0
  22. package/dist/tools/advanced-network.backup.d.ts.map +1 -0
  23. package/dist/tools/advanced-network.backup.js +996 -0
  24. package/dist/tools/advanced-network.backup.js.map +1 -0
  25. package/dist/tools/advanced-network.d.ts +580 -0
  26. package/dist/tools/advanced-network.d.ts.map +1 -0
  27. package/dist/tools/advanced-network.js +1325 -0
  28. package/dist/tools/advanced-network.js.map +1 -0
  29. package/dist/tools/anti-detection.js +5 -5
  30. package/dist/tools/anti-detection.js.map +1 -1
  31. package/dist/tools/capture.d.ts +7 -1
  32. package/dist/tools/capture.d.ts.map +1 -1
  33. package/dist/tools/capture.js +8 -4
  34. package/dist/tools/capture.js.map +1 -1
  35. package/dist/tools/interaction.d.ts +82 -8
  36. package/dist/tools/interaction.d.ts.map +1 -1
  37. package/dist/tools/interaction.js +75 -28
  38. package/dist/tools/interaction.js.map +1 -1
  39. package/dist/tools/navigation.js +7 -7
  40. package/dist/tools/navigation.js.map +1 -1
  41. package/dist/tools/network-accessibility.d.ts +67 -0
  42. package/dist/tools/network-accessibility.d.ts.map +1 -0
  43. package/dist/tools/network-accessibility.js +367 -0
  44. package/dist/tools/network-accessibility.js.map +1 -0
  45. package/dist/tools/playwright-launcher.js +4 -4
  46. package/dist/tools/playwright-launcher.js.map +1 -1
  47. package/dist/tools/service-worker.js +10 -10
  48. package/dist/tools/service-worker.js.map +1 -1
  49. package/dist/tools/session.js +9 -9
  50. package/dist/tools/session.js.map +1 -1
  51. package/dist/tools/system.js +3 -3
  52. package/dist/tools/system.js.map +1 -1
  53. package/dist/utils/truncate.d.ts +29 -0
  54. package/dist/utils/truncate.d.ts.map +1 -0
  55. package/dist/utils/truncate.js +46 -0
  56. package/dist/utils/truncate.js.map +1 -0
  57. package/dist/verify-tools.d.ts +7 -0
  58. package/dist/verify-tools.d.ts.map +1 -0
  59. package/dist/verify-tools.js +137 -0
  60. package/dist/verify-tools.js.map +1 -0
  61. package/package.json +2 -2
  62. package/recordings/demo_recording.har +3036 -0
package/USAGE_GUIDE.md ADDED
@@ -0,0 +1,393 @@
1
+ # Custom Chrome MCP - AI Usage Guide
2
+
3
+ ## 🎯 Philosophy: Always Analyze Before Acting
4
+
5
+ **GOLDEN RULE**: Never guess selectors or click blindly. Always analyze the page structure first.
6
+
7
+ ---
8
+
9
+ ## 📋 Common Workflows
10
+
11
+ ### 1. Basic Web Navigation & Interaction
12
+
13
+ ```
14
+ CORRECT WORKFLOW:
15
+ 1️⃣ navigate - Go to the website
16
+ 2️⃣ wait_for_load_state - Wait for page to fully load (use 'networkidle')
17
+ 3️⃣ get_html or screenshot - ANALYZE the page structure
18
+ 4️⃣ Identify correct CSS selectors from the HTML
19
+ 5️⃣ click or type - Interact using verified selectors
20
+
21
+ EXAMPLE:
22
+ User: "Go to google.com and search for cats"
23
+
24
+ Correct sequence:
25
+ 1. navigate("https://google.com")
26
+ 2. wait_for_load_state("networkidle")
27
+ 3. get_html() → See: <input name="q" class="gLFyf">
28
+ 4. type("input[name='q']", "cats")
29
+ 5. click("input[value='Google Search']")
30
+ ```
31
+
32
+ **❌ WRONG**:
33
+ ```
34
+ navigate → click(".search-button") // NO! You don't know if .search-button exists!
35
+ ```
36
+
37
+ **✅ RIGHT**:
38
+ ```
39
+ navigate → get_html → find selector → click with verified selector
40
+ ```
41
+
42
+ ---
43
+
44
+ ### 2. Extension Debugging
45
+
46
+ ```
47
+ WORKFLOW:
48
+ 1️⃣ list_all_targets - Find all execution contexts
49
+ → Filter by 'service_worker' to see extensions
50
+ 2️⃣ Identify your extension - Look for title/url matching your extension
51
+ 3️⃣ Get targetId - Copy the ID from the target
52
+ 4️⃣ connect_to_target - Establish connection to that target
53
+ 5️⃣ execute_in_target - Run code in the extension context
54
+ 6️⃣ inspect_service_worker_logs - See console output (optional)
55
+
56
+ EXAMPLE:
57
+ User: "Debug my Chrome extension background script"
58
+
59
+ 1. list_all_targets(filterType: 'service_worker')
60
+ → Result: [{id: "ABC123", title: "My Extension", type: "service_worker"}]
61
+ 2. connect_to_target("ABC123")
62
+ 3. execute_in_target("ABC123", "return chrome.runtime.getManifest()")
63
+ 4. inspect_service_worker_logs("ABC123") → See console.log output
64
+ ```
65
+
66
+ **⚠️ CRITICAL**:
67
+ - Use `execute_in_target` for extension contexts, NOT `execute_script`
68
+ - `execute_script` only works on page contexts (tabs)
69
+ - Extension service workers are separate execution contexts
70
+
71
+ ---
72
+
73
+ ### 3. Network Traffic Interception
74
+
75
+ ```
76
+ WORKFLOW FOR INSPECTING REQUESTS:
77
+ 1️⃣ enable_response_interception - Start capturing responses
78
+ → Or use enable_network_interception for simpler request-only capture
79
+ 2️⃣ navigate - Trigger the network request
80
+ 3️⃣ list_intercepted_responses - See what was captured
81
+ 4️⃣ modify_intercepted_response - Change response if needed (optional)
82
+ 5️⃣ disable_response_interception - Stop capturing
83
+
84
+ WORKFLOW FOR MOCKING ENDPOINTS:
85
+ 1️⃣ create_mock_endpoint - Set up fake API response
86
+ → Pattern: "*api.example.com/users*"
87
+ → Response: {"users": [...]}
88
+ 2️⃣ navigate - Page will hit mock instead of real API
89
+ 3️⃣ Test your frontend with fake data
90
+ 4️⃣ delete_mock_endpoint - Clean up
91
+
92
+ ⚠️ CONFLICTS:
93
+ - Cannot use response_interception AND mock_endpoint simultaneously
94
+ - Choose one: interception (for analysis) OR mocking (for testing)
95
+ ```
96
+
97
+ ---
98
+
99
+ ### 4. Form Filling & Submission
100
+
101
+ ```
102
+ WORKFLOW:
103
+ 1️⃣ navigate to form page
104
+ 2️⃣ wait_for_load_state('networkidle')
105
+ 3️⃣ get_html → Analyze form structure
106
+ 4️⃣ Identify input selectors:
107
+ - input#email
108
+ - input[name="password"]
109
+ - button[type="submit"]
110
+ 5️⃣ type into each field with verified selectors
111
+ 6️⃣ click submit button with verified selector
112
+
113
+ EXAMPLE:
114
+ 1. navigate("https://example.com/login")
115
+ 2. wait_for_load_state("networkidle")
116
+ 3. get_html() → See:
117
+ <input id="email" type="email">
118
+ <input id="password" type="password">
119
+ <button type="submit">Login</button>
120
+ 4. type("#email", "user@example.com")
121
+ 5. type("#password", "mypassword")
122
+ 6. click("button[type='submit']")
123
+ ```
124
+
125
+ ---
126
+
127
+ ### 5. Data Extraction / Web Scraping
128
+
129
+ ```
130
+ WORKFLOW:
131
+ 1️⃣ navigate to target page
132
+ 2️⃣ wait_for_load_state('networkidle') - Ensure dynamic content loaded
133
+ 3️⃣ get_html → Get full page structure
134
+ 4️⃣ execute_script with complex query:
135
+ return Array.from(document.querySelectorAll('.item'))
136
+ .map(el => ({
137
+ title: el.querySelector('.title').textContent,
138
+ price: el.querySelector('.price').textContent
139
+ }))
140
+
141
+ WHEN TO USE execute_script:
142
+ ✅ Complex data extraction (querySelectorAll + map/filter)
143
+ ✅ Accessing window variables (return window.appConfig)
144
+ ✅ Triggering custom events
145
+ ✅ Advanced DOM manipulation
146
+
147
+ WHEN NOT TO USE execute_script:
148
+ ❌ Simple clicks (use click tool instead)
149
+ ❌ Simple typing (use type tool instead)
150
+ ❌ Getting HTML (use get_html instead)
151
+ ```
152
+
153
+ ---
154
+
155
+ ### 6. Visual Analysis & Debugging
156
+
157
+ ```
158
+ WORKFLOW:
159
+ 1️⃣ navigate
160
+ 2️⃣ screenshot - Take visual snapshot
161
+ 3️⃣ Analyze screenshot visually
162
+ 4️⃣ Identify elements by their visual position
163
+ 5️⃣ get_html to find selectors for those elements
164
+ 6️⃣ Interact with verified selectors
165
+
166
+ WHEN TO USE SCREENSHOT:
167
+ ✅ Page layout is complex
168
+ ✅ Need visual confirmation (before/after actions)
169
+ ✅ Debugging UI issues
170
+ ✅ HTML is too large to analyze
171
+
172
+ WHEN TO USE GET_HTML:
173
+ ✅ Need exact selectors
174
+ ✅ Scraping structured data
175
+ ✅ Analyzing page structure
176
+ ✅ Finding element attributes/IDs/classes
177
+ ```
178
+
179
+ ---
180
+
181
+ ### 7. HAR Recording (Performance Analysis)
182
+
183
+ ```
184
+ WORKFLOW:
185
+ 1️⃣ start_har_recording - Begin capturing all network traffic
186
+ 2️⃣ navigate or perform actions - Trigger network requests
187
+ 3️⃣ stop_har_recording - Stop capture
188
+ 4️⃣ get_har_entries - Analyze requests/responses
189
+ → Or export_har_file - Save for external analysis
190
+
191
+ USE CASES:
192
+ - Performance testing (find slow requests)
193
+ - Network debugging (see all API calls)
194
+ - Security analysis (inspect headers/cookies)
195
+ - Regression testing (compare HAR files)
196
+ ```
197
+
198
+ ---
199
+
200
+ ### 8. CSS/JS Injection (Persistent Modifications)
201
+
202
+ ```
203
+ WORKFLOW FOR STYLING:
204
+ 1️⃣ inject_css_global - Add persistent styles
205
+ → CSS applies to all new pages automatically
206
+ 2️⃣ navigate to any page
207
+ 3️⃣ CSS is automatically injected
208
+ 4️⃣ clear_all_injections - Remove when done
209
+
210
+ WORKFLOW FOR BEHAVIOR:
211
+ 1️⃣ inject_js_global - Add persistent JavaScript
212
+ → Runs BEFORE page scripts
213
+ → Can intercept functions
214
+ 2️⃣ navigate to any page
215
+ 3️⃣ Your code runs automatically
216
+ 4️⃣ clear_all_injections - Remove when done
217
+
218
+ USE CASES:
219
+ - UI customization (dark mode, hide elements)
220
+ - Function interception (override fetch, console.log)
221
+ - Auto-fill forms
222
+ - Add custom buttons/features
223
+ ```
224
+
225
+ ---
226
+
227
+ ## 🚫 Common Mistakes to Avoid
228
+
229
+ ### ❌ Mistake #1: Guessing Selectors
230
+ ```javascript
231
+ // WRONG
232
+ navigate("https://example.com")
233
+ click(".login-button") // What if .login-button doesn't exist?
234
+ ```
235
+
236
+ ```javascript
237
+ // RIGHT
238
+ navigate("https://example.com")
239
+ get_html() // See: <button id="signin">Login</button>
240
+ click("#signin") // Use verified selector
241
+ ```
242
+
243
+ ---
244
+
245
+ ### ❌ Mistake #2: Not Waiting for Page Load
246
+ ```javascript
247
+ // WRONG
248
+ navigate("https://example.com")
249
+ click("#button") // Button might not exist yet!
250
+ ```
251
+
252
+ ```javascript
253
+ // RIGHT
254
+ navigate("https://example.com")
255
+ wait_for_load_state("networkidle") // Wait for page to finish loading
256
+ get_html() // Now analyze
257
+ click("#button") // Now interact
258
+ ```
259
+
260
+ ---
261
+
262
+ ### ❌ Mistake #3: Using Wrong Tool for Context
263
+ ```javascript
264
+ // WRONG - Trying to debug extension with execute_script
265
+ list_all_targets() // Find extension targetId: "ABC123"
266
+ execute_script("chrome.runtime.getManifest()") // ❌ Won't work!
267
+ ```
268
+
269
+ ```javascript
270
+ // RIGHT - Use execute_in_target for extensions
271
+ list_all_targets() // Find extension: "ABC123"
272
+ connect_to_target("ABC123")
273
+ execute_in_target("ABC123", "return chrome.runtime.getManifest()") // ✅ Works!
274
+ ```
275
+
276
+ ---
277
+
278
+ ### ❌ Mistake #4: Over-using execute_script
279
+ ```javascript
280
+ // WRONG - Using execute_script for simple actions
281
+ execute_script("document.querySelector('#button').click()")
282
+ ```
283
+
284
+ ```javascript
285
+ // RIGHT - Use dedicated tools
286
+ get_html() // Verify selector exists
287
+ click("#button") // Simpler, more reliable
288
+ ```
289
+
290
+ ---
291
+
292
+ ### ❌ Mistake #5: Not Analyzing Before Clicking
293
+ ```javascript
294
+ // WRONG
295
+ User: "Click the submit button on example.com"
296
+ navigate("https://example.com")
297
+ click("button") // Which button? There might be many!
298
+ ```
299
+
300
+ ```javascript
301
+ // RIGHT
302
+ navigate("https://example.com")
303
+ get_html() // Analyze: <button class="submit-btn">Submit</button>
304
+ click(".submit-btn") // Use specific selector
305
+ ```
306
+
307
+ ---
308
+
309
+ ## 🎓 Decision Trees
310
+
311
+ ### "Should I use screenshot or get_html?"
312
+
313
+ ```
314
+ START: Need to analyze page
315
+ ├─ Need exact selectors/IDs/classes? → get_html
316
+ ├─ Need visual layout/position? → screenshot
317
+ ├─ HTML is very large (>50KB)? → screenshot first, then get_html if needed
318
+ └─ Need both? → screenshot (visual), then get_html (selectors)
319
+ ```
320
+
321
+ ### "Should I use execute_script or dedicated tools?"
322
+
323
+ ```
324
+ START: Need to interact with page
325
+ ├─ Simple click? → click tool
326
+ ├─ Simple type? → type tool
327
+ ├─ Get HTML? → get_html tool
328
+ ├─ Complex query (querySelectorAll + map)? → execute_script
329
+ ├─ Access window variables? → execute_script
330
+ └─ Trigger custom events? → execute_script
331
+ ```
332
+
333
+ ### "Which interception tool should I use?"
334
+
335
+ ```
336
+ START: Need to intercept network traffic
337
+ ├─ Need to ANALYZE real traffic? → enable_response_interception
338
+ ├─ Need to MOCK/FAKE responses? → create_mock_endpoint
339
+ ├─ Need WebSocket traffic? → enable_websocket_interception
340
+ ├─ Need HAR file for analysis? → start_har_recording
341
+ └─ Just need simple request logging? → enable_network_interception
342
+ ```
343
+
344
+ ---
345
+
346
+ ## 🔧 Troubleshooting
347
+
348
+ ### Problem: "Element not found" errors
349
+ **Solution**: Always use get_html BEFORE clicking to verify selector exists
350
+
351
+ ### Problem: "Timeout" errors
352
+ **Solution**: Use wait_for_load_state("networkidle") after navigation
353
+
354
+ ### Problem: "Cannot read property of undefined" in extension
355
+ **Solution**: Verify you're using execute_in_target, not execute_script
356
+
357
+ ### Problem: Mock endpoint not working
358
+ **Solution**: Check if response_interception is active (conflicts with mocks)
359
+
360
+ ### Problem: Injection not persisting
361
+ **Solution**: Use inject_css_global/inject_js_global, not execute_script
362
+
363
+ ---
364
+
365
+ ## 💡 Pro Tips
366
+
367
+ 1. **Always analyze before acting** - get_html or screenshot first
368
+ 2. **Use specific selectors** - ID > class > tag name
369
+ 3. **Wait for page load** - Use wait_for_load_state("networkidle")
370
+ 4. **Test selectors in browser console** - Before using them in tools
371
+ 5. **Use timeouts wisely** - Increase for slow pages, decrease for fast ones
372
+ 6. **Clean up after yourself** - Clear injections, disable interceptors
373
+ 7. **Read tool descriptions** - They contain workflows and examples
374
+ 8. **Combine tools logically** - navigate → wait → analyze → interact
375
+
376
+ ---
377
+
378
+ ## 📚 Quick Reference
379
+
380
+ | Task | Tools | Workflow |
381
+ |------|-------|----------|
382
+ | Navigate web | navigate → wait_for_load_state → get_html → click/type | Analysis-first approach |
383
+ | Debug extension | list_all_targets → connect_to_target → execute_in_target | Extension-specific execution |
384
+ | Intercept traffic | enable_response_interception → navigate → list_intercepted_responses | Live traffic capture |
385
+ | Mock APIs | create_mock_endpoint → navigate | Testing without backend |
386
+ | Scrape data | navigate → wait → get_html → execute_script (complex queries) | Structured extraction |
387
+ | Visual debug | navigate → screenshot → analyze → get_html → interact | Visual-first analysis |
388
+ | Performance | start_har_recording → actions → stop → get_har_entries | Full network profile |
389
+ | Inject styles | inject_css_global → navigate → clear_all_injections | Persistent modifications |
390
+
391
+ ---
392
+
393
+ **Remember**: The AI should read page structure BEFORE attempting any interaction. Never guess - always verify!
@@ -0,0 +1,115 @@
1
+
2
+ import { ChromeConnector } from './src/chrome-connector.js';
3
+ import { createAdvancedNetworkTools } from './src/tools/advanced-network.js';
4
+ import { createPlaywrightLauncherTools } from './src/tools/playwright-launcher.js';
5
+ import { createNavigationTools } from './src/tools/navigation.js';
6
+
7
+ async function runDemo() {
8
+ console.log('🚀 Iniciando Demo de Herramientas Avanzadas...');
9
+
10
+ // 1. Inicializar Connector
11
+ const connector = new ChromeConnector(9222);
12
+
13
+ // 2. Obtener manejadores de herramientas
14
+ const launcherTools = createPlaywrightLauncherTools(connector);
15
+ const networkTools = createAdvancedNetworkTools(connector);
16
+ const navTools = createNavigationTools(connector);
17
+
18
+ const getHandler = (tools: any[], name: string) => tools.find(t => t.name === name)?.handler;
19
+
20
+ try {
21
+ // 3. Lanzar Chrome
22
+ console.log('\n🌐 Lanzando Chrome...');
23
+ const launchHandler = getHandler(launcherTools, 'launch_chrome_with_profile');
24
+ if (launchHandler) {
25
+ await launchHandler({ profileDirectory: 'Default' });
26
+ console.log('✅ Chrome lanzado correctamente');
27
+ } else {
28
+ // Si falla el launch (quizas ya esta abierto), intentamos conectar
29
+ console.log('⚠️ No se pudo lanzar (quizás ya abierto), intentando conectar...');
30
+ }
31
+
32
+ // Esperar un momento para la conexión
33
+ await new Promise(r => setTimeout(r, 3000));
34
+
35
+ // 4. Configurar Mock de API
36
+ console.log('\n📦 Configurando Mock de API...');
37
+ const createMock = getHandler(networkTools, 'create_mock_endpoint');
38
+ await createMock({
39
+ urlPattern: '*api.example.com/users*',
40
+ responseBody: JSON.stringify([{ id: 1, name: 'Usuario Demo', role: 'Tester' }]),
41
+ statusCode: 200,
42
+ headers: { 'Content-Type': 'application/json' },
43
+ latency: 1000,
44
+ timeoutMs: 10000
45
+ });
46
+ console.log('✅ Mock registrado para *api.example.com/users*');
47
+
48
+ // 5. Inyectar CSS Global
49
+ console.log('\n🎨 Inyectando CSS Global...');
50
+ const injectCss = getHandler(networkTools, 'inject_css_global');
51
+ await injectCss({
52
+ css: 'body { background-color: #f0f8ff !important; border: 5px solid red !important; }',
53
+ name: 'demo-theme',
54
+ timeoutMs: 5000
55
+ });
56
+ console.log('✅ CSS inyectado (Fondo azul claro, borde rojo)');
57
+
58
+ // 6. Iniciar Grabación HAR
59
+ console.log('\n📹 Iniciando grabación HAR...');
60
+ const startHar = getHandler(networkTools, 'start_har_recording');
61
+ await startHar({});
62
+ console.log('✅ Grabación HAR iniciada');
63
+
64
+ // 7. Navegar a una página para probar
65
+ console.log('\nse Navegando a example.com...');
66
+ const navigate = getHandler(navTools, 'navigate');
67
+ await navigate({ url: 'https://example.com' });
68
+ console.log('✅ Navegación completada');
69
+
70
+ // 8. Simular "fetch" en la consola para probar el Mock
71
+ console.log('\n🧪 Probando Mock (Simulando fetch)...');
72
+ // Esto es un truco: inyectamos JS que hace un fetch
73
+ const injectJs = getHandler(networkTools, 'inject_js_global');
74
+ await injectJs({
75
+ javascript: `
76
+ setTimeout(() => {
77
+ console.log("Haciendo fetch a api.example.com...");
78
+ fetch("https://api.example.com/users")
79
+ .then(r => r.json())
80
+ .then(d => {
81
+ console.log("Respuesta Mock recibida:", d);
82
+ const div = document.createElement("div");
83
+ div.style = "position: fixed; top: 10px; right: 10px; background: gold; padding: 20px; z-index: 9999;";
84
+ div.innerText = "MOCK DATA: " + JSON.stringify(d);
85
+ document.body.appendChild(div);
86
+ });
87
+ }, 1000);
88
+ `,
89
+ name: 'mock-test',
90
+ runImmediately: true
91
+ });
92
+ console.log('✅ JS para probar Mock inyectado');
93
+
94
+ // Esperar para que ocurra el tráfico
95
+ console.log('⏳ Esperando 5 segundos para capturar tráfico...');
96
+ await new Promise(r => setTimeout(r, 5000));
97
+
98
+ // 9. Exportar HAR
99
+ console.log('\n💾 Exportando archivo HAR...');
100
+ const exportHar = getHandler(networkTools, 'export_har_file');
101
+ const harResult = await exportHar({
102
+ filename: 'demo_recording.har',
103
+ outputDir: './recordings',
104
+ timeoutMs: 30000
105
+ });
106
+ console.log(`✅ HAR exportado: ${JSON.stringify(harResult)}`);
107
+
108
+ console.log('\n🎉 DEMO COMPLETADA EXITOSAMENTE');
109
+
110
+ } catch (error) {
111
+ console.error('❌ Error durante la demo:', error);
112
+ }
113
+ }
114
+
115
+ runDemo();
@@ -28,6 +28,7 @@ export declare class ChromeConnector {
28
28
  private currentTabId;
29
29
  private browserContext;
30
30
  private chromeProcess;
31
+ private persistentClients;
31
32
  constructor(port?: number);
32
33
  /**
33
34
  * Get platform-specific Chrome paths
@@ -121,6 +122,15 @@ export declare class ChromeConnector {
121
122
  * Get current tab ID
122
123
  */
123
124
  getCurrentTabId(): string | null;
125
+ /**
126
+ * Get or create a persistent client for interceptors
127
+ * These clients stay alive for the entire session
128
+ */
129
+ getPersistentClient(tabId?: string): Promise<any>;
130
+ /**
131
+ * Close persistent client (used when disabling interceptors)
132
+ */
133
+ closePersistentClient(tabId?: string): Promise<void>;
124
134
  /**
125
135
  * Helper to inject a visual connection status toast into the page
126
136
  */
@@ -1 +1 @@
1
- {"version":3,"file":"chrome-connector.d.ts","sourceRoot":"","sources":["../src/chrome-connector.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAGH,OAAO,EAA0B,KAAK,cAAc,EAAE,MAAM,YAAY,CAAC;AASzE,MAAM,WAAW,gBAAgB;IAC/B,MAAM,EAAE,GAAG,CAAC;IACZ,SAAS,EAAE,OAAO,CAAC;IACnB,IAAI,EAAE,MAAM,CAAC;CACd;AAED,MAAM,WAAW,OAAO;IACtB,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,GAAG,EAAE,MAAM,CAAC;IACZ,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,MAAM,WAAW,aAAa;IAC5B,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB;AAED,qBAAa,eAAe;IAC1B,OAAO,CAAC,UAAU,CAAiC;IACnD,OAAO,CAAC,IAAI,CAAS;IACrB,OAAO,CAAC,YAAY,CAAuB;IAC3C,OAAO,CAAC,cAAc,CAA+B;IACrD,OAAO,CAAC,aAAa,CAA6B;gBAEtC,IAAI,GAAE,MAAa;IAI/B;;OAEG;IACH,OAAO,CAAC,gBAAgB;IAqCxB;;;;OAIG;YACW,mBAAmB;IAuEjC;;;OAGG;IACG,iBAAiB,CAAC,OAAO,GAAE,aAAkB,GAAG,OAAO,CAAC,IAAI,CAAC;IA4RnE;;OAEG;IACH,OAAO,CAAC,kBAAkB;IA6B1B;;OAEG;IACG,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC;IAoBjC;;OAEG;IACG,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;IAuB9B;;OAEG;IACH,iBAAiB,IAAI,cAAc,GAAG,IAAI;IAI1C;;OAEG;IACH,mBAAmB,IAAI,OAAO;IAI9B;;OAEG;IACH,aAAa,IAAI,gBAAgB;IAOjC;;OAEG;IACH,WAAW,IAAI,OAAO;IAItB;;OAEG;IACH,OAAO,IAAI,MAAM;IAIjB;;;OAGG;IACG,gBAAgB,IAAI,OAAO,CAAC,IAAI,CAAC;IAyBvC;;OAEG;IACG,QAAQ,IAAI,OAAO,CAAC,OAAO,EAAE,CAAC;IAoBpC;;OAEG;IACG,YAAY,IAAI,OAAO,CAAC,OAAO,GAAG,IAAI,CAAC;IAK7C;;OAEG;IACG,SAAS,CAAC,GAAG,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAe/C;;OAEG;IACG,QAAQ,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAQ5C;;OAEG;IACG,WAAW,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAS/C;;OAEG;IACG,YAAY,CAAC,KAAK,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC;IA+BhD;;OAEG;IACG,cAAc,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,GAAG,GAAG,OAAO,CAAC,GAAG,CAAC;IAWhF;;OAEG;IACG,UAAU,IAAI,OAAO,CAAC,GAAG,CAAC;IAShC;;OAEG;IACH,aAAa,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI;IAIlC;;OAEG;IACH,eAAe,IAAI,MAAM,GAAG,IAAI;IAIhC;;OAEG;IACG,sBAAsB,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IA0B7D;;OAEG;IACG,mBAAmB,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;CA+E3D"}
1
+ {"version":3,"file":"chrome-connector.d.ts","sourceRoot":"","sources":["../src/chrome-connector.ts"],"names":[],"mappings":"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"}
@@ -17,6 +17,7 @@ export class ChromeConnector {
17
17
  currentTabId = null;
18
18
  browserContext = null;
19
19
  chromeProcess = null;
20
+ persistentClients = new Map(); // Persistent clients for interceptors
20
21
  constructor(port = 9222) {
21
22
  this.port = port;
22
23
  }
@@ -656,6 +657,49 @@ export class ChromeConnector {
656
657
  getCurrentTabId() {
657
658
  return this.currentTabId;
658
659
  }
660
+ /**
661
+ * Get or create a persistent client for interceptors
662
+ * These clients stay alive for the entire session
663
+ */
664
+ async getPersistentClient(tabId) {
665
+ const effectiveTabId = tabId || 'default';
666
+ // Return existing persistent client if available
667
+ if (this.persistentClients.has(effectiveTabId)) {
668
+ return this.persistentClients.get(effectiveTabId);
669
+ }
670
+ // Create new persistent client using same logic as getTabClient
671
+ const target = tabId || this.currentTabId;
672
+ let targetId = target;
673
+ if (!targetId) {
674
+ const tabs = await this.listTabs();
675
+ if (tabs.length === 0) {
676
+ throw new Error('No open tabs available');
677
+ }
678
+ targetId = tabs[0].id;
679
+ }
680
+ const client = await CDP({ port: this.port, target: targetId });
681
+ // Store it persistently
682
+ this.persistentClients.set(effectiveTabId, client);
683
+ console.error(`[Persistent Client] Created for tab: ${effectiveTabId}`);
684
+ return client;
685
+ }
686
+ /**
687
+ * Close persistent client (used when disabling interceptors)
688
+ */
689
+ async closePersistentClient(tabId) {
690
+ const effectiveTabId = tabId || 'default';
691
+ if (this.persistentClients.has(effectiveTabId)) {
692
+ const client = this.persistentClients.get(effectiveTabId);
693
+ try {
694
+ await client.close();
695
+ }
696
+ catch (e) {
697
+ console.error(`[Persistent Client] Error closing client:`, e);
698
+ }
699
+ this.persistentClients.delete(effectiveTabId);
700
+ console.error(`[Persistent Client] Closed for tab: ${effectiveTabId}`);
701
+ }
702
+ }
659
703
  /**
660
704
  * Helper to inject a visual connection status toast into the page
661
705
  */