fix: make browser tabs accessible after app restart

Two issues prevented CLI browser commands from working after restart:

1. Agent-browser daemon persists sessions across Orca restarts. The old
   session holds a stale CDP port and ignores --cdp on reuse. The
   fire-and-forget `close` raced with the first command — await it so
   the daemon forgets the session before we pass the new port.

2. Without --worktree, resolveBrowserWorktreeId returned immediately
   without activating the browser view. After restart in terminal mode,
   webviews stay unmounted (display:none) so registerGuest never fires.
   Now sends browser:activateView when no tabs are registered, triggering
   webview mount and guest registration.
This commit is contained in:
Jinwoo-H 2026-04-20 00:58:21 -04:00
parent f6876a2f73
commit e3d1b9e549
2 changed files with 17 additions and 8 deletions

View file

@ -1164,14 +1164,14 @@ export class AgentBrowserBridge {
}
// Why: agent-browser's daemon persists session state (including the CDP port)
// across Orca restarts. A stale session would try to connect to a dead port.
// Fire-and-forget with a short timeout — never block session creation on cleanup.
execFile(
this.agentBrowserBin,
['--session', sessionName, 'close'],
{ timeout: 3000 },
() => {}
)
// across Orca restarts. A stale session ignores --cdp (already initialized) and
// connects to the dead port. Must await close so the daemon forgets the session
// before we pass --cdp with the new port.
await new Promise<void>((resolve) => {
execFile(this.agentBrowserBin, ['--session', sessionName, 'close'], { timeout: 3000 }, () =>
resolve()
)
})
const proxy = new CdpWsProxy(wc)
const cdpEndpoint = await proxy.start()

View file

@ -1171,6 +1171,15 @@ export class OrcaRuntimeService {
// ID so the bridge can filter tabs correctly.
private async resolveBrowserWorktreeId(selector?: string): Promise<string | undefined> {
if (!selector) {
// Why: after app restart, webviews only mount when the browser pane is visible.
// Without --worktree, we still need to activate the view so persisted tabs
// become operable via registerGuest.
const bridge = this.agentBrowserBridge
if (bridge && bridge.getRegisteredTabs().size === 0) {
const win = this.getAuthoritativeWindow()
win.webContents.send('browser:activateView', {})
await new Promise((resolve) => setTimeout(resolve, 500))
}
return undefined
}
try {