From db735e7b9055c4c75dd834c528badc8cde4d0ba3 Mon Sep 17 00:00:00 2001 From: Alex Schapiro Date: Tue, 1 Sep 2026 20:51:47 +0000 Subject: [PATCH] Bound the Link sign-in with a watchdog that kills a stalled process --- strix/interface/cloud/billing.py | 35 +++++++++++++++++++------------- 1 file changed, 21 insertions(+), 14 deletions(-) diff --git a/strix/interface/cloud/billing.py b/strix/interface/cloud/billing.py index 172448dc..746ff468 100644 --- a/strix/interface/cloud/billing.py +++ b/strix/interface/cloud/billing.py @@ -9,6 +9,7 @@ import shutil import subprocess import sys import tempfile +import threading import webbrowser from contextlib import suppress from dataclasses import dataclass @@ -670,20 +671,26 @@ def _run_link_login(npx: str) -> None: env=_wallet_environment(), cwd=wallet_root, ) as process: - opened = False - if process.stdout is None: - process.wait(timeout=_LINK_LOGIN_TIMEOUT_S + 30) - return - for line in process.stdout: - sys.stdout.write(line) - sys.stdout.flush() - if not opened: - match = _HTTPS_URL.search(sanitize_terminal_text(line)) - if match: - opened = True - with suppress(Exception): - webbrowser.open(match.group(0)) - process.wait(timeout=_LINK_LOGIN_TIMEOUT_S + 30) + watchdog = threading.Timer(_LINK_LOGIN_TIMEOUT_S + 30, process.kill) + watchdog.daemon = True + watchdog.start() + try: + opened = False + if process.stdout is None: + process.wait() + return + for line in process.stdout: + sys.stdout.write(line) + sys.stdout.flush() + if not opened: + match = _HTTPS_URL.search(sanitize_terminal_text(line)) + if match: + opened = True + with suppress(Exception): + webbrowser.open(match.group(0)) + process.wait() + finally: + watchdog.cancel() def _wallet_environment() -> dict[str, str]: