diff --git a/agent/lsp/install.py b/agent/lsp/install.py index 68a9751e7fa9..da8f1fd77882 100644 --- a/agent/lsp/install.py +++ b/agent/lsp/install.py @@ -267,7 +267,7 @@ def _install_npm( [npm, "install", "--prefix", str(staging), "--silent", "--no-fund", "--no-audit", *install_targets], check=False, capture_output=True, - text=True, + text=True, encoding="utf-8", errors="replace", timeout=300, stdin=subprocess.DEVNULL, creationflags=windows_hide_flags(), @@ -316,7 +316,7 @@ def _install_go(pkg: str, bin_name: str) -> Optional[str]: [go, "install", pkg], check=False, capture_output=True, - text=True, + text=True, encoding="utf-8", errors="replace", timeout=600, env=env, stdin=subprocess.DEVNULL, diff --git a/agent/proxy_sources/iron_proxy.py b/agent/proxy_sources/iron_proxy.py index dae910248d56..277cd0186549 100644 --- a/agent/proxy_sources/iron_proxy.py +++ b/agent/proxy_sources/iron_proxy.py @@ -706,7 +706,7 @@ def iron_proxy_version(binary: Path) -> str: res = subprocess.run( # noqa: S603 [str(binary), "--version"], capture_output=True, - text=True, + text=True, encoding="utf-8", errors="replace", timeout=_RUN_TIMEOUT, env=minimal_env, ) @@ -1052,7 +1052,7 @@ def _detect_docker_bridge_ip() -> Optional[str]: try: res = subprocess.run( # noqa: S603 — ip is a system binary ["ip", "-4", "-o", "addr", "show", "docker0"], - capture_output=True, text=True, timeout=2, + capture_output=True, text=True, encoding="utf-8", errors="replace", timeout=2, ) if res.returncode == 0: for line in res.stdout.splitlines(): @@ -1743,7 +1743,7 @@ def _pid_alive(pid: int) -> bool: try: res = subprocess.run( # noqa: S603 ["ps", "-p", str(pid), "-o", "comm="], - capture_output=True, text=True, timeout=2, + capture_output=True, text=True, encoding="utf-8", errors="replace", timeout=2, ) if res.returncode == 0: comm = (res.stdout or "").strip() diff --git a/agent/secret_sources/base.py b/agent/secret_sources/base.py index d4ead7d3f26e..070051e046be 100644 --- a/agent/secret_sources/base.py +++ b/agent/secret_sources/base.py @@ -295,7 +295,7 @@ def run_secret_cli( list(argv), env=env, capture_output=True, - text=True, + text=True, encoding="utf-8", errors="replace", timeout=timeout, stdin=subprocess.DEVNULL, ) diff --git a/agent/trace_upload.py b/agent/trace_upload.py index f65547440c7f..404d9be70b13 100644 --- a/agent/trace_upload.py +++ b/agent/trace_upload.py @@ -162,7 +162,7 @@ def build_trace_jsonl( if cwd: r = subprocess.run( ["git", "rev-parse", "--abbrev-ref", "HEAD"], - capture_output=True, text=True, timeout=3, cwd=cwd, + capture_output=True, text=True, encoding="utf-8", errors="replace", timeout=3, cwd=cwd, ) if r.returncode == 0: git_branch = r.stdout.strip() diff --git a/cli.py b/cli.py index a6586e8eb0e8..26a94f0b1e48 100644 --- a/cli.py +++ b/cli.py @@ -1432,7 +1432,7 @@ def _git_repo_root() -> Optional[str]: try: result = subprocess.run( ["git", "rev-parse", "--show-toplevel"], - capture_output=True, text=True, timeout=5, + capture_output=True, text=True, encoding="utf-8", errors="replace", timeout=5, ) if result.returncode == 0: return _normalize_git_bash_path(result.stdout.strip()) @@ -1479,7 +1479,7 @@ def _resolve_worktree_base(repo_root: str) -> tuple: def _git(args, timeout=20): return subprocess.run( ["git", *args], - capture_output=True, text=True, timeout=timeout, cwd=repo_root, + capture_output=True, text=True, encoding="utf-8", errors="replace", timeout=timeout, cwd=repo_root, ) # 1. Current branch's upstream, if it tracks one. @@ -1578,7 +1578,7 @@ def _setup_worktree(repo_root: str = None, sync_base: bool = True) -> Optional[D try: result = subprocess.run( ["git", "worktree", "add", str(wt_path), "-b", branch_name, base_ref], - capture_output=True, text=True, timeout=30, cwd=repo_root, + capture_output=True, text=True, encoding="utf-8", errors="replace", timeout=30, cwd=repo_root, ) if result.returncode != 0: # If branching from the resolved remote ref failed for any reason @@ -1592,7 +1592,7 @@ def _setup_worktree(repo_root: str = None, sync_base: bool = True) -> Optional[D base_ref, base_label = "HEAD", "HEAD (fallback — remote base failed)" result = subprocess.run( ["git", "worktree", "add", str(wt_path), "-b", branch_name, base_ref], - capture_output=True, text=True, timeout=30, cwd=repo_root, + capture_output=True, text=True, encoding="utf-8", errors="replace", timeout=30, cwd=repo_root, ) if result.returncode != 0: print(f"\033[31m✗ Failed to create worktree: {result.stderr.strip()}\033[0m") @@ -1673,7 +1673,7 @@ def _setup_worktree(repo_root: str = None, sync_base: bool = True) -> Optional[D try: subprocess.run( ["git", "worktree", "lock", "--reason", f"hermes pid={os.getpid()}", str(wt_path)], - capture_output=True, text=True, timeout=10, cwd=repo_root, + capture_output=True, text=True, encoding="utf-8", errors="replace", timeout=10, cwd=repo_root, ) logger.debug("Worktree locked: %s (pid=%s)", wt_path, os.getpid()) except Exception as e: @@ -1706,7 +1706,7 @@ def _worktree_has_unpushed_commits(worktree_path: str, timeout: int = 10) -> boo try: remote_refs = subprocess.run( ["git", "for-each-ref", "--format=%(refname)", "refs/remotes"], - capture_output=True, text=True, timeout=timeout, cwd=worktree_path, + capture_output=True, text=True, encoding="utf-8", errors="replace", timeout=timeout, cwd=worktree_path, ) if remote_refs.returncode != 0: return True @@ -1715,7 +1715,7 @@ def _worktree_has_unpushed_commits(worktree_path: str, timeout: int = 10) -> boo result = subprocess.run( ["git", "log", "--oneline", "HEAD", "--not", "--remotes"], - capture_output=True, text=True, timeout=timeout, cwd=worktree_path, + capture_output=True, text=True, encoding="utf-8", errors="replace", timeout=timeout, cwd=worktree_path, ) if result.returncode != 0: return True @@ -1736,7 +1736,7 @@ def _worktree_is_dirty(worktree_path: str, timeout: int = 10) -> bool: try: result = subprocess.run( ["git", "status", "--porcelain"], - capture_output=True, text=True, timeout=timeout, cwd=worktree_path, + capture_output=True, text=True, encoding="utf-8", errors="replace", timeout=timeout, cwd=worktree_path, ) if result.returncode != 0: return True @@ -1769,7 +1769,7 @@ def _worktree_commits_all_merged_upstream( try: probe = subprocess.run( ["git", "rev-parse", "--verify", "--quiet", candidate], - capture_output=True, text=True, timeout=timeout, cwd=worktree_path, + capture_output=True, text=True, encoding="utf-8", errors="replace", timeout=timeout, cwd=worktree_path, ) if probe.returncode == 0 and probe.stdout.strip(): base = candidate @@ -1782,7 +1782,7 @@ def _worktree_commits_all_merged_upstream( try: ahead = subprocess.run( ["git", "rev-list", "--count", f"{base}..HEAD"], - capture_output=True, text=True, timeout=timeout, cwd=worktree_path, + capture_output=True, text=True, encoding="utf-8", errors="replace", timeout=timeout, cwd=worktree_path, ) if ahead.returncode != 0: return False @@ -1794,7 +1794,7 @@ def _worktree_commits_all_merged_upstream( cherry = subprocess.run( ["git", "cherry", base, "HEAD"], - capture_output=True, text=True, timeout=timeout, cwd=worktree_path, + capture_output=True, text=True, encoding="utf-8", errors="replace", timeout=timeout, cwd=worktree_path, ) if cherry.returncode != 0: return False @@ -1829,7 +1829,7 @@ def _worktree_lock_is_live(repo_root: str, worktree_path: str, timeout: int = 10 try: result = subprocess.run( ["git", "worktree", "list", "--porcelain"], - capture_output=True, text=True, timeout=timeout, cwd=repo_root, + capture_output=True, text=True, encoding="utf-8", errors="replace", timeout=timeout, cwd=repo_root, ) if result.returncode != 0: return "live" @@ -1904,7 +1904,7 @@ def _cleanup_worktree(info: Dict[str, str] = None) -> None: try: subprocess.run( ["git", "worktree", "unlock", wt_path], - capture_output=True, text=True, timeout=10, cwd=repo_root, + capture_output=True, text=True, encoding="utf-8", errors="replace", timeout=10, cwd=repo_root, ) except Exception as e: logger.debug("git worktree unlock failed (non-fatal): %s", e) @@ -1912,7 +1912,7 @@ def _cleanup_worktree(info: Dict[str, str] = None) -> None: try: subprocess.run( ["git", "worktree", "remove", wt_path, "--force"], - capture_output=True, text=True, timeout=15, cwd=repo_root, + capture_output=True, text=True, encoding="utf-8", errors="replace", timeout=15, cwd=repo_root, ) except Exception as e: logger.debug("Failed to remove worktree: %s", e) @@ -1921,7 +1921,7 @@ def _cleanup_worktree(info: Dict[str, str] = None) -> None: try: subprocess.run( ["git", "branch", "-D", branch], - capture_output=True, text=True, timeout=10, cwd=repo_root, + capture_output=True, text=True, encoding="utf-8", errors="replace", timeout=10, cwd=repo_root, ) except Exception as e: logger.debug("Failed to delete branch %s: %s", branch, e) @@ -2122,7 +2122,7 @@ def _prune_stale_worktrees(repo_root: str, max_age_hours: int = 24) -> None: try: subprocess.run( ["git", "worktree", "unlock", str(entry)], - capture_output=True, text=True, timeout=10, cwd=repo_root, + capture_output=True, text=True, encoding="utf-8", errors="replace", timeout=10, cwd=repo_root, ) except Exception as e: logger.debug("Failed to unlock dead worktree %s: %s", entry.name, e) @@ -2131,13 +2131,13 @@ def _prune_stale_worktrees(repo_root: str, max_age_hours: int = 24) -> None: try: branch_result = subprocess.run( ["git", "branch", "--show-current"], - capture_output=True, text=True, timeout=5, cwd=str(entry), + capture_output=True, text=True, encoding="utf-8", errors="replace", timeout=5, cwd=str(entry), ) branch = branch_result.stdout.strip() remove_result = subprocess.run( ["git", "worktree", "remove", str(entry), "--force"], - capture_output=True, text=True, timeout=15, cwd=repo_root, + capture_output=True, text=True, encoding="utf-8", errors="replace", timeout=15, cwd=repo_root, ) if remove_result.returncode != 0: # Removal failed — keep the branch so any commits stay @@ -2150,7 +2150,7 @@ def _prune_stale_worktrees(repo_root: str, max_age_hours: int = 24) -> None: if branch: subprocess.run( ["git", "branch", "-D", branch], - capture_output=True, text=True, timeout=10, cwd=repo_root, + capture_output=True, text=True, encoding="utf-8", errors="replace", timeout=10, cwd=repo_root, ) logger.debug("Pruned stale worktree: %s (force=%s)", entry.name, force) except Exception as e: @@ -2178,7 +2178,7 @@ def _prune_orphaned_branches(repo_root: str) -> None: try: result = subprocess.run( ["git", "branch", "--format=%(refname:short)"], - capture_output=True, text=True, timeout=10, cwd=repo_root, + capture_output=True, text=True, encoding="utf-8", errors="replace", timeout=10, cwd=repo_root, ) if result.returncode != 0: return @@ -2191,7 +2191,7 @@ def _prune_orphaned_branches(repo_root: str) -> None: try: wt_result = subprocess.run( ["git", "worktree", "list", "--porcelain"], - capture_output=True, text=True, timeout=10, cwd=repo_root, + capture_output=True, text=True, encoding="utf-8", errors="replace", timeout=10, cwd=repo_root, ) for line in wt_result.stdout.split("\n"): if line.startswith("branch refs/heads/"): @@ -2203,7 +2203,7 @@ def _prune_orphaned_branches(repo_root: str) -> None: try: head_result = subprocess.run( ["git", "branch", "--show-current"], - capture_output=True, text=True, timeout=5, cwd=repo_root, + capture_output=True, text=True, encoding="utf-8", errors="replace", timeout=5, cwd=repo_root, ) current = head_result.stdout.strip() if current: @@ -2227,7 +2227,7 @@ def _prune_orphaned_branches(repo_root: str) -> None: try: subprocess.run( ["git", "branch", "-D"] + batch, - capture_output=True, text=True, timeout=30, cwd=repo_root, + capture_output=True, text=True, encoding="utf-8", errors="replace", timeout=30, cwd=repo_root, ) except Exception as e: logger.debug("Failed to prune orphaned branches: %s", e) @@ -9528,7 +9528,7 @@ class HermesCLI(CLIAgentSetupMixin, CLICommandsMixin, CLIBillingMixin): from hermes_cli._subprocess_compat import windows_hide_flags result = subprocess.run( exec_cmd, shell=True, capture_output=True, - text=True, timeout=30, env=sanitized_env, + text=True, encoding="utf-8", errors="replace", timeout=30, env=sanitized_env, # No console flash on Windows (#56747). creationflags=windows_hide_flags(), ) diff --git a/gateway/platforms/webhook_filters.py b/gateway/platforms/webhook_filters.py index f8db81005db1..30198c6e52d1 100644 --- a/gateway/platforms/webhook_filters.py +++ b/gateway/platforms/webhook_filters.py @@ -252,7 +252,7 @@ class WebhookRouteProcessor: argv, input=json.dumps(payload), capture_output=True, - text=True, + text=True, encoding="utf-8", errors="replace", timeout=self.script_timeout_seconds, cwd=str(path.parent), env=_sanitize_subprocess_env(os.environ.copy()), diff --git a/gateway/run.py b/gateway/run.py index 3ef880076531..72f2b2626ada 100644 --- a/gateway/run.py +++ b/gateway/run.py @@ -7271,7 +7271,7 @@ class GatewayRunner(GatewayAuthorizationMixin, GatewayKanbanWatchersMixin, Gatew out = subprocess.run( [systemctl, *scope_flags, "show", service_name, "--property=MainPID", "--value"], - capture_output=True, text=True, timeout=2, + capture_output=True, text=True, encoding="utf-8", errors="replace", timeout=2, ) return (out.stdout or "").strip() except Exception: diff --git a/hermes_cli/_early_recovery.py b/hermes_cli/_early_recovery.py index 428232d85735..aaef8ad30b23 100644 --- a/hermes_cli/_early_recovery.py +++ b/hermes_cli/_early_recovery.py @@ -131,7 +131,7 @@ def _run_repair_install(specs: list[str], project_root: Path) -> bool: [sys.executable, "-m", "pip", "install", "--force-reinstall", *specs], cwd=project_root, capture_output=True, - text=True, + text=True, encoding="utf-8", errors="replace", ) except Exception as exc: print(f" ✗ Early venv repair could not run pip: {exc}", file=sys.stderr) diff --git a/hermes_cli/main.py b/hermes_cli/main.py index 1a286739bf47..5ae40df077d9 100644 --- a/hermes_cli/main.py +++ b/hermes_cli/main.py @@ -1330,7 +1330,7 @@ def _probe_container(cmd: list, backend: str, via_sudo: bool = False): all other exceptions propagate naturally. """ try: - return subprocess.run(cmd, capture_output=True, text=True, timeout=15) + return subprocess.run(cmd, capture_output=True, text=True, encoding="utf-8", errors="replace", timeout=15) except subprocess.TimeoutExpired: label = f"sudo {backend}" if via_sudo else backend print( @@ -1843,7 +1843,7 @@ def _restore_tui_workspace(tui_dir: Path) -> bool: [git, "restore", "--", tui_dir.name], cwd=str(tui_dir.parent), capture_output=True, - text=True, + text=True, encoding="utf-8", errors="replace", check=False, ) except OSError: @@ -4729,7 +4729,7 @@ def _capture_head_sha(git_cmd, cwd) -> str | None: git_cmd + ["rev-parse", "HEAD"], cwd=cwd, capture_output=True, - text=True, + text=True, encoding="utf-8", errors="replace", check=True, ) return result.stdout.strip() or None @@ -5088,7 +5088,7 @@ def _nixos_build_env() -> dict[str, str] | None: try: result = subprocess.run( ["nix-shell", "-p", "python3", "--run", "which python3"], - capture_output=True, text=True, check=False, timeout=15, + capture_output=True, text=True, encoding="utf-8", errors="replace", check=False, timeout=15, ) if result.returncode == 0: python3_path = result.stdout.strip() @@ -6290,7 +6290,7 @@ def _find_stale_dashboard_pids( result = subprocess.run( ["ps", "-A", "-o", "pid=,command="], capture_output=True, - text=True, + text=True, encoding="utf-8", errors="replace", timeout=10, ) if result.returncode == 0: @@ -6579,7 +6579,7 @@ def _restart_managed_dashboard_service( return subprocess.run( ["systemctl", *args], capture_output=True, - text=True, + text=True, encoding="utf-8", errors="replace", timeout=timeout, ) @@ -6643,7 +6643,7 @@ def _restart_managed_dashboard_service( result = subprocess.run( list(command), capture_output=True, - text=True, + text=True, encoding="utf-8", errors="replace", timeout=60, ) except (FileNotFoundError, subprocess.TimeoutExpired, OSError) as e: @@ -6732,7 +6732,7 @@ def _kill_stale_dashboard_processes( result = subprocess.run( ["taskkill", "/PID", str(pid), "/F"], capture_output=True, - text=True, + text=True, encoding="utf-8", errors="replace", timeout=10, ) if result.returncode == 0: @@ -7055,7 +7055,7 @@ def _stash_local_changes_if_needed(git_cmd: list[str], cwd: Path) -> Optional[st git_cmd + ["status", "--porcelain"], cwd=cwd, capture_output=True, - text=True, + text=True, encoding="utf-8", errors="replace", check=True, ) if not status.stdout.strip(): @@ -7069,7 +7069,7 @@ def _stash_local_changes_if_needed(git_cmd: list[str], cwd: Path) -> Optional[st git_cmd + ["ls-files", "--unmerged"], cwd=cwd, capture_output=True, - text=True, + text=True, encoding="utf-8", errors="replace", ) if unmerged.stdout.strip(): print("→ Clearing unmerged index entries from a previous conflict...") @@ -7085,13 +7085,13 @@ def _stash_local_changes_if_needed(git_cmd: list[str], cwd: Path) -> Optional[st git_cmd + ["rev-parse", "--verify", "refs/stash"], cwd=cwd, capture_output=True, - text=True, + text=True, encoding="utf-8", errors="replace", ).stdout.strip() push = subprocess.run( git_cmd + ["stash", "push", "--include-untracked", "-m", stash_name], cwd=cwd, capture_output=True, - text=True, + text=True, encoding="utf-8", errors="replace", ) if push.stdout.strip(): print(push.stdout.strip()) @@ -7099,7 +7099,7 @@ def _stash_local_changes_if_needed(git_cmd: list[str], cwd: Path) -> Optional[st git_cmd + ["rev-parse", "--verify", "refs/stash"], cwd=cwd, capture_output=True, - text=True, + text=True, encoding="utf-8", errors="replace", ) stash_ref = stash_probe.stdout.strip() stash_created = ( @@ -7157,7 +7157,7 @@ def _resolve_stash_selector( git_cmd + ["stash", "list", "--format=%gd %H"], cwd=cwd, capture_output=True, - text=True, + text=True, encoding="utf-8", errors="replace", check=True, ) for line in stash_list.stdout.splitlines(): @@ -7242,7 +7242,7 @@ def _restore_stashed_changes( git_cmd + ["stash", "apply", stash_ref], cwd=cwd, capture_output=True, - text=True, + text=True, encoding="utf-8", errors="replace", ) # Check for unmerged (conflicted) files — can happen even when returncode is 0 @@ -7250,7 +7250,7 @@ def _restore_stashed_changes( git_cmd + ["diff", "--name-only", "--diff-filter=U"], cwd=cwd, capture_output=True, - text=True, + text=True, encoding="utf-8", errors="replace", ) has_conflicts = bool(unmerged.stdout.strip()) @@ -7312,7 +7312,7 @@ def _restore_stashed_changes( git_cmd + ["stash", "drop", stash_selector], cwd=cwd, capture_output=True, - text=True, + text=True, encoding="utf-8", errors="replace", ) if drop.returncode != 0: print( @@ -7364,7 +7364,7 @@ def _discard_stashed_changes( git_cmd + ["stash", "drop", stash_selector], cwd=cwd, capture_output=True, - text=True, + text=True, encoding="utf-8", errors="replace", ) if drop.returncode != 0: print( @@ -7401,7 +7401,7 @@ def _get_origin_url(git_cmd: list[str], cwd: Path) -> Optional[str]: git_cmd + ["remote", "get-url", "origin"], cwd=cwd, capture_output=True, - text=True, + text=True, encoding="utf-8", errors="replace", ) if result.returncode == 0: return result.stdout.strip() @@ -7434,7 +7434,7 @@ def _has_upstream_remote(git_cmd: list[str], cwd: Path) -> bool: git_cmd + ["remote", "get-url", "upstream"], cwd=cwd, capture_output=True, - text=True, + text=True, encoding="utf-8", errors="replace", ) return result.returncode == 0 except Exception: @@ -7448,7 +7448,7 @@ def _add_upstream_remote(git_cmd: list[str], cwd: Path) -> bool: git_cmd + ["remote", "add", "upstream", OFFICIAL_REPO_URL], cwd=cwd, capture_output=True, - text=True, + text=True, encoding="utf-8", errors="replace", ) return result.returncode == 0 except Exception: @@ -7462,7 +7462,7 @@ def _count_commits_between(git_cmd: list[str], cwd: Path, base: str, head: str) git_cmd + ["rev-list", "--count", f"{base}..{head}"], cwd=cwd, capture_output=True, - text=True, + text=True, encoding="utf-8", errors="replace", ) if result.returncode == 0: return int(result.stdout.strip()) @@ -7498,7 +7498,7 @@ def _sync_fork_with_upstream(git_cmd: list[str], cwd: Path) -> bool: git_cmd + ["push", "origin", "main", "--force-with-lease"], cwd=cwd, capture_output=True, - text=True, + text=True, encoding="utf-8", errors="replace", ) return result.returncode == 0 except Exception: @@ -8541,7 +8541,7 @@ def _detect_broken_lazy_refresh_imports( result = subprocess.run( [str(venv_python), "-c", check_script], capture_output=True, - text=True, + text=True, encoding="utf-8", errors="replace", check=False, env=env, ) @@ -9000,7 +9000,7 @@ def _verify_core_dependencies_installed( result = subprocess.run( [str(venv_python), "-c", check_script, *applicable], capture_output=True, - text=True, + text=True, encoding="utf-8", errors="replace", check=False, env=env, ) @@ -9722,7 +9722,7 @@ def _cmd_update_check(branch: str = "main", *, branch_explicit: bool = False): git_cmd + ["rev-parse", "--is-shallow-repository"], cwd=PROJECT_ROOT, capture_output=True, - text=True, + text=True, encoding="utf-8", errors="replace", ).stdout.strip() == "true" ) @@ -9734,7 +9734,7 @@ def _cmd_update_check(branch: str = "main", *, branch_explicit: bool = False): git_cmd + ["fetch"] + depth_args + ["upstream", branch], cwd=PROJECT_ROOT, capture_output=True, - text=True, + text=True, encoding="utf-8", errors="replace", ) if fetch_result.returncode != 0: # Fallback to origin if upstream doesn't exist @@ -9743,7 +9743,7 @@ def _cmd_update_check(branch: str = "main", *, branch_explicit: bool = False): git_cmd + ["fetch"] + depth_args + ["origin", branch], cwd=PROJECT_ROOT, capture_output=True, - text=True, + text=True, encoding="utf-8", errors="replace", ) upstream_exists = False compare_branch = f"origin/{branch}" @@ -9757,7 +9757,7 @@ def _cmd_update_check(branch: str = "main", *, branch_explicit: bool = False): git_cmd + ["fetch"] + depth_args + ["origin", branch], cwd=PROJECT_ROOT, capture_output=True, - text=True, + text=True, encoding="utf-8", errors="replace", ) upstream_exists = False compare_branch = f"origin/{branch}" @@ -9782,7 +9782,7 @@ def _cmd_update_check(branch: str = "main", *, branch_explicit: bool = False): git_cmd + ["rev-parse", "--verify", "--quiet", compare_branch], cwd=PROJECT_ROOT, capture_output=True, - text=True, + text=True, encoding="utf-8", errors="replace", ) if verify_result.returncode != 0: print(f"✗ Branch '{branch}' not found on {compare_branch.split('/', 1)[0]}.") @@ -9793,11 +9793,11 @@ def _cmd_update_check(branch: str = "main", *, branch_explicit: bool = False): # report presence-only (mirrors the banner's _check_via_local_git). head_sha = subprocess.run( git_cmd + ["rev-parse", "HEAD"], - cwd=PROJECT_ROOT, capture_output=True, text=True, + cwd=PROJECT_ROOT, capture_output=True, text=True, encoding="utf-8", errors="replace", ).stdout.strip() target_sha = subprocess.run( git_cmd + ["rev-parse", compare_branch], - cwd=PROJECT_ROOT, capture_output=True, text=True, + cwd=PROJECT_ROOT, capture_output=True, text=True, encoding="utf-8", errors="replace", ).stdout.strip() if head_sha and target_sha and head_sha == target_sha: print("✓ Already up to date.") @@ -9812,7 +9812,7 @@ def _cmd_update_check(branch: str = "main", *, branch_explicit: bool = False): git_cmd + ["rev-list", f"HEAD..{compare_branch}", "--count"], cwd=PROJECT_ROOT, capture_output=True, - text=True, + text=True, encoding="utf-8", errors="replace", check=True, ) behind = int(rev_result.stdout.strip()) @@ -9873,7 +9873,7 @@ def _ensure_fhs_path_guard() -> None: "command -v hermes", ], capture_output=True, - text=True, + text=True, encoding="utf-8", errors="replace", timeout=10, ) except (FileNotFoundError, subprocess.TimeoutExpired): @@ -10197,7 +10197,7 @@ def _venv_core_imports_healthy() -> tuple[bool, str]: result = subprocess.run( [str(venv_python), "-c", check], capture_output=True, - text=True, + text=True, encoding="utf-8", errors="replace", timeout=60, cwd=PROJECT_ROOT, ) @@ -10640,7 +10640,7 @@ def _discard_lockfile_churn(git_cmd, repo_root): git_cmd + ["diff", "--name-only"], cwd=repo_root, capture_output=True, - text=True, + text=True, encoding="utf-8", errors="replace", ) if diff.returncode != 0: return @@ -10661,7 +10661,7 @@ def _discard_lockfile_churn(git_cmd, repo_root): git_cmd + ["checkout", "--", *dirty], cwd=repo_root, capture_output=True, - text=True, + text=True, encoding="utf-8", errors="replace", check=False, ) print(f"→ Discarded npm lockfile churn ({len(dirty)} file(s))") @@ -10886,7 +10886,7 @@ def _cmd_update_impl(args, gateway_mode: bool): git_cmd + ["fetch", "origin", branch], cwd=PROJECT_ROOT, capture_output=True, - text=True, + text=True, encoding="utf-8", errors="replace", ) if fetch_result.returncode != 0: stderr = fetch_result.stderr.strip() @@ -10910,7 +10910,7 @@ def _cmd_update_impl(args, gateway_mode: bool): git_cmd + ["rev-parse", "--abbrev-ref", "HEAD"], cwd=PROJECT_ROOT, capture_output=True, - text=True, + text=True, encoding="utf-8", errors="replace", check=True, ) current_branch = result.stdout.strip() @@ -10933,7 +10933,7 @@ def _cmd_update_impl(args, gateway_mode: bool): git_cmd + ["checkout", branch], cwd=PROJECT_ROOT, capture_output=True, - text=True, + text=True, encoding="utf-8", errors="replace", ) if checkout_result.returncode != 0: # Local checkout doesn't have this branch yet. Try to set @@ -10944,7 +10944,7 @@ def _cmd_update_impl(args, gateway_mode: bool): git_cmd + ["checkout", "-B", branch, f"origin/{branch}"], cwd=PROJECT_ROOT, capture_output=True, - text=True, + text=True, encoding="utf-8", errors="replace", ) if track_result.returncode != 0: # Restore the user's prior branch + stash before bailing @@ -10975,7 +10975,7 @@ def _cmd_update_impl(args, gateway_mode: bool): git_cmd + ["rev-list", f"HEAD..origin/{branch}", "--count"], cwd=PROJECT_ROOT, capture_output=True, - text=True, + text=True, encoding="utf-8", errors="replace", check=True, ) commit_count = int(result.stdout.strip()) @@ -11001,7 +11001,7 @@ def _cmd_update_impl(args, gateway_mode: bool): git_cmd + ["checkout", current_branch], cwd=PROJECT_ROOT, capture_output=True, - text=True, + text=True, encoding="utf-8", errors="replace", check=False, ) @@ -11073,7 +11073,7 @@ def _cmd_update_impl(args, gateway_mode: bool): git_cmd + ["pull", "--ff-only", "origin", branch], cwd=PROJECT_ROOT, capture_output=True, - text=True, + text=True, encoding="utf-8", errors="replace", ) if pull_result.returncode != 0: # ff-only failed — local and remote have diverged (e.g. upstream @@ -11086,7 +11086,7 @@ def _cmd_update_impl(args, gateway_mode: bool): git_cmd + ["reset", "--hard", f"origin/{branch}"], cwd=PROJECT_ROOT, capture_output=True, - text=True, + text=True, encoding="utf-8", errors="replace", ) if reset_result.returncode != 0: print(f"✗ Failed to reset to origin/{branch}.") @@ -11122,7 +11122,7 @@ def _cmd_update_impl(args, gateway_mode: bool): git_cmd + ["reset", "--hard", pre_pull_sha], cwd=PROJECT_ROOT, capture_output=True, - text=True, + text=True, encoding="utf-8", errors="replace", ) if rollback_result.returncode == 0: print(" ✓ Rollback complete — your install is unchanged.") @@ -11717,7 +11717,7 @@ def _cmd_update_impl(args, gateway_mode: bool): _verify = subprocess.run( scope_cmd_ + ["is-active", svc_name_], capture_output=True, - text=True, + text=True, encoding="utf-8", errors="replace", timeout=5, ) if _verify.stdout.strip() == "active": @@ -11751,7 +11751,7 @@ def _cmd_update_impl(args, gateway_mode: bool): "--value", ], capture_output=True, - text=True, + text=True, encoding="utf-8", errors="replace", timeout=5, ) except (FileNotFoundError, subprocess.TimeoutExpired): @@ -11900,7 +11900,7 @@ def _cmd_update_impl(args, gateway_mode: bool): "--no-pager", ], capture_output=True, - text=True, + text=True, encoding="utf-8", errors="replace", timeout=10, ) except FileNotFoundError: @@ -11919,7 +11919,7 @@ def _cmd_update_impl(args, gateway_mode: bool): check = subprocess.run( scope_cmd + ["is-active", svc_name], capture_output=True, - text=True, + text=True, encoding="utf-8", errors="replace", timeout=5, ) if check.stdout.strip() != "active": @@ -11952,7 +11952,7 @@ def _cmd_update_impl(args, gateway_mode: bool): "--value", ], capture_output=True, - text=True, + text=True, encoding="utf-8", errors="replace", timeout=5, ) _main_pid = int((_show.stdout or "").strip() or 0) @@ -12005,13 +12005,13 @@ def _cmd_update_impl(args, gateway_mode: bool): subprocess.run( _manage_cmd + ["reset-failed", svc_name], capture_output=True, - text=True, + text=True, encoding="utf-8", errors="replace", timeout=10, ) subprocess.run( _manage_cmd + ["start", svc_name], capture_output=True, - text=True, + text=True, encoding="utf-8", errors="replace", timeout=15, ) # Short poll: the gateway should be up @@ -12095,13 +12095,13 @@ def _cmd_update_impl(args, gateway_mode: bool): subprocess.run( _manage_cmd + ["reset-failed", svc_name], capture_output=True, - text=True, + text=True, encoding="utf-8", errors="replace", timeout=10, ) restart = subprocess.run( _manage_cmd + ["restart", svc_name], capture_output=True, - text=True, + text=True, encoding="utf-8", errors="replace", timeout=15, ) if restart.returncode == 0: @@ -12127,13 +12127,13 @@ def _cmd_update_impl(args, gateway_mode: bool): subprocess.run( _manage_cmd + ["reset-failed", svc_name], capture_output=True, - text=True, + text=True, encoding="utf-8", errors="replace", timeout=10, ) subprocess.run( _manage_cmd + ["restart", svc_name], capture_output=True, - text=True, + text=True, encoding="utf-8", errors="replace", timeout=15, ) if _wait_for_service_active( @@ -12191,7 +12191,7 @@ def _cmd_update_impl(args, gateway_mode: bool): check = subprocess.run( ["launchctl", "list", get_launchd_label()], capture_output=True, - text=True, + text=True, encoding="utf-8", errors="replace", timeout=5, ) if check.returncode == 0: @@ -15016,7 +15016,7 @@ def main(): from hermes_cli.tools_config import _cua_driver_env version = subprocess.run( [path, "--version"], - capture_output=True, text=True, timeout=5, + capture_output=True, text=True, encoding="utf-8", errors="replace", timeout=5, env=_cua_driver_env(), ).stdout.strip() except Exception: diff --git a/hermes_cli/setup.py b/hermes_cli/setup.py index 6922f4f9cb0e..4763e35e9359 100644 --- a/hermes_cli/setup.py +++ b/hermes_cli/setup.py @@ -1450,7 +1450,7 @@ def setup_terminal_backend(config: dict): ssh_cmd.extend(["-p", port]) ssh_cmd.append(f"{user}@{host}" if user else host) ssh_cmd.append("echo ok") - result = subprocess.run(ssh_cmd, capture_output=True, text=True, timeout=10) + result = subprocess.run(ssh_cmd, capture_output=True, text=True, encoding="utf-8", errors="replace", timeout=10) if result.returncode == 0: print_success(" SSH connection successful!") else: diff --git a/hermes_cli/tools_config.py b/hermes_cli/tools_config.py index 7dc4838596d9..2614ead045ec 100644 --- a/hermes_cli/tools_config.py +++ b/hermes_cli/tools_config.py @@ -708,7 +708,7 @@ def _pip_install( try: result = subprocess.run( [uv_bin, "pip", "install", *args], - capture_output=capture_output, text=True, timeout=timeout, + capture_output=capture_output, text=True, encoding="utf-8", errors="replace", timeout=timeout, env=uv_env, creationflags=_post_setup_no_window_flags( streams_to_console=not capture_output @@ -726,7 +726,7 @@ def _pip_install( # Probe for pip; bootstrap via ensurepip if missing (uv venv lacks it). probe = subprocess.run( pip_cmd + ["--version"], - capture_output=True, text=True, timeout=15, + capture_output=True, text=True, encoding="utf-8", errors="replace", timeout=15, creationflags=_post_setup_no_window_flags(), ) if probe.returncode != 0: @@ -735,7 +735,7 @@ def _pip_install( try: subprocess.run( [sys.executable, "-m", "ensurepip", "--upgrade", "--default-pip"], - capture_output=True, text=True, timeout=120, check=True, + capture_output=True, text=True, encoding="utf-8", errors="replace", timeout=120, check=True, creationflags=_post_setup_no_window_flags(), ) except (subprocess.CalledProcessError, subprocess.TimeoutExpired) as e: @@ -747,7 +747,7 @@ def _pip_install( return subprocess.run( pip_cmd + ["install", *args], - capture_output=capture_output, text=True, timeout=timeout, + capture_output=capture_output, text=True, encoding="utf-8", errors="replace", timeout=timeout, creationflags=_post_setup_no_window_flags( streams_to_console=not capture_output ), @@ -859,7 +859,7 @@ def install_cua_driver(upgrade: bool = False) -> bool: try: version = subprocess.run( [binary, "--version"], - capture_output=True, text=True, timeout=5, env=_cua_driver_env(), + capture_output=True, text=True, encoding="utf-8", errors="replace", timeout=5, env=_cua_driver_env(), creationflags=_post_setup_no_window_flags(), ).stdout.strip() _print_success(f" {driver_cmd} already installed: {version or 'unknown version'}") @@ -917,7 +917,7 @@ def install_cua_driver(upgrade: bool = False) -> bool: try: before = subprocess.run( [binary, "--version"], - capture_output=True, text=True, timeout=5, env=_cua_driver_env(), + capture_output=True, text=True, encoding="utf-8", errors="replace", timeout=5, env=_cua_driver_env(), creationflags=_post_setup_no_window_flags(), ).stdout.strip() except Exception: @@ -930,7 +930,7 @@ def install_cua_driver(upgrade: bool = False) -> bool: try: after = subprocess.run( [binary, "--version"], - capture_output=True, text=True, timeout=5, env=_cua_driver_env(), + capture_output=True, text=True, encoding="utf-8", errors="replace", timeout=5, env=_cua_driver_env(), creationflags=_post_setup_no_window_flags(), ).stdout.strip() if after and after != before: @@ -1075,7 +1075,7 @@ def _run_cua_driver_installer(label: str = "Installing", verbose: bool = True) - try: dl = subprocess.run( ["curl", "-fsSL", "-o", script_path, install_url], - capture_output=True, text=True, timeout=120, + capture_output=True, text=True, encoding="utf-8", errors="replace", timeout=120, ) except (subprocess.TimeoutExpired, OSError) as e: _print_warning(f" cua-driver installer download failed: {e}") @@ -1243,7 +1243,7 @@ def _run_post_setup(post_setup_key: str): # only, avoiding the apps/* glob which would pull in # apps/desktop (Electron + node-pty) unnecessarily. See #38772. [npm_bin, "install", "--silent", "--workspaces=false"], - capture_output=True, text=True, cwd=str(PROJECT_ROOT), + capture_output=True, text=True, encoding="utf-8", errors="replace", cwd=str(PROJECT_ROOT), creationflags=_post_setup_no_window_flags(), ) if result.returncode == 0: @@ -1323,7 +1323,7 @@ def _run_post_setup(post_setup_key: str): try: result = subprocess.run( install_cmd, - capture_output=True, text=True, cwd=str(PROJECT_ROOT), timeout=600, + capture_output=True, text=True, encoding="utf-8", errors="replace", cwd=str(PROJECT_ROOT), timeout=600, creationflags=_post_setup_no_window_flags(), ) if result.returncode == 0: @@ -1357,7 +1357,7 @@ def _run_post_setup(post_setup_key: str): result = subprocess.run( # --workspaces=false avoids resolving apps/desktop. See #38772. [_npm_bin, "install", "--silent", "--workspaces=false"], - capture_output=True, text=True, cwd=str(PROJECT_ROOT), + capture_output=True, text=True, encoding="utf-8", errors="replace", cwd=str(PROJECT_ROOT), creationflags=_post_setup_no_window_flags(), ) if result.returncode == 0: diff --git a/hermes_cli/windows_ssh_runtime.py b/hermes_cli/windows_ssh_runtime.py index b80b81e85ba4..2b58e88918c9 100644 --- a/hermes_cli/windows_ssh_runtime.py +++ b/hermes_cli/windows_ssh_runtime.py @@ -362,7 +362,7 @@ def _resolve_direct_interpreter(python_entry: str) -> tuple[str, list[str]]: "print(json.dumps({'base':getattr(sys,'_base_executable','') or sys.executable," "'path':[p for p in sys.path if p],'root':root}))" ) - out = subprocess.run([python_entry, "-c", query], capture_output=True, text=True, timeout=30) + out = subprocess.run([python_entry, "-c", query], capture_output=True, text=True, encoding="utf-8", errors="replace", timeout=30) if out.returncode != 0: raise ValueError("could not resolve the base Python interpreter") info = json.loads(out.stdout.strip().splitlines()[-1]) @@ -437,8 +437,8 @@ def inspect_hermes(hermes_path: str) -> dict[str, Any]: path = os.path.abspath(hermes_path) if not os.path.isabs(hermes_path) or not os.path.isfile(path): raise ValueError("Hermes path is not an executable file") - version = subprocess.run([path, "--version"], capture_output=True, text=True, timeout=20) - help_result = subprocess.run([path, "serve", "--help"], capture_output=True, text=True, timeout=20) + version = subprocess.run([path, "--version"], capture_output=True, text=True, encoding="utf-8", errors="replace", timeout=20) + help_result = subprocess.run([path, "serve", "--help"], capture_output=True, text=True, encoding="utf-8", errors="replace", timeout=20) help_text = help_result.stdout + help_result.stderr return { "path": path, diff --git a/plugins/platforms/photon/adapter.py b/plugins/platforms/photon/adapter.py index 2f8cae3563db..91cd50c3b488 100644 --- a/plugins/platforms/photon/adapter.py +++ b/plugins/platforms/photon/adapter.py @@ -183,7 +183,7 @@ def _reinstall_sidecar_deps() -> None: [npm, "ci"], cwd=str(_SIDECAR_DIR), capture_output=True, - text=True, + text=True, encoding="utf-8", errors="replace", check=False, timeout=_NPM_REINSTALL_TIMEOUT, creationflags=windows_hide_flags(), @@ -196,7 +196,7 @@ def _reinstall_sidecar_deps() -> None: [npm, "install"], cwd=str(_SIDECAR_DIR), capture_output=True, - text=True, + text=True, encoding="utf-8", errors="replace", check=False, timeout=_NPM_REINSTALL_TIMEOUT, creationflags=windows_hide_flags(), diff --git a/plugins/platforms/telegram/adapter.py b/plugins/platforms/telegram/adapter.py index fb7123aaf27e..77eb7dcb42a4 100644 --- a/plugins/platforms/telegram/adapter.py +++ b/plugins/platforms/telegram/adapter.py @@ -355,7 +355,7 @@ def _probe_voice_duration_seconds(path: str) -> Optional[int]: proc = subprocess.run( ["ffprobe", "-v", "error", "-show_entries", "format=duration", "-of", "default=noprint_wrappers=1:nokey=1", path], - capture_output=True, text=True, timeout=5, + capture_output=True, text=True, encoding="utf-8", errors="replace", timeout=5, ) if proc.returncode == 0: return _coerce_duration_seconds(proc.stdout.strip()) diff --git a/scripts/ci/lockfile_diff.py b/scripts/ci/lockfile_diff.py index 46712ad3760e..a118eb1e5dcf 100644 --- a/scripts/ci/lockfile_diff.py +++ b/scripts/ci/lockfile_diff.py @@ -115,7 +115,7 @@ def _git_show(ref: str, path: str, repo_root: str) -> str | None: proc = subprocess.run( ["git", "show", f"{ref}:{path}"], capture_output=True, - text=True, + text=True, encoding="utf-8", errors="replace", cwd=repo_root, ) return proc.stdout if proc.returncode == 0 else None @@ -125,7 +125,7 @@ def _tracked_lockfiles(ref: str, repo_root: str) -> set[str]: proc = subprocess.run( ["git", "ls-tree", "-r", "--name-only", ref], capture_output=True, - text=True, + text=True, encoding="utf-8", errors="replace", cwd=repo_root, check=True, ) diff --git a/scripts/ci/publish_e2e_evidence.py b/scripts/ci/publish_e2e_evidence.py index 94ad6af66594..7d5de4562747 100644 --- a/scripts/ci/publish_e2e_evidence.py +++ b/scripts/ci/publish_e2e_evidence.py @@ -246,7 +246,7 @@ def upload_evidence( ], check=True, capture_output=True, - text=True, + text=True, encoding="utf-8", errors="replace", env=environment, ) except subprocess.CalledProcessError as exc: diff --git a/scripts/iso-certify.py b/scripts/iso-certify.py index c9b217d18355..c01f009c6b43 100755 --- a/scripts/iso-certify.py +++ b/scripts/iso-certify.py @@ -178,7 +178,7 @@ class ScratchDashboard: ] self.proc = subprocess.Popen( cmd, cwd=str(REPO_ROOT), env=env, - stdout=subprocess.PIPE, stderr=subprocess.STDOUT, text=True, bufsize=1, + stdout=subprocess.PIPE, stderr=subprocess.STDOUT, text=True, encoding="utf-8", errors="replace", bufsize=1, ) threading.Thread(target=self._drain, args=(self.proc.stdout,), name="dash-log", daemon=True).start() if not self._ready.wait(timeout=90.0): diff --git a/scripts/release.py b/scripts/release.py index 8f1fb1c7e95d..58734dec76c8 100755 --- a/scripts/release.py +++ b/scripts/release.py @@ -2097,7 +2097,7 @@ def git(*args, cwd=None): """Run a git command and return stdout.""" result = subprocess.run( ["git"] + list(args), - capture_output=True, text=True, + capture_output=True, text=True, encoding="utf-8", errors="replace", cwd=cwd or str(REPO_ROOT), ) if result.returncode != 0: @@ -2111,7 +2111,7 @@ def git_result(*args, cwd=None): return subprocess.run( ["git"] + list(args), capture_output=True, - text=True, + text=True, encoding="utf-8", errors="replace", cwd=cwd or str(REPO_ROOT), ) @@ -2591,7 +2591,7 @@ def main(): if gh_bin: result = subprocess.run( gh_cmd, - capture_output=True, text=True, + capture_output=True, text=True, encoding="utf-8", errors="replace", cwd=str(REPO_ROOT), ) else: diff --git a/scripts/run_tests_parallel.py b/scripts/run_tests_parallel.py index 9a95d39d783e..91cf0373f60b 100755 --- a/scripts/run_tests_parallel.py +++ b/scripts/run_tests_parallel.py @@ -314,7 +314,7 @@ def _run_one_file_once( cwd=repo_root, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, - text=True, + text=True, encoding="utf-8", errors="replace", env=os.environ, # POSIX: place the child at the head of its own process group so # _kill_tree can SIGKILL the group atomically. diff --git a/skills/productivity/docx/scripts/accept_changes.py b/skills/productivity/docx/scripts/accept_changes.py index 8e363161915d..a3cc665a19d5 100755 --- a/skills/productivity/docx/scripts/accept_changes.py +++ b/skills/productivity/docx/scripts/accept_changes.py @@ -68,7 +68,7 @@ def accept_changes( result = subprocess.run( cmd, capture_output=True, - text=True, + text=True, encoding="utf-8", errors="replace", timeout=30, check=False, env=get_soffice_env(), diff --git a/skills/productivity/docx/scripts/office/validators/redlining.py b/skills/productivity/docx/scripts/office/validators/redlining.py index 4185c51f4f10..7d3a08262e88 100644 --- a/skills/productivity/docx/scripts/office/validators/redlining.py +++ b/skills/productivity/docx/scripts/office/validators/redlining.py @@ -201,7 +201,7 @@ class RedliningValidator: str(modified_file), ], capture_output=True, - text=True, + text=True, encoding="utf-8", errors="replace", ) if result.stdout.strip(): @@ -229,7 +229,7 @@ class RedliningValidator: str(modified_file), ], capture_output=True, - text=True, + text=True, encoding="utf-8", errors="replace", ) if result.stdout.strip(): diff --git a/skills/productivity/powerpoint/scripts/office/validators/redlining.py b/skills/productivity/powerpoint/scripts/office/validators/redlining.py index 4185c51f4f10..7d3a08262e88 100644 --- a/skills/productivity/powerpoint/scripts/office/validators/redlining.py +++ b/skills/productivity/powerpoint/scripts/office/validators/redlining.py @@ -201,7 +201,7 @@ class RedliningValidator: str(modified_file), ], capture_output=True, - text=True, + text=True, encoding="utf-8", errors="replace", ) if result.stdout.strip(): @@ -229,7 +229,7 @@ class RedliningValidator: str(modified_file), ], capture_output=True, - text=True, + text=True, encoding="utf-8", errors="replace", ) if result.stdout.strip(): diff --git a/skills/productivity/powerpoint/scripts/thumbnail.py b/skills/productivity/powerpoint/scripts/thumbnail.py index d49cac0e1a13..8735bc6d7201 100755 --- a/skills/productivity/powerpoint/scripts/thumbnail.py +++ b/skills/productivity/powerpoint/scripts/thumbnail.py @@ -192,6 +192,8 @@ def convert_to_images(pptx_path: Path, temp_dir: Path) -> list[Path]: ["--headless", "--convert-to", "pdf", "--outdir", str(temp_dir), str(pptx_path)], capture_output=True, text=True, + encoding="utf-8", + errors="replace", ) if result.returncode != 0 or not pdf_path.exists(): detail = (result.stderr or result.stdout or "").strip() @@ -207,7 +209,7 @@ def convert_to_images(pptx_path: Path, temp_dir: Path) -> list[Path]: str(temp_dir / "slide"), ], capture_output=True, - text=True, + text=True, encoding="utf-8", errors="replace", ) if result.returncode != 0: raise RuntimeError("Image conversion failed") diff --git a/skills/productivity/xlsx/scripts/recalc.py b/skills/productivity/xlsx/scripts/recalc.py index 6232be2deea5..b9f1527b5f30 100755 --- a/skills/productivity/xlsx/scripts/recalc.py +++ b/skills/productivity/xlsx/scripts/recalc.py @@ -189,7 +189,7 @@ def _recalc_with_profile(filename, abs_path, timeout, profile_dir: Path): try: result = subprocess.run( - cmd, capture_output=True, text=True, env=get_soffice_env(), timeout=timeout + 15 + cmd, capture_output=True, text=True, encoding="utf-8", errors="replace", env=get_soffice_env(), timeout=timeout + 15 ) except subprocess.TimeoutExpired: return {"error": timed_out} diff --git a/tools/computer_use/cua_backend.py b/tools/computer_use/cua_backend.py index 94b456dd67f4..98b98ec0be6f 100644 --- a/tools/computer_use/cua_backend.py +++ b/tools/computer_use/cua_backend.py @@ -295,7 +295,7 @@ def _linux_x11_active_window_id() -> Optional[int]: proc = subprocess.run( ["xprop", "-root", "_NET_ACTIVE_WINDOW"], capture_output=True, - text=True, + text=True, encoding="utf-8", errors="replace", timeout=2, check=False, ) @@ -379,7 +379,7 @@ def _resolve_mcp_invocation( from tools.environments.local import _sanitize_subprocess_env proc = subprocess.run( [driver_cmd, "manifest"], - capture_output=True, text=True, timeout=timeout, + capture_output=True, text=True, encoding="utf-8", errors="replace", timeout=timeout, stdin=subprocess.DEVNULL, # cua-driver is a third-party binary — never hand it provider # API keys via inherited env (same policy as the MCP and CLI @@ -445,7 +445,7 @@ def _cua_driver_supports_no_overlay(driver_cmd: str) -> bool: from tools.environments.local import _sanitize_subprocess_env proc = subprocess.run( [driver_cmd, "--help"], - capture_output=True, text=True, timeout=3.0, + capture_output=True, text=True, encoding="utf-8", errors="replace", timeout=3.0, stdin=subprocess.DEVNULL, env=_sanitize_subprocess_env(cua_driver_child_env()), ) @@ -576,7 +576,7 @@ def cua_driver_update_check(*, timeout: float = 8.0) -> Optional[Dict[str, Any]] from tools.environments.local import _sanitize_subprocess_env proc = subprocess.run( [driver_cmd, "check-update", "--json"], - capture_output=True, text=True, timeout=timeout, + capture_output=True, text=True, encoding="utf-8", errors="replace", timeout=timeout, # Some older drivers don't have the verb and fall through to a # stdin-reading mode rather than erroring — DEVNULL gives them EOF # so they exit fast instead of blocking until the timeout. @@ -1256,7 +1256,7 @@ class _CuaDriverSession: for attempt in range(attempts): try: proc = _subprocess.run( - cmd, capture_output=True, text=True, timeout=max(15.0, timeout), + cmd, capture_output=True, text=True, encoding="utf-8", errors="replace", timeout=max(15.0, timeout), env=_sanitize_subprocess_env(cua_driver_child_env()), ) except Exception as e: # pragma: no cover - subprocess spawn failure diff --git a/tools/environments/base.py b/tools/environments/base.py index 1b20cfa90ee0..1b082bd83a0c 100644 --- a/tools/environments/base.py +++ b/tools/environments/base.py @@ -248,7 +248,7 @@ def _popen_bash( stdout=subprocess.PIPE, stderr=subprocess.STDOUT, stdin=subprocess.PIPE if stdin_data is not None else subprocess.DEVNULL, - text=True, + text=True, encoding="utf-8", errors="replace", **kwargs, ) if stdin_data is not None: diff --git a/tools/environments/docker.py b/tools/environments/docker.py index ea436f50237f..def1ac157f19 100644 --- a/tools/environments/docker.py +++ b/tools/environments/docker.py @@ -1377,7 +1377,7 @@ class DockerEnvironment(BaseEnvironment): subprocess.run( [self._docker_exe, "rm", "-f", container_id], capture_output=True, - text=True, + text=True, encoding="utf-8", errors="replace", timeout=30, check=False, stdin=subprocess.DEVNULL, @@ -1701,7 +1701,7 @@ class DockerEnvironment(BaseEnvironment): container_id, ], capture_output=True, - text=True, + text=True, encoding="utf-8", errors="replace", timeout=10, check=False, stdin=subprocess.DEVNULL, diff --git a/tools/environments/local.py b/tools/environments/local.py index fe83ae2a6104..701b1951e2f0 100644 --- a/tools/environments/local.py +++ b/tools/environments/local.py @@ -764,7 +764,7 @@ def _mandatory_aslr_enabled() -> "bool | None": "(Get-ProcessMitigation -System).Aslr.ForceRelocateImages.ToString()", ], capture_output=True, - text=True, + text=True, encoding="utf-8", errors="replace", timeout=10, creationflags=windows_hide_flags(), ) @@ -830,7 +830,7 @@ def _bash_starts(bash: str) -> bool: result = subprocess.run( [bash, "--noprofile", "--norc", "-c", _BASH_EXTERNAL_PROGRAM_PROBE], capture_output=True, - text=True, + text=True, encoding="utf-8", errors="replace", timeout=15, creationflags=windows_hide_flags() if _IS_WINDOWS else 0, )