detached 4a6e7a5

Synchronize auto-compact setting updates

commit
4a6e7a5798972a35878c17aa7280740c5c7bb318
author
patriceckhart · · 2026-07-28 11:49 UTC
parent
d24acdc
signature
unsigned
2 files · +60 -1
M packages/agent/modes/auto_compact_test.go +59 -0
@@ -85,6 +85,65 @@ func TestSettingsDialogOffersAutoCompactThresholdPresets(t *testing.T) {
8585 }
8686 }
8787
88+func TestApplyAutoCompactThresholdSynchronizesLiveUpdate(t *testing.T) {
89+ initialThreshold := 85
90+ releaseStore := make(chan struct{})
91+ store := &blockingAutoCompactSettingsStore{
92+ entered: make(chan int, 1),
93+ release: releaseStore,
94+ }
95+ interactive := NewInteractive(InteractiveConfig{
96+ AutoCompactThreshold: &initialThreshold,
97+ SettingsStore: store,
98+ })
99+
100+ interactive.mu.Lock()
101+ locked := true
102+ released := false
103+ done := make(chan struct{})
104+ go func() {
105+ defer close(done)
106+ interactive.applyAutoCompactThresholdSetting("70")
107+ }()
108+ defer func() {
109+ if !released {
110+ close(releaseStore)
111+ }
112+ if locked {
113+ interactive.mu.Unlock()
114+ }
115+ <-done
116+ }()
117+
118+ if got := <-store.entered; got != 70 {
119+ t.Fatalf("persisted threshold = %d, want 70", got)
120+ }
121+ if got := *interactive.cfg.AutoCompactThreshold; got != 85 {
122+ t.Fatalf("threshold changed without holding Interactive.mu: got %d, want 85", got)
123+ }
124+
125+ close(releaseStore)
126+ released = true
127+ interactive.mu.Unlock()
128+ locked = false
129+ <-done
130+ if got := *interactive.cfg.AutoCompactThreshold; got != 70 {
131+ t.Fatalf("threshold after setting completes = %d, want 70", got)
132+ }
133+}
134+
135+type blockingAutoCompactSettingsStore struct {
136+ SettingsStore
137+ entered chan int
138+ release <-chan struct{}
139+}
140+
141+func (s *blockingAutoCompactSettingsStore) SetAutoCompactThreshold(percent int) error {
142+ s.entered <- percent
143+ <-s.release
144+ return nil
145+}
146+
88147 func autoCompactIntPtr(value int) *int {
89148 return &value
90149 }
@@ -85,6 +85,65 @@ func TestSettingsDialogOffersAutoCompactThresholdPresets(t *testing.T) {
85 }85 }
86 }86 }
87 87
88+func TestApplyAutoCompactThresholdSynchronizesLiveUpdate(t *testing.T) {
89+ initialThreshold := 85
90+ releaseStore := make(chan struct{})
91+ store := &blockingAutoCompactSettingsStore{
92+ entered: make(chan int, 1),
93+ release: releaseStore,
94+ }
95+ interactive := NewInteractive(InteractiveConfig{
96+ AutoCompactThreshold: &initialThreshold,
97+ SettingsStore: store,
98+ })
99+
100+ interactive.mu.Lock()
101+ locked := true
102+ released := false
103+ done := make(chan struct{})
104+ go func() {
105+ defer close(done)
106+ interactive.applyAutoCompactThresholdSetting("70")
107+ }()
108+ defer func() {
109+ if !released {
110+ close(releaseStore)
111+ }
112+ if locked {
113+ interactive.mu.Unlock()
114+ }
115+ <-done
116+ }()
117+
118+ if got := <-store.entered; got != 70 {
119+ t.Fatalf("persisted threshold = %d, want 70", got)
120+ }
121+ if got := *interactive.cfg.AutoCompactThreshold; got != 85 {
122+ t.Fatalf("threshold changed without holding Interactive.mu: got %d, want 85", got)
123+ }
124+
125+ close(releaseStore)
126+ released = true
127+ interactive.mu.Unlock()
128+ locked = false
129+ <-done
130+ if got := *interactive.cfg.AutoCompactThreshold; got != 70 {
131+ t.Fatalf("threshold after setting completes = %d, want 70", got)
132+ }
133+}
134+
135+type blockingAutoCompactSettingsStore struct {
136+ SettingsStore
137+ entered chan int
138+ release <-chan struct{}
139+}
140+
141+func (s *blockingAutoCompactSettingsStore) SetAutoCompactThreshold(percent int) error {
142+ s.entered <- percent
143+ <-s.release
144+ return nil
145+}
146+
88 func autoCompactIntPtr(value int) *int {147 func autoCompactIntPtr(value int) *int {
89 return &value148 return &value
90 }149 }
M packages/agent/modes/interactive.go +1 -1
@@ -3395,7 +3395,6 @@ func (i *Interactive) applyAutoCompactThresholdSetting(value string) {
33953395 return
33963396 }
33973397 threshold = normalizeAutoCompactThreshold(&threshold)
3398- i.cfg.AutoCompactThreshold = &threshold
33993398 if store, ok := i.cfg.SettingsStore.(autoCompactThresholdSettingsStore); ok {
34003399 if err := store.SetAutoCompactThreshold(threshold); err != nil {
34013400 i.mu.Lock()
@@ -3405,6 +3404,7 @@ func (i *Interactive) applyAutoCompactThresholdSetting(value string) {
34053404 }
34063405 }
34073406 i.mu.Lock()
3407+ i.cfg.AutoCompactThreshold = &threshold
34083408 if threshold == 0 {
34093409 i.statusOK = "auto-compact threshold off"
34103410 } else {
@@ -3395,7 +3395,6 @@ func (i *Interactive) applyAutoCompactThresholdSetting(value string) {
3395 return3395 return
3396 }3396 }
3397 threshold = normalizeAutoCompactThreshold(&threshold)3397 threshold = normalizeAutoCompactThreshold(&threshold)
3398- i.cfg.AutoCompactThreshold = &threshold
3399 if store, ok := i.cfg.SettingsStore.(autoCompactThresholdSettingsStore); ok {3398 if store, ok := i.cfg.SettingsStore.(autoCompactThresholdSettingsStore); ok {
3400 if err := store.SetAutoCompactThreshold(threshold); err != nil {3399 if err := store.SetAutoCompactThreshold(threshold); err != nil {
3401 i.mu.Lock()3400 i.mu.Lock()
@@ -3405,6 +3404,7 @@ func (i *Interactive) applyAutoCompactThresholdSetting(value string) {
3405 }3404 }
3406 }3405 }
3407 i.mu.Lock()3406 i.mu.Lock()
3407+ i.cfg.AutoCompactThreshold = &threshold
3408 if threshold == 0 {3408 if threshold == 0 {
3409 i.statusOK = "auto-compact threshold off"3409 i.statusOK = "auto-compact threshold off"
3410 } else {3410 } else {

Keyboard shortcuts

Single-key shortcuts are on. ctrl k and esc work whatever this says.

ctrl k :
go to a section, branch, tag, file or repository
?
this list
j k
move the row cursor down / up
enter
open the row under the cursor; on Files, a directory opens or closes in place
↑ ↓ ← → home end
in the file tree (focus on a row): previous / next row, close / open a directory or go to its parent / first entry, first / last row. They never open a file
l h
on Files: open a directory or a file / close a directory or go up to its parent, then to the parent page. Elsewhere: into the side panel (on a merge request, its files) / back to the content; there j k move between its controls
g g G
first / last row
/
filter the list; on Files, find a file anywhere in the repository (esc clears, enter opens the best match)
b
switch branch or tag
g s g f g c g b g m g i g r g a
tabs: summary, files, commits, branches & tags, merge requests, issues, releases, actions (when available)
g h
home
w
wide mode: use the whole width of the screen, or not (remembered)
y
copy a permalink pinned to the commit
d u x
diff: split / unified / collapse or expand all
e E
diff: the whole file in view / every file, with the lines the hunks hide
n
merge request: next note in the diff
esc
close a dialog, leave a field

Branches 1

Tags 476

↑↓ moveenter openesc close