Skip to content

Commit 13f1b22

Browse files
Copilotbytemain
andauthored
fix(activate): unset inherited hook session vars in IDE env resolution
Agent-Logs-Url: https://github.com/version-fox/vfox/sessions/eb1376c6-75a6-4fc0-8963-99d748132fa2 Co-authored-by: bytemain <13938334+bytemain@users.noreply.github.com>
1 parent 9522202 commit 13f1b22

2 files changed

Lines changed: 24 additions & 3 deletions

File tree

cmd/commands/activate.go

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -218,6 +218,17 @@ func renderActivateScript(name, selfPath string, args []string, exportEnvs env.V
218218
exportOnly[k] = v
219219
}
220220
}
221+
// Explicitly unset hook session vars so they cannot be inherited by the
222+
// IDE process. When VSCode (or other IDEs) resolves the shell
223+
// environment, it spawns a login shell that inherits its own
224+
// process.env. If the IDE itself was launched from a terminal where
225+
// vfox was already activated, those vars leak through the captured
226+
// environment into every integrated terminal, causing them to reuse
227+
// the parent shell's session directory and cached state and breaking
228+
// per-project version activation.
229+
exportOnly[env.HookFlag] = nil
230+
exportOnly[env.PidFlag] = nil
231+
exportOnly[pathmeta.HookCurTmpPath] = nil
221232
return s.Export(exportOnly), nil
222233
}
223234

cmd/commands/activate_test.go

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -23,9 +23,19 @@ func TestRenderActivateScriptForIDEEnvironmentResolutionSkipsHookSessionState(t
2323
t.Fatalf("renderActivateScript() failed: %v", err)
2424
}
2525

26-
for _, forbidden := range []string{env.PidFlag, env.HookFlag, pathmeta.HookCurTmpPath, "_vfox_hook"} {
27-
if strings.Contains(got, forbidden) {
28-
t.Fatalf("IDE environment resolution script contains %q:\n%s", forbidden, got)
26+
if strings.Contains(got, "_vfox_hook") {
27+
t.Fatalf("IDE environment resolution script should not register hook:\n%s", got)
28+
}
29+
// Hook session vars must be unset (not just omitted) so they cannot leak
30+
// from the IDE's parent shell into every integrated terminal.
31+
for _, key := range []string{env.PidFlag, env.HookFlag, pathmeta.HookCurTmpPath} {
32+
want := "unset " + key + ";"
33+
if !strings.Contains(got, want) {
34+
t.Fatalf("IDE environment resolution script should unset %q, got:\n%s", key, got)
35+
}
36+
// And it must never re-export them.
37+
if strings.Contains(got, "export "+key+"=") {
38+
t.Fatalf("IDE environment resolution script should not export %q, got:\n%s", key, got)
2939
}
3040
}
3141

0 commit comments

Comments
 (0)