fix(mcp): dedup PYTHONPATH and drop unsupported win32 platform

Addresses two Greptile findings on #428.

P1 - buildEnv duplicated PYTHONPATH when the parent environment already
set one. POSIX getenv returns the first match, so the user's stale
PYTHONPATH would shadow the engine's cache dir and break
`from lib import ...` with ModuleNotFoundError. buildEnv now filters
any incoming PYTHONPATH= entry before appending the cache dir. Adds
TestRunDropsPreExistingPythonPath (end-to-end through the stub
interpreter) and TestBuildEnvDropsAllPreExistingPythonPath (direct
unit on the helper) to cover the missed case.

P2 - manifest.compatibility.platforms listed "win32" even though the
release matrix doesn't ship a Windows binary; Claude Desktop would
let Windows users start an install with no matching artifact.
Removed until the Windows packaging follow-up lands. Manifest test
renamed to TestPlatformsMatchShippingMatrix and tightened: now
forbids platforms the release CI doesn't build, with a message
pointing at .github/workflows/release.yml.

go test ./... 38 passed across 4 packages.
This commit is contained in:
Matt Van Horn
2026-05-17 21:18:05 -07:00
parent e7b7e61237
commit 61d46b54ee
4 changed files with 91 additions and 12 deletions
+17 -5
View File
@@ -9,6 +9,7 @@ import (
"os/exec"
"path/filepath"
"runtime"
"strings"
"time"
)
@@ -140,12 +141,23 @@ func resolveTimeout(explicit time.Duration) time.Duration {
return DefaultTimeout
}
// buildEnv stitches PYTHONPATH onto os.Environ + ExtraEnv. The engine's
// `from lib import ...` statements resolve because lib/ sits next to
// last30days.py inside CacheDir.
// buildEnv stitches PYTHONPATH onto os.Environ + ExtraEnv. Any pre-existing
// PYTHONPATH in the parent environment is dropped before appending the
// cache dir; otherwise the child sees two PYTHONPATH= entries and POSIX
// getenv returns the first one, so the user's value wins and the engine's
// `from lib import ...` fails with ModuleNotFoundError. The engine is
// self-contained and does not need the user's Python module search path.
func buildEnv(cacheDir string, extra []string) []string {
base := os.Environ()
base = append(base, "PYTHONPATH="+cacheDir)
const pyKey = "PYTHONPATH="
parent := os.Environ()
base := make([]string, 0, len(parent)+1+len(extra))
for _, kv := range parent {
if strings.HasPrefix(kv, pyKey) {
continue
}
base = append(base, kv)
}
base = append(base, pyKey+cacheDir)
base = append(base, extra...)
return base
}