chrome-cdp-cli 2.0.5 → 2.1.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.
@@ -58,8 +58,8 @@ To install Cursor commands:
58
58
  4. Use --force to install anyway
59
59
 
60
60
  Examples:
61
- chrome-cdp-cli install-cursor-command --target-directory /path/to/.cursor/commands
62
- chrome-cdp-cli install-cursor-command --force`
61
+ cdp install-cursor-command --target-directory /path/to/.cursor/commands
62
+ cdp install-cursor-command --force`
63
63
  };
64
64
  }
65
65
  }
@@ -133,60 +133,60 @@ Examples:
133
133
 
134
134
  ### JavaScript Execution
135
135
  - **eval** - Execute JavaScript code and return results
136
- \`chrome-cdp-cli eval "document.title"\`
137
- \`chrome-cdp-cli eval "fetch('/api/data').then(r => r.json())"\`
136
+ \`cdp eval "document.title"\`
137
+ \`cdp eval "fetch('/api/data').then(r => r.json())"\`
138
138
 
139
139
  ### Screenshots and Snapshots
140
140
  - **screenshot** - Capture page screenshot
141
- \`chrome-cdp-cli screenshot --filename page.png\`
142
- \`chrome-cdp-cli screenshot --filename fullpage.png --full-page\`
141
+ \`cdp screenshot --filename page.png\`
142
+ \`cdp screenshot --filename fullpage.png --full-page\`
143
143
 
144
144
  - **snapshot** - Capture complete DOM snapshot
145
- \`chrome-cdp-cli snapshot\`
146
- \`chrome-cdp-cli snapshot --filename dom-snapshot.txt\`
145
+ \`cdp snapshot\`
146
+ \`cdp snapshot --filename dom-snapshot.txt\`
147
147
 
148
148
  ### Element Interaction
149
149
  - **click** - Click page elements
150
- \`chrome-cdp-cli click "#submit-button"\`
151
- \`chrome-cdp-cli click ".menu-item" --timeout 10000\`
150
+ \`cdp click "#submit-button"\`
151
+ \`cdp click ".menu-item" --timeout 10000\`
152
152
 
153
153
  - **hover** - Mouse hover over elements
154
- \`chrome-cdp-cli hover "#dropdown-trigger"\`
154
+ \`cdp hover "#dropdown-trigger"\`
155
155
 
156
156
  - **fill** - Fill form fields
157
- \`chrome-cdp-cli fill "#username" "john@example.com"\`
158
- \`chrome-cdp-cli fill "input[name='password']" "secret123"\`
157
+ \`cdp fill "#username" "john@example.com"\`
158
+ \`cdp fill "input[name='password']" "secret123"\`
159
159
 
160
160
  - **fill_form** - Batch fill forms
161
- \`chrome-cdp-cli fill_form '{"#username": "john", "#password": "secret"}'\`
161
+ \`cdp fill_form '{"#username": "john", "#password": "secret"}'\`
162
162
 
163
163
  ### Advanced Interactions
164
164
  - **drag** - Drag and drop operations
165
- \`chrome-cdp-cli drag "#draggable" "#dropzone"\`
165
+ \`cdp drag "#draggable" "#dropzone"\`
166
166
 
167
167
  - **press_key** - Simulate keyboard input
168
- \`chrome-cdp-cli press_key "Enter"\`
169
- \`chrome-cdp-cli press_key "a" --modifiers Ctrl --selector "#input"\`
168
+ \`cdp press_key "Enter"\`
169
+ \`cdp press_key "a" --modifiers Ctrl --selector "#input"\`
170
170
 
171
171
  - **upload_file** - File upload
172
- \`chrome-cdp-cli upload_file "input[type='file']" "./document.pdf"\`
172
+ \`cdp upload_file "input[type='file']" "./document.pdf"\`
173
173
 
174
174
  - **wait_for** - Wait for elements to appear or meet conditions
175
- \`chrome-cdp-cli wait_for "#loading" --condition hidden\`
176
- \`chrome-cdp-cli wait_for "#submit-btn" --condition enabled\`
175
+ \`cdp wait_for "#loading" --condition hidden\`
176
+ \`cdp wait_for "#submit-btn" --condition enabled\`
177
177
 
178
178
  - **handle_dialog** - Handle browser dialogs
179
- \`chrome-cdp-cli handle_dialog accept\`
180
- \`chrome-cdp-cli handle_dialog accept --text "user input"\`
179
+ \`cdp handle_dialog accept\`
180
+ \`cdp handle_dialog accept --text "user input"\`
181
181
 
182
182
  ### Monitoring
183
183
  - **console** - List console messages or get latest
184
- \`chrome-cdp-cli console --latest\`
185
- \`chrome-cdp-cli console --types error\`
184
+ \`cdp console --latest\`
185
+ \`cdp console --types error\`
186
186
 
187
187
  - **network** - List network requests or get latest
188
- \`chrome-cdp-cli network --latest\`
189
- \`chrome-cdp-cli network --filter '{"methods":["POST"]}'\`
188
+ \`cdp network --latest\`
189
+ \`cdp network --filter '{"methods":["POST"]}'\`
190
190
 
191
191
  ## Common Options
192
192
 
@@ -198,54 +198,54 @@ Examples:
198
198
 
199
199
  ### Form Testing
200
200
  \`\`\`bash
201
- chrome-cdp-cli wait_for "#login-form" --condition visible
202
- chrome-cdp-cli fill "#email" "test@example.com"
203
- chrome-cdp-cli fill "#password" "password123"
204
- chrome-cdp-cli click "#submit-button"
205
- chrome-cdp-cli wait_for "#success-message" --condition visible
206
- chrome-cdp-cli screenshot --filename login-success.png
207
- chrome-cdp-cli console --types error
201
+ cdp wait_for "#login-form" --condition visible
202
+ cdp fill "#email" "test@example.com"
203
+ cdp fill "#password" "password123"
204
+ cdp click "#submit-button"
205
+ cdp wait_for "#success-message" --condition visible
206
+ cdp screenshot --filename login-success.png
207
+ cdp console --types error
208
208
  \`\`\`
209
209
 
210
210
  ### File Upload
211
211
  \`\`\`bash
212
- chrome-cdp-cli click "#upload-trigger"
213
- chrome-cdp-cli upload_file "input[type='file']" "./test-document.pdf"
214
- chrome-cdp-cli wait_for ".upload-success" --condition visible
215
- chrome-cdp-cli eval "document.querySelector('.file-name').textContent"
212
+ cdp click "#upload-trigger"
213
+ cdp upload_file "input[type='file']" "./test-document.pdf"
214
+ cdp wait_for ".upload-success" --condition visible
215
+ cdp eval "document.querySelector('.file-name').textContent"
216
216
  \`\`\`
217
217
 
218
218
  ### Drag and Drop
219
219
  \`\`\`bash
220
- chrome-cdp-cli wait_for "#draggable-item" --condition visible
221
- chrome-cdp-cli wait_for "#drop-zone" --condition visible
222
- chrome-cdp-cli drag "#draggable-item" "#drop-zone"
223
- chrome-cdp-cli eval "document.querySelector('#drop-zone').children.length"
220
+ cdp wait_for "#draggable-item" --condition visible
221
+ cdp wait_for "#drop-zone" --condition visible
222
+ cdp drag "#draggable-item" "#drop-zone"
223
+ cdp eval "document.querySelector('#drop-zone').children.length"
224
224
  \`\`\`
225
225
 
226
226
  ### Keyboard Input
227
227
  \`\`\`bash
228
- chrome-cdp-cli click "#search-input"
229
- chrome-cdp-cli press_key "t"
230
- chrome-cdp-cli press_key "e"
231
- chrome-cdp-cli press_key "s"
232
- chrome-cdp-cli press_key "t"
233
- chrome-cdp-cli press_key "a" --modifiers Ctrl
234
- chrome-cdp-cli press_key "Enter"
235
- chrome-cdp-cli handle_dialog accept
228
+ cdp click "#search-input"
229
+ cdp press_key "t"
230
+ cdp press_key "e"
231
+ cdp press_key "s"
232
+ cdp press_key "t"
233
+ cdp press_key "a" --modifiers Ctrl
234
+ cdp press_key "Enter"
235
+ cdp handle_dialog accept
236
236
  \`\`\``,
