From f26b700c31718ab95bbb2fabff38e7b9836a4178 Mon Sep 17 00:00:00 2001 From: Shaojin Wen Date: Sat, 2 May 2026 23:20:26 +0800 Subject: [PATCH] fix(core): fire statusChange in MonitorRegistry.reset() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The newly-added `setStatusChangeCallback` subscriber misses `reset()`, so a `/clear` or session reset leaves stale monitor rows visible in the combined Background tasks dialog until an unrelated register/settle event happens. Both BackgroundShellRegistry and BackgroundTaskRegistry already fire statusChange on their reset paths — Monitor was the outlier. Fix: fire `statusChange()` (no arg) after `monitors.clear()`, with an early return when the registry is already empty so we don't notify on a no-op reset. Two new tests cover both branches. --- .../core/src/services/monitorRegistry.test.ts | 17 +++++++++++++++++ packages/core/src/services/monitorRegistry.ts | 7 +++++++ 2 files changed, 24 insertions(+) diff --git a/packages/core/src/services/monitorRegistry.test.ts b/packages/core/src/services/monitorRegistry.test.ts index 86a5189c8..dc09ec70e 100644 --- a/packages/core/src/services/monitorRegistry.test.ts +++ b/packages/core/src/services/monitorRegistry.test.ts @@ -664,5 +664,22 @@ describe('MonitorRegistry', () => { ).not.toThrow(); expect(registry.get('a')).toBeDefined(); }); + + it('fires once on reset() so dialog snapshots clear stale rows', () => { + registry.register(createEntry({ monitorId: 'a' })); + registry.register(createEntry({ monitorId: 'b' })); + const cb = vi.fn(); + registry.setStatusChangeCallback(cb); + registry.reset(); + expect(cb).toHaveBeenCalledTimes(1); + expect(registry.getAll()).toEqual([]); + }); + + it('reset() on an empty registry does not fire statusChange', () => { + const cb = vi.fn(); + registry.setStatusChangeCallback(cb); + registry.reset(); + expect(cb).not.toHaveBeenCalled(); + }); }); }); diff --git a/packages/core/src/services/monitorRegistry.ts b/packages/core/src/services/monitorRegistry.ts index 710f856f7..ff14c2542 100644 --- a/packages/core/src/services/monitorRegistry.ts +++ b/packages/core/src/services/monitorRegistry.ts @@ -250,6 +250,7 @@ export class MonitorRegistry { } reset(): void { + if (this.monitors.size === 0) return; for (const entry of this.monitors.values()) { this.clearIdleTimer(entry); if (entry.status === 'running') { @@ -257,6 +258,12 @@ export class MonitorRegistry { } } this.monitors.clear(); + // Notify subscribers that the registry's contents changed wholesale + // — without this, the dialog snapshot in `useBackgroundTaskView` + // would keep rendering the now-cleared rows until an unrelated + // register/settle event happens. Mirrors BackgroundShellRegistry / + // BackgroundTaskRegistry's reset paths. + this.fireStatusChange(); } // --- Internal helpers ---