@dynamicu/chromedebug-mcp 2.6.7 → 2.7.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 (39) hide show
  1. package/CLAUDE.md +1 -1
  2. package/README.md +1 -1
  3. package/chrome-extension/background.js +611 -505
  4. package/chrome-extension/browser-recording-manager.js +1 -1
  5. package/chrome-extension/chrome-debug-logger.js +168 -0
  6. package/chrome-extension/console-interception-library.js +430 -0
  7. package/chrome-extension/content.css +16 -16
  8. package/chrome-extension/content.js +458 -126
  9. package/chrome-extension/extension-config.js +1 -1
  10. package/chrome-extension/license-helper.js +26 -0
  11. package/chrome-extension/manifest.free.json +0 -3
  12. package/chrome-extension/options.js +1 -1
  13. package/chrome-extension/popup.html +221 -191
  14. package/chrome-extension/popup.js +88 -379
  15. package/chrome-extension/pro/enhanced-capture.js +406 -0
  16. package/chrome-extension/pro/frame-editor.html +410 -0
  17. package/chrome-extension/pro/frame-editor.js +1496 -0
  18. package/chrome-extension/pro/function-tracker.js +843 -0
  19. package/chrome-extension/pro/jszip.min.js +13 -0
  20. package/dist/chromedebug-extension-free.zip +0 -0
  21. package/package.json +3 -1
  22. package/scripts/webpack.config.free.cjs +8 -8
  23. package/scripts/webpack.config.pro.cjs +2 -0
  24. package/src/cli.js +2 -2
  25. package/src/database.js +55 -7
  26. package/src/index.js +9 -6
  27. package/src/mcp/server.js +2 -2
  28. package/src/services/process-manager.js +10 -6
  29. package/src/services/process-tracker.js +10 -5
  30. package/src/services/profile-manager.js +17 -2
  31. package/src/validation/schemas.js +2 -2
  32. package/src/index-direct.js +0 -157
  33. package/src/index-modular.js +0 -219
  34. package/src/index-monolithic-backup.js +0 -2230
  35. package/src/legacy/chrome-controller-old.js +0 -1406
  36. package/src/legacy/index-express.js +0 -625
  37. package/src/legacy/index-old.js +0 -977
  38. package/src/legacy/routes.js +0 -260
  39. package/src/legacy/shared-storage.js +0 -101
