fix(browse): clean stale SingletonLock in handoff() before relaunch

handoff() hand-rolled its own chromium-profile path and skipped the
stale-lock cleanup that launchHeaded() already does. A prior
hard-killed/crashed headed session leaves SingletonLock/Socket/Cookie
pointing at a dead PID; Chromium's ProcessSingleton then silently hands
startup off to the dead process instead of launching cleanly, and the
new process exits within seconds — read as a clean disconnect, taking
the whole daemon down with it. Now uses resolveChromiumProfile() +
cleanSingletonLocks(), matching launchHeaded().

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
Jason Myers 2026-07-20 18:27:21 -05:00
parent a3259400a3
commit 72bbe39777
1 changed files with 10 additions and 2 deletions

View File

@ -1551,7 +1551,6 @@ export class BrowserManager {
let newContext: BrowserContext;
try {
const fs = require('fs');
const path = require('path');
const extensionPath = this.findExtensionPath();
const { STEALTH_LAUNCH_ARGS, buildGStackLaunchArgs } = await import('./stealth');
// Same blink-level stealth flags as launch()/launchHeaded(). Without
@ -1568,9 +1567,18 @@ export class BrowserManager {
console.log('[browse] Handoff: extension not found — headed mode without side panel');
}
const userDataDir = path.join(process.env.HOME || '/tmp', '.gstack', 'chromium-profile');
const userDataDir = resolveChromiumProfile();
fs.mkdirSync(userDataDir, { recursive: true });
// Pre-launch cleanup of stale SingletonLock/Socket/Cookie, same as
// launchHeaded(). Without this, a prior hard-killed/crashed headed
// session leaves lockfiles pointing at a dead PID; Chromium's
// ProcessSingleton then silently hands off startup to the (dead or
// zombie) old process instead of launching cleanly, and the new
// process exits shortly after — which reads as a clean disconnect
// and takes the whole daemon down with it.
cleanSingletonLocks(userDataDir);
// T1: same automation-tell-stripping defaults as launchHeaded().
// The handoff path (headless → headed re-launch) takes the same
// anti-detection posture.