- Add relayListService to load kind:10002 (user relay list) and kind:10006 (blocked relays)
- Add relayManager to compute active relay set and dynamically manage pool membership
- Update App.tsx to fetch and apply user relays on login, reset on logout
- Replace all hardcoded RELAYS usages with dynamic getActiveRelayUrls() across services and components
- Always preserve localhost relays (ws://localhost:10547, ws://localhost:4869) regardless of user blocks
- Merge bunker relays, user relays, and hardcoded relays while excluding blocked relays
- Update keep-alive subscription and address loaders to use dynamic relay set
- Modified files: App.tsx, relayListService.ts (new), relayManager.ts (new), readsService.ts, readingProgressController.ts, archiveController.ts, libraryService.ts, reactionService.ts, writeService.ts, HighlightItem.tsx, ContentPanel.tsx, BookmarkList.tsx, Profile.tsx
- Create src/config/kinds.ts with named Nostr kind constants
- Add streaming support to fetchAllReads and fetchLinks with onItem callbacks
- Update all services to use KINDS constants instead of magic numbers
- Add mergeReadItem utility for DRY state management
- Add fallbackTitleFromUrl for external links without titles
- Relax validation to allow external items without titles
- Update Me.tsx to use streaming with Map-based state for reads/links
- Fix refresh to merge new data instead of clearing state
- Fix empty states for Reads and Links tabs (no more infinite skeletons)
- Services updated: readsService, linksService, libraryService, bookmarkService, exploreService, highlights/fetchByAuthor