@dynamicu/chromedebug-mcp 2.2.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 (95) hide show
  1. package/CLAUDE.md +344 -0
  2. package/LICENSE +21 -0
  3. package/README.md +250 -0
  4. package/chrome-extension/README.md +41 -0
  5. package/chrome-extension/background.js +3917 -0
  6. package/chrome-extension/chrome-session-manager.js +706 -0
  7. package/chrome-extension/content.css +181 -0
  8. package/chrome-extension/content.js +3022 -0
  9. package/chrome-extension/data-buffer.js +435 -0
  10. package/chrome-extension/dom-tracker.js +411 -0
  11. package/chrome-extension/extension-config.js +78 -0
  12. package/chrome-extension/firebase-client.js +278 -0
  13. package/chrome-extension/firebase-config.js +32 -0
  14. package/chrome-extension/firebase-config.module.js +22 -0
  15. package/chrome-extension/firebase-config.module.template.js +27 -0
  16. package/chrome-extension/firebase-config.template.js +36 -0
  17. package/chrome-extension/frame-capture.js +407 -0
  18. package/chrome-extension/icon128.png +1 -0
  19. package/chrome-extension/icon16.png +1 -0
  20. package/chrome-extension/icon48.png +1 -0
  21. package/chrome-extension/license-helper.js +181 -0
  22. package/chrome-extension/logger.js +23 -0
  23. package/chrome-extension/manifest.json +73 -0
  24. package/chrome-extension/network-tracker.js +510 -0
  25. package/chrome-extension/offscreen.html +10 -0
  26. package/chrome-extension/options.html +203 -0
  27. package/chrome-extension/options.js +282 -0
  28. package/chrome-extension/pako.min.js +2 -0
  29. package/chrome-extension/performance-monitor.js +533 -0
  30. package/chrome-extension/pii-redactor.js +405 -0
  31. package/chrome-extension/popup.html +532 -0
  32. package/chrome-extension/popup.js +2446 -0
  33. package/chrome-extension/upload-manager.js +323 -0
  34. package/chrome-extension/web-vitals.iife.js +1 -0
  35. package/config/api-keys.json +11 -0
  36. package/config/chrome-pilot-config.json +45 -0
  37. package/package.json +126 -0
  38. package/scripts/cleanup-processes.js +109 -0
  39. package/scripts/config-manager.js +280 -0
  40. package/scripts/generate-extension-config.js +53 -0
  41. package/scripts/setup-security.js +64 -0
  42. package/src/capture/architecture.js +426 -0
  43. package/src/capture/error-handling-tests.md +38 -0
  44. package/src/capture/error-handling-types.ts +360 -0
  45. package/src/capture/index.js +508 -0
  46. package/src/capture/interfaces.js +625 -0
  47. package/src/capture/memory-manager.js +713 -0
  48. package/src/capture/types.js +342 -0
  49. package/src/chrome-controller.js +2658 -0
  50. package/src/cli.js +19 -0
  51. package/src/config-loader.js +303 -0
  52. package/src/database.js +2178 -0
  53. package/src/firebase-license-manager.js +462 -0
  54. package/src/firebase-privacy-guard.js +397 -0
  55. package/src/http-server.js +1516 -0
  56. package/src/index-direct.js +157 -0
  57. package/src/index-modular.js +219 -0
  58. package/src/index-monolithic-backup.js +2230 -0
  59. package/src/index.js +305 -0
  60. package/src/legacy/chrome-controller-old.js +1406 -0
  61. package/src/legacy/index-express.js +625 -0
  62. package/src/legacy/index-old.js +977 -0
  63. package/src/legacy/routes.js +260 -0
  64. package/src/legacy/shared-storage.js +101 -0
  65. package/src/logger.js +10 -0
  66. package/src/mcp/handlers/chrome-tool-handler.js +306 -0
  67. package/src/mcp/handlers/element-tool-handler.js +51 -0
  68. package/src/mcp/handlers/frame-tool-handler.js +957 -0
  69. package/src/mcp/handlers/request-handler.js +104 -0
  70. package/src/mcp/handlers/workflow-tool-handler.js +636 -0
  71. package/src/mcp/server.js +68 -0
  72. package/src/mcp/tools/index.js +701 -0
  73. package/src/middleware/auth.js +371 -0
  74. package/src/middleware/security.js +267 -0
  75. package/src/port-discovery.js +258 -0
  76. package/src/routes/admin.js +182 -0
  77. package/src/services/browser-daemon.js +494 -0
  78. package/src/services/chrome-service.js +375 -0
  79. package/src/services/failover-manager.js +412 -0
  80. package/src/services/git-safety-service.js +675 -0
  81. package/src/services/heartbeat-manager.js +200 -0
  82. package/src/services/http-client.js +195 -0
  83. package/src/services/process-manager.js +318 -0
  84. package/src/services/process-tracker.js +574 -0
  85. package/src/services/profile-manager.js +449 -0
  86. package/src/services/project-manager.js +415 -0
  87. package/src/services/session-manager.js +497 -0
  88. package/src/services/session-registry.js +491 -0
  89. package/src/services/unified-session-manager.js +678 -0
  90. package/src/shared-storage-old.js +267 -0
  91. package/src/standalone-server.js +53 -0
  92. package/src/utils/extension-path.js +145 -0
  93. package/src/utils.js +187 -0
  94. package/src/validation/log-transformer.js +125 -0
  95. package/src/validation/schemas.js +391 -0
