fix about:blank gray icon and add auto-recovery after extension replacement
This commit is contained in:
@@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"manifest_version": 3,
|
"manifest_version": 3,
|
||||||
"name": "Playwriter MCP",
|
"name": "Playwriter MCP",
|
||||||
"version": "0.0.54",
|
"version": "0.0.55",
|
||||||
"description": "Automate your Browser using Cursor, Claude, VS Code. More capable and context efficient than Playwright MCP.",
|
"description": "Automate your Browser using Cursor, Claude, VS Code. More capable and context efficient than Playwright MCP.",
|
||||||
"permissions": ["debugger", "tabGroups"],
|
"permissions": ["debugger", "tabGroups"],
|
||||||
"host_permissions": ["<all_urls>"],
|
"host_permissions": ["<all_urls>"],
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "mcp-extension",
|
"name": "mcp-extension",
|
||||||
"version": "0.0.54",
|
"version": "0.0.55",
|
||||||
"description": "Playwright MCP Browser Extension",
|
"description": "Playwright MCP Browser Extension",
|
||||||
"private": true,
|
"private": true,
|
||||||
"repository": {
|
"repository": {
|
||||||
|
|||||||
@@ -14,6 +14,7 @@ let childSessions: Map<string, number> = new Map()
|
|||||||
let nextSessionId = 1
|
let nextSessionId = 1
|
||||||
let playwriterGroupId: number | null = null
|
let playwriterGroupId: number | null = null
|
||||||
let syncTabGroupQueue: Promise<void> = Promise.resolve()
|
let syncTabGroupQueue: Promise<void> = Promise.resolve()
|
||||||
|
let replacedRetryInterval: ReturnType<typeof setInterval> | null = null
|
||||||
|
|
||||||
const store = createStore<ExtensionState>(() => ({
|
const store = createStore<ExtensionState>(() => ({
|
||||||
tabs: new Map(),
|
tabs: new Map(),
|
||||||
@@ -450,6 +451,31 @@ function closeConnection(reason: string): void {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function startReplacedRetryLoop(): void {
|
||||||
|
if (replacedRetryInterval) return
|
||||||
|
logger.debug('Starting replaced retry loop (every 3 seconds)')
|
||||||
|
replacedRetryInterval = setInterval(async () => {
|
||||||
|
if (ws?.readyState === WebSocket.OPEN || store.getState().connectionState !== 'error') {
|
||||||
|
clearInterval(replacedRetryInterval!)
|
||||||
|
replacedRetryInterval = null
|
||||||
|
logger.debug('Stopped replaced retry loop')
|
||||||
|
return
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
const response = await fetch('http://localhost:19988/extension/status')
|
||||||
|
const data = await response.json()
|
||||||
|
if (!data.connected) {
|
||||||
|
store.setState({ connectionState: 'disconnected', errorText: undefined })
|
||||||
|
logger.debug('Extension slot is free, cleared error state')
|
||||||
|
} else {
|
||||||
|
logger.debug('Extension slot still taken, will retry...')
|
||||||
|
}
|
||||||
|
} catch {
|
||||||
|
logger.debug('Server not available, will retry...')
|
||||||
|
}
|
||||||
|
}, 3000)
|
||||||
|
}
|
||||||
|
|
||||||
function handleConnectionClose(reason: string, code: number): void {
|
function handleConnectionClose(reason: string, code: number): void {
|
||||||
logger.debug('Connection closed:', { reason, code })
|
logger.debug('Connection closed:', { reason, code })
|
||||||
|
|
||||||
@@ -474,6 +500,7 @@ function handleConnectionClose(reason: string, code: number): void {
|
|||||||
connectionState: 'error',
|
connectionState: 'error',
|
||||||
errorText: 'Disconnected: Replaced by another extension',
|
errorText: 'Disconnected: Replaced by another extension',
|
||||||
})
|
})
|
||||||
|
startReplacedRetryLoop()
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,12 @@
|
|||||||
# Changelog
|
# Changelog
|
||||||
|
|
||||||
|
## 0.0.27
|
||||||
|
|
||||||
|
### Patch Changes
|
||||||
|
|
||||||
|
- **Fixed gray icon on about:blank pages**: `about:blank` pages now show the black (clickable) icon instead of gray (restricted). Chrome returns `undefined` for `tab.url` on blank pages, which was incorrectly treated as restricted.
|
||||||
|
- **Auto-recovery after extension replacement**: When another extension instance takes over the connection, the replaced extension now polls `/extension/status` every 3 seconds. When the slot becomes free, it clears the error state so the user can click to reconnect.
|
||||||
|
|
||||||
## 0.0.26
|
## 0.0.26
|
||||||
|
|
||||||
### Patch Changes
|
### Patch Changes
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"name": "playwriter",
|
"name": "playwriter",
|
||||||
"description": "",
|
"description": "",
|
||||||
"version": "0.0.26",
|
"version": "0.0.27",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"main": "dist/index.js",
|
"main": "dist/index.js",
|
||||||
"types": "dist/index.d.ts",
|
"types": "dist/index.d.ts",
|
||||||
|
|||||||
@@ -281,6 +281,10 @@ export async function startPlayWriterCDPRelayServer({ port = 19988, host = '127.
|
|||||||
return c.json({ version: VERSION })
|
return c.json({ version: VERSION })
|
||||||
})
|
})
|
||||||
|
|
||||||
|
app.get('/extension/status', (c) => {
|
||||||
|
return c.json({ connected: extensionWs !== null })
|
||||||
|
})
|
||||||
|
|
||||||
app.post('/mcp-log', async (c) => {
|
app.post('/mcp-log', async (c) => {
|
||||||
try {
|
try {
|
||||||
const { level, args } = await c.req.json()
|
const { level, args } = await c.req.json()
|
||||||
|
|||||||
Reference in New Issue
Block a user