diff --git a/cmd/launch/hermes.go b/cmd/launch/hermes.go index 56c40b9b..3fa7087e 100644 --- a/cmd/launch/hermes.go +++ b/cmd/launch/hermes.go @@ -452,12 +452,33 @@ func hermesWindowsBinaryFallbacks() []string { return fallbacks } -func hermesConfigPath() (string, error) { +func hermesHomePath() (string, error) { + if hermesHome := strings.TrimSpace(os.Getenv("HERMES_HOME")); hermesHome != "" { + return filepath.Clean(hermesHome), nil + } + if hermesGOOS == "windows" { + if localAppData := strings.TrimSpace(os.Getenv("LOCALAPPDATA")); localAppData != "" { + return filepath.Join(localAppData, "hermes"), nil + } + home, err := hermesUserHome() + if err != nil { + return "", err + } + return filepath.Join(home, "AppData", "Local", "hermes"), nil + } home, err := hermesUserHome() if err != nil { return "", err } - return filepath.Join(home, ".hermes", "config.yaml"), nil + return filepath.Join(home, ".hermes"), nil +} + +func hermesConfigPath() (string, error) { + home, err := hermesHomePath() + if err != nil { + return "", err + } + return filepath.Join(home, "config.yaml"), nil } func hermesBaseURL() string { @@ -465,11 +486,11 @@ func hermesBaseURL() string { } func hermesEnvPath() (string, error) { - home, err := hermesUserHome() + home, err := hermesHomePath() if err != nil { return "", err } - return filepath.Join(home, ".hermes", ".env"), nil + return filepath.Join(home, ".env"), nil } func (h *Hermes) runGatewaySetupPreflight(args []string, runSetup func() error) error { diff --git a/cmd/launch/hermes_test.go b/cmd/launch/hermes_test.go index 162b8199..8dfd733a 100644 --- a/cmd/launch/hermes_test.go +++ b/cmd/launch/hermes_test.go @@ -423,19 +423,36 @@ func TestHermesConfigureMigratesLegacyManagedAliases(t *testing.T) { func TestHermesPathsUsesLocalConfigPathForNativeWindowsHermes(t *testing.T) { tmpDir := t.TempDir() winHome := filepath.Join(tmpDir, "winhome") + localAppData := filepath.Join(tmpDir, "LocalAppData") setTestHome(t, winHome) withHermesPlatform(t, "windows") withHermesUserHome(t, winHome) t.Setenv("PATH", tmpDir) + t.Setenv("LOCALAPPDATA", localAppData) writeFakeBinary(t, tmpDir, "hermes") got := (&Hermes{}).Paths() - want := filepath.Join(winHome, ".hermes", "config.yaml") + want := filepath.Join(localAppData, "hermes", "config.yaml") if len(got) != 1 || got[0] != want { t.Fatalf("expected local config path %q, got %v", want, got) } } +func TestHermesPathsUsesHermesHomeOverride(t *testing.T) { + tmpDir := t.TempDir() + hermesHome := filepath.Join(tmpDir, "custom-hermes-home") + setTestHome(t, filepath.Join(tmpDir, "home")) + withHermesPlatform(t, "windows") + t.Setenv("HERMES_HOME", hermesHome) + t.Setenv("LOCALAPPDATA", filepath.Join(tmpDir, "LocalAppData")) + + got := (&Hermes{}).Paths() + want := filepath.Join(hermesHome, "config.yaml") + if len(got) != 1 || got[0] != want { + t.Fatalf("expected HERMES_HOME config path %q, got %v", want, got) + } +} + func TestHermesCurrentModelRequiresHealthyManagedConfig(t *testing.T) { tmpDir := t.TempDir() setTestHome(t, tmpDir)