Files
wehub-resource-sync 4b6817381b
CI (OpenClaw E2E) / openclaw test (push) Has been cancelled
CI / coverage-report (push) Has been cancelled
CI / test-kubernetes (push) Has been cancelled
CI / should-run-thorough (push) Has been cancelled
CI / test-thorough (cloudwatch-demo) (push) Has been cancelled
CI / test-thorough (flink-ecs) (push) Has been cancelled
CI / test-thorough (upstream-lambda) (push) Has been cancelled
CI / test-thorough (prefect-ecs-fargate) (push) Has been cancelled
Release / build-binaries (zip, opensre.exe, onefile, windows-latest, windows-x64) (push) Has been cancelled
Benchmark image — build + push to ECR (any adapter) / build + push (push) Has been cancelled
CI / quality (ubuntu-latest) (push) Has been cancelled
CI / test (tools-runtime) (push) Has been cancelled
CI / test (e2e-general) (push) Has been cancelled
CI / test (cli-runtime) (push) Has been cancelled
CI / test (e2e-provider-and-openclaw) (push) Has been cancelled
CI / test (integrations-and-misc) (push) Has been cancelled
Release / verify (push) Has been cancelled
Release / build-python-dist (push) Has been cancelled
Release / build-binaries (tar.gz, opensre, onedir, macos-15-intel, darwin-x64) (push) Has been cancelled
Release / build-binaries (tar.gz, opensre, onedir, macos-latest, darwin-arm64) (push) Has been cancelled
Release / build-binaries (tar.gz, opensre, onedir, ubuntu-22.04, linux-x64) (push) Has been cancelled
Release / publish-release (push) Has been cancelled
Release / publish-main-release (push) Has been cancelled
Interactive Shell Live (PR + post-merge) / turn-checks (no-LLM) (push) Has been cancelled
CodeQL / Analyze (python) (push) Has been cancelled
Interactive Shell Live (PR + post-merge) / turn-live shard ${{ matrix.shard_index }} (push) Has been cancelled
Release / prepare (push) Has been cancelled
Release / build-binaries (tar.gz, opensre, onedir, ubuntu-22.04-arm, linux-arm64) (push) Has been cancelled
Synthetic Deterministic Tests / Synthetic offline (deterministic) (push) Has been cancelled
chore: import upstream snapshot with attribution
2026-07-13 13:10:45 +08:00

94 lines
3.1 KiB
Python

"""Filtered environment for spawning LLM CLI subprocesses.
Only keys needed for binary resolution, locale, proxies, TLS, and adapter-specific
prefixes are forwarded from ``os.environ``. Adapter implementations merge their
own overrides (for example explicit API keys for that CLI only).
"""
from __future__ import annotations
import os
_SAFE_SUBPROCESS_ENV_KEYS = frozenset(
{
"HOME",
# macOS Keychain item lookup (where `claude login` stores OAuth on darwin)
# requires USER. LOGNAME is the POSIX/Linux equivalent kept for parity.
"USER",
"LOGNAME",
"USERPROFILE",
"APPDATA",
"LOCALAPPDATA",
"PATH",
"PATHEXT",
"SYSTEMROOT",
"WINDIR",
"COMSPEC",
"SHELL",
"TMP",
"TEMP",
"TMPDIR",
"LANG",
"TERM",
"TZ",
"NO_PROXY",
"HTTP_PROXY",
"HTTPS_PROXY",
"ALL_PROXY",
"SSL_CERT_FILE",
"SSL_CERT_DIR",
"REQUESTS_CA_BUNDLE",
"CURL_CA_BUNDLE",
"NO_COLOR",
"FORCE_COLOR",
"COLORTERM",
"XDG_CONFIG_HOME",
"XDG_CACHE_HOME",
"XDG_DATA_HOME",
"XDG_STATE_HOME",
}
)
_SAFE_SUBPROCESS_ENV_PREFIXES = (
"LC_",
"CODEX_",
"CURSOR_",
"CLAUDE_",
"GEMINI_",
"GOOGLE_",
# ``ANTIGRAVITY_*`` currently only carries non-secret config
# (``ANTIGRAVITY_CLI_BIN`` path, ``ANTIGRAVITY_CLI_TIMEOUT_SECONDS``
# numeric). If Google ever ships a secret-bearing env (e.g.
# ``ANTIGRAVITY_API_KEY``), revisit this — a blanket prefix would
# leak the secret into every other CLI subprocess. Mirror the
# COPILOT_ pattern below if that happens.
"ANTIGRAVITY_",
"OPENCODE_",
"KIMI_",
# Pi CLI (pi.dev) non-secret config vars (e.g. ``PI_AGENT_DIR`` /
# ``PI_CONFIG_DIR``, ``PI_BIN``, ``PI_MODEL``). Pi's per-provider API keys
# are NOT ``PI_``-prefixed (they are ``ANTHROPIC_API_KEY`` etc.) and are
# forwarded only via the Pi adapter's ``CLIInvocation.env`` — see
# ``PI_PROVIDER_ENV_KEYS`` in ``env_overrides.py`` — so this prefix carries
# no secrets.
"PI_",
# NOTE: deliberately NO ``COPILOT_`` entry. ``COPILOT_GITHUB_TOKEN`` is a
# GitHub PAT; if we forwarded it via this prefix allowlist it would leak
# into every other CLI subprocess (Codex, Kimi, Claude Code, etc.). All
# Copilot envs (config + credentials) flow through ``CLIInvocation.env``
# built by ``CopilotAdapter.build`` so they only reach the Copilot
# subprocess. See ``env_overrides.py`` for the COPILOT_*_ENV_KEYS tuples.
)
def build_cli_subprocess_env(overrides: dict[str, str] | None) -> dict[str, str]:
"""Return a subprocess ``env`` dict: safe inherited keys plus optional overrides."""
env: dict[str, str] = {}
for key, value in os.environ.items():
if key in _SAFE_SUBPROCESS_ENV_KEYS or any(
key.startswith(prefix) for prefix in _SAFE_SUBPROCESS_ENV_PREFIXES
):
env[key] = value
if overrides:
env.update(overrides)
return env