From f10e448d7891be1391e251e9f8dff9575c10c2aa Mon Sep 17 00:00:00 2001 From: Rolando Santamaria Maso Date: Sun, 26 Jul 2026 21:38:29 +0200 Subject: [PATCH] fix(tui): auto-dismiss skill loaded notices after 3 seconds Transient notices (skill loaded, memory, signal, subagent logs) were piling up because every new event reset the single expiry sweep timer. Now each transient notice gets its own 3-second sweep, so expired notices are pruned independently instead of waiting for a quiet gap. - Reduce noticeTTL from 5s to 3s. - Always prune on noticeExpireMsg; drop the stale-sequence guard that delayed expiry when newer notices arrived. --- internal/tui/coverage_test.go | 2 +- internal/tui/model.go | 10 ++++------ 2 files changed, 5 insertions(+), 7 deletions(-) diff --git a/internal/tui/coverage_test.go b/internal/tui/coverage_test.go index 835d863..f338c5e 100644 --- a/internal/tui/coverage_test.go +++ b/internal/tui/coverage_test.go @@ -96,7 +96,7 @@ func TestTransientNoticeExpires(t *testing.T) { if got := strings.Join(m.notices, "\n"); got != "sticky" { t.Errorf("notices after expiry = %q", got) } - // A stale timer (superseded by a newer notice) must not clear anything. + // A stale timer must not clear notices that have not expired yet. m.addTransientNote("skill ยท saved") m.Update(noticeExpireMsg{seq: m.noticeSeq - 1}) if len(m.notices) != 2 { diff --git a/internal/tui/model.go b/internal/tui/model.go index 1516c0f..a4ac873 100644 --- a/internal/tui/model.go +++ b/internal/tui/model.go @@ -169,9 +169,9 @@ func (a autocomplete) height() int { // noticeTTL is how long transient info traces (skill / memory / signal / // subagent) stay on screen before fading out. -const noticeTTL = 5 * time.Second +const noticeTTL = 3 * time.Second -// noticeExpireMsg fires noticeTTL after the last transient notice was added. +// noticeExpireMsg fires noticeTTL after a transient notice was added. type noticeExpireMsg struct { seq int } @@ -287,10 +287,8 @@ func (m *Model) Update(msg tea.Msg) (tea.Model, tea.Cmd) { return m.handleEvent(client.Event(msg)) case noticeExpireMsg: - if msg.seq == m.noticeSeq { - m.pruneNotices(time.Now()) - m.refresh() - } + m.pruneNotices(time.Now()) + m.refresh() return m, nil case tea.MouseMsg: