chrome-cdp-cli 2.1.4 → 2.1.5

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/README.md CHANGED
@@ -81,6 +81,9 @@ cdp log -f
81
81
  # Follow network requests in real time
82
82
  cdp network -f
83
83
 
84
+ # List available Chrome pages
85
+ cdp list
86
+
84
87
  # Element interactions
85
88
  cdp click "#submit-button"
86
89
  cdp fill "#email" "user@example.com"
@@ -126,6 +129,7 @@ Use arrow keys to navigate, Enter to select, `q`/ESC/Ctrl+C to cancel (exits cle
126
129
  To skip the prompt, pass `-i` before or after the command:
127
130
 
128
131
  ```bash
132
+ cdp list
129
133
  cdp -i 1 eval "document.title"
130
134
  cdp eval "document.title" -i 1 # also works
131
135
  ```
@@ -84,6 +84,12 @@ class CLIApplication {
84
84
  this.configureDebugMode(command.config.debug);
85
85
  this.logger.debug("CLIApplication.run called with argv:", argv);
86
86
  this.logger.debug("Parsed command:", command);
87
+ if (command.name === "list") {
88
+ const result = await this.executeListCommand(command);
89
+ this.outputResult(result, command);
90
+ return (result.exitCode ||
91
+ (result.success ? CommandRouter_1.ExitCode.SUCCESS : CommandRouter_1.ExitCode.GENERAL_ERROR));
92
+ }
87
93
  if (this.needsConnection(command.name)) {
88
94
  this.logger.debug("Command needs connection, ensuring connection...");
89
95
  try {
@@ -131,11 +137,65 @@ class CLIApplication {
131
137
  "help",
132
138
  "connect",
133
139
  "disconnect",
140
+ "list",
134
141
  "install_cursor_command",
135
142
  "install_claude_skill",
136
143
  ];
137
144
  return !noConnectionCommands.includes(commandName);
138
145
  }
146
+ async executeListCommand(command) {
147
+ try {
148
+ const targets = await this.connectionManager.discoverTargets(command.config.host, command.config.port);
149
+ const selectableTargets = targets
150
+ .filter((target) => target.type === "page")
151
+ .filter((target) => !this.isDevToolsWindow(target));
152
+ if (command.config.outputFormat === "json") {
153
+ return {
154
+ success: true,
155
+ data: {
156
+ count: selectableTargets.length,
157
+ targets: selectableTargets.map((target, index) => ({
158
+ index: index + 1,
159
+ id: target.id,
160
+ title: target.title || "(Untitled)",
161
+ url: target.url,
162
+ type: target.type,
163
+ })),
164
+ },
165
+ };
166
+ }
167
+ if (selectableTargets.length === 0) {
168
+ return {
169
+ success: true,
170
+ data: `No selectable Chrome pages found at ${command.config.host}:${command.config.port}.\n` +
171
+ "Open a regular tab in Chrome and try again.",
172
+ };
173
+ }
174
+ const lines = [
175
+ `Found ${selectableTargets.length} selectable Chrome page(s):`,
176
+ "",
177
+ ...selectableTargets.flatMap((target, index) => [
178
+ `[${index + 1}] ${target.title || "(Untitled)"}`,
179
+ ` ${target.url}`,
180
+ ]),
181
+ "",
182
+ "Use `cdp -i <number> <command>` to target one of these pages.",
183
+ ];
184
+ return {
185
+ success: true,
186
+ data: lines.join("\n"),
187
+ };
188
+ }
189
+ catch (error) {
190
+ return {
191
+ success: false,
192
+ error: error instanceof Error
193
+ ? error.message
194
+ : String(error),
195
+ exitCode: CommandRouter_1.ExitCode.CONNECTION_ERROR,
196
+ };
197
+ }
198
+ }
139
199
  isDevToolsWindow(target) {
140
200
  const url = target.url.toLowerCase();
141
201
  const title = target.title.toLowerCase();
@@ -55,6 +55,28 @@ class CommandSchemaRegistry {
55
55
  options: [],
56
56
  arguments: [],
57
57
  });
58
+ this.registerCommand({
59
+ name: "list",
60
+ aliases: ["ls"],
61
+ description: "List available Chrome pages you can target",
62
+ usage: "cdp [global-options] list",
63
+ examples: [
64
+ {
65
+ command: "cdp list",
66
+ description: "List selectable Chrome pages",
67
+ },
68
+ {
69
+ command: "cdp --format json list",
70
+ description: "List selectable Chrome pages as JSON",
71
+ },
72
+ {
73
+ command: "cdp --host localhost --port 9223 list",
74
+ description: "List pages from a specific Chrome instance",
75
+ },
76
+ ],
77
+ options: [],
78
+ arguments: [],
79
+ });
58
80
  this.registerCommand({
59
81
  name: "eval",
60
82
  aliases: ["js", "execute"],
@@ -163,7 +163,7 @@ class HelpSystem {
163
163
  orderedCategories.push([cat, categorizedCommands.get(cat)]);
164
164
  }
165
165
  }
166
- for (const [cat, cmds] of categorizedCommands) {
166
+ for (const [cat, cmds] of Array.from(categorizedCommands.entries())) {
167
167
  if (!categoryOrder.includes(cat)) {
168
168
  orderedCategories.push([cat, cmds]);
169
169
  }
@@ -310,11 +310,11 @@ class HelpSystem {
310
310
  }
311
311
  }
312
312
  }
313
- return [...new Set(similar)].slice(0, 5);
313
+ return Array.from(new Set(similar)).slice(0, 5);
314
314
  }
315
315
  findContextualSuggestions(error, commandName) {
316
316
  const suggestions = [];
317
- for (const [errorPattern, helpers] of this.contextualHelpers) {
317
+ for (const [errorPattern, helpers] of Array.from(this.contextualHelpers.entries())) {
318
318
  if (error.toLowerCase().includes(errorPattern.toLowerCase())) {
319
319
  suggestions.push(...helpers);
320
320
  }
@@ -351,7 +351,7 @@ class HelpSystem {
351
351
  else if (command.name.includes("install")) {
352
352
  category = "Installation & Setup";
353
353
  }
354
- else if (["help", "version"].includes(command.name)) {
354
+ else if (["help", "version", "list"].includes(command.name)) {
355
355
  category = "Help & Information";
356
356
  }
357
357
  if (!categories.has(category)) {
@@ -359,7 +359,7 @@ class HelpSystem {
359
359
  }
360
360
  categories.get(category).push(command);
361
361
  }
362
- for (const [, categoryCommands] of categories) {
362
+ for (const [, categoryCommands] of Array.from(categories.entries())) {
363
363
  categoryCommands.sort((a, b) => a.name.localeCompare(b.name));
364
364
  }
365
365
  return categories;
@@ -4,7 +4,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
4
4
  };
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
6
  exports.CDPClient = void 0;
7
- const ws_1 = __importDefault(require("ws"));
7
+ const WebSocket = require("ws");
8
8
  const node_fetch_1 = __importDefault(require("node-fetch"));
9
9
  class CDPClient {
10
10
  constructor() {
@@ -26,7 +26,7 @@ class CDPClient {
26
26
  targetId = pageTarget.id;
27
27
  }
28
28
  const wsUrl = await this.getWebSocketUrl(host, port, targetId);
29
- this.ws = new ws_1.default(wsUrl);
29
+ this.ws = new WebSocket(wsUrl);
30
30
  return new Promise((resolve, reject) => {
31
31
  if (!this.ws) {
32
32
  reject(new Error('WebSocket not initialized'));
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "chrome-cdp-cli",
3
- "version": "2.1.4",
3
+ "version": "2.1.5",
4
4
  "description": "Browser automation CLI via Chrome DevTools Protocol. Designed for developers and AI assistants - combines dedicated commands for common tasks with flexible JavaScript execution for complex scenarios. Features: element interaction, screenshots, DOM snapshots, console/network monitoring. Built-in IDE integration for Cursor and Claude.",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",