import subprocess import sys import os import platform import shutil from typing import List, Optional from .paths import ROOT_DIR # centralized project paths def _find_terminal_emulator() -> Optional[str]: """ Try to find an available terminal emulator on Linux. Returns the command name if found, otherwise None. """ candidates = [ "x-terminal-emulator", "gnome-terminal", "konsole", "xfce4-terminal", "lxterminal", "mate-terminal", "tilix", "terminator", "xterm" ] for term in candidates: if shutil.which(term): return term return None def new_python_process( script_path: str, python_exec: str = sys.executable, args: Optional[List[str]] = None, cwd: str = str(ROOT_DIR), wait: bool = False, new_console: bool = False ) -> int: """ Start a new Python process running the given script. Args: script_path (str): Path to the Python script to execute. python_exec (str): Path to the Python executable. args (List[str], optional): Arguments to pass to the script. Defaults to []. cwd (str): Working directory for the process. Defaults to project root. wait (bool): If True, waits for process completion. Defaults to False. new_console (bool): If True, tries to open process in a new console window. Returns: int: PID of the created process. """ if not os.path.isabs(python_exec): python_exec = os.path.normpath(os.path.join(cwd, python_exec)) if not os.path.isabs(script_path): script_path = os.path.normpath(os.path.join(cwd, script_path)) if args is None: args = [] command = [python_exec, script_path] + args creation_flags = 0 shell = False system = platform.system().lower() if new_console: if system == "windows": creation_flags = subprocess.CREATE_NEW_CONSOLE elif system == "linux": term = _find_terminal_emulator() if term: command = [term, "-e"] + command else: # fallback: run in same terminal pass elif system == "darwin": # MacOS osa_cmd = f'tell app "Terminal" to do script "{python_exec} {script_path} {" ".join(args)}"' process = subprocess.Popen(["osascript", "-e", osa_cmd], cwd=cwd) if wait: process.wait() return process.pid process = subprocess.Popen( command, cwd=cwd, creationflags=creation_flags, shell=shell ) if wait: process.wait() return process.pid