@@ -1,260 +0,0 @@
1
- import express from 'express';
2
-
3
- export function createRoutes(chromeController) {
4
- const router = express.Router();
5
-
6
- const asyncHandler = (fn) => (req, res, next) => {
7
- Promise.resolve(fn(req, res, next)).catch(next);
8
- };
9
-
10
- router.post('/chrome-pilot/launch', asyncHandler(async (req, res) => {
11
- const result = await chromeController.launch();
12
- res.json(result);
13
- }));
14
-
15
- router.post('/chrome-pilot/navigate', asyncHandler(async (req, res) => {
16
- const { url } = req.body;
17
- if (!url) {
18
- return res.status(400).json({ error: 'URL is required' });
19
- }
20
- const result = await chromeController.navigateTo(url);
21
- res.json(result);
22
- }));
23
-
24
- router.post('/chrome-pilot/pause', asyncHandler(async (req, res) => {
25
- const result = await chromeController.pause();
26
- res.json(result);
27
- }));
28
-
29
- router.post('/chrome-pilot/resume', asyncHandler(async (req, res) => {
30
- const result = await chromeController.resume();
31
- res.json(result);
32
- }));
33
-
34
- router.post('/chrome-pilot/step-over', asyncHandler(async (req, res) => {
35
- const result = await chromeController.stepOver();
36
- res.json(result);
37
- }));
38
-
39
- router.post('/chrome-pilot/evaluate', asyncHandler(async (req, res) => {
40
- const { expression } = req.body;
41
- if (!expression) {
42
- return res.status(400).json({ error: 'Expression is required' });
43
- }
44
- const result = await chromeController.evaluate(expression);
45
- res.json(result);
46
- }));
47
-
48
- router.get('/chrome-pilot/scopes', asyncHandler(async (req, res) => {
49
- const result = await chromeController.getScopes();
50
- res.json(result);
51
- }));
52
-
53
- router.post('/chrome-pilot/set-breakpoint', asyncHandler(async (req, res) => {
54
- const { url, lineNumber } = req.body;
55
- if (!url || lineNumber === undefined) {
56
- return res.status(400).json({ error: 'URL and lineNumber are required' });
57
- }
58
- const result = await chromeController.setBreakpoint(url, lineNumber);
59
- res.json(result);
60
- }));
61
-
62
- router.get('/chrome-pilot/logs', asyncHandler(async (req, res) => {
63
- const result = chromeController.getLogs();
64
- res.json(result);
65
- }));
66
-
67
- router.post('/chrome-pilot/screenshot', asyncHandler(async (req, res) => {
68
- const { type, fullPage, path } = req.body || {};
69
- const options = {};
70
- if (type) options.type = type;
71
- if (fullPage !== undefined) options.fullPage = fullPage;
72
- if (path) options.path = path;
73
-
74
- const result = await chromeController.takeScreenshot(options);
75
- res.json(result);
76
- }));
77
-
78
- router.post('/chrome-pilot/dom-intent', asyncHandler(async (req, res) => {
79
- const { selector, instruction, elementInfo } = req.body;
80
- if (!selector) {
81
- return res.status(400).json({ error: 'Selector is required' });
82
- }
83
- const result = await chromeController.selectElement(selector, instruction, elementInfo);
84
- res.json(result);
85
- }));
86
-
87
- router.get('/chrome-pilot/status', asyncHandler(async (req, res) => {
88
- const isConnected = await chromeController.isConnected();
89
- res.json({ connected: isConnected, status: 'ok' });
90
- }));
91
-
92
- // Port discovery endpoint for Claude to find the server
93
- router.get('/chrome-pilot/port', (req, res) => {
94
- const serverPort = process.env.SERVER_PORT || process.env.PORT || 3000;
95
- res.json({
96
- port: serverPort,
97
- message: 'Chrome Debug server port',
98
- timestamp: new Date().toISOString()
99
- });
100
- });
101
-
102
- router.get('/chrome-pilot/recording/:id', asyncHandler(async (req, res) => {
103
- // Get recording for Claude to analyze
104
- const result = await chromeController.getRecording(req.params.id);
105
- if (result.error) {
106
- return res.status(404).json(result);
107
- }
108
- res.json(result);
109
- }));
110
-
111
- router.delete('/chrome-pilot/recording/:id', asyncHandler(async (req, res) => {
112
- // Delete recording
113
- const result = await chromeController.deleteRecording(req.params.id);
114
- if (result.error) {
115
- return res.status(404).json(result);
116
- }
117
- res.json(result);
118
- }));
119
-
120
- // New frame capture endpoints
121
- router.post('/chrome-pilot/frame-batch', (req, res, next) => {
122
- // Use multer middleware for this specific route
123
- chromeController.upload(req, res, async (err) => {
124
- if (err) {
125
- console.error('Multer error:', err);
126
- return res.status(400).json({ error: true, message: err.message });
127
- }
128
-
129
- try {
130
- // Extract data from req.body (populated by multer)
131
- const { sessionId, frames } = req.body;
132
-
133
- console.log('Route received sessionId:', sessionId);
134
- console.log('Route received frames (type):', typeof frames);
135
-
136
- if (!sessionId || !frames) {
137
- return res.status(400).json({ error: 'Missing sessionId or frames in request body' });
138
- }
139
-
140
- // Parse the stringified frames and call the controller method correctly
141
- const parsedFrames = JSON.parse(frames);
142
- console.log('Parsed frames count:', parsedFrames.length);
143
-
144
- const result = await chromeController.storeFrameBatch(sessionId, parsedFrames);
145
- res.json(result);
146
-
147
- } catch (error) {
148
- console.error('Error processing frame batch:', error);
149
- res.status(500).json({ error: 'Failed to store frame batch', details: error.message });
150
- }
151
- });
152
- });
153
-
154
- router.get('/chrome-pilot/check-session/:sessionId', asyncHandler(async (req, res) => {
155
- const { sessionId } = req.params;
156
- const result = await chromeController.checkFrameSession(sessionId);
157
- if (result.found) {
158
- return res.status(200).json({ status: 'found', sessionId, ...result });
159
- } else {
160
- return res.status(404).json({ status: 'not_found', sessionId });
161
- }
162
- }));
163
-
164
- router.post('/chrome-pilot/associate-logs', asyncHandler(async (req, res) => {
165
- const { sessionId, logs } = req.body;
166
- if (!sessionId || !logs) {
167
- return res.status(400).json({ error: 'sessionId and logs are required' });
168
- }
169
- const result = await chromeController.associateLogsWithFrames(sessionId, logs);
170
- res.json(result);
171
- }));
172
-
173
- router.post('/chrome-pilot/save-edited-session', asyncHandler(async (req, res) => {
174
- const { sessionId, sessionData } = req.body;
175
- if (!sessionId || !sessionData) {
176
- return res.status(400).json({ error: 'sessionId and sessionData are required' });
177
- }
178
- const result = await chromeController.saveEditedSession(sessionId, sessionData);
179
- res.json(result);
180
- }));
181
-
182
- router.get('/chrome-pilot/session/:sessionId', asyncHandler(async (req, res) => {
183
- const { sessionId } = req.params;
184
- const result = await chromeController.getFrameSession(sessionId);
185
- if (result) {
186
- res.json(result);
187
- } else {
188
- res.status(404).json({ error: 'Session not found' });
189
- }
190
- }));
191
-
192
- // Import session from Chrome extension storage format
193
- router.post('/chrome-pilot/import-session', asyncHandler(async (req, res) => {
194
- const { sessionId, sessionData } = req.body;
195
- if (!sessionId || !sessionData) {
196
- return res.status(400).json({ error: 'sessionId and sessionData are required' });
197
- }
198
- const result = await chromeController.importSessionFromChrome(sessionId, sessionData);
199
- res.json(result);
200
- }));
201
-
202
- // Workflow recording endpoints
203
- router.post('/chrome-pilot/workflow-recording', asyncHandler(async (req, res) => {
204
- const { sessionId, url, title, includeLogs, actions, logs } = req.body;
205
- if (!sessionId || !actions) {
206
- return res.status(400).json({ error: 'sessionId and actions are required' });
207
- }
208
- const result = await chromeController.storeWorkflowRecording(sessionId, url, title, includeLogs, actions, logs);
209
- res.json(result);
210
- }));
211
-
212
- router.get('/chrome-pilot/workflow-recording/:sessionId', asyncHandler(async (req, res) => {
213
- const { sessionId } = req.params;
214
- const result = await chromeController.getWorkflowRecording(sessionId);
215
- if (result.error) {
216
- return res.status(404).json(result);
217
- }
218
- res.json(result);
219
- }));
220
-
221
- router.get('/chrome-pilot/workflow-recordings', asyncHandler(async (req, res) => {
222
- const result = await chromeController.listWorkflowRecordings();
223
- res.json(result);
224
- }));
225
-
226
- // Restore point endpoints
227
- router.post('/chrome-pilot/restore-point', asyncHandler(async (req, res) => {
228
- const result = await chromeController.saveRestorePoint(req.body);
229
- res.json(result);
230
- }));
231
-
232
- router.get('/chrome-pilot/restore-point/:id', asyncHandler(async (req, res) => {
233
- const result = await chromeController.getRestorePoint(req.params.id);
234
- if (result.error) {
235
- res.status(404).json(result);
236
- } else {
237
- res.json(result);
238
- }
239
- }));
240
-
241
- router.get('/chrome-pilot/restore-points/:workflowId', asyncHandler(async (req, res) => {
242
- const result = await chromeController.listRestorePoints(req.params.workflowId);
243
- res.json(result);
244
- }));
245
-
246
- router.delete('/chrome-pilot/restore-point/:id', asyncHandler(async (req, res) => {
247
- const result = await chromeController.deleteRestorePoint(req.params.id);
248
- res.json(result);
249
- }));
250
-
251
- router.use((error, req, res, next) => {
252
- console.error('Error:', error);
253
- res.status(500).json({
254
- error: true,
255
- message: error.message || 'Internal server error'
256
- });
257
- });
258
-
259
- return router;
260
- }
@@ -1,101 +0,0 @@
1
- // New shared storage implementation using SQLite database
2
- import { database } from './database.js';
3
-
4
- class SharedRecordingStorage {
5
- constructor() {
6
- this.initialized = false;
7
- this.initPromise = this.init();
8
- }
9
-
10
- async init() {
11
- database.init();
12
- this.initialized = true;
13
- }
14
-
15
- async ensureInitialized() {
16
- if (!this.initialized) {
17
- await this.initPromise;
18
- }
19
- }
20
-
21
- // Legacy method - no longer needed with SQLite
22
- async loadFromDisk() {
23
- // SQLite handles persistence automatically
24
- }
25
-
26
- // Legacy method - no longer needed with SQLite
27
- async saveToDisk() {
28
- // SQLite handles persistence automatically
29
- }
30
-
31
- async get(id) {
32
- await this.ensureInitialized();
33
- return database.getRecording(id);
34
- }
35
-
36
- async delete(id) {
37
- await this.ensureInitialized();
38
- return database.deleteRecording(id);
39
- }
40
-
41
- async list() {
42
- await this.ensureInitialized();
43
- return database.listRecordings();
44
- }
45
-
46
- // Store frame batch for frame capture sessions
47
- async storeFrameBatch(sessionId, frames) {
48
- await this.ensureInitialized();
49
- return database.storeFrameBatch(sessionId, frames);
50
- }
51
-
52
- // Get frame session info
53
- async getFrameSessionInfo(sessionId) {
54
- await this.ensureInitialized();
55
- return database.getFrameSessionInfo(sessionId);
56
- }
57
-
58
- // Get specific frame from session
59
- async getFrame(sessionId, frameIndex) {
60
- await this.ensureInitialized();
61
- return database.getFrame(sessionId, frameIndex);
62
- }
63
-
64
- // Get entire frame session
65
- async getFrameSession(sessionId) {
66
- await this.ensureInitialized();
67
- return database.getFrameSession(sessionId);
68
- }
69
-
70
- // Update frame session - for SQLite this is handled by associateLogsWithFrames
71
- async updateFrameSession(sessionId, updatedSession) {
72
- await this.ensureInitialized();
73
-
74
- // With SQLite, we don't update the entire session at once
75
- // Instead, we use the database's structured approach
76
- // This method is kept for backward compatibility
77
-
78
- if (updatedSession.frames) {
79
- // Store the frames
80
- const result = database.storeFrameBatch(sessionId, updatedSession.frames);
81
- return result;
82
- }
83
-
84
- throw new Error('Frame session update not supported in SQLite mode');
85
- }
86
-
87
- // Associate logs with frames
88
- async associateLogsWithFrames(sessionId, logs) {
89
- await this.ensureInitialized();
90
- return database.associateLogsWithFrames(sessionId, logs);
91
- }
92
-
93
- // Get database statistics
94
- async getStats() {
95
- await this.ensureInitialized();
96
- return database.getStats();
97
- }
98
- }
99
-
100
- // Export singleton instance
101
- export const sharedStorage = new SharedRecordingStorage();