feat: auto-start a debug browser for agent-browser on Windows

On Windows agent-browser cannot launch Chrome by itself: the Chrome
launcher process hands off to a child and exits, which agent-browser
mistakes for a crash ("Chrome exited early without writing
DevToolsActivePort"). On such machines the export never gets a browser.

Before creating the session, resolve a CDP endpoint (Windows only):

1. honor AGENT_BROWSER_CDP if it answers /json/version;
2. else reuse a live endpoint on port 9337;
3. else launch Chrome/Edge with --remote-debugging-port and a fixed
   profile, and pass the port to agent-browser via AGENT_BROWSER_CDP.

The instance is intentionally left running: relaunching with the same
profile joins the existing browser, so repeated exports reuse one
instance instead of piling up processes. Non-Windows platforms are
untouched.

Discussed in #4.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
yoruuuchan
2026-08-06 21:43:02 +09:00
co-authored by Claude Fable 5
parent f77ee8dfcb
commit 9acf2025e4
2 changed files with 118 additions and 2 deletions
@@ -177,6 +177,29 @@ class ExportPptxTests(unittest.TestCase):
timeout=90,
)
def test_ensure_debug_chrome_is_windows_only(self):
with patch.object(MODULE.sys, "platform", "linux"):
self.assertIsNone(MODULE.ensure_debug_chrome())
@patch.object(MODULE, "cdp_alive", return_value=True)
def test_ensure_debug_chrome_prefers_working_explicit_port(self, cdp_alive):
with patch.object(MODULE.sys, "platform", "win32"), \
patch.dict(MODULE.os.environ, {"AGENT_BROWSER_CDP": "9444"}):
self.assertEqual(MODULE.ensure_debug_chrome(), 9444)
cdp_alive.assert_called_once_with(9444)
def test_browser_session_exports_cdp_port_to_env(self):
with patch.dict(MODULE.os.environ, {}, clear=False):
MODULE.os.environ.pop("AGENT_BROWSER_CDP", None)
with_port = MODULE.BrowserSession(
"/bin/agent-browser", "s", Path("."), Path("/tmp/d"), cdp_port=9337
)
self.assertEqual(with_port.env["AGENT_BROWSER_CDP"], "9337")
without_port = MODULE.BrowserSession(
"/bin/agent-browser", "s", Path("."), Path("/tmp/d")
)
self.assertNotIn("AGENT_BROWSER_CDP", without_port.env)
if __name__ == "__main__":
unittest.main()