fix: add explicit UTF-8 encoding to all subprocess text=True calls (#53428)

On Windows with Chinese locale (GBK), subprocess.run(text=True) without
explicit encoding causes UnicodeDecodeError crashes. This fix adds
encoding='utf-8', errors='replace' to all subprocess.run() and
subprocess.Popen() calls that use text=True across 76 non-test Python files.

Fixes #53428 (master tracker for Windows GBK locale crash).

Note: credential_pool.py and electron changes excluded per reviewer request —
those will be submitted as separate focused PRs.
This commit is contained in:
Stoltemberg
2026-06-29 23:42:46 -03:00
committed by Teknium
parent d460118a1d
commit c89481db5e
61 changed files with 161 additions and 161 deletions
+2 -2
View File
@@ -368,7 +368,7 @@ def _detect_claude_code_version() -> str:
try:
result = _sp.run(
[cmd, "--version"],
capture_output=True, text=True, timeout=5,
capture_output=True, text=True, encoding='utf-8', errors='replace', timeout=5,
)
if result.returncode == 0 and result.stdout.strip():
# Output is like "2.1.74 (Claude Code)" or just "2.1.74"
@@ -914,7 +914,7 @@ def _read_claude_code_credentials_from_keychain() -> Optional[Dict[str, Any]]:
"-s", "Claude Code-credentials",
"-w"],
capture_output=True,
text=True,
text=True, encoding='utf-8', errors='replace',
timeout=5,
stdin=subprocess.DEVNULL,
)
+2 -2
View File
@@ -308,7 +308,7 @@ def _expand_git_reference(
["git", *args],
cwd=cwd,
capture_output=True,
text=True,
text=True, encoding='utf-8', errors='replace',
timeout=30,
stdin=subprocess.DEVNULL,
**_popen_kwargs,
@@ -534,7 +534,7 @@ def _rg_files(path: Path, cwd: Path, limit: int) -> list[Path] | None:
["rg", "--files", str(path.relative_to(cwd))],
cwd=cwd,
capture_output=True,
text=True,
text=True, encoding='utf-8', errors='replace',
timeout=10,
stdin=subprocess.DEVNULL,
**_popen_kwargs,
+1 -1
View File
@@ -512,7 +512,7 @@ class CopilotACPClient:
stdin=subprocess.PIPE,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE,
text=True,
text=True, encoding='utf-8', errors='replace',
bufsize=1,
cwd=self._acp_cwd,
env=_build_subprocess_env(),
+2 -2
View File
@@ -200,7 +200,7 @@ def _platform_asset_name() -> str:
res = subprocess.run(
["ldd", "--version"],
capture_output=True,
text=True,
text=True, encoding='utf-8', errors='replace',
timeout=2,
stdin=subprocess.DEVNULL,
)
@@ -684,7 +684,7 @@ def _run_bws_list(
cmd,
env=env,
capture_output=True,
text=True,
text=True, encoding='utf-8', errors='replace',
timeout=_BWS_RUN_TIMEOUT,
stdin=subprocess.DEVNULL,
)
+1 -1
View File
@@ -464,7 +464,7 @@ def _spawn(spec: ShellHookSpec, stdin_json: str) -> Dict[str, Any]:
input=stdin_json,
capture_output=True,
timeout=spec.timeout,
text=True,
text=True, encoding='utf-8', errors='replace',
shell=False,
**_popen_kwargs,
)
+1 -1
View File
@@ -74,7 +74,7 @@ def run_inline_shell(command: str, cwd: Path | None, timeout: int) -> str:
["bash", "-c", command],
cwd=str(cwd) if cwd else None,
capture_output=True,
text=True,
text=True, encoding='utf-8', errors='replace',
timeout=max(1, int(timeout)),
check=False,
stdin=subprocess.DEVNULL,
+1 -1
View File
@@ -394,7 +394,7 @@ def check_codex_binary(
proc = subprocess.run(
[codex_bin, "--version"],
capture_output=True,
text=True,
text=True, encoding='utf-8', errors='replace',
timeout=10,
stdin=subprocess.DEVNULL,
)
+1 -1
View File
@@ -282,7 +282,7 @@ def _process_single_prompt(
print(f" Prompt {prompt_index}: Pulling docker image {container_image}...", flush=True)
pull = _sp.run(
["docker", "pull", container_image],
capture_output=True, text=True, timeout=600,
capture_output=True, text=True, encoding='utf-8', errors='replace', timeout=600,
)
if pull.returncode != 0:
return {
+1 -1
View File
@@ -2301,7 +2301,7 @@ def _run_job_script(script_path: str) -> tuple[bool, str]:
result = subprocess.run(
argv,
capture_output=True,
text=True,
text=True, encoding='utf-8', errors='replace',
timeout=script_timeout,
cwd=str(path.parent),
env=env,
+1 -1
View File
@@ -250,7 +250,7 @@ def _detect_macos_system_proxy() -> str | None:
return None
try:
out = subprocess.check_output(
["scutil", "--proxy"], timeout=3, text=True, stderr=subprocess.DEVNULL,
["scutil", "--proxy"], timeout=3, text=True, encoding='utf-8', errors='replace', stderr=subprocess.DEVNULL,
)
except Exception:
return None
+1 -1
View File
@@ -1259,7 +1259,7 @@ class WebhookAdapter(BasePlatformAdapter):
content,
],
capture_output=True,
text=True,
text=True, encoding='utf-8', errors='replace',
timeout=30,
)
if result.returncode == 0:
+1 -1
View File
@@ -368,7 +368,7 @@ def check_systemd_timing_alignment(drain_timeout: float) -> Optional[Dict[str, A
try:
result = subprocess.run(
["systemctl", *flag, "show", unit_name, "--property=TimeoutStopUSec"],
capture_output=True, text=True, timeout=2.0,
capture_output=True, text=True, encoding='utf-8', errors='replace', timeout=2.0,
)
except (FileNotFoundError, subprocess.TimeoutExpired, OSError):
continue
+3 -3
View File
@@ -258,7 +258,7 @@ def terminate_pid(pid: int, *, force: bool = False) -> None:
result = subprocess.run(
["taskkill", "/PID", str(pid), "/T", "/F"],
capture_output=True,
text=True,
text=True, encoding='utf-8', errors='replace',
timeout=10,
creationflags=windows_hide_flags(),
)
@@ -344,7 +344,7 @@ def _read_process_cmdline(pid: int) -> Optional[str]:
result = subprocess.run(
["ps", "-p", str(pid), "-o", "command="],
capture_output=True,
text=True,
text=True, encoding='utf-8', errors='replace',
timeout=5,
)
if result.returncode == 0 and result.stdout.strip():
@@ -827,7 +827,7 @@ def _pid_exists(pid: int) -> bool:
r = subprocess.run(
["ps", "-o", "state=", "-p", str(int(pid))],
capture_output=True,
text=True,
text=True, encoding='utf-8', errors='replace',
timeout=5,
)
if r.returncode == 0 and r.stdout.strip().startswith("Z"):
+4 -4
View File
@@ -68,7 +68,7 @@ def _detect_openclaw_processes() -> list[str]:
try:
result = subprocess.run(
["systemctl", "--user", "is-active", "openclaw-gateway.service"],
capture_output=True, text=True, timeout=5,
capture_output=True, text=True, encoding='utf-8', errors='replace', timeout=5,
)
if result.stdout.strip() == "active":
found.append("systemd service: openclaw-gateway.service")
@@ -81,7 +81,7 @@ def _detect_openclaw_processes() -> list[str]:
for exe in ("openclaw.exe", "clawd.exe"):
result = subprocess.run(
["tasklist", "/FI", f"IMAGENAME eq {exe}"],
capture_output=True, text=True, timeout=5,
capture_output=True, text=True, encoding='utf-8', errors='replace', timeout=5,
)
if exe in result.stdout.lower():
found.append(f"process: {exe}")
@@ -95,7 +95,7 @@ def _detect_openclaw_processes() -> list[str]:
)
result = subprocess.run(
["powershell", "-NoProfile", "-Command", ps_cmd],
capture_output=True, text=True, timeout=5,
capture_output=True, text=True, encoding='utf-8', errors='replace', timeout=5,
)
if result.stdout.strip():
found.append(f"node.exe process with openclaw in command line (PID {result.stdout.strip()})")
@@ -105,7 +105,7 @@ def _detect_openclaw_processes() -> list[str]:
try:
result = subprocess.run(
["pgrep", "-f", "openclaw"],
capture_output=True, text=True, timeout=3,
capture_output=True, text=True, encoding='utf-8', errors='replace', timeout=3,
)
if result.returncode == 0:
pids = result.stdout.strip().split()
+8 -8
View File
@@ -67,7 +67,7 @@ def _macos_has_image() -> bool:
try:
info = subprocess.run(
["osascript", "-e", "clipboard info"],
capture_output=True, text=True, timeout=3,
capture_output=True, text=True, encoding='utf-8', errors='replace', timeout=3,
)
return "«class PNGf»" in info.stdout or "«class TIFF»" in info.stdout
except Exception:
@@ -109,7 +109,7 @@ def _macos_osascript(dest: Path) -> bool:
try:
r = subprocess.run(
["osascript", "-e", script],
capture_output=True, text=True, timeout=5,
capture_output=True, text=True, encoding='utf-8', errors='replace', timeout=5,
)
if r.returncode == 0 and "fail" not in r.stdout and dest.exists() and dest.stat().st_size > 0:
return True
@@ -200,7 +200,7 @@ _POWERSHELL_EXTRACT_IMAGE_SCRIPTS = (
def _run_powershell(exe: str, script: str, timeout: int) -> subprocess.CompletedProcess:
return subprocess.run(
[exe, "-NoProfile", "-NonInteractive", "-Command", script],
capture_output=True, text=True, timeout=timeout,
capture_output=True, text=True, encoding='utf-8', errors='replace', timeout=timeout,
)
@@ -258,7 +258,7 @@ def _find_powershell() -> str | None:
try:
r = subprocess.run(
[name, "-NoProfile", "-NonInteractive", "-Command", "echo ok"],
capture_output=True, text=True, timeout=5,
capture_output=True, text=True, encoding='utf-8', errors='replace', timeout=5,
)
if r.returncode == 0 and "ok" in r.stdout:
return name
@@ -333,7 +333,7 @@ def _wayland_has_image() -> bool:
try:
r = subprocess.run(
["wl-paste", "--list-types"],
capture_output=True, text=True, timeout=3,
capture_output=True, text=True, encoding='utf-8', errors='replace', timeout=3,
)
return r.returncode == 0 and any(
t.startswith("image/") for t in r.stdout.splitlines()
@@ -351,7 +351,7 @@ def _wayland_save(dest: Path) -> bool:
# Check available MIME types
types_r = subprocess.run(
["wl-paste", "--list-types"],
capture_output=True, text=True, timeout=3,
capture_output=True, text=True, encoding='utf-8', errors='replace', timeout=3,
)
if types_r.returncode != 0:
return False
@@ -453,7 +453,7 @@ def _xclip_has_image() -> bool:
try:
r = subprocess.run(
["xclip", "-selection", "clipboard", "-t", "TARGETS", "-o"],
capture_output=True, text=True, timeout=3,
capture_output=True, text=True, encoding='utf-8', errors='replace', timeout=3,
)
return r.returncode == 0 and "image/png" in r.stdout
except FileNotFoundError:
@@ -469,7 +469,7 @@ def _xclip_save(dest: Path) -> bool:
try:
targets = subprocess.run(
["xclip", "-selection", "clipboard", "-t", "TARGETS", "-o"],
capture_output=True, text=True, timeout=3,
capture_output=True, text=True, encoding='utf-8', errors='replace', timeout=3,
)
if "image/png" not in targets.stdout:
return False
+1 -1
View File
@@ -1669,7 +1669,7 @@ class SlashCommandCompleter(Completer):
continue
try:
proc = subprocess.run(
cmd, capture_output=True, text=True, timeout=2,
cmd, capture_output=True, text=True, encoding='utf-8', errors='replace', timeout=2,
cwd=cwd, encoding="utf-8", errors="replace",
)
if proc.returncode == 0 and proc.stdout and proc.stdout.strip():
+1 -1
View File
@@ -147,7 +147,7 @@ def _try_gh_cli_token() -> Optional[str]:
result = subprocess.run(
cmd,
capture_output=True,
text=True,
text=True, encoding='utf-8', errors='replace',
timeout=5,
env=clean_env,
**_popen_kwargs,
+2 -2
View File
@@ -1672,7 +1672,7 @@ def run_doctor(args):
result = subprocess.run(
cmd,
capture_output=True,
text=True,
text=True, encoding='utf-8', errors='replace',
timeout=15
)
except subprocess.TimeoutExpired:
@@ -1836,7 +1836,7 @@ def run_doctor(args):
audit_result = subprocess.run(
[_npm_bin, "audit", "--json", *audit_extra],
cwd=str(npm_dir),
capture_output=True, text=True, timeout=30,
capture_output=True, text=True, encoding='utf-8', errors='replace', timeout=30,
)
import json as _json
audit_data = _json.loads(audit_result.stdout) if audit_result.stdout.strip() else {}
+2 -2
View File
@@ -64,7 +64,7 @@ def _get_git_commit(project_root: Path) -> str:
try:
result = subprocess.run(
["git", "rev-parse", "--short=8", "HEAD"],
capture_output=True, text=True, timeout=5,
capture_output=True, text=True, encoding='utf-8', errors='replace', timeout=5,
cwd=str(project_root),
)
if result.returncode == 0:
@@ -99,7 +99,7 @@ def _get_git_commit_date(project_root: Path) -> str:
try:
result = subprocess.run(
["git", "log", "-1", "--format=%cd", "--date=short", "HEAD"],
capture_output=True, text=True, timeout=5,
capture_output=True, text=True, encoding='utf-8', errors='replace', timeout=5,
cwd=str(project_root),
)
if result.returncode == 0:
+21 -21
View File
@@ -118,7 +118,7 @@ def _get_service_pids() -> set:
"--no-pager",
],
capture_output=True,
text=True,
text=True, encoding='utf-8', errors='replace',
timeout=5,
)
for line in result.stdout.strip().splitlines():
@@ -130,7 +130,7 @@ def _get_service_pids() -> set:
show = subprocess.run(
scope_args + ["show", svc, "--property=MainPID", "--value"],
capture_output=True,
text=True,
text=True, encoding='utf-8', errors='replace',
timeout=5,
)
pid = int(show.stdout.strip())
@@ -148,7 +148,7 @@ def _get_service_pids() -> set:
result = subprocess.run(
["launchctl", "list", label],
capture_output=True,
text=True,
text=True, encoding='utf-8', errors='replace',
timeout=5,
)
if result.returncode == 0:
@@ -204,7 +204,7 @@ def _get_parent_pid(pid: int) -> int | None:
result = subprocess.run(
["ps", "-o", "ppid=", "-p", str(pid)],
capture_output=True,
text=True,
text=True, encoding='utf-8', errors='replace',
timeout=5,
)
except (FileNotFoundError, subprocess.TimeoutExpired):
@@ -421,7 +421,7 @@ def _scan_gateway_pids(
"/FORMAT:LIST",
],
capture_output=True,
text=True,
text=True, encoding='utf-8', errors='replace',
encoding="utf-8",
errors="ignore",
timeout=10,
@@ -447,7 +447,7 @@ def _scan_gateway_pids(
result = subprocess.run(
[powershell, "-NoProfile", "-Command", ps_cmd],
capture_output=True,
text=True,
text=True, encoding='utf-8', errors='replace',
encoding="utf-8",
errors="ignore",
timeout=15,
@@ -504,7 +504,7 @@ def _scan_gateway_pids(
result = subprocess.run(
["ps", "-A", "eww", "-o", "pid=,command="],
capture_output=True,
text=True,
text=True, encoding='utf-8', errors='replace',
timeout=10,
)
if result.returncode != 0:
@@ -911,7 +911,7 @@ def _probe_systemd_service_running(system: bool = False) -> tuple[bool, bool]:
["is-active", get_service_name()],
system=selected_system,
capture_output=True,
text=True,
text=True, encoding='utf-8', errors='replace',
timeout=10,
)
except (RuntimeError, subprocess.TimeoutExpired):
@@ -938,7 +938,7 @@ def _read_systemd_unit_environment(system: bool = False) -> dict[str, str]:
],
system=selected_system,
capture_output=True,
text=True,
text=True, encoding='utf-8', errors='replace',
timeout=10,
)
except (RuntimeError, subprocess.TimeoutExpired, OSError):
@@ -1031,7 +1031,7 @@ def _read_systemd_unit_properties(
],
system=selected_system,
capture_output=True,
text=True,
text=True, encoding='utf-8', errors='replace',
timeout=10,
)
except (RuntimeError, subprocess.TimeoutExpired, OSError):
@@ -1288,7 +1288,7 @@ def _probe_launchd_service_running() -> bool:
result = subprocess.run(
["launchctl", "list", get_launchd_label()],
capture_output=True,
text=True,
text=True, encoding='utf-8', errors='replace',
timeout=10,
)
except subprocess.TimeoutExpired:
@@ -1646,7 +1646,7 @@ def _systemd_operational(system: bool = False) -> bool:
["is-system-running"],
system=system,
capture_output=True,
text=True,
text=True, encoding='utf-8', errors='replace',
timeout=5,
)
# "running", "degraded", "starting" all mean systemd is PID 1
@@ -1955,7 +1955,7 @@ def _preflight_user_systemd(*, auto_enable_linger: bool = True) -> None:
result = subprocess.run(
["loginctl", "enable-linger", username],
capture_output=True,
text=True,
text=True, encoding='utf-8', errors='replace',
check=False,
timeout=30,
)
@@ -2432,7 +2432,7 @@ def get_systemd_linger_status() -> tuple[bool | None, str]:
result = subprocess.run(
["loginctl", "show-user", username, "--property=Linger", "--value"],
capture_output=True,
text=True,
text=True, encoding='utf-8', errors='replace',
check=False,
timeout=10,
)
@@ -3115,7 +3115,7 @@ def _ensure_linger_enabled() -> None:
result = subprocess.run(
["loginctl", "enable-linger", username],
capture_output=True,
text=True,
text=True, encoding='utf-8', errors='replace',
check=False,
timeout=30,
)
@@ -3498,7 +3498,7 @@ def systemd_status(deep: bool = False, system: bool = False, full: bool = False)
["is-active", get_service_name()],
system=system,
capture_output=True,
text=True,
text=True, encoding='utf-8', errors='replace',
timeout=10,
)
@@ -3646,7 +3646,7 @@ def _launchd_domain() -> str:
result = subprocess.run(
["launchctl", "managername"],
capture_output=True,
text=True,
text=True, encoding='utf-8', errors='replace',
timeout=5,
)
if "Aqua" in (result.stdout or ""):
@@ -4479,7 +4479,7 @@ def launchd_status(deep: bool = False):
result = subprocess.run(
["launchctl", "list", label],
capture_output=True,
text=True,
text=True, encoding='utf-8', errors='replace',
timeout=10,
)
service_listed = result.returncode == 0
@@ -5650,7 +5650,7 @@ def _is_service_running() -> bool:
["is-active", get_service_name()],
system=False,
capture_output=True,
text=True,
text=True, encoding='utf-8', errors='replace',
timeout=10,
)
if result.stdout.strip() == "active":
@@ -5664,7 +5664,7 @@ def _is_service_running() -> bool:
["is-active", get_service_name()],
system=True,
capture_output=True,
text=True,
text=True, encoding='utf-8', errors='replace',
timeout=10,
)
if result.stdout.strip() == "active":
@@ -5678,7 +5678,7 @@ def _is_service_running() -> bool:
result = subprocess.run(
["launchctl", "list", get_launchd_label()],
capture_output=True,
text=True,
text=True, encoding='utf-8', errors='replace',
timeout=10,
)
return result.returncode == 0
+1 -1
View File
@@ -160,7 +160,7 @@ def _exec_schtasks(args: list[str]) -> tuple[int, str, str]:
proc = subprocess.run(
[schtasks, *args],
capture_output=True,
text=True,
text=True, encoding='utf-8', errors='replace',
# Localized Windows emits schtasks output in the console code page,
# not UTF-8. Decode with the locale encoding and replace undecodable
# bytes so a non-UTF-8 status line never surfaces a UnicodeDecodeError
+8 -8
View File
@@ -5212,7 +5212,7 @@ def _cleanup_worker_tmux(conn: sqlite3.Connection, task_id: str) -> None:
# Check if session exists and pane is dead before killing
out = subprocess.run(
["tmux", "list-panes", "-t", session, "-F", "#{pane_dead}"],
capture_output=True, text=True, timeout=5,
capture_output=True, text=True, encoding='utf-8', errors='replace', timeout=5,
)
if out.stdout.strip() == "1":
subprocess.run(
@@ -6138,7 +6138,7 @@ def _git_toplevel(path: Path) -> Optional[Path]:
result = subprocess.run(
["git", "-C", str(path), "rev-parse", "--show-toplevel"],
capture_output=True,
text=True,
text=True, encoding='utf-8', errors='replace',
timeout=30,
check=False,
)
@@ -6160,7 +6160,7 @@ def _git_branch_exists(repo_root: Path, branch_name: str) -> bool:
result = subprocess.run(
["git", "-C", str(repo_root), "show-ref", "--verify", f"refs/heads/{branch_name}"],
capture_output=True,
text=True,
text=True, encoding='utf-8', errors='replace',
timeout=30,
check=False,
)
@@ -6174,7 +6174,7 @@ def _git_common_dir(path: Path) -> Optional[Path]:
result = subprocess.run(
["git", "-C", str(path), "rev-parse", "--path-format=absolute", "--git-common-dir"],
capture_output=True,
text=True,
text=True, encoding='utf-8', errors='replace',
timeout=30,
check=False,
)
@@ -6193,7 +6193,7 @@ def _git_dir(path: Path) -> Optional[Path]:
result = subprocess.run(
["git", "-C", str(path), "rev-parse", "--path-format=absolute", "--git-dir"],
capture_output=True,
text=True,
text=True, encoding='utf-8', errors='replace',
timeout=30,
check=False,
)
@@ -6212,7 +6212,7 @@ def _git_current_branch(path: Path) -> Optional[str]:
result = subprocess.run(
["git", "-C", str(path), "branch", "--show-current"],
capture_output=True,
text=True,
text=True, encoding='utf-8', errors='replace',
timeout=30,
check=False,
)
@@ -6269,7 +6269,7 @@ def _ensure_git_worktree(repo_root: Path, target: Path, branch_name: str) -> Non
result = subprocess.run(
cmd,
capture_output=True,
text=True,
text=True, encoding='utf-8', errors='replace',
timeout=60,
check=False,
)
@@ -6765,7 +6765,7 @@ def _pid_alive(pid: Optional[int]) -> bool:
["ps", "-o", "stat=", "-p", str(int(pid))],
stdout=subprocess.PIPE,
stderr=subprocess.DEVNULL,
text=True,
text=True, encoding='utf-8', errors='replace',
timeout=1,
check=False,
)
+3 -3
View File
@@ -115,7 +115,7 @@ def _ensure_uv_path() -> Optional[str]:
version = subprocess.run(
[result, "--version"],
capture_output=True,
text=True,
text=True, encoding='utf-8', errors='replace',
check=False,
).stdout.strip()
print(f" ✓ Managed uv installed ({version})")
@@ -170,14 +170,14 @@ def update_managed_uv() -> Optional[str]:
result = subprocess.run(
[existing, "self", "update"],
capture_output=True,
text=True,
text=True, encoding='utf-8', errors='replace',
check=False,
)
if result.returncode == 0:
version = subprocess.run(
[existing, "--version"],
capture_output=True,
text=True,
text=True, encoding='utf-8', errors='replace',
check=False,
).stdout.strip()
print(f" ✓ Managed uv updated ({version})")
+2 -2
View File
@@ -472,7 +472,7 @@ def _install_plugin_core(identifier: str, *, force: bool) -> tuple[Path, dict, s
result = subprocess.run(
[git_exe, "clone", "--depth", "1", git_url, str(tmp_clone)],
capture_output=True,
text=True,
text=True, encoding='utf-8', errors='replace',
timeout=60,
)
except FileNotFoundError as e:
@@ -1969,7 +1969,7 @@ def _git_pull_plugin_dir(target: Path) -> tuple[bool, str]:
result = subprocess.run(
[git_exe, "pull", "--ff-only"],
capture_output=True,
text=True,
text=True, encoding='utf-8', errors='replace',
timeout=60,
cwd=str(target),
)
+2 -2
View File
@@ -406,7 +406,7 @@ def check_alias_collision(name: str) -> Optional[str]:
try:
result = subprocess.run(
["where" if is_windows else "which", canon],
capture_output=True, text=True, timeout=5,
capture_output=True, text=True, encoding='utf-8', errors='replace', timeout=5,
)
if result.returncode == 0:
existing_path = result.stdout.strip().splitlines()[0]
@@ -1206,7 +1206,7 @@ def seed_profile_skills(profile_dir: Path, quiet: bool = False) -> Optional[dict
"r = sync_skills(quiet=True); print(json.dumps(r))"],
env={**os.environ, "HERMES_HOME": str(profile_dir)},
cwd=str(project_root),
capture_output=True, text=True, timeout=60,
capture_output=True, text=True, encoding='utf-8', errors='replace', timeout=60,
)
if result.returncode == 0 and result.stdout.strip():
return json.loads(result.stdout.strip())
+2 -2
View File
@@ -562,7 +562,7 @@ def _bws_version(binary: Path) -> str:
res = subprocess.run(
[str(binary), "--version"],
capture_output=True,
text=True,
text=True, encoding='utf-8', errors='replace',
timeout=5,
)
if res.returncode == 0:
@@ -618,7 +618,7 @@ def _list_projects(
[str(binary), "project", "list", "--output", "json"],
env=env,
capture_output=True,
text=True,
text=True, encoding='utf-8', errors='replace',
timeout=15,
)
except (OSError, subprocess.TimeoutExpired) as exc:
+7 -7
View File
@@ -838,7 +838,7 @@ class S6ServiceManager:
try:
subprocess.run(
[f"{_S6_BIN_DIR}/s6-svc", action_flag, str(service_dir)],
check=True, capture_output=True, text=True, timeout=5,
check=True, capture_output=True, text=True, encoding='utf-8', errors='replace', timeout=5,
)
except subprocess.CalledProcessError as exc:
raise S6CommandError(
@@ -873,7 +873,7 @@ class S6ServiceManager:
try:
result = subprocess.run(
[f"{_S6_BIN_DIR}/s6-svstat", str(self.scandir / name)],
capture_output=True, text=True, timeout=5,
capture_output=True, text=True, encoding='utf-8', errors='replace', timeout=5,
)
except (OSError, subprocess.SubprocessError):
return None
@@ -926,7 +926,7 @@ class S6ServiceManager:
import subprocess
result = subprocess.run(
[f"{_S6_BIN_DIR}/s6-svstat", str(self.scandir / name)],
capture_output=True, text=True, timeout=5,
capture_output=True, text=True, encoding='utf-8', errors='replace', timeout=5,
)
return result.returncode == 0 and "up " in result.stdout
@@ -1029,7 +1029,7 @@ class S6ServiceManager:
# Trigger rescan so s6-svscan picks up the new service.
result = subprocess.run(
[f"{_S6_BIN_DIR}/s6-svscanctl", "-a", str(self.scandir)],
capture_output=True, text=True, timeout=5,
capture_output=True, text=True, encoding='utf-8', errors='replace', timeout=5,
)
if result.returncode != 0:
# Clean up: rescan failed, leave the directory in place would
@@ -1066,13 +1066,13 @@ class S6ServiceManager:
# Stop the service (best effort — service may already be down).
subprocess.run(
[f"{_S6_BIN_DIR}/s6-svc", "-d", str(svc_dir)],
capture_output=True, text=True, timeout=5,
capture_output=True, text=True, encoding='utf-8', errors='replace', timeout=5,
check=False,
)
# Wait for it to actually go down (up to 10s).
subprocess.run(
[f"{_S6_BIN_DIR}/s6-svwait", "-D", "-t", "10000", str(svc_dir)],
capture_output=True, text=True, timeout=15,
capture_output=True, text=True, encoding='utf-8', errors='replace', timeout=15,
check=False,
)
@@ -1084,7 +1084,7 @@ class S6ServiceManager:
# files inside the slot, so the upcoming rmtree doesn't race.
subprocess.run(
[f"{_S6_BIN_DIR}/s6-svscanctl", "-an", str(self.scandir)],
capture_output=True, text=True, timeout=5,
capture_output=True, text=True, encoding='utf-8', errors='replace', timeout=5,
check=False,
)
# Give s6-svscan a moment to reap. There's no synchronous
+1 -1
View File
@@ -465,7 +465,7 @@ def _uninstall_profile(profile) -> None:
subprocess.run(
hermes_invocation + ["gateway", subcmd],
capture_output=True,
text=True,
text=True, encoding='utf-8', errors='replace',
timeout=60,
check=False,
)
+2 -2
View File
@@ -37,7 +37,7 @@ def _git(cwd: str, args: list[str], *, timeout: int = _GIT_TIMEOUT) -> tuple[int
["git", *args],
cwd=cwd,
capture_output=True,
text=True,
text=True, encoding='utf-8', errors='replace',
timeout=timeout,
)
except (OSError, subprocess.SubprocessError):
@@ -421,7 +421,7 @@ def _gh(cwd: str, args: list[str]) -> tuple[bool, str]:
return False, ""
try:
proc = subprocess.run(
["gh", *args], cwd=cwd, capture_output=True, text=True, timeout=_GH_TIMEOUT
["gh", *args], cwd=cwd, capture_output=True, text=True, encoding='utf-8', errors='replace', timeout=_GH_TIMEOUT
)
except (OSError, subprocess.SubprocessError):
return False, ""
+1 -1
View File
@@ -59,7 +59,7 @@ def _save_subscriptions(subs: Dict[str, dict]) -> None:
prefix=f".{path.name}.",
suffix=".tmp",
dir=path.parent,
text=True,
text=True, encoding='utf-8', errors='replace',
)
tmp_path = Path(tmp_name)
try:
@@ -36,7 +36,7 @@ def kanban_list(tenant: str) -> list[dict]:
try:
out = subprocess.run(
["hermes", "kanban", "list", "--tenant", tenant, "--json"],
capture_output=True, text=True, check=False,
capture_output=True, text=True, encoding='utf-8', errors='replace', check=False,
)
if out.returncode == 0 and out.stdout.strip().startswith("["):
return json.loads(out.stdout)
@@ -45,7 +45,7 @@ def kanban_list(tenant: str) -> list[dict]:
# Fallback: textual parse of `hermes kanban list`
out = subprocess.run(
["hermes", "kanban", "list", "--tenant", tenant],
capture_output=True, text=True, check=False,
capture_output=True, text=True, encoding='utf-8', errors='replace', check=False,
)
rows = []
for line in out.stdout.splitlines():
@@ -69,7 +69,7 @@ def kanban_list(tenant: str) -> list[dict]:
def kanban_show(task_id: str) -> dict | None:
out = subprocess.run(
["hermes", "kanban", "show", task_id, "--json"],
capture_output=True, text=True, check=False,
capture_output=True, text=True, encoding='utf-8', errors='replace', check=False,
)
if out.returncode != 0:
return None
+3 -3
View File
@@ -111,7 +111,7 @@ class AudioBridge:
],
check=True,
capture_output=True,
text=True,
text=True, encoding='utf-8', errors='replace',
stdin=subprocess.DEVNULL,
)
except FileNotFoundError as exc:
@@ -136,7 +136,7 @@ class AudioBridge:
],
check=True,
capture_output=True,
text=True,
text=True, encoding='utf-8', errors='replace',
stdin=subprocess.DEVNULL,
)
except subprocess.CalledProcessError as exc:
@@ -172,7 +172,7 @@ class AudioBridge:
try:
out = subprocess.check_output(
["system_profiler", "SPAudioDataType"],
text=True,
text=True, encoding='utf-8', errors='replace',
stderr=subprocess.STDOUT,
)
except FileNotFoundError as exc:
+1 -1
View File
@@ -293,7 +293,7 @@ def _cmd_install(*, realtime: bool, assume_yes: bool) -> int:
elif system == "Darwin":
have_bh = False
try:
out = _sp.check_output(["system_profiler", "SPAudioDataType"], text=True)
out = _sp.check_output(["system_profiler", "SPAudioDataType"], text=True, encoding='utf-8', errors='replace')
have_bh = "BlackHole" in out
except Exception:
pass
+1 -1
View File
@@ -425,7 +425,7 @@ def _mac_audio_device_index(device_name: str) -> str:
out = _sp.run(
["ffmpeg", "-f", "avfoundation", "-list_devices", "true", "-i", ""],
capture_output=True,
text=True,
text=True, encoding='utf-8', errors='replace',
timeout=10,
)
except Exception:
+1 -1
View File
@@ -140,7 +140,7 @@ def _run_brv(args: List[str], timeout: int = _QUERY_TIMEOUT,
try:
result = subprocess.run(
cmd, capture_output=True, text=True,
cmd, capture_output=True, text=True, encoding='utf-8', errors='replace',
timeout=timeout, cwd=effective_cwd, env=env,
stdin=subprocess.DEVNULL,
)
+1 -1
View File
@@ -742,7 +742,7 @@ class HonchoClientConfig:
try:
root = subprocess.run(
["git", "rev-parse", "--show-toplevel"],
capture_output=True, text=True, cwd=cwd, timeout=5,
capture_output=True, text=True, encoding='utf-8', errors='replace', cwd=cwd, timeout=5,
stdin=subprocess.DEVNULL,
)
if root.returncode == 0:
+1 -1
View File
@@ -525,7 +525,7 @@ def _ensure_pgvector(host: str = "localhost", port: int = 5432) -> dict | None:
try:
result = subprocess.run(
["docker", "inspect", _PGVECTOR_CONTAINER, "--format", "{{.State.Status}}"],
capture_output=True, text=True, timeout=10, stdin=subprocess.DEVNULL,
capture_output=True, text=True, encoding='utf-8', errors='replace', timeout=10, stdin=subprocess.DEVNULL,
)
if result.returncode == 0 and "exited" in result.stdout:
print(f" Found stopped container '{_PGVECTOR_CONTAINER}', restarting...")
+3 -3
View File
@@ -834,7 +834,7 @@ class PhotonAdapter(BasePlatformAdapter):
try:
out = subprocess.run( # noqa: S603, S607
["lsof", "-ti", f"tcp:{port}", "-sTCP:LISTEN"],
capture_output=True, text=True, timeout=5.0, check=False,
capture_output=True, text=True, encoding='utf-8', errors='replace', timeout=5.0, check=False,
)
except (OSError, subprocess.TimeoutExpired):
return []
@@ -846,7 +846,7 @@ class PhotonAdapter(BasePlatformAdapter):
try:
out = subprocess.run( # noqa: S603, S607
["ps", "-p", str(pid), "-o", "command="],
capture_output=True, text=True, timeout=5.0, check=False,
capture_output=True, text=True, encoding='utf-8', errors='replace', timeout=5.0, check=False,
)
except (OSError, subprocess.TimeoutExpired):
return False
@@ -962,7 +962,7 @@ class PhotonAdapter(BasePlatformAdapter):
str(_SIDECAR_DIR),
],
capture_output=True,
text=True,
text=True, encoding='utf-8', errors='replace',
timeout=10,
check=False,
# Windows: suppress the brief console flash this short-lived
+6 -6
View File
@@ -55,7 +55,7 @@ def _listener_pids_on_port(port: int) -> list:
try:
result = subprocess.run(
["lsof", "-ti", f"tcp:{port}", "-sTCP:LISTEN"],
capture_output=True, text=True, timeout=5,
capture_output=True, text=True, encoding='utf-8', errors='replace', timeout=5,
)
for line in result.stdout.strip().splitlines():
try:
@@ -70,7 +70,7 @@ def _listener_pids_on_port(port: int) -> list:
try:
result = subprocess.run(
["ss", "-ltnHp", f"sport = :{port}"],
capture_output=True, text=True, timeout=5,
capture_output=True, text=True, encoding='utf-8', errors='replace', timeout=5,
)
for m in re.finditer(r"pid=(\d+)", result.stdout):
pids.append(int(m.group(1)))
@@ -88,7 +88,7 @@ def _kill_port_process(port: int) -> None:
# Use netstat to find the PID bound to this port, then taskkill
result = subprocess.run(
["netstat", "-ano", "-p", "TCP"],
capture_output=True, text=True, timeout=5,
capture_output=True, text=True, encoding='utf-8', errors='replace', timeout=5,
creationflags=windows_hide_flags(),
)
for line in result.stdout.splitlines():
@@ -223,7 +223,7 @@ def _terminate_bridge_process(proc, *, force: bool = False) -> None:
result = subprocess.run(
cmd,
capture_output=True,
text=True,
text=True, encoding='utf-8', errors='replace',
timeout=10,
)
except FileNotFoundError:
@@ -349,7 +349,7 @@ def check_whatsapp_requirements() -> bool:
result = subprocess.run(
[_node, "--version"],
capture_output=True,
text=True,
text=True, encoding='utf-8', errors='replace',
timeout=5
)
return result.returncode == 0
@@ -547,7 +547,7 @@ class WhatsAppAdapter(WhatsAppBehaviorMixin, BasePlatformAdapter):
[_npm_bin, "install", "--silent"],
cwd=str(bridge_dir),
capture_output=True,
text=True,
text=True, encoding='utf-8', errors='replace',
timeout=npm_install_timeout,
env=with_hermes_node_path(),
)
+1 -1
View File
@@ -170,7 +170,7 @@ class ExaWebSearchProvider(WebSearchProvider):
]
logger.info("Exa extract: %d URL(s)", len(urls))
response = _get_exa_client().get_contents(urls, text=True)
response = _get_exa_client().get_contents(urls, text=True, encoding='utf-8', errors='replace')
results: List[Dict[str, Any]] = []
for result in response.results or []:
+2 -2
View File
@@ -492,7 +492,7 @@ def get_staged_files() -> list[Path]:
["git", "diff", "--cached", "--name-only", "--diff-filter=ACMR"],
cwd=REPO_ROOT,
stderr=subprocess.DEVNULL,
text=True,
text=True, encoding='utf-8', errors='replace',
)
except (subprocess.CalledProcessError, FileNotFoundError):
return []
@@ -506,7 +506,7 @@ def get_diff_files(ref: str) -> list[Path]:
["git", "diff", f"{ref}...HEAD", "--name-only", "--diff-filter=ACMR"],
cwd=REPO_ROOT,
stderr=subprocess.DEVNULL,
text=True,
text=True, encoding='utf-8', errors='replace',
)
except (subprocess.CalledProcessError, FileNotFoundError):
return []
+2 -2
View File
@@ -87,7 +87,7 @@ def git(*args, cwd=None):
result = subprocess.run(
["git"] + list(args),
capture_output=True,
text=True,
text=True, encoding='utf-8', errors='replace',
cwd=cwd or str(REPO_ROOT),
)
if result.returncode != 0:
@@ -112,7 +112,7 @@ def gh_pr_list():
"--limit", "300",
],
capture_output=True,
text=True,
text=True, encoding='utf-8', errors='replace',
timeout=60,
)
if result.returncode != 0:
+1 -1
View File
@@ -572,7 +572,7 @@ def loop_mode(args: argparse.Namespace) -> int:
["npm", "run", "build"],
cwd=tui_dir,
capture_output=True,
text=True,
text=True, encoding='utf-8', errors='replace',
)
if result.returncode != 0:
print("✗ build failed:")
@@ -51,7 +51,7 @@ def run_cmd(cmd: list[str], *, dry_run: bool = False) -> tuple[int, str]:
if dry_run:
return 0, "[dry-run]"
log(f"$ {' '.join(cmd)}")
proc = subprocess.run(cmd, capture_output=True, text=True, check=False)
proc = subprocess.run(cmd, capture_output=True, text=True, encoding='utf-8', errors='replace', check=False)
out = (proc.stdout or "") + (proc.stderr or "")
return proc.returncode, out
@@ -54,7 +54,7 @@ _COMFY_CLI_FLAG = {
def _run(cmd: list[str], timeout: int = 8) -> str:
try:
out = subprocess.run(
cmd, capture_output=True, text=True, timeout=timeout, check=False
cmd, capture_output=True, text=True, encoding='utf-8', errors='replace', timeout=timeout, check=False
)
return (out.stdout or "") + (out.stderr or "")
except (FileNotFoundError, subprocess.TimeoutExpired, OSError):
@@ -108,7 +108,7 @@ def _run_gws(parts: list[str], *, params: dict | None = None, body: dict | None
result = subprocess.run(
cmd,
capture_output=True,
text=True,
text=True, encoding='utf-8', errors='replace',
env=_gws_env(),
)
if result.returncode != 0:
+1 -1
View File
@@ -4687,7 +4687,7 @@ def _maybe_autoinstall_chromium() -> bool:
proc = subprocess.run(
install_cmd,
capture_output=True,
text=True,
text=True, encoding='utf-8', errors='replace',
timeout=600,
env=_build_browser_env(),
)
+2 -2
View File
@@ -327,7 +327,7 @@ def _run_git(
result = subprocess.run(
cmd,
capture_output=True,
text=True,
text=True, encoding='utf-8', errors='replace',
timeout=timeout,
env=env,
cwd=str(normalized_working_dir),
@@ -453,7 +453,7 @@ def _init_store(store: Path, working_dir: str) -> Optional[str]:
try:
result = subprocess.run(
["git", "init", "--bare", str(store)],
capture_output=True, text=True,
capture_output=True, text=True, encoding='utf-8', errors='replace',
env=init_env, timeout=_GIT_TIMEOUT,
stdin=subprocess.DEVNULL,
creationflags=windows_hide_flags(),
+1 -1
View File
@@ -99,7 +99,7 @@ def _drive_health_report(
stdin=subprocess.PIPE,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE,
text=True,
text=True, encoding='utf-8', errors='replace',
encoding="utf-8",
errors="replace",
bufsize=1,
+1 -1
View File
@@ -66,7 +66,7 @@ def _run(binary: str, *args: str, timeout: float) -> subprocess.CompletedProcess
return subprocess.run(
[binary, *args],
capture_output=True,
text=True,
text=True, encoding='utf-8', errors='replace',
timeout=timeout,
env=_child_env(),
stdin=subprocess.DEVNULL,
+13 -13
View File
@@ -181,7 +181,7 @@ def reap_orphan_containers(
try:
listing = subprocess.run(
[docker, "ps", "-a", *filters, "--format", "{{.ID}}"],
capture_output=True, text=True, timeout=15, check=False,
capture_output=True, text=True, encoding='utf-8', errors='replace', timeout=15, check=False,
stdin=subprocess.DEVNULL,
)
except (subprocess.TimeoutExpired, OSError) as e:
@@ -215,7 +215,7 @@ def reap_orphan_containers(
try:
result = subprocess.run(
[docker, "rm", "-f", cid],
capture_output=True, text=True, timeout=30,
capture_output=True, text=True, encoding='utf-8', errors='replace', timeout=30,
stdin=subprocess.DEVNULL,
)
if result.returncode == 0:
@@ -245,7 +245,7 @@ def _container_finished_at(docker_exe: str, container_id: str):
try:
result = subprocess.run(
[docker_exe, "inspect", "--format", "{{.State.FinishedAt}}", container_id],
capture_output=True, text=True, timeout=10, check=False,
capture_output=True, text=True, encoding='utf-8', errors='replace', timeout=10, check=False,
stdin=subprocess.DEVNULL,
)
except (subprocess.TimeoutExpired, OSError) as e:
@@ -637,7 +637,7 @@ def _image_uses_init_entrypoint(docker_exe: str, image: str) -> bool:
[docker_exe, "image", "inspect", image,
"--format", "{{json .Config.Entrypoint}}"],
capture_output=True,
text=True,
text=True, encoding='utf-8', errors='replace',
timeout=15,
stdin=subprocess.DEVNULL,
)
@@ -720,7 +720,7 @@ def _cgroup_limits_available(image: str) -> bool:
"--cpus", "0.5", "--memory", "64m", "--pids-limit", "32",
image, "sleep", "0"],
capture_output=True,
text=True,
text=True, encoding='utf-8', errors='replace',
timeout=60,
stdin=subprocess.DEVNULL,
)
@@ -763,7 +763,7 @@ def _ensure_docker_available() -> None:
result = subprocess.run(
[docker_exe, "version"],
capture_output=True,
text=True,
text=True, encoding='utf-8', errors='replace',
timeout=5,
stdin=subprocess.DEVNULL,
)
@@ -1393,7 +1393,7 @@ class DockerEnvironment(BaseEnvironment):
subprocess.run(
[self._docker_exe, "start", container_id],
capture_output=True,
text=True,
text=True, encoding='utf-8', errors='replace',
timeout=30,
check=True,
stdin=subprocess.DEVNULL,
@@ -1432,7 +1432,7 @@ class DockerEnvironment(BaseEnvironment):
result = subprocess.run(
run_cmd,
capture_output=True,
text=True,
text=True, encoding='utf-8', errors='replace',
timeout=120, # image pull may take a while
check=True,
stdin=subprocess.DEVNULL,
@@ -1569,7 +1569,7 @@ class DockerEnvironment(BaseEnvironment):
try:
subprocess.run(
[self._docker_exe, "start", cid],
capture_output=True, text=True, timeout=30, check=True,
capture_output=True, text=True, encoding='utf-8', errors='replace', timeout=30, check=True,
stdin=subprocess.DEVNULL,
)
self._container_id = cid
@@ -1600,7 +1600,7 @@ class DockerEnvironment(BaseEnvironment):
"sleep", "infinity",
]
result = subprocess.run(
run_cmd, capture_output=True, text=True, timeout=120, check=True,
run_cmd, capture_output=True, text=True, encoding='utf-8', errors='replace', timeout=120, check=True,
stdin=subprocess.DEVNULL,
)
self._container_id = result.stdout.strip()
@@ -1655,7 +1655,7 @@ class DockerEnvironment(BaseEnvironment):
docker = find_docker() or "docker"
result = subprocess.run(
[docker, "info", "--format", "{{.Driver}}"],
capture_output=True, text=True, timeout=10,
capture_output=True, text=True, encoding='utf-8', errors='replace', timeout=10,
stdin=subprocess.DEVNULL,
)
driver = result.stdout.strip().lower()
@@ -1666,7 +1666,7 @@ class DockerEnvironment(BaseEnvironment):
# Probe by attempting a dry-ish run — the fastest reliable check.
probe = subprocess.run(
[docker, "create", "--storage-opt", "size=1m", "hello-world"],
capture_output=True, text=True, timeout=15,
capture_output=True, text=True, encoding='utf-8', errors='replace', timeout=15,
stdin=subprocess.DEVNULL,
)
if probe.returncode == 0:
@@ -1761,7 +1761,7 @@ class DockerEnvironment(BaseEnvironment):
"--format", fmt,
],
capture_output=True,
text=True,
text=True, encoding='utf-8', errors='replace',
timeout=10,
check=False,
stdin=subprocess.DEVNULL,
+1 -1
View File
@@ -1403,7 +1403,7 @@ class LocalEnvironment(BaseEnvironment):
proc = subprocess.Popen(
args,
text=True,
text=True, encoding='utf-8', errors='replace',
env=run_env,
encoding="utf-8",
errors="replace",
+4 -4
View File
@@ -45,7 +45,7 @@ def _ensure_singularity_available() -> str:
exe = _find_singularity_executable()
try:
result = subprocess.run(
[exe, "version"], capture_output=True, text=True, timeout=10,
[exe, "version"], capture_output=True, text=True, encoding='utf-8', errors='replace', timeout=10,
stdin=subprocess.DEVNULL,
)
except FileNotFoundError:
@@ -136,7 +136,7 @@ def _get_or_build_sif(image: str, executable: str = "apptainer") -> str:
try:
result = subprocess.run(
[executable, "build", str(sif_path), image],
capture_output=True, text=True, timeout=600, env=env,
capture_output=True, text=True, encoding='utf-8', errors='replace', timeout=600, env=env,
stdin=subprocess.DEVNULL,
)
if result.returncode != 0:
@@ -220,7 +220,7 @@ class SingularityEnvironment(BaseEnvironment):
cmd.extend([str(self.image), self.instance_id])
try:
result = subprocess.run(cmd, capture_output=True, text=True, timeout=120, stdin=subprocess.DEVNULL)
result = subprocess.run(cmd, capture_output=True, text=True, encoding='utf-8', errors='replace', timeout=120, stdin=subprocess.DEVNULL)
if result.returncode != 0:
raise RuntimeError(f"Failed to start instance: {result.stderr}")
self._instance_started = True
@@ -251,7 +251,7 @@ class SingularityEnvironment(BaseEnvironment):
try:
subprocess.run(
[self.executable, "instance", "stop", self.instance_id],
capture_output=True, text=True, timeout=30,
capture_output=True, text=True, encoding='utf-8', errors='replace', timeout=30,
stdin=subprocess.DEVNULL,
)
logger.info("Singularity instance %s stopped", self.instance_id)
+7 -7
View File
@@ -104,7 +104,7 @@ class SSHEnvironment(BaseEnvironment):
result = subprocess.run(
cmd,
capture_output=True,
text=True,
text=True, encoding='utf-8', errors='replace',
timeout=15,
stdin=subprocess.DEVNULL,
)
@@ -122,7 +122,7 @@ class SSHEnvironment(BaseEnvironment):
result = subprocess.run(
cmd,
capture_output=True,
text=True,
text=True, encoding='utf-8', errors='replace',
timeout=10,
stdin=subprocess.DEVNULL,
)
@@ -149,7 +149,7 @@ class SSHEnvironment(BaseEnvironment):
subprocess.run(
cmd,
capture_output=True,
text=True,
text=True, encoding='utf-8', errors='replace',
timeout=10,
stdin=subprocess.DEVNULL,
)
@@ -164,7 +164,7 @@ class SSHEnvironment(BaseEnvironment):
subprocess.run(
mkdir_cmd,
capture_output=True,
text=True,
text=True, encoding='utf-8', errors='replace',
timeout=10,
stdin=subprocess.DEVNULL,
)
@@ -178,7 +178,7 @@ class SSHEnvironment(BaseEnvironment):
result = subprocess.run(
scp_cmd,
capture_output=True,
text=True,
text=True, encoding='utf-8', errors='replace',
timeout=30,
stdin=subprocess.DEVNULL,
)
@@ -207,7 +207,7 @@ class SSHEnvironment(BaseEnvironment):
result = subprocess.run(
cmd,
capture_output=True,
text=True,
text=True, encoding='utf-8', errors='replace',
timeout=30,
stdin=subprocess.DEVNULL,
)
@@ -325,7 +325,7 @@ class SSHEnvironment(BaseEnvironment):
result = subprocess.run(
cmd,
capture_output=True,
text=True,
text=True, encoding='utf-8', errors='replace',
timeout=10,
stdin=subprocess.DEVNULL,
)
+4 -4
View File
@@ -668,7 +668,7 @@ def _venv_pip_install(specs: tuple[str, ...], *, timeout: int = 300) -> _Install
try:
r = subprocess.run(
[uv_bin, "pip", "install", *target_args, *constraint_args, *specs],
capture_output=True, text=True, timeout=timeout, env=uv_env,
capture_output=True, text=True, encoding='utf-8', errors='replace', timeout=timeout, env=uv_env,
stdin=subprocess.DEVNULL,
creationflags=windows_hide_flags(),
)
@@ -685,7 +685,7 @@ def _venv_pip_install(specs: tuple[str, ...], *, timeout: int = 300) -> _Install
try:
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,
stdin=subprocess.DEVNULL,
creationflags=windows_hide_flags(),
)
@@ -695,7 +695,7 @@ def _venv_pip_install(specs: tuple[str, ...], *, timeout: int = 300) -> _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,
stdin=subprocess.DEVNULL,
creationflags=windows_hide_flags(),
)
@@ -706,7 +706,7 @@ def _venv_pip_install(specs: tuple[str, ...], *, timeout: int = 300) -> _Install
try:
r = subprocess.run(
pip_cmd + ["install", *target_args, *constraint_args, *specs],
capture_output=True, text=True, timeout=timeout,
capture_output=True, text=True, encoding='utf-8', errors='replace', timeout=timeout,
stdin=subprocess.DEVNULL,
creationflags=windows_hide_flags(),
)
+1 -1
View File
@@ -600,7 +600,7 @@ class ProcessRegistry:
subprocess.run(
["taskkill", "/PID", str(pid), "/T", "/F"],
capture_output=True,
text=True,
text=True, encoding='utf-8', errors='replace',
timeout=10,
creationflags=windows_hide_flags(),
stdin=subprocess.DEVNULL,
+1 -1
View File
@@ -412,7 +412,7 @@ class GitHubAuth:
try:
result = subprocess.run(
["gh", "auth", "token"],
capture_output=True, text=True, timeout=5,
capture_output=True, text=True, encoding='utf-8', errors='replace', timeout=5,
stdin=subprocess.DEVNULL,
creationflags=windows_hide_flags(),
)
+2 -2
View File
@@ -315,7 +315,7 @@ def _verify_cosign(checksums_path: str, sig_path: str, cert_path: str) -> bool |
"--certificate-oidc-issuer", _COSIGN_ISSUER,
checksums_path],
capture_output=True,
text=True,
text=True, encoding='utf-8', errors='replace',
timeout=15,
stdin=subprocess.DEVNULL,
)
@@ -776,7 +776,7 @@ def check_command_security(command: str) -> dict:
[tirith_path, "check", "--json", "--non-interactive",
"--shell", "posix", "--", command],
capture_output=True,
text=True,
text=True, encoding='utf-8', errors='replace',
timeout=timeout,
stdin=subprocess.DEVNULL,
)
+3 -3
View File
@@ -1210,7 +1210,7 @@ def _prepare_local_audio(file_path: str, work_dir: str) -> tuple[Optional[str],
command = [ffmpeg, "-y", "-i", file_path, converted_path]
try:
subprocess.run(command, check=True, capture_output=True, text=True, timeout=300, stdin=subprocess.DEVNULL, creationflags=windows_hide_flags())
subprocess.run(command, check=True, capture_output=True, text=True, encoding='utf-8', errors='replace', timeout=300, stdin=subprocess.DEVNULL, creationflags=windows_hide_flags())
return converted_path, None
except subprocess.TimeoutExpired:
logger.error("ffmpeg conversion timed out for %s", file_path)
@@ -1256,9 +1256,9 @@ def _transcribe_local_command(file_path: str, model_name: str) -> Dict[str, Any]
# User-provided templates (env var) may contain shell syntax; auto-detected commands are safe for list mode.
use_shell = bool(os.getenv(LOCAL_STT_COMMAND_ENV, "").strip())
if use_shell:
subprocess.run(command, shell=True, check=True, capture_output=True, text=True, timeout=300, stdin=subprocess.DEVNULL, creationflags=windows_hide_flags())
subprocess.run(command, shell=True, check=True, capture_output=True, text=True, encoding='utf-8', errors='replace', timeout=300, stdin=subprocess.DEVNULL, creationflags=windows_hide_flags())
else:
subprocess.run(shlex.split(command), check=True, capture_output=True, text=True, timeout=300, stdin=subprocess.DEVNULL, creationflags=windows_hide_flags())
subprocess.run(shlex.split(command), check=True, capture_output=True, text=True, encoding='utf-8', errors='replace', timeout=300, stdin=subprocess.DEVNULL, creationflags=windows_hide_flags())
txt_files = sorted(Path(output_dir).glob("*.txt"))
+2 -2
View File
@@ -2015,7 +2015,7 @@ def _generate_neutts(text: str, output_path: str, tts_config: Dict[str, Any]) ->
"--device", device,
]
result = subprocess.run(cmd, capture_output=True, text=True, timeout=120, stdin=subprocess.DEVNULL)
result = subprocess.run(cmd, capture_output=True, text=True, encoding='utf-8', errors='replace', timeout=120, stdin=subprocess.DEVNULL)
if result.returncode != 0:
stderr = result.stderr.strip()
# Filter out the "OK:" line from stderr
@@ -2097,7 +2097,7 @@ def _resolve_piper_voice_path(voice: str, download_dir: Path) -> str:
result = subprocess.run(
[_sys.executable, "-m", "piper.download_voices", voice,
"--download-dir", str(download_dir)],
capture_output=True, text=True, timeout=300,
capture_output=True, text=True, encoding='utf-8', errors='replace', timeout=300,
stdin=subprocess.DEVNULL,
)
except subprocess.TimeoutExpired as exc:
+3 -3
View File
@@ -72,7 +72,7 @@ def _termux_api_app_installed() -> bool:
result = subprocess.run(
["pm", "list", "packages", "com.termux.api"],
capture_output=True,
text=True,
text=True, encoding='utf-8', errors='replace',
timeout=5,
check=False,
stdin=subprocess.DEVNULL,
@@ -389,7 +389,7 @@ class TermuxAudioRecorder:
"-c", str(CHANNELS),
]
try:
subprocess.run(command, capture_output=True, text=True, timeout=15, check=True, stdin=subprocess.DEVNULL)
subprocess.run(command, capture_output=True, text=True, encoding='utf-8', errors='replace', timeout=15, check=True, stdin=subprocess.DEVNULL)
except subprocess.CalledProcessError as e:
details = (e.stderr or e.stdout or str(e)).strip()
raise RuntimeError(f"Termux microphone start failed: {details}") from e
@@ -406,7 +406,7 @@ class TermuxAudioRecorder:
mic_cmd = _termux_microphone_command()
if not mic_cmd:
return
subprocess.run([mic_cmd, "-q"], capture_output=True, text=True, timeout=15, check=False, stdin=subprocess.DEVNULL)
subprocess.run([mic_cmd, "-q"], capture_output=True, text=True, encoding='utf-8', errors='replace', timeout=15, check=False, stdin=subprocess.DEVNULL)
def stop(self) -> Optional[str]:
with self._lock: