add support for tab groups. green

This commit is contained in:
Tommy D. Rossi
2025-12-19 18:34:39 +01:00
parent 0940402fed
commit 04b757a7c8
2 changed files with 47 additions and 1 deletions
+1 -1
View File
@@ -3,7 +3,7 @@
"name": "Playwriter MCP",
"version": "0.0.52",
"description": "Automate your Browser using Cursor, Claude, VS Code. More capable and context efficient than Playwright MCP.",
"permissions": ["debugger"],
"permissions": ["debugger", "tabGroups"],
"host_permissions": ["<all_urls>"],
"background": {
"service_worker": "lib/background.mjs",
+46
View File
@@ -8,6 +8,7 @@ const RELAY_URL = 'ws://localhost:19988/extension'
let ws: WebSocket | null = null
let childSessions: Map<string, number> = new Map()
let nextSessionId = 1
let playwriterGroupId: number | null = null
const store = createStore<ExtensionState>(() => ({
tabs: new Map(),
@@ -94,6 +95,46 @@ function sendMessage(message: any): void {
}
}
async function addTabToGroup(tabId: number): Promise<void> {
try {
if (playwriterGroupId !== null) {
const existingGroups = await chrome.tabGroups.query({ title: 'playwriter' })
if (!existingGroups.some((g) => g.id === playwriterGroupId)) {
playwriterGroupId = null
}
}
if (playwriterGroupId === null) {
playwriterGroupId = await chrome.tabs.group({ tabIds: [tabId] })
await chrome.tabGroups.update(playwriterGroupId, { title: 'playwriter', color: 'green' })
logger.debug('Created tab group:', playwriterGroupId)
} else {
await chrome.tabs.group({ tabIds: [tabId], groupId: playwriterGroupId })
logger.debug('Added tab to existing group:', tabId)
}
} catch (error: any) {
logger.debug('Failed to add tab to group:', error.message)
}
}
async function removeTabFromGroup(tabId: number): Promise<void> {
try {
await chrome.tabs.ungroup(tabId)
logger.debug('Removed tab from group:', tabId)
if (playwriterGroupId !== null) {
const groups = await chrome.tabGroups.query({ title: 'playwriter' })
const group = groups.find((g) => g.id === playwriterGroupId)
if (!group) {
playwriterGroupId = null
logger.debug('Tab group was deleted')
}
}
} catch (error: any) {
logger.debug('Failed to remove tab from group:', error.message)
}
}
function getTabBySessionId(sessionId: string): { tabId: number; tab: TabInfo } | undefined {
for (const [tabId, tab] of store.getState().tabs) {
if (tab.sessionId === sessionId) {
@@ -299,6 +340,7 @@ async function attachTab(tabId: number): Promise<Protocol.Target.TargetInfo> {
})
logger.debug('Tab attached successfully:', tabId, 'sessionId:', sessionId, 'targetId:', targetInfo.targetId)
await addTabToGroup(tabId)
return targetInfo
}
@@ -311,6 +353,8 @@ function detachTab(tabId: number, shouldDetachDebugger: boolean): void {
logger.debug('Detaching tab:', tabId, 'sessionId:', tab.sessionId, 'shouldDetach:', shouldDetachDebugger)
void removeTabFromGroup(tabId)
sendMessage({
method: 'forwardCDPEvent',
params: {
@@ -353,6 +397,7 @@ function closeConnection(reason: string): void {
store.setState({ tabs: new Map(), connectionState: 'disconnected', errorText: undefined })
childSessions.clear()
playwriterGroupId = null
if (ws) {
ws.close(1000, reason)
@@ -375,6 +420,7 @@ function handleConnectionClose(reason: string, code: number): void {
}
childSessions.clear()
playwriterGroupId = null
ws = null
if (reason === 'Extension Replaced' || code === 4001) {