chromex-mcp 1.8.0 → 1.8.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/README.md CHANGED
@@ -78,7 +78,7 @@ Chromex is a direct CDP layer for coding agents. It sits between raw Chrome DevT
78
78
 
79
79
  The core runtime uses only Node.js built-in modules. Chromex does not install heavy browser automation runtimes, Selenium, browser drivers, telemetry SDKs, update checkers, or bundled browsers.
80
80
 
81
- The only exception is the optional `audit` command: it shells out to Lighthouse with `npx --yes lighthouse` when you explicitly run an audit. All other CLI and MCP commands run through Chromex's own CDP client.
81
+ The only exception is the optional `audit` command: it runs Lighthouse as a subprocess with `npx --yes lighthouse` when you explicitly run an audit. All other CLI and MCP commands run through Chromex's own CDP client.
82
82
 
83
83
  Development dependencies are used only for tests and token benchmarks.
84
84
 
package/docs/security.md CHANGED
@@ -2,6 +2,12 @@
2
2
 
3
3
  Chromex is designed for AI agents interacting with real browsers. Security is a first-class concern.
4
4
 
5
+ ## Reporting Vulnerabilities
6
+
7
+ Report suspected vulnerabilities privately to `whallysson.dev@gmail.com`. Do not open a public issue for an undisclosed vulnerability.
8
+
9
+ Include the affected versions and platforms, reproducible steps or a proof of concept, the expected impact, and any suggested remediation. Keep the report and technical details private until a fixed release is available or a disclosure date is agreed.
10
+
5
11
  ## Config File
6
12
 
7
13
  All security settings live in `~/.chromex/config.json` (auto-created on first run).
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "chromex-mcp",
3
- "version": "1.8.0",
3
+ "version": "1.8.1",
4
4
  "description": "Agent-first Chrome DevTools toolkit with a token-efficient CLI, 85 typed MCP tools, modal-free pipe transport, diagnostics, memory analysis, extensions, and WebMCP.",
5
5
  "type": "module",
6
6
  "bin": {
@@ -50,6 +50,13 @@
50
50
  },
51
51
  "devDependencies": {
52
52
  "js-tiktoken": "^1.0.21",
53
- "vitest": "^3.0.0"
53
+ "vitest": "^4.1.11"
54
+ },
55
+ "overrides": {
56
+ "esbuild": "^0.28.1",
57
+ "nanoid": "^3.3.16",
58
+ "picomatch": "^4.0.4",
59
+ "postcss": "^8.5.23",
60
+ "vite": "^7.3.5"
54
61
  }
55
62
  }
@@ -2,7 +2,7 @@
2
2
  // Chrome: connects to existing browser via --port (reuses session)
3
3
  // Other browsers (Brave, Edge, etc.): Lighthouse launches its own headless Chrome
4
4
 
5
- import { execSync } from 'child_process';
5
+ import { execFileSync } from 'child_process';
6
6
  import { existsSync } from 'fs';
7
7
  import { resolveArtifactPath } from '../artifacts.mjs';
8
8
  import { evalStr } from './evaluate.mjs';
@@ -30,8 +30,9 @@ function findChromiumPath() {
30
30
  // Check if Chrome's HTTP debug endpoint is available (Brave/Edge don't expose it)
31
31
  function isHttpDebugAvailable(port) {
32
32
  try {
33
- const result = execSync(`curl -sf http://127.0.0.1:${port}/json/version`, {
33
+ const result = execFileSync('curl', ['-sf', `http://127.0.0.1:${port}/json/version`], {
34
34
  encoding: 'utf8', timeout: 3000, stdio: ['pipe', 'pipe', 'pipe'],
35
+ shell: false,
35
36
  });
36
37
  return result.length > 0;
37
38
  } catch {
@@ -88,7 +89,7 @@ export async function auditStr(cdp, sid, categories, device, reportPath) {
88
89
  mode = 'standalone (headless Chrome)';
89
90
  }
90
91
 
91
- const cmd = `npx --yes lighthouse ${JSON.stringify(url)} ${args.join(' ')}`;
92
+ const lighthouseArgs = ['--yes', 'lighthouse', url, ...args];
92
93
 
93
94
  // Set CHROME_PATH for standalone mode (Lighthouse uses chrome-launcher which reads it)
94
95
  const env = { ...process.env };
@@ -99,16 +100,17 @@ export async function auditStr(cdp, sid, categories, device, reportPath) {
99
100
 
100
101
  let jsonOutput;
101
102
  try {
102
- jsonOutput = execSync(cmd, {
103
+ jsonOutput = execFileSync('npx', lighthouseArgs, {
103
104
  encoding: 'utf8',
104
105
  timeout: 120000,
105
106
  stdio: ['pipe', 'pipe', 'pipe'],
106
107
  maxBuffer: 50 * 1024 * 1024,
107
108
  env,
109
+ shell: false,
108
110
  });
109
111
  } catch (e) {
110
112
  const stderr = e.stderr?.toString().trim() || '';
111
- if (stderr.includes('not found') || stderr.includes('ENOENT')) {
113
+ if (e.code === 'ENOENT' || stderr.includes('not found') || stderr.includes('ENOENT')) {
112
114
  throw new Error('lighthouse not found. Install: npm i -g lighthouse');
113
115
  }
114
116
  if (stderr.includes('No Chrome installations found')) {
@@ -801,7 +801,7 @@ const TOOLS = [
801
801
  categories: { type: 'string', description: 'Comma-separated: performance,accessibility,seo,best-practices (default: all)' },
802
802
  device: { type: 'string', enum: ['mobile', 'desktop'], description: 'Device preset (default: mobile)' },
803
803
  reportPath: { type: 'string', description: 'Path to save full HTML report' },
804
- }, ['target'], RO),
804
+ }, ['target'], RW),
805
805
 
806
806
  tool('chromex_stats',
807
807
  'Session analytics: command counts, average timing, error rates, action timeline. All data is local, never sent externally.',