personal memory agent
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

fix: capture real PATH from environment for service unit files

_collect_env() now reads os.environ["PATH"] instead of hardcoding
a minimal path. Venv bin is prepended and duplicates are removed.
Falls back to /usr/local/bin:/usr/bin:/bin if PATH is unset.

+39 -5
+31 -1
tests/test_service.py
··· 100 100 101 101 def test_includes_venv_in_path(self, monkeypatch, tmp_path): 102 102 monkeypatch.setenv("_SOLSTONE_JOURNAL_OVERRIDE", str(tmp_path)) 103 + monkeypatch.setenv("PATH", "/opt/homebrew/bin:/usr/local/bin:/usr/bin:/bin") 104 + monkeypatch.setattr( 105 + sys, "executable", str(tmp_path / ".venv" / "bin" / "python") 106 + ) 103 107 104 108 env = service._collect_env() 105 109 venv_bin = str(Path(sys.executable).parent) 106 - assert env["PATH"].startswith(venv_bin) 110 + assert env["PATH"] == ( 111 + f"{venv_bin}:/opt/homebrew/bin:/usr/local/bin:/usr/bin:/bin" 112 + ) 113 + 114 + def test_path_fallback_when_unset(self, monkeypatch, tmp_path): 115 + monkeypatch.setenv("_SOLSTONE_JOURNAL_OVERRIDE", str(tmp_path)) 116 + monkeypatch.delenv("PATH", raising=False) 117 + monkeypatch.setattr( 118 + sys, "executable", str(tmp_path / ".venv" / "bin" / "python") 119 + ) 120 + 121 + env = service._collect_env() 122 + venv_bin = str(Path(sys.executable).parent) 123 + assert env["PATH"] == f"{venv_bin}:/usr/local/bin:/usr/bin:/bin" 124 + 125 + def test_path_deduplicates_venv_bin(self, monkeypatch, tmp_path): 126 + monkeypatch.setenv("_SOLSTONE_JOURNAL_OVERRIDE", str(tmp_path)) 127 + monkeypatch.setattr( 128 + sys, "executable", str(tmp_path / ".venv" / "bin" / "python") 129 + ) 130 + venv_bin = str(Path(sys.executable).parent) 131 + monkeypatch.setenv("PATH", f"{venv_bin}:/usr/local/bin:/usr/bin:/bin") 132 + 133 + env = service._collect_env() 134 + parts = env["PATH"].split(":") 135 + assert parts[0] == venv_bin 136 + assert parts.count(venv_bin) == 1 107 137 108 138 def test_journal_override_not_propagated(self, monkeypatch, tmp_path): 109 139 monkeypatch.setenv("_SOLSTONE_JOURNAL_OVERRIDE", str(tmp_path))
+8 -4
think/service.py
··· 61 61 def _collect_env() -> dict[str, str]: 62 62 """Collect environment variables for the service file. 63 63 64 - Only captures HOME and PATH (with venv bin). API keys are NOT written 65 - into service files — the supervisor reads them from journal.json at 66 - process startup via setup_cli(). Never propagate _SOLSTONE_JOURNAL_OVERRIDE 64 + Captures HOME and PATH (with venv bin prepended). The real PATH is read 65 + from os.environ so installed services inherit the shell's tool visibility. 66 + Falls back to /usr/local/bin:/usr/bin:/bin if PATH is unset. API keys are 67 + NOT written into service files — the supervisor reads them from journal.json 68 + at process startup via setup_cli(). Never propagate _SOLSTONE_JOURNAL_OVERRIDE 67 69 into service files — installed services should use default path resolution. 68 70 """ 69 71 venv_bin = str(Path(sys.executable).parent) 72 + base_path = os.environ.get("PATH", "/usr/local/bin:/usr/bin:/bin") 73 + path = ":".join(dict.fromkeys([venv_bin] + base_path.split(":"))) 70 74 71 75 return { 72 76 "HOME": str(Path.home()), 73 - "PATH": f"{venv_bin}:/usr/local/bin:/usr/bin:/bin", 77 + "PATH": path, 74 78 } 75 79 76 80