@dynamicu/chromedebug-mcp 2.5.14 → 2.6.1
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/package.json +3 -1
- package/scripts/webpack.config.pro.cjs +2 -2
- package/src/capture/memory-manager.js +3 -3
- package/src/cli.js +4 -0
- package/src/commands/install-pro.js +37 -37
- package/src/firebase-license-manager.js +4 -4
- package/src/http-server.js +144 -140
- package/src/index-modular.js +1 -1
- package/src/index.js +6 -1
- package/src/logger.js +102 -11
- package/src/mcp/handlers/chrome-tool-handler.js +3 -3
- package/src/mcp/handlers/frame-tool-handler.js +10 -10
- package/src/mcp/handlers/workflow-tool-handler.js +2 -2
- package/src/middleware/security.js +4 -4
- package/src/services/browser-daemon.js +17 -17
- package/src/services/git-safety-service.js +3 -3
- package/src/services/heartbeat-manager.js +7 -7
- package/src/services/process-manager.js +1 -1
- package/src/services/process-tracker.js +22 -22
- package/src/services/profile-manager.js +18 -18
- package/src/services/session-manager.js +21 -21
- package/src/services/session-registry.js +21 -21
- package/src/services/unified-session-manager.js +13 -13
- package/src/standalone-server.js +21 -17
- package/src/utils/extension-path.js +9 -9
- package/src/utils.js +2 -2
- package/src/validation/schemas.js +2 -2
|
@@ -81,10 +81,10 @@ export class UnifiedSessionManager {
|
|
|
81
81
|
this.initialized = true;
|
|
82
82
|
|
|
83
83
|
if (this.verbose) {
|
|
84
|
-
console.
|
|
85
|
-
console.
|
|
86
|
-
console.
|
|
87
|
-
console.
|
|
84
|
+
console.error(`Session initialized: ${this.sessionId}`);
|
|
85
|
+
console.error(` PID: ${this.state.pid}`);
|
|
86
|
+
console.error(` Port: ${this.state.port}`);
|
|
87
|
+
console.error(` Session file: ${this.sessionFile}`);
|
|
88
88
|
}
|
|
89
89
|
|
|
90
90
|
return this.state;
|
|
@@ -338,7 +338,7 @@ export class UnifiedSessionManager {
|
|
|
338
338
|
await this.updateSessionFile();
|
|
339
339
|
|
|
340
340
|
if (this.verbose) {
|
|
341
|
-
console.
|
|
341
|
+
console.error(`Registered process: PID ${pid} (${type}) [Session: ${this.sessionId}]`);
|
|
342
342
|
}
|
|
343
343
|
}
|
|
344
344
|
|
|
@@ -350,7 +350,7 @@ export class UnifiedSessionManager {
|
|
|
350
350
|
await this.updateSessionFile();
|
|
351
351
|
|
|
352
352
|
if (this.verbose) {
|
|
353
|
-
console.
|
|
353
|
+
console.error(`Unregistered process: PID ${pid} [Session: ${this.sessionId}]`);
|
|
354
354
|
}
|
|
355
355
|
}
|
|
356
356
|
|
|
@@ -365,7 +365,7 @@ export class UnifiedSessionManager {
|
|
|
365
365
|
// Handle specific error cases that indicate session cleanup
|
|
366
366
|
if (error.code === 'ENOENT' || error.message.includes('Session file does not exist')) {
|
|
367
367
|
if (this.verbose) {
|
|
368
|
-
console.
|
|
368
|
+
console.error(`Session file removed, stopping heartbeat for session ${this.sessionId}`);
|
|
369
369
|
}
|
|
370
370
|
this.stopHeartbeat();
|
|
371
371
|
return;
|
|
@@ -373,7 +373,7 @@ export class UnifiedSessionManager {
|
|
|
373
373
|
|
|
374
374
|
// Handle permission errors gracefully
|
|
375
375
|
if (error.code === 'EPERM' || error.code === 'EACCES' || error.message.includes('Permission denied')) {
|
|
376
|
-
console.
|
|
376
|
+
console.error(`Heartbeat permission error for session ${this.sessionId}:`, error.message);
|
|
377
377
|
this.stopHeartbeat();
|
|
378
378
|
return;
|
|
379
379
|
}
|
|
@@ -396,7 +396,7 @@ export class UnifiedSessionManager {
|
|
|
396
396
|
this.initialized = false;
|
|
397
397
|
|
|
398
398
|
if (this.verbose) {
|
|
399
|
-
console.
|
|
399
|
+
console.error(`Heartbeat stopped for session ${this.sessionId}`);
|
|
400
400
|
}
|
|
401
401
|
}
|
|
402
402
|
}
|
|
@@ -471,7 +471,7 @@ export class UnifiedSessionManager {
|
|
|
471
471
|
cleanedCount++;
|
|
472
472
|
|
|
473
473
|
if (this.verbose) {
|
|
474
|
-
console.
|
|
474
|
+
console.error(`Cleaned up stale session: ${sessionData.sessionId}`);
|
|
475
475
|
}
|
|
476
476
|
}
|
|
477
477
|
} catch (error) {
|
|
@@ -487,7 +487,7 @@ export class UnifiedSessionManager {
|
|
|
487
487
|
await this.cleanupStalePortLocks();
|
|
488
488
|
|
|
489
489
|
if (cleanedCount > 0 && this.verbose) {
|
|
490
|
-
console.
|
|
490
|
+
console.error(`Cleaned up ${cleanedCount} stale sessions`);
|
|
491
491
|
}
|
|
492
492
|
} catch (error) {
|
|
493
493
|
// Directory might not exist
|
|
@@ -539,7 +539,7 @@ export class UnifiedSessionManager {
|
|
|
539
539
|
|
|
540
540
|
const cleanup = async (reason) => {
|
|
541
541
|
if (this.verbose) {
|
|
542
|
-
console.
|
|
542
|
+
console.error(`Session ${this.sessionId} exiting (${reason}), cleaning up...`);
|
|
543
543
|
}
|
|
544
544
|
await this.cleanup();
|
|
545
545
|
};
|
|
@@ -617,7 +617,7 @@ export class UnifiedSessionManager {
|
|
|
617
617
|
} catch {}
|
|
618
618
|
|
|
619
619
|
if (this.verbose) {
|
|
620
|
-
console.
|
|
620
|
+
console.error(`Session ${this.sessionId} cleaned up`);
|
|
621
621
|
}
|
|
622
622
|
} catch (error) {
|
|
623
623
|
console.error(`Error during session cleanup:`, error.message);
|
package/src/standalone-server.js
CHANGED
|
@@ -5,32 +5,36 @@
|
|
|
5
5
|
|
|
6
6
|
import { startHttpServer, startWebSocketServer } from './http-server.js';
|
|
7
7
|
import { removePortFile } from './port-discovery.js';
|
|
8
|
+
import { interceptStdout } from './logger.js';
|
|
8
9
|
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
console.
|
|
13
|
-
console.
|
|
14
|
-
console.
|
|
15
|
-
console.
|
|
16
|
-
console.
|
|
17
|
-
console.
|
|
18
|
-
console.
|
|
19
|
-
console.
|
|
10
|
+
// CRITICAL: Intercept stdout FIRST to prevent MCP JSON-RPC pollution
|
|
11
|
+
interceptStdout();
|
|
12
|
+
|
|
13
|
+
console.error('╔════════════════════════════════════════════════════════════════╗');
|
|
14
|
+
console.error('║ Chrome Debug HTTP Server ║');
|
|
15
|
+
console.error('║ ║');
|
|
16
|
+
console.error('║ This server enables Chrome extension features like: ║');
|
|
17
|
+
console.error('║ - Frame recording ║');
|
|
18
|
+
console.error('║ - Workflow recording ║');
|
|
19
|
+
console.error('║ - Visual element selection ║');
|
|
20
|
+
console.error('║ ║');
|
|
21
|
+
console.error('║ Keep this running while using Chrome Debug through Claude ║');
|
|
22
|
+
console.error('╚════════════════════════════════════════════════════════════════╝');
|
|
23
|
+
console.error('');
|
|
20
24
|
|
|
21
25
|
async function main() {
|
|
22
26
|
try {
|
|
23
27
|
// Start HTTP server
|
|
24
28
|
const httpPort = await startHttpServer();
|
|
25
|
-
console.
|
|
29
|
+
console.error(`✓ HTTP server started on port ${httpPort}`);
|
|
26
30
|
|
|
27
31
|
// Start WebSocket server
|
|
28
32
|
await startWebSocketServer();
|
|
29
|
-
console.
|
|
33
|
+
console.error('✓ WebSocket server started');
|
|
30
34
|
|
|
31
|
-
console.
|
|
32
|
-
console.
|
|
33
|
-
console.
|
|
35
|
+
console.error('');
|
|
36
|
+
console.error('Server is ready! Chrome extension features are now available.');
|
|
37
|
+
console.error('Press Ctrl+C to stop the server.');
|
|
34
38
|
|
|
35
39
|
} catch (error) {
|
|
36
40
|
console.error('Failed to start server:', error.message);
|
|
@@ -40,7 +44,7 @@ async function main() {
|
|
|
40
44
|
|
|
41
45
|
// Cleanup on exit
|
|
42
46
|
process.on('SIGINT', () => {
|
|
43
|
-
console.
|
|
47
|
+
console.error('\nShutting down server...');
|
|
44
48
|
removePortFile();
|
|
45
49
|
process.exit(0);
|
|
46
50
|
});
|
|
@@ -52,18 +52,18 @@ export function getExtensionPath(config = {}) {
|
|
|
52
52
|
const resolvedPath = path.resolve(searchPath);
|
|
53
53
|
|
|
54
54
|
if (validateExtensionPath(resolvedPath)) {
|
|
55
|
-
console.
|
|
55
|
+
console.error(`[ExtensionPath] ✓ Found ChromeDebug extension at: ${resolvedPath}`);
|
|
56
56
|
return resolvedPath;
|
|
57
57
|
}
|
|
58
58
|
}
|
|
59
59
|
|
|
60
|
-
console.
|
|
61
|
-
console.
|
|
62
|
-
searchPaths.filter(Boolean).forEach(p => console.
|
|
63
|
-
console.
|
|
64
|
-
console.
|
|
65
|
-
console.
|
|
66
|
-
console.
|
|
60
|
+
console.error('[ExtensionPath] ⚠ ChromeDebug extension not found in any standard location');
|
|
61
|
+
console.error('[ExtensionPath] Searched locations:');
|
|
62
|
+
searchPaths.filter(Boolean).forEach(p => console.error(`[ExtensionPath] - ${p}`));
|
|
63
|
+
console.error('[ExtensionPath]');
|
|
64
|
+
console.error('[ExtensionPath] To specify a custom location, use:');
|
|
65
|
+
console.error('[ExtensionPath] • Environment variable: CHROMEDEBUG_EXTENSION_PATH=/path/to/extension');
|
|
66
|
+
console.error('[ExtensionPath] • Config file: Set "extensionPath" in config/chrome-pilot-config.json');
|
|
67
67
|
|
|
68
68
|
return null;
|
|
69
69
|
}
|
|
@@ -114,7 +114,7 @@ export function validateExtensionPath(extensionPath) {
|
|
|
114
114
|
|
|
115
115
|
// Verify it's the ChromeDebug extension
|
|
116
116
|
if (!manifest.name?.includes('ChromeDebug')) {
|
|
117
|
-
console.
|
|
117
|
+
console.error(`[ExtensionPath] ⚠ Extension at ${extensionPath} is not ChromeDebug (found: ${manifest.name})`);
|
|
118
118
|
return false;
|
|
119
119
|
}
|
|
120
120
|
|
package/src/utils.js
CHANGED
|
@@ -88,7 +88,7 @@ async function handleExistingLock(lockFile, port) {
|
|
|
88
88
|
// Try to remove stale lock
|
|
89
89
|
try {
|
|
90
90
|
await fs.promises.unlink(lockFile);
|
|
91
|
-
console.
|
|
91
|
+
console.error(`Cleaned up stale port lock for port ${port}`);
|
|
92
92
|
return true;
|
|
93
93
|
} catch (cleanupError) {
|
|
94
94
|
// Another process might have cleaned it up, that's fine
|
|
@@ -127,7 +127,7 @@ async function cleanupStaleLocks(lockDir) {
|
|
|
127
127
|
|
|
128
128
|
if (lockAge > STALE_LOCK_THRESHOLD) {
|
|
129
129
|
await fs.promises.unlink(lockFile);
|
|
130
|
-
console.
|
|
130
|
+
console.error(`Cleaned up stale lock file: ${file}`);
|
|
131
131
|
}
|
|
132
132
|
} catch (error) {
|
|
133
133
|
// Corrupted lock file, remove it
|
|
@@ -269,8 +269,8 @@ export function createValidator(schema, target = 'body') {
|
|
|
269
269
|
|
|
270
270
|
if (error) {
|
|
271
271
|
// Diagnostic logging for validation failures
|
|
272
|
-
console.
|
|
273
|
-
console.
|
|
272
|
+
console.error(`[Validation] Failed for ${target}:`, JSON.stringify(data, null, 2));
|
|
273
|
+
console.error(`[Validation] Errors:`, error.details.map(d => ({ field: d.path.join('.'), message: d.message, value: d.context?.value })));
|
|
274
274
|
|
|
275
275
|
return res.status(400).json({
|
|
276
276
|
error: 'Validation failed',
|