237
237
  examples: [
238
- 'chrome-cdp-cli eval "document.title"',
239
- 'chrome-cdp-cli screenshot --filename page.png',
240
- 'chrome-cdp-cli click "#submit-button"',
241
- 'chrome-cdp-cli fill "#username" "test@example.com"',
242
- 'chrome-cdp-cli drag "#item" "#target"',
243
- 'chrome-cdp-cli press_key "Enter"',
244
- 'chrome-cdp-cli upload_file "input[type=file]" "./doc.pdf"',
245
- 'chrome-cdp-cli wait_for "#loading" --condition hidden',
246
- 'chrome-cdp-cli handle_dialog accept',
247
- 'chrome-cdp-cli console --latest',
248
- 'chrome-cdp-cli network'
238
+ 'cdp eval "document.title"',
239
+ 'cdp screenshot --filename page.png',
240
+ 'cdp click "#submit-button"',
241
+ 'cdp fill "#username" "test@example.com"',
242
+ 'cdp drag "#item" "#target"',
243
+ 'cdp press_key "Enter"',
244
+ 'cdp upload_file "input[type=file]" "./doc.pdf"',
245
+ 'cdp wait_for "#loading" --condition hidden',
246
+ 'cdp handle_dialog accept',
247
+ 'cdp console --latest',
248
+ 'cdp network'
249
249
  ]
