package app import ( "encoding/json" "os" "path/filepath" ) // prefs is the TUI's local, persisted preferences (display-only client state — kept out // of the server config, which is shared/replayed). Stored as JSON in the correx config dir. type prefs struct { StatusbarHidden []string `json:"statusbarHidden"` } // statusSegment is one toggleable status-bar segment. The always-on segments (correx label, // connection, session name, spinner, background-updates) are not listed — they are load-bearing. type statusSegment struct{ id, label string } var statusSegments = []statusSegment{ {"stage", "current stage (⟐)"}, {"status", "session status"}, {"workspace", "workspace path (⌂)"}, {"model", "model name"}, {"clock", "last-event clock"}, {"gauge", "resource gauge"}, } func prefsPath() string { dir := os.Getenv("CORREX_CONFIG_HOME") if dir == "" { home, err := os.UserHomeDir() if err != nil { return "" } dir = filepath.Join(home, ".config", "correx") } return filepath.Join(dir, "tui-prefs.json") } // loadStatusbarHidden reads the persisted hidden-segment set (best-effort: a missing or // corrupt file yields an empty set, i.e. everything shown). func loadStatusbarHidden() map[string]bool { out := map[string]bool{} path := prefsPath() if path == "" { return out } data, err := os.ReadFile(path) if err != nil { return out } var p prefs if json.Unmarshal(data, &p) == nil { for _, id := range p.StatusbarHidden { out[id] = true } } return out } // saveStatusbarHidden writes the hidden set back to disk (best-effort; ignores IO errors so // a read-only home never crashes the UI). Order follows statusSegments for a stable file. func saveStatusbarHidden(hidden map[string]bool) { path := prefsPath() if path == "" { return } var ids []string for _, seg := range statusSegments { if hidden[seg.id] { ids = append(ids, seg.id) } } if err := os.MkdirAll(filepath.Dir(path), 0o755); err != nil { return } if data, err := json.MarshalIndent(prefs{StatusbarHidden: ids}, "", " "); err == nil { _ = os.WriteFile(path, data, 0o644) } }