- MCP teardown race: add shutdownGeneration counter to prevent
in-flight connections from resurrecting after disconnectAll
- MCP multi-key disconnect race: replace disconnectedSessions Set
with generation-based Map to track per-session disconnect events
- MCP clients: check shutdownGeneration in stdio/http client
creators before inserting into state.clients
- BackgroundManager: call clearTaskHistoryWhenParentTasksGone after
timer-based task removal in scheduleTaskRemoval and notifyParentSession
- BackgroundManager: clean completedTaskSummaries when parent has
no remaining tasks
- Plugin dispose: remove duplicate tmuxSessionManager.cleanup call
since BackgroundManager.shutdown already handles it via onShutdown
Plugin created managers, hooks, intervals, and process listeners on
every load but had no teardown mechanism. On plugin reload, old
instances remained alive causing cumulative memory leaks.
- Add createPluginDispose() orchestrating shutdown sequence:
backgroundManager.shutdown() → skillMcpManager.disconnectAll() →
disposeHooks()
- Add disposeHooks() aggregator with safe optional chaining
- Wire dispose into index.ts to clean previous instance on reload
- Make dispose idempotent (safe to call multiple times)
Tests: 4 pass, 8 expects