@romanmatena/browsermonitor 2.0.0 → 2.1.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/README.md CHANGED
@@ -5,8 +5,8 @@
5
5
  # Browser Monitor
6
6
 
7
7
  [![CI](https://github.com/romanmatena/browsermonitor/actions/workflows/ci.yml/badge.svg)](https://github.com/romanmatena/browsermonitor/actions/workflows/ci.yml)
8
- [![npm](https://img.shields.io/npm/v/browsermonitor.svg)](https://www.npmjs.com/package/browsermonitor)
9
- [![npm downloads](https://img.shields.io/npm/dm/browsermonitor.svg)](https://www.npmjs.com/package/browsermonitor)
8
+ [![npm](https://img.shields.io/npm/v/@romanmatena/browsermonitor.svg)](https://www.npmjs.com/package/@romanmatena/browsermonitor)
9
+ [![npm downloads](https://img.shields.io/npm/dm/@romanmatena/browsermonitor.svg)](https://www.npmjs.com/package/@romanmatena/browsermonitor)
10
10
  [![Node](https://img.shields.io/badge/node-%3E%3D18.0.0-brightgreen)](https://nodejs.org/)
11
11
  [![License](https://img.shields.io/badge/license-MIT-blue.svg)](LICENSE)
12
12
  [![GitHub](https://img.shields.io/badge/GitHub-romanmatena%2Fbrowsermonitor-24292e?logo=github)](https://github.com/romanmatena/browsermonitor)
@@ -14,7 +14,7 @@
14
14
 
15
15
  Browser console, network, DOM, and screenshot monitoring for debugging and LLM workflows.
16
16
 
17
- **[npm](https://www.npmjs.com/package/browsermonitor)** · **[GitHub](https://github.com/romanmatena/browsermonitor)**
17
+ **[npm](https://www.npmjs.com/package/@romanmatena/browsermonitor)** · **[GitHub](https://github.com/romanmatena/browsermonitor)**
18
18
 
19
19
  [Installation](#installation) · [Quick Start](#quick-start) · [HTTP API](#http-api) · [Contributing](CONTRIBUTING.md)
20
20
 
@@ -46,21 +46,21 @@ Browser console, network, DOM, and screenshot monitoring for debugging and LLM w
46
46
 
47
47
  ## Installation
48
48
 
49
- Install globally from [npm](https://www.npmjs.com/package/browsermonitor):
49
+ Install globally from [npm](https://www.npmjs.com/package/@romanmatena/browsermonitor):
50
50
 
51
51
  ```bash
52
52
  # Using npm
53
- npm install -g browsermonitor
53
+ npm install -g @romanmatena/browsermonitor
54
54
 
55
55
  # Or pnpm
56
- pnpm add -g browsermonitor
56
+ pnpm add -g @romanmatena/browsermonitor
57
57
  ```
58
58
 
59
59
  **Note:** Chromium download is skipped — browsermonitor uses your system Chrome/Chromium. No extra 300 MB download.
60
60
 
61
- **First run:** When you run `browsermonitor` in a project directory for the first time, it auto-creates `.browsermonitor/` with `settings.json` and optionally updates agent files (`CLAUDE.md`, `AGENTS.md`, `memory.md`).
61
+ **First run (interactive):** When you run `browsermonitor` for the first time in a project directory, interactive mode asks for HTTP API port, saves `settings.json`, and updates agent files (`CLAUDE.md`, `AGENTS.md`, `memory.md`). When you press `o` (open), it asks for the default URL.
62
62
 
63
- **Manual setup:** Run `browsermonitor init` to re-run the setup wizard.
63
+ **Re-init:** Run `browsermonitor init` to recreate settings and update agent files.
64
64
 
65
65
  ## Quick Start
66
66
 
@@ -74,7 +74,7 @@ browsermonitor --join=9222 # Join mode: attach to existing Chrome on port
74
74
 
75
75
  | Mode | How to run | When to use |
76
76
  |------------|--------------------------|-------------|
77
- | **Interactive** | `browsermonitor` (no flags) | Menu asks for project root, then: **o** = open Chrome, **j** = join running Chrome, **q** = quit. |
77
+ | **Interactive** | `browsermonitor` (no flags) | First run asks HTTP port. Then menu: **o** = open Chrome (asks URL on first use), **j** = join running Chrome, **q** = quit. |
78
78
  | **Open** | `browsermonitor --open [url]` | Launch a new Chrome and monitor it. Uses current dir for logs. |
79
79
  | **Join** | `browsermonitor --join=PORT` | Attach to an existing Chrome with remote debugging on PORT (e.g. 9222). Port is required. |
80
80
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@romanmatena/browsermonitor",
3
- "version": "2.0.0",
3
+ "version": "2.1.0",
4
4
  "description": "Browser console, network, DOM monitoring for debugging and LLM workflows. Captures console, network, cookies, screenshot, DOM. HTTP API for LLM/scripts. WSL+Windows, Linux, Open/Join modes.",
5
5
  "type": "module",
6
6
  "bin": {
@@ -3,16 +3,18 @@
3
3
 
4
4
  **Why use this:** Do not ask the user to copy or paste content from the browser (DOM, console, network). You can obtain the current page state yourself: the project has browsermonitor; after a dump you read the generated files.
5
5
 
6
+ **Monitored URL:** `{{DEFAULT_URL}}`
7
+
6
8
  **What to do when you need the live page (elements, console, requests):**
7
- 1. Trigger a dump: `curl -s http://localhost:60001/dump` (monitor must be running; user runs `browsermonitor` or `browsermonitor --open` / `--join=9222` to start it).
9
+ 1. Trigger a dump: `curl -s http://localhost:{{HTTP_PORT}}/dump` (monitor must be running; user runs `browsermonitor` or `browsermonitor --open` / `--join=9222` to start it).
8
10
  2. Read the written files in `.browsermonitor/.puppeteer/`:
9
11
  - **.browsermonitor/.puppeteer/dom.html** – current page HTML (JS-modified DOM). Use this for the element tree and structure.
10
12
  - **.browsermonitor/.puppeteer/screenshot.png** – screenshot of the current tab viewport.
11
13
  - **.browsermonitor/.puppeteer/console.log** – browser console output.
12
14
  - **.browsermonitor/.puppeteer/network.log** and **.browsermonitor/.puppeteer/network-log/*.json** – network requests and responses.
13
15
  - **.browsermonitor/.puppeteer/cookies/** – cookies per domain (JSON files).
14
- 3. Optional: `curl -s http://localhost:60001/status` for buffer status.
15
- 4. Optional: `curl -s http://localhost:60001/tabs` to list tabs; `curl -s "http://localhost:60001/tab?index=2"` to switch tab.
16
- 5. Optional: `curl -s http://localhost:60001/clear` to clear buffers.
16
+ 3. Optional: `curl -s http://localhost:{{HTTP_PORT}}/status` for buffer status.
17
+ 4. Optional: `curl -s http://localhost:{{HTTP_PORT}}/tabs` to list tabs; `curl -s "http://localhost:{{HTTP_PORT}}/tab?index=2"` to switch tab.
18
+ 5. Optional: `curl -s http://localhost:{{HTTP_PORT}}/clear` to clear buffers.
17
19
 
18
20
  <!-- END browser-monitor-llm-section - LLM: do not remove this block; required for automatic section updates -->
package/src/cli.mjs CHANGED
@@ -6,7 +6,7 @@
6
6
  * Configuration in .browsermonitor/settings.json (created on first run).
7
7
  *
8
8
  * Subcommands:
9
- * init → Run setup (create .browsermonitor/, update agent files)
9
+ * init → Create .browsermonitor/, settings.json, update agent files
10
10
  *
11
11
  * Mode is chosen by arguments:
12
12
  * (none) → Interactive: menu (o = open, j = join, q = quit)
@@ -21,29 +21,49 @@
21
21
  * --help Show help
22
22
  */
23
23
 
24
- import { runInteractiveMode, runJoinMode, runOpenMode } from './monitor.mjs';
24
+ import { parseArgs } from 'node:util';
25
+ import { runJoinMode } from './monitor/join-mode.mjs';
26
+ import { runOpenMode } from './monitor/open-mode.mjs';
25
27
  import { printAppIntro } from './intro.mjs';
26
28
  import { createHttpServer } from './http-server.mjs';
27
29
  import { printApiHelpTable } from './templates/api-help.mjs';
28
30
  import { printCliCommandsTable } from './templates/cli-commands.mjs';
29
- import { askHttpPort } from './utils/ask.mjs';
30
- import { loadSettings, isInitialized, getPaths, ensureDirectories } from './settings.mjs';
31
+ import { printModeHeading } from './templates/section-heading.mjs';
32
+ import { loadSettings, getPaths, ensureDirectories, isInitialized, DEFAULT_SETTINGS, saveSettings } from './settings.mjs';
31
33
  import { runInit } from './init.mjs';
32
-
33
- // Project root = current working directory
34
- const projectRoot = process.cwd();
35
-
36
- // Parse arguments
37
- const args = process.argv.slice(2);
38
-
39
- // Handle `browsermonitor init` subcommand
40
- if (args[0] === 'init') {
41
- await runInit(projectRoot, { askForUrl: true, updateAgentFiles: true });
34
+ import { resolveHttpPort, resolveDefaultUrl, askMode } from './utils/ask.mjs';
35
+
36
+ // ---- Parse CLI arguments ----
37
+ const { values: flags, positionals } = parseArgs({
38
+ args: process.argv.slice(2),
39
+ options: {
40
+ open: { type: 'boolean', default: false },
41
+ join: { type: 'string' },
42
+ port: { type: 'string' },
43
+ realtime: { type: 'boolean', default: false },
44
+ headless: { type: 'boolean', default: false },
45
+ timeout: { type: 'string', default: '0' },
46
+ 'nav-timeout': { type: 'string' },
47
+ help: { type: 'boolean', short: 'h', default: false },
48
+ },
49
+ allowPositionals: true,
50
+ strict: false,
51
+ });
52
+
53
+ const subcommand = positionals[0];
54
+ const urlFromArgs = positionals.find((a) => /^https?:\/\//.test(a) || a.includes('localhost'));
55
+ const joinPort = flags.join ? parseInt(flags.join, 10) : null;
56
+ const httpPortFromArgs = flags.port ? parseInt(flags.port, 10) : null;
57
+ const hardTimeout = parseInt(flags.timeout, 10) || 0;
58
+
59
+ // Handle `browsermonitor init`
60
+ if (subcommand === 'init') {
61
+ await runInit(process.cwd());
42
62
  process.exit(0);
43
63
  }
44
64
 
45
65
  // Show help
46
- if (args.includes('--help') || args.includes('-h')) {
66
+ if (flags.help) {
47
67
  console.log(`
48
68
  Browser Monitor – capture browser console, network, and DOM for debugging and LLM workflows.
49
69
 
@@ -57,29 +77,23 @@ What it does:
57
77
  printCliCommandsTable({ showEntry: true, showUsage: true });
58
78
  console.log(`
59
79
  Subcommands:
60
- init Run setup: create .browsermonitor/, settings.json, update agent files
80
+ init Create .browsermonitor/, settings.json with defaults, update agent files
61
81
 
62
82
  Modes (chosen by flags; only one applies):
63
- INTERACTIVE (default) No flag. Asks for project root, then menu:
64
- o = open Chrome (launch and monitor)
65
- j = join running Chrome (pick instance/tab)
66
- q = quit
83
+ INTERACTIVE (default) No flag. First run asks HTTP port and URL. Then menu:
84
+ o = open Chrome, j = join running Chrome, q = quit
67
85
 
68
86
  OPEN (--open) Launch a new Chrome and monitor it. URL = first positional or config.
69
- Uses current directory for logs. Good for local dev with a fresh profile.
70
87
 
71
- JOIN (--join=PORT) Attach to an existing Chrome with remote debugging on PORT.
72
- Port is required (e.g. --join=9222). Use when Chrome is already
73
- running (e.g. started by a script or on another machine via tunnel).
88
+ JOIN (--join=PORT) Attach to existing Chrome with remote debugging on PORT.
89
+ If PORT omitted, scans for running instances.
74
90
 
75
91
  Options:
76
92
  --port=PORT HTTP API port (default: from settings or 60001)
77
- --realtime Write each event to files immediately (default: lazy, buffer in memory)
93
+ --realtime Write each event to files immediately (default: lazy)
78
94
  --headless Run Chrome without GUI
79
- --open Go directly to open mode
80
- --join=PORT Go directly to join mode (PORT required)
81
95
  --timeout=MS Hard timeout in ms; process exits after (0 = disabled)
82
- --nav-timeout=MS Navigation timeout in ms (default: from settings, 0 = no limit)
96
+ --nav-timeout=MS Navigation timeout in ms (default: from settings)
83
97
  --help, -h Show this help
84
98
 
85
99
  Config (.browsermonitor/settings.json):
@@ -90,67 +104,42 @@ Config (.browsermonitor/settings.json):
90
104
  process.exit(0);
91
105
  }
92
106
 
93
- // Auto-init on first run
94
- if (!isInitialized(projectRoot)) {
95
- console.log('[browsermonitor] First run detected. Setting up .browsermonitor/ ...');
96
- await runInit(projectRoot, { askForUrl: process.stdin.isTTY, updateAgentFiles: true });
97
- }
98
-
99
- // Ensure directories exist (in case user deleted .puppeteer/ subdir)
100
- ensureDirectories(projectRoot);
101
-
102
- // Load settings from .browsermonitor/settings.json
103
- const config = loadSettings(projectRoot);
104
- const paths = getPaths(projectRoot);
105
-
106
- // ---- Mode dispatch: --open | --join=PORT | interactive ----
107
- const openMode = args.some((a) => a === '--open' || a.startsWith('--open='));
108
- const joinArg = args.find((a) => a.startsWith('--join'));
109
- let joinPort = null;
110
- if (joinArg) {
111
- if (joinArg === '--join' || !joinArg.includes('=')) {
112
- console.error('Error: --join requires a port (e.g. --join=9222)');
113
- process.exit(1);
114
- }
115
- const portStr = joinArg.split('=')[1];
116
- joinPort = parseInt(portStr, 10);
117
- if (Number.isNaN(joinPort) || joinPort < 1 || joinPort > 65535) {
118
- console.error(`Error: invalid port for --join: ${portStr}`);
119
- process.exit(1);
120
- }
121
- }
122
-
123
- // Shared options (CLI args override settings.json)
124
- const realtimeMode = args.includes('--realtime') || config.realtime;
125
- const headlessCli = args.includes('--headless');
126
- const timeoutArg = args.find((a) => a.startsWith('--timeout='));
127
- const hardTimeout = timeoutArg ? parseInt(timeoutArg.split('=')[1], 10) : 0;
128
- const navTimeoutArg = args.find((a) => a.startsWith('--nav-timeout='));
129
- const navigationTimeout = navTimeoutArg
130
- ? parseInt(navTimeoutArg.split('=')[1], 10)
131
- : (config.navigationTimeout !== undefined ? config.navigationTimeout : 60_000);
132
- const urlFromArgs = args.find((a) => !a.startsWith('--'));
133
- const url = urlFromArgs || config.defaultUrl || 'https://localhost:4000/';
134
- const headless = headlessCli || config.headless || false;
135
- const ignorePatterns = config.ignorePatterns || [];
136
- const outputDir = projectRoot;
137
-
138
- const DEFAULT_HTTP_PORT = config.httpPort || 60001;
139
- const portArg = args.find((a) => a === '--port' || a.startsWith('--port='));
140
- let httpPortFromArgs = null;
141
- if (portArg) {
142
- const val = portArg.includes('=') ? portArg.split('=')[1] : '';
143
- const num = parseInt(val, 10);
144
- if (!Number.isNaN(num) && num >= 1 && num <= 65535) httpPortFromArgs = num;
145
- }
146
-
147
107
  (async () => {
108
+ // 1. Intro
148
109
  printAppIntro();
149
110
 
150
- printApiHelpTable({ port: DEFAULT_HTTP_PORT, showApi: true, showInteractive: false, showOutputFiles: true, noLeadingNewline: true });
111
+ // 2. Project root = cwd, load existing settings (may be empty/missing)
112
+ const projectRoot = process.cwd();
113
+ ensureDirectories(projectRoot);
114
+ let config = loadSettings(projectRoot);
115
+ const paths = getPaths(projectRoot);
116
+
117
+ // 3. CLI args override settings.json
118
+ const realtimeMode = flags.realtime || config.realtime;
119
+ const navTimeoutFromArgs = flags['nav-timeout'] ? parseInt(flags['nav-timeout'], 10) : null;
120
+ const navigationTimeout = navTimeoutFromArgs
121
+ ?? (config.navigationTimeout !== undefined ? config.navigationTimeout : 60_000);
122
+ const headless = flags.headless || config.headless || false;
123
+ const httpPort = await resolveHttpPort(httpPortFromArgs ?? config.httpPort, DEFAULT_SETTINGS.httpPort);
124
+ const url = await resolveDefaultUrl(urlFromArgs || config.defaultUrl, DEFAULT_SETTINGS.defaultUrl);
125
+
126
+ // 4. Need to initialize project (create .browsermonitor/, settings.json) before showing API info, because API port is part of config
127
+ if (!isInitialized(projectRoot)) {
128
+ saveSettings(projectRoot, { ...DEFAULT_SETTINGS, httpPort, defaultUrl: url, headless, navigationTimeout, realtime: realtimeMode });
129
+ config = loadSettings(projectRoot);
130
+ await runInit(projectRoot, config);
131
+ }
151
132
 
152
- const httpPort =
153
- httpPortFromArgs ?? (process.stdin.isTTY ? await askHttpPort(DEFAULT_HTTP_PORT) : DEFAULT_HTTP_PORT);
133
+ // 5. Show API/output info (now httpPort is known)
134
+ printApiHelpTable({
135
+ url: config.defaultUrl,
136
+ port: config.httpPort,
137
+ showApi: true,
138
+ showInteractive: false,
139
+ showOutputFiles: true,
140
+ noLeadingNewline: true,
141
+ context: paths,
142
+ });
154
143
 
155
144
  const sharedHttpState = {
156
145
  mode: 'interactive',
@@ -162,41 +151,50 @@ if (portArg) {
162
151
  getAllTabs: async () => [],
163
152
  };
164
153
  const sharedHttpServer = createHttpServer({
165
- port: httpPort,
166
- defaultPort: DEFAULT_HTTP_PORT,
154
+ port: config.httpPort,
155
+ defaultPort: config.httpPort,
167
156
  getState: () => sharedHttpState,
168
157
  });
169
158
 
170
159
  const commonOptions = {
171
- realtime: realtimeMode,
172
- outputDir,
160
+ outputDir: projectRoot,
173
161
  paths,
174
- ignorePatterns,
162
+ realtime: realtimeMode,
163
+ ignorePatterns: config.ignorePatterns,
175
164
  hardTimeout,
176
- httpPort,
165
+ httpPort: config.httpPort,
166
+ joinPort,
177
167
  sharedHttpState,
178
168
  sharedHttpServer,
179
169
  };
180
170
 
181
- if (openMode) {
182
- console.log(` [CLI] Open mode → ${url}`);
183
- await runOpenMode(url, {
171
+ // 8. Dispatch to mode
172
+ if (flags.open) {
173
+ await runOpenMode(config.defaultUrl, {
184
174
  ...commonOptions,
185
175
  headless,
186
176
  navigationTimeout,
187
177
  });
188
178
  } else if (joinPort !== null) {
189
- console.log(` [CLI] Join mode → localhost:${joinPort}`);
190
- await runJoinMode(joinPort, {
191
- ...commonOptions,
192
- defaultUrl: url,
193
- });
179
+ await runJoinMode(config.defaultUrl, commonOptions);
194
180
  } else {
195
- await runInteractiveMode({
196
- ...commonOptions,
197
- defaultUrl: url,
198
- headless,
199
- navigationTimeout,
200
- });
181
+ // No mode flag → ask user
182
+ printModeHeading('Choose mode');
183
+ const mode = await askMode();
184
+ if (mode === 'q') process.exit(0);
185
+
186
+ if (mode === 'o') {
187
+ await runOpenMode(config.defaultUrl, {
188
+ ...commonOptions,
189
+ headless,
190
+ navigationTimeout,
191
+ skipModeHeading: true,
192
+ });
193
+ } else if (mode === 'j') {
194
+ await runJoinMode(config.defaultUrl, {
195
+ ...commonOptions,
196
+ skipModeHeading: true,
197
+ });
198
+ }
201
199
  }
202
200
  })();
@@ -12,8 +12,8 @@ import http from 'http';
12
12
  import { C, log } from './utils/colors.mjs';
13
13
  import { getFullTimestamp } from './logging/index.mjs';
14
14
  import { getComputedStylesFromPage } from './logging/dump.mjs';
15
- import { printApiHelpTable, API_ENDPOINTS } from './templates/api-help.mjs';
16
- import { printSectionHeading } from './templates/section-heading.mjs';
15
+ import { API_ENDPOINTS } from './templates/api-help.mjs';
16
+
17
17
 
18
18
  /** Default timeout for Puppeteer operations (ms). */
19
19
  const PUPPETEER_CALL_TIMEOUT_MS = 30_000;
@@ -155,7 +155,6 @@ export function createHttpServer(options) {
155
155
  return;
156
156
  }
157
157
  try {
158
- const statsBeforeDump = s.logBuffer.getStats();
159
158
  const pages = s.getPages();
160
159
  const page = pages.length > 0 ? pages[0] : null;
161
160
 
@@ -172,26 +171,14 @@ export function createHttpServer(options) {
172
171
  success: true,
173
172
  timestamp: getFullTimestamp(),
174
173
  message: 'Dump completed. Read the files below.',
175
- stats: statsBeforeDump,
176
- outputFiles: {
177
- consoleLog: s.logBuffer.CONSOLE_LOG,
178
- networkLog: s.logBuffer.NETWORK_LOG,
179
- networkDir: s.logBuffer.NETWORK_DIR,
180
- cookiesDir: s.logBuffer.COOKIES_DIR,
181
- domHtml: s.logBuffer.DOM_HTML,
182
- screenshot: s.logBuffer.SCREENSHOT,
183
- },
184
- llm: {
185
- instruction: 'Read or download these files to get the current browser state. Do not ask the user to copy/paste from the browser.',
186
- files: [
187
- { path: s.logBuffer.DOM_HTML, what: 'Current page HTML (JS-modified DOM). Use for element tree and structure.' },
188
- { path: s.logBuffer.SCREENSHOT, what: 'Screenshot of the current tab viewport (PNG).' },
189
- { path: s.logBuffer.CONSOLE_LOG, what: 'Browser console output (logs, errors, warnings).' },
190
- { path: s.logBuffer.NETWORK_LOG, what: 'Network requests overview (one line per request with ID).' },
191
- { path: s.logBuffer.NETWORK_DIR, what: 'Directory with one JSON per request: full headers, payload, response (see IDs in network log).' },
192
- { path: s.logBuffer.COOKIES_DIR, what: 'Directory with cookies per domain (JSON files).' },
193
- ],
194
- },
174
+ files: [
175
+ { path: s.logBuffer.DOM_HTML, what: 'Current page HTML (JS-modified DOM). Use for element tree and structure.' },
176
+ { path: s.logBuffer.SCREENSHOT, what: 'Screenshot of the current tab viewport (PNG).' },
177
+ { path: s.logBuffer.CONSOLE_LOG, what: 'Browser console output (logs, errors, warnings).' },
178
+ { path: s.logBuffer.NETWORK_LOG, what: 'Network requests overview (one line per request with ID).' },
179
+ { path: s.logBuffer.NETWORK_DIR, what: 'Directory with one JSON per request: full headers, payload, response (see IDs in network log).' },
180
+ { path: s.logBuffer.COOKIES_DIR, what: 'Directory with cookies per domain (JSON files).' },
181
+ ],
195
182
  }, null, 2));
196
183
  } catch (error) {
197
184
  res.writeHead(500, { 'Content-Type': 'application/json' });
@@ -200,7 +187,7 @@ export function createHttpServer(options) {
200
187
  return;
201
188
  }
202
189
 
203
- // GET /status
190
+ // GET /status — state only (no file paths; use GET /dump for that)
204
191
  if (req.url === '/status' && req.method === 'GET') {
205
192
  const pages = s.getPages();
206
193
  const collectingPaused = s.getCollectingPaused();
@@ -215,14 +202,6 @@ export function createHttpServer(options) {
215
202
  if (!noBrowser) {
216
203
  payload.collecting = collectingPaused ? 'paused' : 'running';
217
204
  payload.stats = s.logBuffer.getStats();
218
- payload.outputFiles = {
219
- consoleLog: s.logBuffer.CONSOLE_LOG,
220
- networkLog: s.logBuffer.NETWORK_LOG,
221
- networkDir: s.logBuffer.NETWORK_DIR,
222
- cookiesDir: s.logBuffer.COOKIES_DIR,
223
- domHtml: s.logBuffer.DOM_HTML,
224
- screenshot: s.logBuffer.SCREENSHOT,
225
- };
226
205
  } else {
227
206
  payload.message = 'No browser. Use interactive (o/j) or --open / --join.';
228
207
  }
@@ -500,12 +479,7 @@ export function createHttpServer(options) {
500
479
  }, null, 2));
501
480
  });
502
481
 
503
- server.listen(port, host, () => {
504
- const url = `http://${host}:${port}`;
505
- const changed = port !== defaultPort ? ` ${C.red}(changed)${C.reset}` : '';
506
- const title = `HTTP API URL: ${url}${changed}`;
507
- printSectionHeading(title, ' ');
508
- });
482
+ server.listen(port, host);
509
483
 
510
484
  server.on('error', (err) => {
511
485
  if (err.code === 'EADDRINUSE') {