@@ -0,0 +1,375 @@
1
+ /**
2
+ * Chrome Service Wrapper - Service layer for Chrome controller integration
3
+ * Provides a clean interface between MCP tools and Chrome controller
4
+ */
5
+
6
+ import { ProcessManager } from './process-manager.js';
7
+ import { discoverServer } from '../port-discovery.js';
8
+ import { startHttpServer } from '../http-server.js';
9
+
10
+ /**
11
+ * Chrome Service class that wraps ChromeController with additional services
12
+ * Manages HTTP server integration and process lifecycle
13
+ */
14
+ export class ChromeService {
15
+ constructor(chromeController) {
16
+ this.chromeController = chromeController;
17
+ this.processManager = new ProcessManager();
18
+ this.httpServerPort = null;
19
+ this.httpServer = null;
20
+
21
+ // Add Chrome controller cleanup to process manager
22
+ this.processManager.addShutdownHandler(async () => {
23
+ await this.cleanup();
24
+ });
25
+ }
26
+
27
+ /**
28
+ * Initializes the Chrome service with HTTP server if needed
29
+ * @param {Object} options - Initialization options
30
+ * @returns {Promise<Object>} Initialization result
31
+ */
32
+ async initialize(options = {}) {
33
+ const { startHttp = true, singleServer = false, sessionManager = null } = options;
34
+
35
+ const result = {
36
+ chromeService: 'initialized',
37
+ httpServer: null,
38
+ processManager: this.processManager.getStatistics()
39
+ };
40
+
41
+ if (startHttp && !singleServer) {
42
+ try {
43
+ // Use port from session manager if available, otherwise use discovery
44
+ let targetPort = null;
45
+
46
+ if (sessionManager) {
47
+ const sessionInfo = sessionManager.getSessionInfo();
48
+ if (sessionInfo && sessionInfo.port) {
49
+ targetPort = sessionInfo.port;
50
+ console.error(`Using session manager allocated port: ${targetPort}`);
51
+ }
52
+ }
53
+
54
+ if (!targetPort) {
55
+ // Fallback to discovery
56
+ const serverInfo = await discoverServer();
57
+ console.error('Falling back to port discovery');
58
+ }
59
+
60
+ const { httpServer, serverPort } = await startHttpServer(this.chromeController, targetPort);
61
+
62
+ this.httpServer = httpServer;
63
+ this.httpServerPort = serverPort;
64
+
65
+ result.httpServer = {
66
+ port: serverPort,
67
+ status: 'running'
68
+ };
69
+
70
+ console.error(`HTTP server started on port ${serverPort}`);
71
+ } catch (error) {
72
+ console.error('Failed to start HTTP server:', error);
73
+ result.httpServer = {
74
+ error: error.message,
75
+ status: 'failed'
76
+ };
77
+ }
78
+ }
79
+
80
+ return result;
81
+ }
82
+
83
+ /**
84
+ * Gets the Chrome controller instance
85
+ * @returns {Object} Chrome controller
86
+ */
87
+ getController() {
88
+ return this.chromeController;
89
+ }
90
+
91
+ /**
92
+ * Gets the process manager instance
93
+ * @returns {ProcessManager} Process manager
94
+ */
95
+ getProcessManager() {
96
+ return this.processManager;
97
+ }
98
+
99
+ /**
100
+ * Gets HTTP server information
101
+ * @returns {Object} HTTP server info
102
+ */
103
+ getHttpServerInfo() {
104
+ return {
105
+ port: this.httpServerPort,
106
+ running: !!this.httpServer,
107
+ server: this.httpServer
108
+ };
109
+ }
110
+
111
+ /**
112
+ * Safely launches Chrome with process management
113
+ * @param {Object} options - Launch options
114
+ * @returns {Promise<Object>} Launch result
115
+ */
116
+ async launchChrome(options = {}) {
117
+ try {
118
+ const result = await this.chromeController.launch(options);
119
+
120
+ // Register Chrome process for management if available
121
+ if (result.chromeProcess && result.chromeProcess.pid) {
122
+ this.processManager.registerProcess(result.chromeProcess.pid);
123
+ }
124
+
125
+ return result;
126
+ } catch (error) {
127
+ console.error('Error launching Chrome:', error);
128
+ throw error;
129
+ }
130
+ }
131
+
132
+ /**
133
+ * Connects to existing Chrome with process management
134
+ * @param {number} port - Chrome debugging port
135
+ * @returns {Promise<Object>} Connection result
136
+ */
137
+ async connectToExistingChrome(port = 9222) {
138
+ try {
139
+ const result = await this.chromeController.connectToExisting(port);
140
+
141
+ // Note: We don't register external Chrome processes for management
142
+ // since we didn't create them and shouldn't kill them
143
+
144
+ return result;
145
+ } catch (error) {
146
+ console.error('Error connecting to Chrome:', error);
147
+ throw error;
148
+ }
149
+ }
150
+
151
+ /**
152
+ * Alias for connectToExistingChrome for MCP ChromeToolHandler compatibility
153
+ * @param {number} port - Chrome debugging port
154
+ * @returns {Promise<Object>} Connection result
155
+ */
156
+ async connectToExisting(port = 9222) {
157
+ // Alias for ChromeToolHandler compatibility
158
+ return this.connectToExistingChrome(port);
159
+ }
160
+
161
+ /**
162
+ * Force reset Chrome with comprehensive cleanup
163
+ * @returns {Promise<Object>} Reset result
164
+ */
165
+ async forceReset() {
166
+ try {
167
+ // First, let the chrome controller handle its cleanup
168
+ const chromeResult = await this.chromeController.forceReset();
169
+
170
+ // Then use process manager to clean up any remaining processes
171
+ const processResult = await this.processManager.cleanupChromePilotProcesses();
172
+
173
+ return {
174
+ chromeController: chromeResult,
175
+ processCleanup: processResult,
176
+ httpServer: this.httpServerPort ? {
177
+ port: this.httpServerPort,
178
+ running: !!this.httpServer
179
+ } : null
180
+ };
181
+ } catch (error) {
182
+ console.error('Error during force reset:', error);
183
+ throw error;
184
+ }
185
+ }
186
+
187
+ /**
188
+ * Gets comprehensive connection status
189
+ * @returns {Promise<Object>} Status information
190
+ */
191
+ async getStatus() {
192
+ const chromeStatus = await this.chromeController.getConnectionStatus();
193
+ const processStats = this.processManager.getStatistics();
194
+ const httpInfo = this.getHttpServerInfo();
195
+
196
+ return {
197
+ chrome: chromeStatus,
198
+ httpServer: httpInfo,
199
+ processManager: processStats,
200
+ timestamp: new Date().toISOString()
201
+ };
202
+ }
203
+
204
+ /**
205
+ * Cleans up all managed resources
206
+ * @returns {Promise<void>}
207
+ */
208
+ async cleanup() {
209
+ try {
210
+ // Stop HTTP server if running
211
+ if (this.httpServer) {
212
+ this.httpServer.close();
213
+ this.httpServer = null;
214
+ this.httpServerPort = null;
215
+ }
216
+
217
+ // Clean up Chrome controller
218
+ if (this.chromeController && typeof this.chromeController.cleanup === 'function') {
219
+ await this.chromeController.cleanup();
220
+ }
221
+
222
+ console.error('Chrome service cleanup completed');
223
+ } catch (error) {
224
+ console.error('Error during Chrome service cleanup:', error);
225
+ }
226
+ }
227
+
228
+ // MCP Tool Interface Compatibility Methods
229
+ // These proxy methods provide the expected interface for MCP tools
230
+
231
+ /**
232
+ * Launch Chrome - proxy to launchChrome for MCP compatibility
233
+ * @param {Object} options - Launch options
234
+ * @returns {Promise<Object>} Launch result
235
+ */
236
+ async launch(options = {}) {
237
+ return this.launchChrome(options);
238
+ }
239
+
240
+ /**
241
+ * Get connection status - proxy to chromeController for MCP compatibility
242
+ * @returns {Promise<Object>} Connection status
243
+ */
244
+ async getConnectionStatus() {
245
+ return await this.chromeController.getConnectionStatus();
246
+ }
247
+
248
+ /**
249
+ * Delegates method calls to the Chrome controller
250
+ * This allows the service to act as a proxy while adding process management
251
+ */
252
+
253
+ // Navigation methods
254
+ async navigateTo(url) {
255
+ return await this.chromeController.navigateTo(url);
256
+ }
257
+
258
+ // Debug methods
259
+ async pause() {
260
+ return await this.chromeController.pause();
261
+ }
262
+
263
+ async resume() {
264
+ return await this.chromeController.resume();
265
+ }
266
+
267
+ async stepOver() {
268
+ return await this.chromeController.stepOver();
269
+ }
270
+
271
+ async evaluate(expression) {
272
+ return await this.chromeController.evaluate(expression);
273
+ }
274
+
275
+ async getScopes() {
276
+ return await this.chromeController.getScopes();
277
+ }
278
+
279
+ async setBreakpoint(url, lineNumber) {
280
+ return await this.chromeController.setBreakpoint(url, lineNumber);
281
+ }
282
+
283
+ // Content methods
284
+ async takeScreenshot(options) {
285
+ return await this.chromeController.takeScreenshot(options);
286
+ }
287
+
288
+ async getPageContent(options) {
289
+ return await this.chromeController.getPageContent(options);
290
+ }
291
+
292
+ // Element methods
293
+ async getSelectedElement() {
294
+ return await this.chromeController.getSelectedElement();
295
+ }
296
+
297
+ async applyToSelectedElement(css) {
298
+ return await this.chromeController.applyToSelectedElement(css);
299
+ }
300
+
301
+ async executeOnSelectedElement(code) {
302
+ return await this.chromeController.executeOnSelectedElement(code);
303
+ }
304
+
305
+ async clearSelectedElement() {
306
+ return await this.chromeController.clearSelectedElement();
307
+ }
308
+
309
+ // Workflow methods
310
+ async getWorkflowRecording(sessionId) {
311
+ return await this.chromeController.getWorkflowRecording(sessionId);
312
+ }
313
+
314
+ async listWorkflowRecordings() {
315
+ return await this.chromeController.listWorkflowRecordings();
316
+ }
317
+
318
+ async saveRestorePoint(data) {
319
+ return await this.chromeController.saveRestorePoint(data);
320
+ }
321
+
322
+ async getRestorePoint(id) {
323
+ return await this.chromeController.getRestorePoint(id);
324
+ }
325
+
326
+ async listRestorePoints(workflowId) {
327
+ return await this.chromeController.listRestorePoints(workflowId);
328
+ }
329
+
330
+ async playWorkflowRecording(sessionId, speed) {
331
+ return await this.chromeController.playWorkflowRecording(sessionId, speed);
332
+ }
333
+
334
+ async playWorkflowByName(name, speed) {
335
+ return await this.chromeController.playWorkflowByName(name, speed);
336
+ }
337
+
338
+ // Frame methods
339
+ async getFrameSessionInfo(sessionId) {
340
+ return await this.chromeController.getFrameSessionInfo(sessionId);
341
+ }
342
+
343
+ async listFrameSessions() {
344
+ return await this.chromeController.listFrameSessions();
345
+ }
346
+
347
+ async getFrame(sessionId, frameIndex) {
348
+ return await this.chromeController.getFrame(sessionId, frameIndex);
349
+ }
350
+
351
+ async searchFrameLogs(sessionId, searchText, logLevel, maxResults) {
352
+ return await this.chromeController.searchFrameLogs(sessionId, searchText, logLevel, maxResults);
353
+ }
354
+
355
+ async getFrameLogsPaginated(sessionId, frameIndex, offset, limit, logLevel, searchText) {
356
+ return await this.chromeController.getFrameLogsPaginated(sessionId, frameIndex, offset, limit, logLevel, searchText);
357
+ }
358
+
359
+ async getScreenInteractions(sessionId) {
360
+ return await this.chromeController.getScreenInteractions(sessionId);
361
+ }
362
+
363
+ async getFrameInteractions(sessionId, frameIndex) {
364
+ return await this.chromeController.getFrameInteractions(sessionId, frameIndex);
365
+ }
366
+
367
+ // Utility methods
368
+ getLogs() {
369
+ return this.chromeController.getLogs();
370
+ }
371
+
372
+ async getPage() {
373
+ return await this.chromeController.getPage();
374
+ }
375
+ }