From f793dd8ac4631f527f114abc504c3f431edf9858 Mon Sep 17 00:00:00 2001 From: "Tommy D. Rossi" Date: Sat, 28 Feb 2026 22:12:07 +0100 Subject: [PATCH] feat: harden relay sessions and recording UX across extension + playwriter This commit batches the pending workspace updates that were coupled in practice: extension reliability fixes, ghost cursor persistence across MPA navigations, timeout tuning, and aligned docs/versioning updates so behavior and guidance stay in sync. Key updates:\n- extension: add MV3 keepalive via chrome.alarms, add alarms permission, and bump extension changelog/version to 0.0.73 to reduce silent relay disconnects while idle\n- playwriter runtime: raise default action timeout to 60s while keeping navigation timeout separate; increase relay /version fetch timeout to 2000ms\n- recording + cursor: add persistent cursor init scripts with Page.addScriptToEvaluateOnNewDocument, remove init script on teardown, and ensure cursor enablement before applying mouse actions\n- demo video defaults: use 0.5s side buffer (1s total) and default idle speed 6x for createDemoVideo/computeIdleSections\n- tests/docs: keep click-error tests deterministic with explicit 5000ms per-click timeout, remove outdated click-timeout section from skill mistakes, and update package/changelog entries --- extension/CHANGELOG.md | 6 ++ extension/manifest.json | 3 +- extension/src/background.ts | 12 +++ playwriter/CHANGELOG.md | 30 ++++++++ playwriter/package.json | 2 +- playwriter/src/executor.ts | 14 ++-- playwriter/src/ffmpeg.ts | 16 ++-- playwriter/src/ghost-cursor-client.ts | 5 +- playwriter/src/ghost-cursor.ts | 96 +++++++++++++++++++----- playwriter/src/recording-ghost-cursor.ts | 37 ++++++++- playwriter/src/relay-client.ts | 2 +- playwriter/src/relay-core.test.ts | 12 +-- playwriter/src/skill.md | 26 +------ 13 files changed, 191 insertions(+), 70 deletions(-) diff --git a/extension/CHANGELOG.md b/extension/CHANGELOG.md index 4c34ab9..e57d633 100644 --- a/extension/CHANGELOG.md +++ b/extension/CHANGELOG.md @@ -1,5 +1,11 @@ # Changelog +## 0.0.73 + +### Bug Fixes + +- **Service worker keepalive via chrome.alarms**: Added `chrome.alarms` keepalive to prevent Chrome MV3 from terminating the service worker when idle. Without this, the `maintainLoop` stops, the WebSocket closes, and the extension silently disconnects from the relay server — causing `session new` to fail with "Extension did not connect within timeout." + ## 0.0.72 ### Bug Fixes diff --git a/extension/manifest.json b/extension/manifest.json index da15201..a5a4d19 100644 --- a/extension/manifest.json +++ b/extension/manifest.json @@ -1,9 +1,10 @@ { "manifest_version": 3, "name": "Playwriter", - "version": "0.0.72", + "version": "0.0.73", "description": "Automate your Browser using Cursor, Claude, VS Code. More capable and context efficient than Playwright MCP.", "permissions": [ + "alarms", "debugger", "tabGroups", "contextMenus", diff --git a/extension/src/background.ts b/extension/src/background.ts index f8428ec..2924af4 100644 --- a/extension/src/background.ts +++ b/extension/src/background.ts @@ -1483,6 +1483,18 @@ async function onActionClicked(tab: chrome.tabs.Tab): Promise { resetDebugger() connectionManager.maintainLoop() +// MV3 service workers can be terminated by Chrome despite setInterval. +// chrome.alarms is the only reliable way to keep a service worker alive. +// Without this, the maintainLoop stops, the WebSocket closes, and the +// extension silently disconnects from the relay server. +chrome.alarms.create('keepalive', { periodInMinutes: 0.25 }) +chrome.alarms.onAlarm.addListener((alarm) => { + if (alarm.name === 'keepalive') { + // No-op — the alarm firing is enough to wake the service worker. + // The maintainLoop will handle reconnection if needed. + } +}) + chrome.contextMenus .remove('playwriter-pin-element') .catch(() => {}) diff --git a/playwriter/CHANGELOG.md b/playwriter/CHANGELOG.md index e0e8b5b..edf38a0 100644 --- a/playwriter/CHANGELOG.md +++ b/playwriter/CHANGELOG.md @@ -1,7 +1,37 @@ # Changelog +## 0.0.84 + +### Docs + +- **Remove click-timeout section from `skill.md` mistakes list**: Deleted the dedicated post-click timeout section per docs cleanup request and renumbered the following mistake item. + +## 0.0.83 + +### Docs + +- **Correct click-timeout guidance in `skill.md`**: Replaced the incorrect "SPA does not fire load" explanation with the actual behavior: click succeeds, then Playwright times out during post-click navigation waiting when action timeout budget is exceeded. + +## 0.0.82 + +### Improvements + +- **Increase default action timeout to 60s**: Raised `context.setDefaultTimeout` from `5000ms` to `60000ms` to avoid false click failures on slower real-world flows where the interaction succeeds but Playwright post-action navigation waiting exceeds short budgets. + +## 0.0.81 + +### Improvements + +- **Increase default action timeout to 5s**: Raised `context.setDefaultTimeout` from `2000ms` to `5000ms` to reduce false `locator.click()` timeouts on slower navigation flows (for example GitHub/Turbo links) where the click succeeds but post-click navigation settling exceeds 2 seconds. Default navigation timeout remains `10000ms`. + ## 0.0.80 +### Bug Fixes + +- **Relaxed relay server version check timeout**: Increased `getRelayServerVersion` timeout from 500ms to 2000ms to prevent false "server not running" detections that kill a healthy relay server and disconnect the extension. This was causing intermittent `session new` failures when the relay was briefly busy (e.g. processing recording chunks). + +## 0.0.80 (previous) + ### Improvements - **Descriptive click timeout errors**: When `locator.click()` times out due to actionability failures, the error now includes the reason (e.g. "Element is not visible", "Element is not stable", "