@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.
- package/CLAUDE.md +344 -0
- package/LICENSE +21 -0
- package/README.md +250 -0
- package/chrome-extension/README.md +41 -0
- package/chrome-extension/background.js +3917 -0
- package/chrome-extension/chrome-session-manager.js +706 -0
- package/chrome-extension/content.css +181 -0
- package/chrome-extension/content.js +3022 -0
- package/chrome-extension/data-buffer.js +435 -0
- package/chrome-extension/dom-tracker.js +411 -0
- package/chrome-extension/extension-config.js +78 -0
- package/chrome-extension/firebase-client.js +278 -0
- package/chrome-extension/firebase-config.js +32 -0
- package/chrome-extension/firebase-config.module.js +22 -0
- package/chrome-extension/firebase-config.module.template.js +27 -0
- package/chrome-extension/firebase-config.template.js +36 -0
- package/chrome-extension/frame-capture.js +407 -0
- package/chrome-extension/icon128.png +1 -0
- package/chrome-extension/icon16.png +1 -0
- package/chrome-extension/icon48.png +1 -0
- package/chrome-extension/license-helper.js +181 -0
- package/chrome-extension/logger.js +23 -0
- package/chrome-extension/manifest.json +73 -0
- package/chrome-extension/network-tracker.js +510 -0
- package/chrome-extension/offscreen.html +10 -0
- package/chrome-extension/options.html +203 -0
- package/chrome-extension/options.js +282 -0
- package/chrome-extension/pako.min.js +2 -0
- package/chrome-extension/performance-monitor.js +533 -0
- package/chrome-extension/pii-redactor.js +405 -0
- package/chrome-extension/popup.html +532 -0
- package/chrome-extension/popup.js +2446 -0
- package/chrome-extension/upload-manager.js +323 -0
- package/chrome-extension/web-vitals.iife.js +1 -0
- package/config/api-keys.json +11 -0
- package/config/chrome-pilot-config.json +45 -0
- package/package.json +126 -0
- package/scripts/cleanup-processes.js +109 -0
- package/scripts/config-manager.js +280 -0
- package/scripts/generate-extension-config.js +53 -0
- package/scripts/setup-security.js +64 -0
- package/src/capture/architecture.js +426 -0
- package/src/capture/error-handling-tests.md +38 -0
- package/src/capture/error-handling-types.ts +360 -0
- package/src/capture/index.js +508 -0
- package/src/capture/interfaces.js +625 -0
- package/src/capture/memory-manager.js +713 -0
- package/src/capture/types.js +342 -0
- package/src/chrome-controller.js +2658 -0
- package/src/cli.js +19 -0
- package/src/config-loader.js +303 -0
- package/src/database.js +2178 -0
- package/src/firebase-license-manager.js +462 -0
- package/src/firebase-privacy-guard.js +397 -0
- package/src/http-server.js +1516 -0
- package/src/index-direct.js +157 -0
- package/src/index-modular.js +219 -0
- package/src/index-monolithic-backup.js +2230 -0
- package/src/index.js +305 -0
- package/src/legacy/chrome-controller-old.js +1406 -0
- package/src/legacy/index-express.js +625 -0
- package/src/legacy/index-old.js +977 -0
- package/src/legacy/routes.js +260 -0
- package/src/legacy/shared-storage.js +101 -0
- package/src/logger.js +10 -0
- package/src/mcp/handlers/chrome-tool-handler.js +306 -0
- package/src/mcp/handlers/element-tool-handler.js +51 -0
- package/src/mcp/handlers/frame-tool-handler.js +957 -0
- package/src/mcp/handlers/request-handler.js +104 -0
- package/src/mcp/handlers/workflow-tool-handler.js +636 -0
- package/src/mcp/server.js +68 -0
- package/src/mcp/tools/index.js +701 -0
- package/src/middleware/auth.js +371 -0
- package/src/middleware/security.js +267 -0
- package/src/port-discovery.js +258 -0
- package/src/routes/admin.js +182 -0
- package/src/services/browser-daemon.js +494 -0
- package/src/services/chrome-service.js +375 -0
- package/src/services/failover-manager.js +412 -0
- package/src/services/git-safety-service.js +675 -0
- package/src/services/heartbeat-manager.js +200 -0
- package/src/services/http-client.js +195 -0
- package/src/services/process-manager.js +318 -0
- package/src/services/process-tracker.js +574 -0
- package/src/services/profile-manager.js +449 -0
- package/src/services/project-manager.js +415 -0
- package/src/services/session-manager.js +497 -0
- package/src/services/session-registry.js +491 -0
- package/src/services/unified-session-manager.js +678 -0
- package/src/shared-storage-old.js +267 -0
- package/src/standalone-server.js +53 -0
- package/src/utils/extension-path.js +145 -0
- package/src/utils.js +187 -0
- package/src/validation/log-transformer.js +125 -0
- package/src/validation/schemas.js +391 -0
package/src/cli.js
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
import { spawn } from 'child_process';
|
|
4
|
+
import { fileURLToPath } from 'url';
|
|
5
|
+
import { dirname, join } from 'path';
|
|
6
|
+
|
|
7
|
+
const __filename = fileURLToPath(import.meta.url);
|
|
8
|
+
const __dirname = dirname(__filename);
|
|
9
|
+
|
|
10
|
+
const indexPath = join(__dirname, 'index.js');
|
|
11
|
+
|
|
12
|
+
const child = spawn('node', [indexPath], {
|
|
13
|
+
stdio: 'inherit',
|
|
14
|
+
env: process.env
|
|
15
|
+
});
|
|
16
|
+
|
|
17
|
+
child.on('exit', (code) => {
|
|
18
|
+
process.exit(code);
|
|
19
|
+
});
|
|
@@ -0,0 +1,303 @@
|
|
|
1
|
+
// Configuration loader for Chrome Debug
|
|
2
|
+
import fs from 'fs';
|
|
3
|
+
import path from 'path';
|
|
4
|
+
import { fileURLToPath } from 'url';
|
|
5
|
+
import { ProjectManager } from './services/project-manager.js';
|
|
6
|
+
|
|
7
|
+
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
|
8
|
+
|
|
9
|
+
// Default configuration
|
|
10
|
+
const DEFAULT_CONFIG = {
|
|
11
|
+
serverPorts: {
|
|
12
|
+
httpServer: {
|
|
13
|
+
preferredPorts: [
|
|
14
|
+
// Original range (maintain backward compatibility)
|
|
15
|
+
3001, 3000, 3002, 3028,
|
|
16
|
+
// Extended original range
|
|
17
|
+
3029, 3030, 3031, 3032, 3033, 3034, 3035, 3036,
|
|
18
|
+
// Safer fallback ranges (avoid common service conflicts)
|
|
19
|
+
8080, 8081, 8082, 8083, 8084, 8085, 8086, 8087, 8088, 8089, 8090,
|
|
20
|
+
9000, 9001, 9002, 9003, 9004, 9005, 9006, 9007, 9008, 9009, 9010
|
|
21
|
+
],
|
|
22
|
+
description: "Ports to try for HTTP server discovery, in priority order"
|
|
23
|
+
},
|
|
24
|
+
mcpServer: {
|
|
25
|
+
preferredPorts: [
|
|
26
|
+
// Original range (maintain backward compatibility)
|
|
27
|
+
3028, 3023, 3002, 3003, 3004, 3005,
|
|
28
|
+
// Extended original range
|
|
29
|
+
3029, 3030, 3031, 3032, 3033, 3034, 3035, 3036,
|
|
30
|
+
// Safer fallback ranges (avoid common service conflicts)
|
|
31
|
+
8080, 8081, 8082, 8083, 8084, 8085, 8086, 8087, 8088, 8089, 8090,
|
|
32
|
+
9000, 9001, 9002, 9003, 9004, 9005, 9006, 9007, 9008, 9009, 9010
|
|
33
|
+
],
|
|
34
|
+
description: "Ports to try for MCP server discovery, in priority order"
|
|
35
|
+
},
|
|
36
|
+
discoveryRange: {
|
|
37
|
+
start: 3000,
|
|
38
|
+
end: 9010,
|
|
39
|
+
description: "Port range for automatic discovery when preferred ports are not available"
|
|
40
|
+
}
|
|
41
|
+
},
|
|
42
|
+
chromeExtension: {
|
|
43
|
+
serverDiscovery: {
|
|
44
|
+
timeoutMs: 3000,
|
|
45
|
+
description: "Timeout for server discovery requests in milliseconds"
|
|
46
|
+
},
|
|
47
|
+
portScanOrder: "httpFirst",
|
|
48
|
+
description: "Order to try ports: 'httpFirst' tries HTTP ports first, 'mcpFirst' tries MCP ports first, 'sequential' tries all ports in numerical order"
|
|
49
|
+
},
|
|
50
|
+
logging: {
|
|
51
|
+
level: "info",
|
|
52
|
+
description: "Logging level: debug, info, warn, error"
|
|
53
|
+
}
|
|
54
|
+
};
|
|
55
|
+
|
|
56
|
+
class ConfigLoader {
|
|
57
|
+
constructor() {
|
|
58
|
+
this.config = null;
|
|
59
|
+
this.configPath = null;
|
|
60
|
+
this.projectManager = new ProjectManager();
|
|
61
|
+
this._determineConfigPath();
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
/**
|
|
65
|
+
* Determines the appropriate config path based on project mode
|
|
66
|
+
*/
|
|
67
|
+
_determineConfigPath() {
|
|
68
|
+
try {
|
|
69
|
+
// Try project-local config first
|
|
70
|
+
const projectInfo = this.projectManager.detectProject();
|
|
71
|
+
if (projectInfo) {
|
|
72
|
+
try {
|
|
73
|
+
// Initialize project structure synchronously if possible
|
|
74
|
+
const projectConfigPath = path.join(projectInfo.projectDir, '.chromedebug', 'config', 'config.json');
|
|
75
|
+
|
|
76
|
+
// Ensure config directory exists
|
|
77
|
+
const configDir = path.dirname(projectConfigPath);
|
|
78
|
+
if (!fs.existsSync(configDir)) {
|
|
79
|
+
fs.mkdirSync(configDir, { recursive: true });
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
this.configPath = projectConfigPath;
|
|
83
|
+
console.log(`[ConfigLoader] Using project-local config: ${projectConfigPath}`);
|
|
84
|
+
return;
|
|
85
|
+
} catch (error) {
|
|
86
|
+
console.warn('[ConfigLoader] Project structure not ready, using global config:', error.message);
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
} catch (error) {
|
|
90
|
+
console.warn('[ConfigLoader] Failed project detection, using global config:', error.message);
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
// Fallback to global config
|
|
94
|
+
this.configPath = path.join(__dirname, '../config/chromedebug-config.json');
|
|
95
|
+
console.log(`[ConfigLoader] Using global config: ${this.configPath}`);
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
// Load configuration from file
|
|
99
|
+
loadConfig() {
|
|
100
|
+
if (this.config) return this.config;
|
|
101
|
+
|
|
102
|
+
try {
|
|
103
|
+
if (fs.existsSync(this.configPath)) {
|
|
104
|
+
const configData = fs.readFileSync(this.configPath, 'utf8');
|
|
105
|
+
this.config = { ...DEFAULT_CONFIG, ...JSON.parse(configData) };
|
|
106
|
+
console.log(`Configuration loaded from: ${this.configPath}`);
|
|
107
|
+
} else {
|
|
108
|
+
console.log('No configuration file found, using defaults');
|
|
109
|
+
this.config = DEFAULT_CONFIG;
|
|
110
|
+
|
|
111
|
+
// If we're in project mode and global config exists, copy it first
|
|
112
|
+
if (this.isProjectLocalConfig() && this.hasGlobalConfig()) {
|
|
113
|
+
this.copyGlobalConfigToProject();
|
|
114
|
+
} else {
|
|
115
|
+
this.createDefaultConfigFile();
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
} catch (error) {
|
|
119
|
+
console.warn(`Error loading configuration: ${error.message}`);
|
|
120
|
+
console.log('Using default configuration');
|
|
121
|
+
this.config = DEFAULT_CONFIG;
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
return this.config;
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
/**
|
|
128
|
+
* Checks if current config path is project-local
|
|
129
|
+
* @returns {boolean} True if using project-local config
|
|
130
|
+
*/
|
|
131
|
+
isProjectLocalConfig() {
|
|
132
|
+
return this.configPath && this.configPath.includes('.chromedebug');
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
/**
|
|
136
|
+
* Checks if global config file exists
|
|
137
|
+
* @returns {boolean} True if global config exists
|
|
138
|
+
*/
|
|
139
|
+
hasGlobalConfig() {
|
|
140
|
+
const globalConfigPath = path.join(__dirname, '../config/chromedebug-config.json');
|
|
141
|
+
return fs.existsSync(globalConfigPath);
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
/**
|
|
145
|
+
* Copies global config to project-local config
|
|
146
|
+
*/
|
|
147
|
+
copyGlobalConfigToProject() {
|
|
148
|
+
try {
|
|
149
|
+
const globalConfigPath = path.join(__dirname, '../config/chromedebug-config.json');
|
|
150
|
+
const globalConfigData = fs.readFileSync(globalConfigPath, 'utf8');
|
|
151
|
+
const globalConfig = JSON.parse(globalConfigData);
|
|
152
|
+
|
|
153
|
+
// Merge with defaults and write to project config
|
|
154
|
+
this.config = { ...DEFAULT_CONFIG, ...globalConfig };
|
|
155
|
+
fs.writeFileSync(this.configPath, JSON.stringify(this.config, null, 2));
|
|
156
|
+
|
|
157
|
+
console.log(`[ConfigLoader] Copied global config to project: ${this.configPath}`);
|
|
158
|
+
} catch (error) {
|
|
159
|
+
console.warn(`[ConfigLoader] Failed to copy global config: ${error.message}`);
|
|
160
|
+
this.createDefaultConfigFile();
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
// Create default configuration file
|
|
165
|
+
createDefaultConfigFile() {
|
|
166
|
+
try {
|
|
167
|
+
const configDir = path.dirname(this.configPath);
|
|
168
|
+
if (!fs.existsSync(configDir)) {
|
|
169
|
+
fs.mkdirSync(configDir, { recursive: true });
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
fs.writeFileSync(this.configPath, JSON.stringify(DEFAULT_CONFIG, null, 2));
|
|
173
|
+
console.log(`Default configuration file created at: ${this.configPath}`);
|
|
174
|
+
} catch (error) {
|
|
175
|
+
console.warn(`Could not create default configuration file: ${error.message}`);
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
// Get HTTP server ports in priority order
|
|
180
|
+
getHttpServerPorts() {
|
|
181
|
+
const config = this.loadConfig();
|
|
182
|
+
return [...config.serverPorts.httpServer.preferredPorts];
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
// Get MCP server ports in priority order
|
|
186
|
+
getMcpServerPorts() {
|
|
187
|
+
const config = this.loadConfig();
|
|
188
|
+
return [...config.serverPorts.mcpServer.preferredPorts];
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
// Get combined port list for Chrome extension based on scan order
|
|
192
|
+
getExtensionPortList() {
|
|
193
|
+
const config = this.loadConfig();
|
|
194
|
+
const httpPorts = this.getHttpServerPorts();
|
|
195
|
+
const mcpPorts = this.getMcpServerPorts();
|
|
196
|
+
|
|
197
|
+
let combinedPorts = [];
|
|
198
|
+
|
|
199
|
+
switch (config.chromeExtension.portScanOrder) {
|
|
200
|
+
case 'httpFirst':
|
|
201
|
+
// HTTP ports first, then MCP ports, avoiding duplicates
|
|
202
|
+
combinedPorts = [...httpPorts];
|
|
203
|
+
mcpPorts.forEach(port => {
|
|
204
|
+
if (!combinedPorts.includes(port)) {
|
|
205
|
+
combinedPorts.push(port);
|
|
206
|
+
}
|
|
207
|
+
});
|
|
208
|
+
break;
|
|
209
|
+
|
|
210
|
+
case 'mcpFirst':
|
|
211
|
+
// MCP ports first, then HTTP ports, avoiding duplicates
|
|
212
|
+
combinedPorts = [...mcpPorts];
|
|
213
|
+
httpPorts.forEach(port => {
|
|
214
|
+
if (!combinedPorts.includes(port)) {
|
|
215
|
+
combinedPorts.push(port);
|
|
216
|
+
}
|
|
217
|
+
});
|
|
218
|
+
break;
|
|
219
|
+
|
|
220
|
+
case 'sequential':
|
|
221
|
+
// All ports in numerical order
|
|
222
|
+
const allPorts = [...new Set([...httpPorts, ...mcpPorts])];
|
|
223
|
+
combinedPorts = allPorts.sort((a, b) => a - b);
|
|
224
|
+
break;
|
|
225
|
+
|
|
226
|
+
default:
|
|
227
|
+
// Default to httpFirst
|
|
228
|
+
combinedPorts = [...httpPorts];
|
|
229
|
+
mcpPorts.forEach(port => {
|
|
230
|
+
if (!combinedPorts.includes(port)) {
|
|
231
|
+
combinedPorts.push(port);
|
|
232
|
+
}
|
|
233
|
+
});
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
// Add discovery range if enabled
|
|
237
|
+
const discoveryRange = config.serverPorts.discoveryRange;
|
|
238
|
+
if (discoveryRange.start && discoveryRange.end) {
|
|
239
|
+
for (let port = discoveryRange.start; port <= discoveryRange.end; port++) {
|
|
240
|
+
if (!combinedPorts.includes(port)) {
|
|
241
|
+
combinedPorts.push(port);
|
|
242
|
+
}
|
|
243
|
+
}
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
return combinedPorts;
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
// Get server discovery timeout
|
|
250
|
+
getDiscoveryTimeout() {
|
|
251
|
+
const config = this.loadConfig();
|
|
252
|
+
return config.chromeExtension.serverDiscovery.timeoutMs;
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
// Get logging level
|
|
256
|
+
getLoggingLevel() {
|
|
257
|
+
const config = this.loadConfig();
|
|
258
|
+
return config.logging.level;
|
|
259
|
+
}
|
|
260
|
+
|
|
261
|
+
// Update configuration
|
|
262
|
+
updateConfig(updates) {
|
|
263
|
+
const config = this.loadConfig();
|
|
264
|
+
const newConfig = { ...config, ...updates };
|
|
265
|
+
|
|
266
|
+
try {
|
|
267
|
+
fs.writeFileSync(this.configPath, JSON.stringify(newConfig, null, 2));
|
|
268
|
+
this.config = newConfig;
|
|
269
|
+
console.log('Configuration updated successfully');
|
|
270
|
+
return true;
|
|
271
|
+
} catch (error) {
|
|
272
|
+
console.error(`Error updating configuration: ${error.message}`);
|
|
273
|
+
return false;
|
|
274
|
+
}
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
/**
|
|
278
|
+
* Gets configuration mode information
|
|
279
|
+
* @returns {object} Configuration mode info
|
|
280
|
+
*/
|
|
281
|
+
getConfigInfo() {
|
|
282
|
+
return {
|
|
283
|
+
mode: this.isProjectLocalConfig() ? 'project' : 'global',
|
|
284
|
+
configPath: this.configPath,
|
|
285
|
+
isProjectLocal: this.isProjectLocalConfig(),
|
|
286
|
+
projectInfo: this.projectManager.projectInfo,
|
|
287
|
+
hasGlobalConfig: this.hasGlobalConfig(),
|
|
288
|
+
configExists: fs.existsSync(this.configPath)
|
|
289
|
+
};
|
|
290
|
+
}
|
|
291
|
+
|
|
292
|
+
/**
|
|
293
|
+
* Gets the current config file path
|
|
294
|
+
* @returns {string} Config file path
|
|
295
|
+
*/
|
|
296
|
+
getConfigPath() {
|
|
297
|
+
return this.configPath;
|
|
298
|
+
}
|
|
299
|
+
}
|
|
300
|
+
|
|
301
|
+
// Export singleton instance
|
|
302
|
+
export const configLoader = new ConfigLoader();
|
|
303
|
+
export default configLoader;
|