v10.6.2

thedotmack/claude-memv10.6.2Mar 21, 2026by thedotmack

AI Summary

This release fixes a critical bug where the viewer UI activity spinner would get stuck spinning forever due to orphaned messages from dead sessions being incorrectly included in processing checks. The fix scopes message queries to only active in-memory sessions and adds a `terminateSession()` method to enforce proper cleanup invariants.

Key Highlights

  • Fixed activity spinner stuck spinning by scoping `isAnySessionProcessing()` and `hasPendingMessages()` to only active in-memory sessions
  • Added `terminateSession()` method enforcing restart-or-terminate invariant for generator exits
  • Fixed 3 zombie paths in `.finally()` handler that left sessions alive without generators
  • Fixed idle-timeout race condition where fresh messages could be silently dropped
  • Removed redundant `isProcessing: true` broadcast and eliminated double-iteration in `broadcastProcessingStatus()`

New Features

  • New `terminateSession()` method with restart-or-terminate invariant enforcement
  • 8 regression tests added for session termination invariant

Full Release Notes

## fix: Activity spinner stuck spinning forever

The viewer UI activity spinner would spin indefinitely because `isAnySessionProcessing()` queried all pending/processing messages in the database globally — including orphaned messages from dead sessions that no generator would ever process. These orphans caused `isProcessing=true` forever.

### Changes

- Scoped `isAnySessionProcessing()` and `hasPendingMessages()` to only check sessions in the active in-memory Map, so orphaned DB messages no longer affect the spinner
- Added `terminateSession()` method enforcing a restart-or-terminate invariant — every generator exit must either restart or fully clean up
- Fixed 3 zombie paths in the `.finally()` handler that previously left sessions alive in memory with no generator running
- Fixed idle-timeout race condition where fresh messages arriving between idle abort and cleanup could be silently dropped
- Removed redundant bare `isProcessing: true` broadcast and eliminated double-iteration in `broadcastProcessingStatus()`
- Replaced inline `require()` with proper accessor via `sessionManager.getPendingMessageStore()`
- Added 8 regression tests for session termination invariant