web-fetcher-mcp 1.0.13 → 1.0.16

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.
@@ -1,18 +1,22 @@
1
- import { getBrowser, getPage, closeBrowser } from '../utils/browser.js';
1
+ import { getBrowser, getPageWithTab, closeBrowser } from '../utils/browser.js';
2
2
  import { loadCookies, saveCookies } from '../utils/cookies.js';
3
3
  import { checkLoginRequired, waitForManualLogin } from '../utils/login-check.js';
4
4
  import { extractPageContent } from '../utils/page-content.js';
5
5
  import { downloadAndConvertImage } from '../utils/images.js';
6
6
  // 主函数:获取网页内容
7
- export async function fetchWebPage(url, contentSelector = 'body', downloadImages = true, loginMode = 'skip', waitForLogin = false, includeHtmlSkeleton = false, includeFormElements = false) {
7
+ export async function fetchWebPage(url, contentSelector = 'body', downloadImages = true, loginMode = 'skip', waitForLogin = false, includeHtmlSkeleton = false, includeFormElements = false, tabId) {
8
8
  let browserConnection = null;
9
9
  try {
10
10
  // 获取浏览器实例
11
11
  browserConnection = await getBrowser();
12
12
  const { browser, useExistingBrowser } = browserConnection;
13
- // 获取页面
14
- const page = await getPage(browser, useExistingBrowser);
15
- console.error('正在访问网页...');
13
+ // 获取页面(支持多标签页)
14
+ const pageResult = await getPageWithTab(browser, useExistingBrowser, {
15
+ tabId: tabId, // 如果提供 tabId 则使用该标签页,否则新建
16
+ url: url,
17
+ });
18
+ const page = pageResult.page;
19
+ console.error(`正在访问网页 (标签页: ${pageResult.tabId})...`);
16
20
  await page.goto(url, {
17
21
  waitUntil: 'networkidle2',
18
22
  timeout: 60000
@@ -1 +1 @@
1
- {"version":3,"file":"web-page-fetcher.js","sourceRoot":"","sources":["../../src/tools/web-page-fetcher.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"web-page-fetcher.js","sourceRoot":"","sources":["../../src/tools/web-page-fetcher.ts"],"names":[],"mappings":"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"}
@@ -190,4 +190,28 @@ export interface UploadFileResult {
190
190
  accept?: string;
191
191
  };
192
192
  }
193
+ export interface TabInfo {
194
+ id: string;
195
+ url: string;
196
+ title: string;
197
+ isActive: boolean;
198
+ }
199
+ export interface ListTabsResult {
200
+ success: boolean;
201
+ error?: string;
202
+ tabs: TabInfo[];
203
+ activeTabId?: string | null;
204
+ totalTabs: number;
205
+ }
206
+ export interface SwitchTabResult {
207
+ success: boolean;
208
+ error?: string;
209
+ tabInfo?: TabInfo;
210
+ }
211
+ export interface CloseTabResult {
212
+ success: boolean;
213
+ error?: string;
214
+ closedTabId?: string;
215
+ newActiveTabId?: string | null;
216
+ }
193
217
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/types/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/types/index.ts"],"names":[],"mappings":"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"}
@@ -1,6 +1,22 @@
1
1
  import { Browser, Page } from 'puppeteer';
2
2
  import { BrowserConnection } from '../types/index.js';
3
3
  export declare function getBrowser(): Promise<BrowserConnection>;
4
+ /**
5
+ * 获取或创建页面(保持向后兼容,返回 Page)
6
+ * 用于除 fetch-web-page 外的所有工具
7
+ */
4
8
  export declare function getPage(browser: Browser, useExistingBrowser: boolean, url?: string): Promise<Page>;
9
+ /**
10
+ * 获取或创建标签页(支持多标签页,返回 tabId)
11
+ * 仅用于 fetch-web-page 工具
12
+ */
13
+ export declare function getPageWithTab(browser: Browser, useExistingBrowser: boolean, options?: {
14
+ tabId?: string;
15
+ url?: string;
16
+ createNew?: boolean;
17
+ }): Promise<{
18
+ page: Page;
19
+ tabId: string;
20
+ }>;
5
21
  export declare function closeBrowser(browser: Browser, useExistingBrowser: boolean, keepOpen?: boolean): Promise<void>;
6
22
  //# sourceMappingURL=browser.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"browser.d.ts","sourceRoot":"","sources":["../../src/utils/browser.ts"],"names":[],"mappings":"AAAA,OAAkB,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAGrD,OAAO,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAC;AActD,wBAAsB,UAAU,IAAI,OAAO,CAAC,iBAAiB,CAAC,CAiD7D;AAGD,wBAAsB,OAAO,CAAC,OAAO,EAAE,OAAO,EAAE,kBAAkB,EAAE,OAAO,EAAE,GAAG,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CA0BxG;AAGD,wBAAsB,YAAY,CAAC,OAAO,EAAE,OAAO,EAAE,kBAAkB,EAAE,OAAO,EAAE,QAAQ,GAAE,OAAe,GAAG,OAAO,CAAC,IAAI,CAAC,CAmB1H"}
1
+ {"version":3,"file":"browser.d.ts","sourceRoot":"","sources":["../../src/utils/browser.ts"],"names":[],"mappings":"AAAA,OAAkB,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAGrD,OAAO,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAC;AAmBtD,wBAAsB,UAAU,IAAI,OAAO,CAAC,iBAAiB,CAAC,CAkE7D;AAED;;;GAGG;AACH,wBAAsB,OAAO,CAC3B,OAAO,EAAE,OAAO,EAChB,kBAAkB,EAAE,OAAO,EAC3B,GAAG,CAAC,EAAE,MAAM,GACX,OAAO,CAAC,IAAI,CAAC,CAIf;AAED;;;GAGG;AACH,wBAAsB,cAAc,CAClC,OAAO,EAAE,OAAO,EAChB,kBAAkB,EAAE,OAAO,EAC3B,OAAO,CAAC,EAAE;IACR,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,SAAS,CAAC,EAAE,OAAO,CAAC;CACrB,GACA,OAAO,CAAC;IAAE,IAAI,EAAE,IAAI,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CAAC,CAExC;AAGD,wBAAsB,YAAY,CAAC,OAAO,EAAE,OAAO,EAAE,kBAAkB,EAAE,OAAO,EAAE,QAAQ,GAAE,OAAe,GAAG,OAAO,CAAC,IAAI,CAAC,CAmB1H"}
@@ -1,7 +1,8 @@
1
1
  import puppeteer from 'puppeteer';
2
2
  import * as fs from 'fs';
3
3
  import { CHROME_PATH, DEBUGGING_PORT, USER_DATA_DIR, DATA_DIR } from './config.js';
4
- import { setupConsoleCollector, setupBrowserConsoleCollector } from './console-logger.js';
4
+ import { setupBrowserConsoleCollector } from './console-logger.js';
5
+ import { getOrCreateTab, cleanupClosedTabs, clearAllTabs } from './tabs.js';
5
6
  // 确保数据目录存在
6
7
  function ensureDataDir() {
7
8
  if (!fs.existsSync(DATA_DIR)) {
@@ -11,10 +12,22 @@ function ensureDataDir() {
11
12
  fs.mkdirSync(USER_DATA_DIR, { recursive: true });
12
13
  }
13
14
  }
15
+ // 浏览器实例缓存(避免每次工具调用都启动/连接新实例)
16
+ let cachedBrowser = null;
17
+ let cachedUseExisting = false;
14
18
  // 连接到已有 Chrome 实例或启动新实例
15
19
  export async function getBrowser() {
16
20
  ensureDataDir();
17
- // 优先尝试连接已有的 Chrome 实例
21
+ // 先清理已关闭的标签页
22
+ cleanupClosedTabs();
23
+ // 如果已有缓存的浏览器实例且未断开,直接复用
24
+ if (cachedBrowser && cachedBrowser.isConnected()) {
25
+ console.error('复用缓存的浏览器实例');
26
+ return { browser: cachedBrowser, useExistingBrowser: cachedUseExisting };
27
+ }
28
+ // 🔧 缓存失效或不存在,需要新建连接。先清空旧标签页映射(旧 Page 对象已失效)
29
+ clearAllTabs();
30
+ // 优先尝试连接已有的 Chrome 实例(用户手动启动的)
18
31
  try {
19
32
  console.error('尝试连接到已有的 Chrome 实例 (端口 9222)...');
20
33
  const browser = await puppeteer.connect({
@@ -24,6 +37,8 @@ export async function getBrowser() {
24
37
  console.error('成功连接到已有的 Chrome 实例!');
25
38
  // 设置全局日志收集器
26
39
  setupBrowserConsoleCollector(browser);
40
+ cachedBrowser = browser;
41
+ cachedUseExisting = true;
27
42
  return { browser, useExistingBrowser: true };
28
43
  }
29
44
  catch (connectError) {
@@ -49,12 +64,15 @@ export async function getBrowser() {
49
64
  '--safebrowsing-disable-auto-update',
50
65
  '--disable-infobars',
51
66
  '--disable-notifications',
52
- '--disable-popup-blocking'
67
+ '--disable-popup-blocking',
68
+ `--remote-debugging-port=${DEBUGGING_PORT}`
53
69
  ]
54
70
  });
55
71
  console.error('已启动独立的 Chrome 实例');
56
72
  // 设置全局日志收集器
57
73
  setupBrowserConsoleCollector(browser);
74
+ cachedBrowser = browser;
75
+ cachedUseExisting = false;
58
76
  return { browser, useExistingBrowser: false };
59
77
  }
60
78
  catch (launchError) {
@@ -62,29 +80,21 @@ export async function getBrowser() {
62
80
  throw new Error(`无法启动浏览器:${launchError.message}。请确保已安装 Google Chrome 浏览器,并且路径正确。`);
63
81
  }
64
82
  }
65
- // 获取或创建页面
83
+ /**
84
+ * 获取或创建页面(保持向后兼容,返回 Page)
85
+ * 用于除 fetch-web-page 外的所有工具
86
+ */
66
87
  export async function getPage(browser, useExistingBrowser, url) {
67
- let page;
68
- if (useExistingBrowser) {
69
- const pages = await browser.pages();
70
- page = pages.length > 0 ? pages[0] : await browser.newPage();
71
- }
72
- else {
73
- page = await browser.newPage();
74
- }
75
- // 设置控制台日志收集器
76
- setupConsoleCollector(page);
77
- // 设置全屏(不使用固定视口)
78
- await page.setViewport({ width: 0, height: 0 });
79
- // 如果需要导航到指定 URL
80
- if (url && url !== 'current') {
81
- const currentUrl = page.url();
82
- if (currentUrl !== url) {
83
- console.error(`导航到: ${url}`);
84
- await page.goto(url, { waitUntil: 'networkidle2', timeout: 60000 });
85
- }
86
- }
87
- return page;
88
+ // 使用标签页管理器,但对外只暴露 page 对象
89
+ const result = await getOrCreateTab(browser, useExistingBrowser, { url });
90
+ return result.page;
91
+ }
92
+ /**
93
+ * 获取或创建标签页(支持多标签页,返回 tabId)
94
+ * 仅用于 fetch-web-page 工具
95
+ */
96
+ export async function getPageWithTab(browser, useExistingBrowser, options) {
97
+ return getOrCreateTab(browser, useExistingBrowser, options);
88
98
  }
89
99
  // 关闭浏览器或断开连接
90
100
  export async function closeBrowser(browser, useExistingBrowser, keepOpen = false) {
@@ -1 +1 @@
1
- {"version":3,"file":"browser.js","sourceRoot":"","sources":["../../src/utils/browser.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"browser.js","sourceRoot":"","sources":["../../src/utils/browser.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,64 @@
1
+ import { Browser, Page } from 'puppeteer';
2
+ export interface TabInfo {
3
+ id: string;
4
+ url: string;
5
+ title: string;
6
+ isActive: boolean;
7
+ }
8
+ /**
9
+ * 同步浏览器真实页面到 tabMap(处理 MCP 重启后 tabMap 丢失的情况)
10
+ * 使用 URL 匹配保持 tabId 稳定(不依赖 Page 对象引用,引用在重连后会失效)
11
+ */
12
+ export declare function syncBrowserPages(browser: Browser): Promise<void>;
13
+ /**
14
+ * 获取或创建指定标签页
15
+ * @param browser 浏览器实例
16
+ * @param useExistingBrowser 是否使用已有浏览器
17
+ * @param tabId 指定标签页 ID(可选)
18
+ * @param url 导航到的 URL(可选,仅在 fetch-web-page 时使用)
19
+ */
20
+ export declare function getOrCreateTab(browser: Browser, useExistingBrowser: boolean, options?: {
21
+ tabId?: string;
22
+ url?: string;
23
+ createNew?: boolean;
24
+ }): Promise<{
25
+ page: Page;
26
+ tabId: string;
27
+ }>;
28
+ /**
29
+ * 根据 tabId 获取页面
30
+ */
31
+ export declare function getPageByTabId(tabId: string): Page | undefined;
32
+ /**
33
+ * 获取当前活跃标签页 ID
34
+ */
35
+ export declare function getActiveTabId(): string | null;
36
+ /**
37
+ * 获取所有标签页列表
38
+ */
39
+ export declare function listTabs(browser: Browser): Promise<TabInfo[]>;
40
+ /**
41
+ * 切换到指定标签页
42
+ */
43
+ export declare function switchTab(tabId: string, browser?: Browser): Promise<{
44
+ success: boolean;
45
+ error?: string;
46
+ tabInfo?: TabInfo;
47
+ }>;
48
+ /**
49
+ * 关闭指定标签页
50
+ */
51
+ export declare function closeTab(tabId: string, browser?: Browser): Promise<{
52
+ success: boolean;
53
+ error?: string;
54
+ closedTabId?: string;
55
+ }>;
56
+ /**
57
+ * 清理已关闭的标签页(从 map 中移除)
58
+ */
59
+ export declare function cleanupClosedTabs(): void;
60
+ /**
61
+ * 清空所有标签页映射(浏览器重连时需要,因为旧 Page 对象已失效)
62
+ */
63
+ export declare function clearAllTabs(): void;
64
+ //# sourceMappingURL=tabs.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tabs.d.ts","sourceRoot":"","sources":["../../src/utils/tabs.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAI1C,MAAM,WAAW,OAAO;IACtB,EAAE,EAAE,MAAM,CAAC;IACX,GAAG,EAAE,MAAM,CAAC;IACZ,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,OAAO,CAAC;CACnB;AAmBD;;;GAGG;AACH,wBAAsB,gBAAgB,CAAC,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC,CA2GtE;AAED;;;;;;GAMG;AACH,wBAAsB,cAAc,CAClC,OAAO,EAAE,OAAO,EAChB,kBAAkB,EAAE,OAAO,EAC3B,OAAO,CAAC,EAAE;IACR,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,SAAS,CAAC,EAAE,OAAO,CAAC;CACrB,GACA,OAAO,CAAC;IAAE,IAAI,EAAE,IAAI,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CAAC,CAuFxC;AAED;;GAEG;AACH,wBAAgB,cAAc,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,CAE9D;AAED;;GAEG;AACH,wBAAgB,cAAc,IAAI,MAAM,GAAG,IAAI,CAE9C;AAED;;GAEG;AACH,wBAAsB,QAAQ,CAAC,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,OAAO,EAAE,CAAC,CA0BnE;AAED;;GAEG;AACH,wBAAsB,SAAS,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,OAAO,GAAG,OAAO,CAAC;IAAE,OAAO,EAAE,OAAO,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IAAC,OAAO,CAAC,EAAE,OAAO,CAAA;CAAE,CAAC,CAkClI;AAED;;GAEG;AACH,wBAAsB,QAAQ,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,OAAO,GAAG,OAAO,CAAC;IAAE,OAAO,EAAE,OAAO,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IAAC,WAAW,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC,CA0BpI;AAED;;GAEG;AACH,wBAAgB,iBAAiB,IAAI,IAAI,CAMxC;AAED;;GAEG;AACH,wBAAgB,YAAY,IAAI,IAAI,CAInC"}
@@ -0,0 +1,325 @@
1
+ import { setupConsoleCollector } from './console-logger.js';
2
+ // 标签页存储:key=tabId, value=Page
3
+ const tabMap = new Map();
4
+ // 当前活跃的标签页 ID
5
+ let activeTabId = null;
6
+ // 标签页 ID 计数器
7
+ let tabIdCounter = 0;
8
+ /**
9
+ * 生成唯一标签页 ID
10
+ */
11
+ function generateTabId() {
12
+ tabIdCounter++;
13
+ return `tab_${tabIdCounter}`;
14
+ }
15
+ /**
16
+ * 同步浏览器真实页面到 tabMap(处理 MCP 重启后 tabMap 丢失的情况)
17
+ * 使用 URL 匹配保持 tabId 稳定(不依赖 Page 对象引用,引用在重连后会失效)
18
+ */
19
+ export async function syncBrowserPages(browser) {
20
+ const allPages = await browser.pages();
21
+ // 建立当前浏览器中真实页面的 URL 集合(排除 about:blank 等)
22
+ const aliveUrls = new Set();
23
+ const alivePages = new Map(); // URL → Page
24
+ for (const page of allPages) {
25
+ try {
26
+ const url = page.url();
27
+ if (!url
28
+ || url === 'about:blank'
29
+ || url.startsWith('devtools://')
30
+ || url.startsWith('chrome://')
31
+ || url.startsWith('chrome-extension://'))
32
+ continue;
33
+ aliveUrls.add(url);
34
+ // 如果相同 URL 有多个页面,只保留第一个
35
+ if (!alivePages.has(url)) {
36
+ alivePages.set(url, page);
37
+ }
38
+ else {
39
+ // 重复页面,关闭它
40
+ try {
41
+ await page.close();
42
+ }
43
+ catch (e) { /* ignore */ }
44
+ console.error(`清理重复页面: ${url}`);
45
+ }
46
+ }
47
+ catch (e) { /* 忽略无法访问的页面 */ }
48
+ }
49
+ // 建立当前 tabMap 中 URL → tabId 的反向映射
50
+ const existingUrlToTabId = new Map();
51
+ for (const [tabId, page] of tabMap.entries()) {
52
+ try {
53
+ const url = page.url();
54
+ if (url && url !== 'about:blank') {
55
+ existingUrlToTabId.set(url, tabId);
56
+ }
57
+ }
58
+ catch (e) { /* 旧 Page 可能失效 */ }
59
+ }
60
+ // 更新 tabMap:保留已有的 tabId,新增或移除页面
61
+ const newTabMap = new Map();
62
+ for (const [url, page] of alivePages) {
63
+ const existingTabId = existingUrlToTabId.get(url);
64
+ if (existingTabId) {
65
+ // 复用已有 tabId,更新 Page 引用
66
+ newTabMap.set(existingTabId, page);
67
+ }
68
+ else {
69
+ // 新页面,生成新 tabId
70
+ const newTabId = generateTabId();
71
+ newTabMap.set(newTabId, page);
72
+ setupConsoleCollector(page);
73
+ console.error(`发现新标签页: ${newTabId} (${url})`);
74
+ }
75
+ }
76
+ // 清理不再存在的旧页面
77
+ for (const [tabId, page] of tabMap.entries()) {
78
+ if (!newTabMap.has(tabId)) {
79
+ try {
80
+ if (!page.isClosed())
81
+ await page.close();
82
+ }
83
+ catch (e) { /* ignore */ }
84
+ }
85
+ }
86
+ // 替换 tabMap
87
+ tabMap.clear();
88
+ for (const [tabId, page] of newTabMap) {
89
+ tabMap.set(tabId, page);
90
+ // 同步 Page 引用到旧条目(用于 getOrCreateTab 中已持有的引用)
91
+ try {
92
+ const url = page.url();
93
+ if (url) {
94
+ const oldPage = existingUrlToTabId.has(url) ? tabMap.get(existingUrlToTabId.get(url)) : null;
95
+ // Page 引用已在 newTabMap 中同步,无需额外操作
96
+ }
97
+ }
98
+ catch (e) { /* ignore */ }
99
+ }
100
+ // 检测活跃标签页
101
+ if (tabMap.size > 0) {
102
+ let detectedActive = null;
103
+ for (const [tabId, page] of tabMap.entries()) {
104
+ try {
105
+ const visible = await page.evaluate(() => {
106
+ return document.visibilityState === 'visible';
107
+ });
108
+ if (visible) {
109
+ detectedActive = tabId;
110
+ break;
111
+ }
112
+ }
113
+ catch (e) { /* ignore */ }
114
+ }
115
+ if (detectedActive) {
116
+ activeTabId = detectedActive;
117
+ }
118
+ else if (!activeTabId || !tabMap.has(activeTabId)) {
119
+ // 回退:取第一个作为活跃
120
+ for (const [tabId] of tabMap.entries()) {
121
+ activeTabId = tabId;
122
+ break;
123
+ }
124
+ }
125
+ }
126
+ }
127
+ /**
128
+ * 获取或创建指定标签页
129
+ * @param browser 浏览器实例
130
+ * @param useExistingBrowser 是否使用已有浏览器
131
+ * @param tabId 指定标签页 ID(可选)
132
+ * @param url 导航到的 URL(可选,仅在 fetch-web-page 时使用)
133
+ */
134
+ export async function getOrCreateTab(browser, useExistingBrowser, options) {
135
+ const { tabId: targetTabId, url, createNew } = options || {};
136
+ // 如果指定了 tabId 且不要求新建,先同步浏览器页面再查找
137
+ if (targetTabId && !createNew) {
138
+ // 从浏览器同步页面到 tabMap(解决 MCP 重启后 tabMap 丢失的问题)
139
+ await syncBrowserPages(browser);
140
+ const existingPage = tabMap.get(targetTabId);
141
+ if (existingPage && !existingPage.isClosed()) {
142
+ // 设置为当前活跃标签
143
+ activeTabId = targetTabId;
144
+ console.error(`使用已有标签页: ${targetTabId}`);
145
+ // 如果需要导航到新 URL
146
+ if (url && url !== 'current') {
147
+ const currentUrl = existingPage.url();
148
+ if (currentUrl !== url) {
149
+ console.error(`标签页 ${targetTabId} 导航到: ${url}`);
150
+ await existingPage.goto(url, { waitUntil: 'networkidle2', timeout: 60000 });
151
+ }
152
+ }
153
+ return { page: existingPage, tabId: targetTabId };
154
+ }
155
+ // 页面已关闭,从 map 中移除
156
+ tabMap.delete(targetTabId);
157
+ console.error(`标签页 ${targetTabId} 已关闭或不存在`);
158
+ }
159
+ // 🔧 无 tabId 且 url='current':复用浏览器的活跃标签页,不新建空白页
160
+ if (!targetTabId && url === 'current' && !createNew) {
161
+ await syncBrowserPages(browser);
162
+ // 优先使用检测到的活跃标签页
163
+ if (activeTabId) {
164
+ const activePage = tabMap.get(activeTabId);
165
+ if (activePage && !activePage.isClosed()) {
166
+ console.error(`复用活跃标签页: ${activeTabId}`);
167
+ return { page: activePage, tabId: activeTabId };
168
+ }
169
+ }
170
+ // 没有活跃标签页,取第一个可用的
171
+ for (const [tabId, page] of tabMap.entries()) {
172
+ if (!page.isClosed()) {
173
+ activeTabId = tabId;
174
+ console.error(`复用第一个可用标签页: ${tabId}`);
175
+ return { page, tabId };
176
+ }
177
+ }
178
+ }
179
+ // 创建新标签页
180
+ let newPage;
181
+ if (useExistingBrowser) {
182
+ // 连接已有浏览器模式:直接新建页面
183
+ newPage = await browser.newPage();
184
+ }
185
+ else {
186
+ // 独立浏览器模式
187
+ newPage = await browser.newPage();
188
+ }
189
+ // 生成新的标签页 ID(如果没指定或指定的已失效)
190
+ const newTabId = targetTabId ? targetTabId : generateTabId();
191
+ // 设置控制台日志收集
192
+ setupConsoleCollector(newPage);
193
+ // 设置全屏视口
194
+ await newPage.setViewport({ width: 0, height: 0 });
195
+ // 存储到 map
196
+ tabMap.set(newTabId, newPage);
197
+ activeTabId = newTabId;
198
+ console.error(`创建新标签页: ${newTabId}`);
199
+ // 如果需要导航到 URL
200
+ if (url && url !== 'current') {
201
+ console.error(`标签页 ${newTabId} 导航到: ${url}`);
202
+ await newPage.goto(url, { waitUntil: 'networkidle2', timeout: 60000 });
203
+ }
204
+ return { page: newPage, tabId: newTabId };
205
+ }
206
+ /**
207
+ * 根据 tabId 获取页面
208
+ */
209
+ export function getPageByTabId(tabId) {
210
+ return tabMap.get(tabId);
211
+ }
212
+ /**
213
+ * 获取当前活跃标签页 ID
214
+ */
215
+ export function getActiveTabId() {
216
+ return activeTabId;
217
+ }
218
+ /**
219
+ * 获取所有标签页列表
220
+ */
221
+ export async function listTabs(browser) {
222
+ // 先同步浏览器真实页面到 tabMap(处理 MCP 重启后 tabMap 丢失的情况)
223
+ await syncBrowserPages(browser);
224
+ const tabs = [];
225
+ // 列出所有标签页
226
+ for (const [tabId, page] of tabMap.entries()) {
227
+ if (!page.isClosed()) {
228
+ try {
229
+ tabs.push({
230
+ id: tabId,
231
+ url: page.url(),
232
+ title: await page.title(),
233
+ isActive: tabId === activeTabId,
234
+ });
235
+ }
236
+ catch (e) {
237
+ // 页面可能已损坏,跳过
238
+ tabMap.delete(tabId);
239
+ }
240
+ }
241
+ else {
242
+ tabMap.delete(tabId);
243
+ }
244
+ }
245
+ return tabs;
246
+ }
247
+ /**
248
+ * 切换到指定标签页
249
+ */
250
+ export async function switchTab(tabId, browser) {
251
+ // 从浏览器同步页面到 tabMap(解决 MCP 重启后 tabMap 丢失的问题)
252
+ if (browser) {
253
+ await syncBrowserPages(browser);
254
+ }
255
+ const page = tabMap.get(tabId);
256
+ if (!page) {
257
+ return { success: false, error: `标签页 ${tabId} 不存在` };
258
+ }
259
+ if (page.isClosed()) {
260
+ tabMap.delete(tabId);
261
+ return { success: false, error: `标签页 ${tabId} 已被关闭` };
262
+ }
263
+ try {
264
+ // 将该标签页带到前台
265
+ await page.bringToFront();
266
+ activeTabId = tabId;
267
+ return {
268
+ success: true,
269
+ tabInfo: {
270
+ id: tabId,
271
+ url: page.url(),
272
+ title: await page.title(),
273
+ isActive: true,
274
+ },
275
+ };
276
+ }
277
+ catch (e) {
278
+ return { success: false, error: e.message };
279
+ }
280
+ }
281
+ /**
282
+ * 关闭指定标签页
283
+ */
284
+ export async function closeTab(tabId, browser) {
285
+ // 从浏览器同步页面到 tabMap(解决 MCP 重启后 tabMap 丢失的问题)
286
+ if (browser) {
287
+ await syncBrowserPages(browser);
288
+ }
289
+ const page = tabMap.get(tabId);
290
+ if (!page) {
291
+ return { success: false, error: `标签页 ${tabId} 不存在` };
292
+ }
293
+ try {
294
+ await page.close();
295
+ tabMap.delete(tabId);
296
+ // 如果关闭的是当前活跃标签,切换到最后一个标签
297
+ if (activeTabId === tabId) {
298
+ const remainingTabs = Array.from(tabMap.keys());
299
+ activeTabId = remainingTabs.length > 0 ? remainingTabs[remainingTabs.length - 1] : null;
300
+ }
301
+ return { success: true, closedTabId: tabId };
302
+ }
303
+ catch (e) {
304
+ return { success: false, error: e.message };
305
+ }
306
+ }
307
+ /**
308
+ * 清理已关闭的标签页(从 map 中移除)
309
+ */
310
+ export function cleanupClosedTabs() {
311
+ for (const [tabId, page] of tabMap.entries()) {
312
+ if (page.isClosed()) {
313
+ tabMap.delete(tabId);
314
+ }
315
+ }
316
+ }
317
+ /**
318
+ * 清空所有标签页映射(浏览器重连时需要,因为旧 Page 对象已失效)
319
+ */
320
+ export function clearAllTabs() {
321
+ tabMap.clear();
322
+ activeTabId = null;
323
+ console.error('已清空所有标签页映射(浏览器重连)');
324
+ }
325
+ //# sourceMappingURL=tabs.js.map