chrome-devtools-mcp-for-extension 0.25.6 → 0.25.7

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.
@@ -6,11 +6,11 @@
6
6
  import fs from 'node:fs/promises';
7
7
  import os from 'node:os';
8
8
  import path from 'node:path';
9
+ import { BrowserConnectionManager, } from './browser-connection-manager.js';
9
10
  import { NetworkCollector, PageCollector } from './PageCollector.js';
10
11
  import { pages } from './tools/pages.js';
11
12
  import { CLOSE_PAGE_ERROR } from './tools/ToolDefinition.js';
12
13
  import { WaitForHelper } from './WaitForHelper.js';
13
- import { BrowserConnectionManager, } from './browser-connection-manager.js';
14
14
  const DEFAULT_TIMEOUT = 5_000;
15
15
  const NAVIGATION_TIMEOUT = 10_000;
16
16
  function getNetworkMultiplierFromString(condition) {
@@ -1,8 +1,8 @@
1
+ import { getDevelopmentExtensionPaths } from './browser.js';
1
2
  import { formatConsoleEvent } from './formatters/consoleFormatter.js';
3
+ import { formatExtensionsPage } from './formatters/extensionsPageFormatter.js';
2
4
  import { getFormattedHeaderValue, getShortDescriptionForRequest, getStatusFromRequest, } from './formatters/networkFormatter.js';
3
5
  import { formatA11ySnapshot } from './formatters/snapshotFormatter.js';
4
- import { formatExtensionsPage } from './formatters/extensionsPageFormatter.js';
5
- import { getDevelopmentExtensionPaths } from './browser.js';
6
6
  import { paginate } from './utils/pagination.js';
7
7
  export class McpResponse {
8
8
  #includePages = false;
@@ -296,7 +296,7 @@ function getChromeExtensionsDirectory(channel) {
296
296
  const homeDir = os.homedir();
297
297
  const platform = os.platform();
298
298
  let chromeDataPath;
299
- let profileName = 'Default';
299
+ const profileName = 'Default';
300
300
  if (platform === 'darwin') {
301
301
  // macOS
302
302
  chromeDataPath = path.join(homeDir, 'Library', 'Application Support', 'Google', 'Chrome');
@@ -450,8 +450,8 @@ export async function launch(options) {
450
450
  if (resolved.reason === 'AUTO') {
451
451
  console.error(` Root: ${process.cwd()}`);
452
452
  }
453
- let usingSystemProfile = false;
454
- let profileDirectory = 'Default';
453
+ const usingSystemProfile = false;
454
+ const profileDirectory = 'Default';
455
455
  const args = [
456
456
  '--hide-crash-restore-bubble',
457
457
  `--profile-directory=${profileDirectory}`,
@@ -87,7 +87,7 @@ function groupExtensions(root, developmentPaths) {
87
87
  // Find sibling nodes that belong to this extension
88
88
  const siblings = [];
89
89
  let version = '';
90
- let enabled = true;
90
+ const enabled = true;
91
91
  let location = '';
92
92
  const errors = [];
93
93
  // Collect related nodes (buttons, switches, text)
package/build/src/main.js CHANGED
@@ -39,13 +39,13 @@ import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js'
39
39
  import { SetLevelRequestSchema, RootsListChangedNotificationSchema } from '@modelcontextprotocol/sdk/types.js';
40
40
  import { resolveBrowser } from './browser.js';
41
41
  import { parseArguments } from './cli.js';
42
+ import { setupGraceful } from './graceful.js';
42
43
  import { logger, saveLogsToFile } from './logger.js';
43
44
  import { McpContext } from './McpContext.js';
44
45
  import { McpResponse } from './McpResponse.js';
45
46
  import { Mutex } from './Mutex.js';
46
- import { resolveRoots } from './roots-manager.js';
47
47
  import { setProjectRoot } from './project-root-state.js';
48
- import { setupGraceful } from './graceful.js';
48
+ import { resolveRoots } from './roots-manager.js';
49
49
  import * as chatgptWebTools from './tools/chatgpt-web.js';
50
50
  import * as consoleTools from './tools/console.js';
51
51
  import * as emulationTools from './tools/emulation.js';
@@ -92,7 +92,7 @@ server.server.setNotificationHandler(RootsListChangedNotificationSchema, async (
92
92
  logger('[roots] Cached roots cleared - will re-fetch on next browser launch');
93
93
  });
94
94
  let context;
95
- let uiHealthCheckRun = false; // Track if UI health check has been run
95
+ const uiHealthCheckRun = false; // Track if UI health check has been run
96
96
  let cachedRootsInfo = null; // Cache roots info
97
97
  let initializationComplete = false; // Track if MCP initialization is complete
98
98
  // Setup graceful shutdown
@@ -1,3 +1,8 @@
1
+ /**
2
+ * @license
3
+ * Copyright 2026 Google LLC
4
+ * SPDX-License-Identifier: Apache-2.0
5
+ */
1
6
  // src/profile-migration.ts
2
7
  // Legacy profile migration utilities
3
8
  // Creates symlinks from new stable paths to existing legacy paths
@@ -1,3 +1,8 @@
1
+ /**
2
+ * @license
3
+ * Copyright 2026 Google LLC
4
+ * SPDX-License-Identifier: Apache-2.0
5
+ */
1
6
  // src/profile-resolver.ts
2
7
  // Phase 1 (v0.15.0) + v0.15.1 (MCP_CLIENT_ID support) + v0.17.0 (Hierarchical profiles)
3
8
  // - Hybrid priority (CLI > MCP_USER_DATA_DIR > MCP_PROJECT_ID > AUTO > DEFAULT)
@@ -9,12 +14,12 @@
9
14
  // - Client ID isolation (MCP_CLIENT_ID environment variable)
10
15
  // - Hierarchical structure: {project}/{client}/{channel} (v0.17.0)
11
16
  // - Minimal console.error() logging of decision
17
+ import crypto from 'node:crypto';
12
18
  import fs from 'node:fs';
13
19
  import os from 'node:os';
14
20
  import path from 'node:path';
15
- import crypto from 'node:crypto';
16
- import { detectProjectName, detectProjectRoot } from './project-detector.js';
17
21
  import { detectClientType } from './client-detector.js';
22
+ import { detectProjectName, detectProjectRoot } from './project-detector.js';
18
23
  import { getProjectRoot } from './project-root-state.js';
19
24
  import { resolveStableIdentity, } from './stable-identity.js';
20
25
  const CACHE_ROOT = path.join(os.homedir(), '.cache', 'chrome-devtools-mcp');
@@ -25,8 +30,8 @@ export function resolveUserDataDir(opts) {
25
30
  if (opts.rootsInfo) {
26
31
  const stableProfilePath = path.join(CACHE_ROOT, 'profiles', opts.rootsInfo.profileKey, opts.rootsInfo.clientName, channel);
27
32
  const normalized = pathNormalize(stableProfilePath);
28
- // v0.25.5: Migration from directory-based profile to stable identity profile
29
- // Check if directory-based profile exists (for projects that added git later)
33
+ // v0.25.6: Migration from legacy profile formats to stable identity profile
34
+ // Supports: (1) v0.25.4以前のURI+clientベースハッシュ, (2) ディレクトリパスベースハッシュ
30
35
  if (!fs.existsSync(stableProfilePath) && opts.rootsInfo.rootsUris.length > 0) {
31
36
  try {
32
37
  const firstUri = opts.rootsInfo.rootsUris[0];
@@ -34,28 +39,46 @@ export function resolveUserDataDir(opts) {
34
39
  if (url.protocol === 'file:') {
35
40
  const rootPath = url.pathname;
36
41
  const realRoot = realpathSafe(rootPath);
37
- const dirHash = shortHash(realRoot);
38
- const dirBasedKey = `${opts.rootsInfo.projectName}_${dirHash}`;
39
- const dirBasedPath = path.join(CACHE_ROOT, 'profiles', dirBasedKey, opts.rootsInfo.clientName, channel);
40
- // If directory-based profile exists, create symlink for migration
41
- if (fs.existsSync(dirBasedPath)) {
42
- console.error(`[profiles] Migration: Found directory-based profile: ${dirBasedPath}`);
43
- console.error(`[profiles] Migration: Creating symlink to stable profile: ${stableProfilePath}`);
44
- try {
45
- // Create parent directories
46
- fs.mkdirSync(path.dirname(stableProfilePath), { recursive: true });
47
- // Create symlink: stable -> directory-based
48
- fs.symlinkSync(dirBasedPath, stableProfilePath, 'dir');
49
- console.error(`[profiles] Migration: ✅ Symlink created successfully`);
50
- }
51
- catch (e) {
52
- console.error(`[profiles] Migration: ⚠️ Failed to create symlink: ${e}`);
42
+ // Try multiple legacy hash formats
43
+ const legacyHashFormats = [
44
+ // Format 1: v0.25.4以前 roots-manager.ts (URI + client JSON hash)
45
+ {
46
+ name: 'uri+client',
47
+ hash: (() => {
48
+ const sortedUris = [firstUri].sort();
49
+ const keyMaterial = JSON.stringify({
50
+ roots: sortedUris,
51
+ client: opts.rootsInfo.clientName,
52
+ });
53
+ return crypto.createHash('sha256').update(keyMaterial).digest('hex').slice(0, 8);
54
+ })(),
55
+ },
56
+ // Format 2: Directory path hash (shortHash)
57
+ {
58
+ name: 'directory-path',
59
+ hash: shortHash(realRoot),
60
+ },
61
+ ];
62
+ for (const format of legacyHashFormats) {
63
+ const legacyKey = `${opts.rootsInfo.projectName}_${format.hash}`;
64
+ const legacyPath = path.join(CACHE_ROOT, 'profiles', legacyKey, opts.rootsInfo.clientName, channel);
65
+ if (fs.existsSync(legacyPath)) {
66
+ console.error(`[profiles] Migration: Found legacy profile (${format.name}): ${legacyPath}`);
67
+ console.error(`[profiles] Migration: Creating symlink to stable profile: ${stableProfilePath}`);
68
+ try {
69
+ fs.mkdirSync(path.dirname(stableProfilePath), { recursive: true });
70
+ fs.symlinkSync(legacyPath, stableProfilePath, 'dir');
71
+ console.error(`[profiles] Migration: ✅ Symlink created successfully`);
72
+ break; // Stop after first successful migration
73
+ }
74
+ catch (e) {
75
+ console.error(`[profiles] Migration: ⚠️ Failed to create symlink: ${e}`);
76
+ }
53
77
  }
54
78
  }
55
79
  }
56
80
  }
57
81
  catch (e) {
58
- // Ignore migration errors, continue with normal flow
59
82
  console.error(`[profiles] Migration check failed: ${e}`);
60
83
  }
61
84
  }
@@ -1,12 +1,17 @@
1
+ /**
2
+ * @license
3
+ * Copyright 2026 Google LLC
4
+ * SPDX-License-Identifier: Apache-2.0
5
+ */
1
6
  // src/project-detector.ts
2
7
  // Phase 1 (v0.15.0)
3
8
  // - detectProjectRoot: git root → nearest package.json → cwd
4
9
  // - detectProjectName: package.json "name" → dirname
5
10
  // - Use spawnSync with 500ms timeout to avoid blocking long
6
11
  // - Realpath normalization
12
+ import { spawnSync } from 'node:child_process';
7
13
  import fs from 'node:fs';
8
14
  import path from 'node:path';
9
- import { spawnSync } from 'node:child_process';
10
15
  export function detectProjectRoot(cwd) {
11
16
  const realCwd = realpathSafe(cwd);
12
17
  // 1) Try 'git rev-parse --show-toplevel' with 500ms timeout
@@ -1,3 +1,8 @@
1
+ /**
2
+ * @license
3
+ * Copyright 2026 Google LLC
4
+ * SPDX-License-Identifier: Apache-2.0
5
+ */
1
6
  // src/project-root-state.ts
2
7
  // Global state for MCP project root (set during initialization)
3
8
  let projectRoot;
@@ -1,10 +1,15 @@
1
+ /**
2
+ * @license
3
+ * Copyright 2026 Google LLC
4
+ * SPDX-License-Identifier: Apache-2.0
5
+ */
1
6
  // src/stable-identity.ts
2
7
  // Stable project identity detection for profile persistence across directory moves
3
8
  // Priority: MCP_PROFILE_ID > git remote origin > git first commit > package.json name > directory fallback
9
+ import { spawnSync } from 'node:child_process';
10
+ import crypto from 'node:crypto';
4
11
  import fs from 'node:fs';
5
12
  import path from 'node:path';
6
- import crypto from 'node:crypto';
7
- import { spawnSync } from 'node:child_process';
8
13
  /**
9
14
  * Resolve stable project identity in priority order.
10
15
  * This identity remains stable even when the project directory is moved.
@@ -4,9 +4,9 @@
4
4
  * SPDX-License-Identifier: Apache-2.0
5
5
  */
6
6
  import { z } from 'zod';
7
+ import { CHATGPT_CONFIG } from '../config.js';
7
8
  import { ToolCategories } from './categories.js';
8
9
  import { defineTool } from './ToolDefinition.js';
9
- import { CHATGPT_CONFIG } from '../config.js';
10
10
  // Default development bookmarks
11
11
  function getDefaultBookmarks() {
12
12
  return {
@@ -6,10 +6,10 @@
6
6
  import fs from 'node:fs';
7
7
  import path from 'node:path';
8
8
  import z from 'zod';
9
- import { ToolCategories } from './categories.js';
10
- import { defineTool } from './ToolDefinition.js';
11
9
  import { CHATGPT_CONFIG } from '../config.js';
12
10
  import { getLoginStatus, waitForLoginStatus, LoginStatus } from '../login-helper.js';
11
+ import { ToolCategories } from './categories.js';
12
+ import { defineTool } from './ToolDefinition.js';
13
13
  /**
14
14
  * Navigate with retry logic for handling ERR_ABORTED and other network errors
15
15
  */
@@ -6,10 +6,10 @@
6
6
  import fs from 'node:fs';
7
7
  import path from 'node:path';
8
8
  import z from 'zod';
9
- import { ToolCategories } from './categories.js';
10
- import { defineTool } from './ToolDefinition.js';
11
9
  import { CHATGPT_CONFIG } from '../config.js';
12
10
  import { isLoginRequired } from '../login-helper.js';
11
+ import { ToolCategories } from './categories.js';
12
+ import { defineTool } from './ToolDefinition.js';
13
13
  /**
14
14
  * Known important elements in ChatGPT UI
15
15
  */
@@ -3,11 +3,10 @@
3
3
  * Copyright 2025 Google LLC
4
4
  * SPDX-License-Identifier: Apache-2.0
5
5
  */
6
- /* eslint-disable @typescript-eslint/no-explicit-any */
7
6
  import z from 'zod';
8
7
  import { ToolCategories } from './categories.js';
9
- import { defineTool } from './ToolDefinition.js';
10
8
  import * as iframePopupTools from './iframe-popup-tools.js';
9
+ import { defineTool } from './ToolDefinition.js';
11
10
  /**
12
11
  * Consolidated extension popup tool.
13
12
  * Combines: open_extension_popup, close_extension_popup
@@ -6,10 +6,10 @@
6
6
  import fs from 'node:fs';
7
7
  import path from 'node:path';
8
8
  import z from 'zod';
9
- import { ToolCategories } from './categories.js';
10
- import { defineTool } from './ToolDefinition.js';
11
9
  import { GEMINI_CONFIG } from '../config.js';
12
10
  import { getLoginStatus, waitForLoginStatus, LoginStatus } from '../login-helper.js';
11
+ import { ToolCategories } from './categories.js';
12
+ import { defineTool } from './ToolDefinition.js';
13
13
  /**
14
14
  * Navigate with retry logic for handling ERR_ABORTED and other network errors
15
15
  */
@@ -1,3 +1,8 @@
1
+ /**
2
+ * @license
3
+ * Copyright 2026 Google LLC
4
+ * SPDX-License-Identifier: Apache-2.0
5
+ */
1
6
  // src/tools/iframe-popup-tools.ts
2
7
  // Tools for inspecting & editing in-page iframe popups via CDP.
3
8
  // These tools enable direct access to iframe-embedded extension popups.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "chrome-devtools-mcp-for-extension",
3
- "version": "0.25.6",
3
+ "version": "0.25.7",
4
4
  "description": "MCP server for Chrome extension development with Web Store automation. Fork of chrome-devtools-mcp with extension-specific tools.",
5
5
  "type": "module",
6
6
  "bin": "./scripts/cli.mjs",