250
250
  }
251
251
  ];
@@ -2,118 +2,29 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.ListConsoleMessagesHandler = void 0;
4
4
  const ConsoleMonitor_1 = require("../monitors/ConsoleMonitor");
5
- const ProxyClient_1 = require("../client/ProxyClient");
6
5
  class ListConsoleMessagesHandler {
7
6
  constructor() {
8
- this.name = 'console';
7
+ this.name = "log";
8
+ this.aliases = ["console"];
9
9
  this.consoleMonitor = null;
10
- this.proxyClient = null;
11
10
  }
12
11
  async execute(client, args) {
13
12
  try {
14
13
  const params = args;
15
- const proxyResult = await this.tryProxyExecution(params);
16
- if (proxyResult) {
17
- return proxyResult;
18
- }
19
- return await this.executeDirectCDP(client, params);
14
+ return await this.executeFollowMode(client, params);
20
15
  }
21
16
  catch (error) {
22
17
  return {
23
18
  success: false,
24
- error: error instanceof Error ? error.message : 'Unknown error occurred'
19
+ error: error instanceof Error ? error.message : "Unknown error occurred",
25
20
  };
26
21
  }
27
22
  }
28
- async tryProxyExecution(params) {
29
- try {
30
- if (!this.proxyClient) {
31
- this.proxyClient = new ProxyClient_1.ProxyClient();
32
- }
33
- const isProxyAvailable = await this.proxyClient.isProxyAvailable();
34
- if (!isProxyAvailable) {
35
- console.warn('⚠️ Proxy server unavailable. Falling back to direct CDP connection.');
36
- console.warn('⚠️ Note: Direct connection only captures NEW console messages, not historical data.');
37
- return null;
38
- }
39
- if (!this.proxyClient.getConnectionId()) {
40
- const host = params.host || 'localhost';
41
- const port = params.port || 9222;
42
- await this.proxyClient.connect(host, port, params.targetId);
43
- }
44
- const filter = {};
45
- if (params.types && params.types.length > 0) {
46
- filter.types = params.types;
47
- }
48
- if (params.textPattern) {
49
- filter.textPattern = params.textPattern;
50
- }
51
- if (params.latest) {
52
- filter.maxMessages = 1;
53
- }
54
- else if (params.maxMessages && params.maxMessages > 0) {
55
- filter.maxMessages = params.maxMessages;
56
- }
57
- if (params.startTime) {
58
- filter.startTime = params.startTime;
59
- }
60
- if (params.endTime) {
61
- filter.endTime = params.endTime;
62
- }
63
- const messages = await this.proxyClient.getConsoleMessages(filter);
64
- if (params.latest) {
65
- const latestMessage = messages.length > 0 ? messages[messages.length - 1] : null;
66
- if (!latestMessage) {
67
- return {
68
- success: true,
69
- data: null,
70
- dataSource: 'proxy',
71
- hasHistoricalData: true
72
- };
73
- }
74
- return {
75
- success: true,
76
- data: {
77
- type: latestMessage.type,
78
- text: latestMessage.text,
79
- args: latestMessage.args,
80
- timestamp: latestMessage.timestamp,
81
- stackTrace: latestMessage.stackTrace
82
- },
83
- dataSource: 'proxy',
84
- hasHistoricalData: true
85
- };
86
- }
87
- return {
88
- success: true,
89
- data: {
90
- messages: messages.map(msg => ({
91
- type: msg.type,
92
- text: msg.text,
93
- args: msg.args,
94
- timestamp: msg.timestamp,
95
- stackTrace: msg.stackTrace
96
- })),
97
- totalCount: messages.length,
98
- isMonitoring: true
99
- },
100
- dataSource: 'proxy',
101
- hasHistoricalData: true
102
- };
103
- }
104
- catch (error) {
105
- console.warn('⚠️ Proxy execution failed, falling back to direct CDP:', error instanceof Error ? error.message : error);
106
- console.warn('⚠️ Note: Direct connection only captures NEW console messages, not historical data.');
107
- return null;
108
- }
109
- }
110
- async executeDirectCDP(client, params) {
23
+ async executeFollowMode(client, params) {
111
24
  if (!this.consoleMonitor) {
112
25
  this.consoleMonitor = new ConsoleMonitor_1.ConsoleMonitor(client);
113
26
  }
114
- if (params.startMonitoring || !this.consoleMonitor.isActive()) {
115
- await this.consoleMonitor.startMonitoring();
116
- }
27
+ await this.consoleMonitor.startMonitoring();
117
28
  const filter = {};
118
29
  if (params.types && params.types.length > 0) {
119
30
  filter.types = params.types;
@@ -121,120 +32,157 @@ class ListConsoleMessagesHandler {
121
32
  if (params.textPattern) {
122
33
  filter.textPattern = params.textPattern;
123
34
  }
124
- if (params.maxMessages && params.maxMessages > 0) {
125
- filter.maxMessages = params.maxMessages;
126
- }
127
- if (params.startTime) {
128
- filter.startTime = params.startTime;
129
- }
130
- if (params.endTime) {
131
- filter.endTime = params.endTime;
132
- }
133
- if (params.latest) {
134
- const latestMessage = this.consoleMonitor.getLatestMessage(filter);
135
- if (!latestMessage) {
136
- return {
137
- success: true,
138
- data: null,
139
- dataSource: 'direct',
140
- hasHistoricalData: false
141
- };
35
+ const outputFormat = params.format || "text";
36
+ const messageCallback = (message) => {
37
+ if (!this.shouldOutputMessage(message, filter)) {
38
+ return;
142
39
  }
143
- return {
144
- success: true,
145
- data: {
146
- type: latestMessage.type,
147
- text: latestMessage.text,
148
- args: latestMessage.args,
149
- timestamp: latestMessage.timestamp,
150
- stackTrace: latestMessage.stackTrace
151
- },
152
- dataSource: 'direct',
153
- hasHistoricalData: false
154
- };
40
+ this.outputMessage(message, outputFormat);
41
+ };
42
+ this.consoleMonitor.onMessage(messageCallback);
43
+ let isShuttingDown = false;
44
+ const cleanup = async () => {
45
+ if (isShuttingDown)
46
+ return;
47
+ isShuttingDown = true;
48
+ this.consoleMonitor?.offMessage(messageCallback);
49
+ await this.consoleMonitor?.stopMonitoring();
50
+ };
51
+ const signalHandler = async () => {
52
+ process.stderr.write("\n");
53
+ await cleanup();
54
+ process.exit(0);
55
+ };
56
+ process.removeAllListeners("SIGINT");
57
+ process.removeAllListeners("SIGTERM");
58
+ process.on("SIGINT", signalHandler);
59
+ process.on("SIGTERM", signalHandler);
60
+ if (outputFormat === "text") {
61
+ console.log("Following console messages (press Ctrl+C to stop)...\n");
155
62
  }
156
- const messages = this.consoleMonitor.getMessages(filter);
157
63
  return {
158
64
  success: true,
159
65
  data: {
160
- messages: messages.map(msg => ({
161
- type: msg.type,
162
- text: msg.text,
163
- args: msg.args,
164
- timestamp: msg.timestamp,
165
- stackTrace: msg.stackTrace
166
- })),
167
- totalCount: messages.length,
168
- isMonitoring: this.consoleMonitor.isActive()
66
+ message: "Following console messages in real-time. Press Ctrl+C to stop.",
67
+ isLongRunning: true,
169
68
  },
170
- dataSource: 'direct',
171
- hasHistoricalData: false
69
+ isLongRunning: true,
172
70
  };
173
71
  }
72
+ shouldOutputMessage(message, filter) {
73
+ if (filter.types && filter.types.length > 0) {
74
+ if (!filter.types.includes(message.type)) {
75
+ return false;
76
+ }
77
+ }
78
+ if (filter.textPattern) {
79
+ const pattern = new RegExp(filter.textPattern, "i");
80
+ if (!pattern.test(message.text)) {
81
+ return false;
82
+ }
83
+ }
84
+ return true;
85
+ }
86
+ outputMessage(message, format) {
87
+ switch (format) {
88
+ case "json":
89
+ console.log(JSON.stringify({
90
+ type: message.type,
91
+ text: message.text,
92
+ timestamp: message.timestamp,
93
+ args: message.args,
94
+ stackTrace: message.stackTrace,
95
+ }));
96
+ break;
97
+ case "pretty": {
98
+ const timestamp = new Date(message.timestamp).toISOString();
99
+ const typeColor = this.getTypeColor(message.type);
100
+ const typeLabel = message.type.toUpperCase().padEnd(5);
101
+ console.log(`[${timestamp}] ${typeColor}${typeLabel}\x1b[0m ${message.text}`);
102
+ if (message.stackTrace && message.stackTrace.length > 0) {
103
+ const frame = message.stackTrace[0];
104
+ console.log(` at ${frame.functionName} (${frame.url}:${frame.lineNumber}:${frame.columnNumber})`);
105
+ }
106
+ break;
107
+ }
108
+ case "text":
109
+ default: {
110
+ const time = new Date(message.timestamp).toISOString();
111
+ const type = message.type.toUpperCase().padEnd(5);
112
+ console.log(`[${time}] ${type} ${message.text}`);
113
+ break;
114
+ }
115
+ }
116
+ }
117
+ getTypeColor(type) {
118
+ switch (type) {
119
+ case "error":
120
+ return "\x1b[31m";
121
+ case "warn":
122
+ return "\x1b[33m";
123
+ case "info":
124
+ return "\x1b[36m";
125
+ case "debug":
126
+ return "\x1b[90m";
127
+ default:
128
+ return "\x1b[0m";
129
+ }
130
+ }
174
131
  validateArgs(args) {
175
- if (!args || typeof args !== 'object') {
132
+ if (!args || typeof args !== "object") {
176
133
  return true;
177
134
  }
178
135
  const params = args;
179
136
  if (params.types !== undefined) {
180
- if (!Array.isArray(params.types)) {
137
+ if (!Array.isArray(params.types))
181
138
  return false;
182
- }
183
- const validTypes = ['log', 'info', 'warn', 'error', 'debug'];
139
+ const validTypes = ["log", "info", "warn", "error", "debug"];
184
140
  for (const type of params.types) {
185
- if (typeof type !== 'string' || !validTypes.includes(type)) {
141
+ if (typeof type !== "string" || !validTypes.includes(type))
186
142
  return false;
187
- }
188
143
  }
189
144
  }
190
- if (params.textPattern !== undefined && typeof params.textPattern !== 'string') {
145
+ if (params.textPattern !== undefined &&
146
+ typeof params.textPattern !== "string") {
191
147
  return false;
192
148
  }
193
- if (params.maxMessages !== undefined) {
194
- if (typeof params.maxMessages !== 'number' || params.maxMessages <= 0) {
149
+ if (params.format !== undefined) {
150
+ const validFormats = ["text", "json", "pretty"];
151
+ if (typeof params.format !== "string" ||
152
+ !validFormats.includes(params.format)) {
195
153
  return false;
196
154
  }
197
155
  }
198
- if (params.startTime !== undefined && typeof params.startTime !== 'number') {
199
- return false;
200
- }
201
- if (params.endTime !== undefined && typeof params.endTime !== 'number') {
202
- return false;
203
- }
204
- if (params.startMonitoring !== undefined && typeof params.startMonitoring !== 'boolean') {
205
- return false;
206
- }
207
- if (params.latest !== undefined && typeof params.latest !== 'boolean') {
208
- return false;
209
- }
210
156
  return true;
211
157
  }
212
158
  getHelp() {
213
- return `console - List console messages
214
-
159
+ return `log - Follow console messages in real-time
160
+
215
161
  Usage:
216
- console [options]
217
-
162
+ cdp log [options]
163
+
218
164
  Options:
219
- --latest Get only the latest console message
220
165
  --types <types> Filter by message types (comma-separated: log,info,warn,error,debug)
221
- --textPattern <pattern> Filter by text pattern (regex)
222
- --maxMessages <count> Maximum number of messages to return
223
- --startTime <timestamp> Filter messages after this timestamp
224
- --endTime <timestamp> Filter messages before this timestamp
225
- --startMonitoring Start monitoring if not already active
226
-
166
+ --textPattern <pattern> Filter by text pattern (regex, case-insensitive)
167
+ --format <format> Output format: text, json, or pretty (default: text)
168
+ -f, --follow Alias flag (follow mode is always active)
169
+
227
170
  Examples:
228
- console
229
- console --latest
230
- console --types error,warn
231
- console --latest --type error
232
- console --textPattern "API" --maxMessages 10
233
- console --startTime 1640995200000
171
+ cdp log # Follow all console messages
172
+ cdp log --types error,warn # Follow only errors and warnings
173
+ cdp log --textPattern "API" # Follow messages matching /API/i
174
+ cdp log --format json # Output as JSON (one object per line)
175
+ cdp log --format pretty # Colorized output
176
+ cdp log --types error --textPattern "404" # Combined filters
177
+
178
+ Note:
179
+ This command runs continuously and streams console messages in real-time.
180
+ Press Ctrl+C to stop. The command connects directly to Chrome via CDP —
181
+ no background process is required. Only messages arriving after the command
182
+ starts will be shown.
234
183
 
235
- Note: This command now uses the proxy server when available, providing access to
236
- historical console messages from connection establishment. When proxy is unavailable,
237
- falls back to direct CDP connection (captures only new messages).`;
184
+ Aliases:
185
+ cdp console (deprecated, use cdp log)`;
238
186
  }
239
187
  }
240
188
  exports.ListConsoleMessagesHandler = ListConsoleMessagesHandler;