fix: tab cleanup regex to match actual Playwright MCP tab format

The tab list from Playwright MCP uses '- N: (current) [title](url)' format,
but extractTabEntries only matched 'Tab N ...' format. This caused
_initialTabIdentities to always be empty, so tabs were never cleaned up.

Now supports both formats.
This commit is contained in:
jackwener committed 2026-03-16 12:54:44 +08:00
1 parent 76eefed83d
commit 7ee0c9c96b
3 files changed
+31 -6

No files matched your search

+3
View File
@@ -24,6 +24,9 @@
"tsx": "^4.19.3",
"typescript": "^5.8.2",
"vitest": "^4.1.0"
},
"engines": {
"node": ">=18.0.0"
}
},
"node_modules/@colors/colors": {
+11
View File
@@ -20,6 +20,17 @@ describe('browser helpers', () => {
]);
});
it('extracts tab entries from MCP markdown format', () => {
const entries = __test__.extractTabEntries(
'- 0: (current) [Playwright MCP extension](chrome-extension://abc/connect.html)\n- 1: [知乎 - 首页](https://www.zhihu.com/)'
);
expect(entries).toEqual([
{ index: 0, identity: '(current) [Playwright MCP extension](chrome-extension://abc/connect.html)' },
{ index: 1, identity: '[知乎 - 首页](https://www.zhihu.com/)' },
]);
});
it('closes only tabs that were opened during the session', () => {
const tabsToClose = __test__.diffTabIndexes(
['https://example.com', 'Chrome Extension'],
+17 -6
View File
@@ -610,12 +610,23 @@ function extractTabEntries(raw: any): Array<{ index: number; identity: string }>
.map(line => line.trim())
.filter(Boolean)
.map(line => {
const match = line.match(/Tab\s+(\d+)\s*(.*)$/);
if (!match) return null;
return {
index: parseInt(match[1], 10),
identity: match[2].trim() || `tab-${match[1]}`,
};
// Match actual Playwright MCP format: "- 0: (current) [title](url)" or "- 1: [title](url)"
const mcpMatch = line.match(/^-\s+(\d+):\s*(.*)$/);
if (mcpMatch) {
return {
index: parseInt(mcpMatch[1], 10),
identity: mcpMatch[2].trim() || `tab-${mcpMatch[1]}`,
};
}
// Legacy format: "Tab 0 ..."
const legacyMatch = line.match(/Tab\s+(\d+)\s*(.*)$/);
if (legacyMatch) {
return {
index: parseInt(legacyMatch[1], 10),
identity: legacyMatch[2].trim() || `tab-${legacyMatch[1]}`,
};
}
return null;
})
.filter((entry): entry is { index: number; identity: string } => entry !== null);
}