diff --git a/hermes_cli/web_server.py b/hermes_cli/web_server.py index b4ee6077bc5..d8ba44d8504 100644 --- a/hermes_cli/web_server.py +++ b/hermes_cli/web_server.py @@ -2239,6 +2239,59 @@ async def get_profile_setup_command(name: str): return {"command": _profile_setup_command(name)} +@app.post("/api/profiles/{name}/open-terminal") +async def open_profile_terminal_endpoint(name: str): + try: + command = _profile_setup_command(name) + + if sys.platform.startswith("win"): + subprocess.Popen(["cmd.exe", "/k", command]) + elif sys.platform == "darwin": + applescript = ( + 'tell application "Terminal"\n' + "activate\n" + f'do script "{command.replace("\\\\", "\\\\\\\\").replace(\'"\', \'\\\\"\')}"\n' + "end tell" + ) + subprocess.Popen(["osascript", "-e", applescript]) + else: + terminal_commands = [ + ("x-terminal-emulator", ["x-terminal-emulator", "-e", "sh", "-lc", command]), + ("gnome-terminal", ["gnome-terminal", "--", "sh", "-lc", command]), + ("konsole", ["konsole", "-e", "sh", "-lc", command]), + ("xfce4-terminal", ["xfce4-terminal", "-e", f"sh -lc '{command}'"]), + ("mate-terminal", ["mate-terminal", "-e", f"sh -lc '{command}'"]), + ("lxterminal", ["lxterminal", "-e", f"sh -lc '{command}'"]), + ("tilix", ["tilix", "-e", "sh", "-lc", command]), + ("alacritty", ["alacritty", "-e", "sh", "-lc", command]), + ("kitty", ["kitty", "sh", "-lc", command]), + ("xterm", ["xterm", "-e", "sh", "-lc", command]), + ] + for executable, popen_args in terminal_commands: + if subprocess.call( + ["which", executable], + stdout=subprocess.DEVNULL, + stderr=subprocess.DEVNULL, + ) == 0: + subprocess.Popen(popen_args) + break + else: + raise HTTPException( + status_code=400, + detail="No supported terminal emulator found", + ) + except FileNotFoundError as e: + raise HTTPException(status_code=404, detail=str(e)) + except ValueError as e: + raise HTTPException(status_code=400, detail=str(e)) + except HTTPException: + raise + except Exception as e: + _log.exception("POST /api/profiles/%s/open-terminal failed", name) + raise HTTPException(status_code=500, detail=str(e)) + return {"ok": True, "command": command} + + @app.patch("/api/profiles/{name}") async def rename_profile_endpoint(name: str, body: ProfileRename): from hermes_cli import profiles as profiles_mod