| 170 | /** Close the browser. Idempotent. When ATTACHED to the user's own browser we drop the |
| 171 | * connection WITHOUT closing it — killing someone's logged-in Chrome would be hostile. */ |
| 172 | export async function closeBrowser(): Promise<void> { |
| 173 | if (!session) return; |
| 174 | if (session.attached) { |
| 175 | logger.debug('Browser was attached over CDP — disconnecting, not closing'); |
| 176 | session = null; // let the CDP socket GC; the user's browser keeps running |
| 177 | return; |
| 178 | } |
| 179 | try { |
| 180 | await session.browser.close(); |
| 181 | } catch (e: any) { |
| 182 | logger.debug('Browser close failed', { err: e?.message }); |
| 183 | } |
| 184 | session = null; |
| 185 | } |
| 186 | |
| 187 | /** Whether playwright is available on this machine. Used by `/network` etc. */ |
| 188 | export async function isPlaywrightAvailable(): Promise<boolean> { |