From 650cbc659c17777c449e5ba128931795569cef8a Mon Sep 17 00:00:00 2001 From: dgokeeffe <17697537+dgokeeffe@users.noreply.github.com> Date: Sat, 25 Jul 2026 08:51:30 +1000 Subject: [PATCH] fix(pi): point pi at config dir via PI_CODING_AGENT_DIR instead of redirecting HOME Pi honors the PI_CODING_AGENT_DIR env var to resolve its config directory (~/.pi/agent), so redirecting /Users/david.okeeffe to APP_DIR/pi-home was unnecessary. The HOME redirect broke macOS keychain default resolution under ucode: the Security framework looks for the login keychain under the redirected HOME, finds none, and security default-keychain returns 'A default keychain could not be found'. As a result gh auth, the git credential helper, and any keychain-backed tool failed inside pi. Setting PI_CODING_AGENT_DIR to the existing PI_CONFIG_DIR preserves config isolation (models.json/settings.json/sessions still land under APP_DIR/pi-home/.pi/agent) while leaving /Users/david.okeeffe as the user's real home, so the login keychain stays discoverable. Tests: the two pi e2e sites monkeypatched PI_UCODE_HOME/PI_CONFIG_PATH to redirect pi at a tmp home. They now also patch PI_CONFIG_DIR (read by build_runtime_env) and PI_SETTINGS_PATH/PI_SETTINGS_BACKUP_PATH (previously masked because the HOME redirect made pi read settings from the un-patched real APP_DIR path). --- src/ucode/agents/pi.py | 2 +- tests/test_agent_pi.py | 2 +- tests/test_e2e.py | 3 +++ tests/test_e2e_user_agent.py | 3 +++ 4 files changed, 8 insertions(+), 2 deletions(-) diff --git a/src/ucode/agents/pi.py b/src/ucode/agents/pi.py index e7c1760..f65b75e 100644 --- a/src/ucode/agents/pi.py +++ b/src/ucode/agents/pi.py @@ -237,7 +237,7 @@ def _refresh_forever(state: dict, stop_event: threading.Event) -> None: def build_runtime_env(token: str) -> dict[str, str]: env = os.environ.copy() env["OAUTH_TOKEN"] = token - env["HOME"] = str(PI_UCODE_HOME) + env["PI_CODING_AGENT_DIR"] = str(PI_CONFIG_DIR) return env diff --git a/tests/test_agent_pi.py b/tests/test_agent_pi.py index 0afc5fb..e0dbe84 100644 --- a/tests/test_agent_pi.py +++ b/tests/test_agent_pi.py @@ -242,7 +242,7 @@ def test_sets_oauth_token(self): def test_sets_ucode_home(self): env = pi.build_runtime_env("tok") - assert env["HOME"] == str(pi.PI_UCODE_HOME) + assert env["PI_CODING_AGENT_DIR"] == str(pi.PI_CONFIG_DIR) class TestPiValidateCmd: diff --git a/tests/test_e2e.py b/tests/test_e2e.py index 30ce287..a5aea6d 100644 --- a/tests/test_e2e.py +++ b/tests/test_e2e.py @@ -910,7 +910,10 @@ def test_launch_pi_per_model(self, tmp_path, monkeypatch, e2e_state, e2e_workspa config_path = pi_dir / "models.json" backup_path = tmp_path / "pi-models.backup.json" monkeypatch.setattr(pi, "PI_UCODE_HOME", pi_home) + monkeypatch.setattr(pi, "PI_CONFIG_DIR", pi_dir) monkeypatch.setattr(pi, "PI_CONFIG_PATH", config_path) + monkeypatch.setattr(pi, "PI_SETTINGS_PATH", pi_dir / "settings.json") + monkeypatch.setattr(pi, "PI_SETTINGS_BACKUP_PATH", tmp_path / "pi-settings.backup.json") monkeypatch.setattr(pi, "PI_BACKUP_PATH", backup_path) failures = [] diff --git a/tests/test_e2e_user_agent.py b/tests/test_e2e_user_agent.py index 884e663..e6cec21 100644 --- a/tests/test_e2e_user_agent.py +++ b/tests/test_e2e_user_agent.py @@ -325,7 +325,10 @@ def test_user_agent_arrives_at_gateway(self, tmp_path, monkeypatch, capture_serv monkeypatch.setattr(config_io_mod, "APP_DIR", tmp_path) monkeypatch.setattr(pi, "PI_UCODE_HOME", pi_home) + monkeypatch.setattr(pi, "PI_CONFIG_DIR", pi_dir) monkeypatch.setattr(pi, "PI_CONFIG_PATH", config_path) + monkeypatch.setattr(pi, "PI_SETTINGS_PATH", pi_dir / "settings.json") + monkeypatch.setattr(pi, "PI_SETTINGS_BACKUP_PATH", tmp_path / "pi-settings.backup.json") monkeypatch.setattr(pi, "PI_BACKUP_PATH", tmp_path / "pi.backup.json") state = {