[6.3.2] - 2026-03-04
Enhancements
- Test Connection Buttons: Added diagnostic "Test" buttons to every service section in Settings (ABS, KOSync, Storyteller, Booklore, CWA, Hardcover, Telegram). Each button performs a live connectivity check and returns specific error messages — distinguishing wrong URL, wrong credentials, DNS failure, timeout, and disabled/unconfigured states.
- Instant Sync Toggle: Added
INSTANT_SYNC_ENABLEDsetting to enable or disable event-driven instant sync globally. When off, the ABS Socket.IO listener and KoSync push trigger are both inactive and the bridge falls back to the standard background poll cycle. - Instant Sync Settings: Added
ABS_SOCKET_DEBOUNCE_SECONDS(default 30s) to control how long the socket listener waits after a playback event before triggering a sync. Tune this lower for faster response or higher to avoid hammering downstream services during active scrubbing. - Per-Client Polling: Storyteller and Booklore can now be configured with their own poll intervals, independent of the global sync cycle. Set either client to
custommode in Settings and choose a polling interval (in seconds). The poller checks for position changes on active books only and triggers a targeted sync when a real change is detected. - Shared Write Suppression: Centralized write-tracking into a single
write_trackermodule. All clients (ABS, KoSync, Storyteller, Booklore) now share the same suppression logic to prevent feedback loops after the bridge pushes a progress update. - Storyteller Transcript Priority Source: Added Storyteller forced-alignment transcript ingestion as the top transcript source during matching/linking (priority: Storyteller -> SMIL -> Whisper).
- New Optional Setting
STORYTELLER_ASSETS_DIR: Added Settings/UI support for Storyteller assets root ({root}/assets/{title}/transcriptions). This source is opt-in and skipped when unset. - Native Storyteller Alignment Maps: Added direct map generation from
wordTimelinedata (chapter, local UTF-16 char, local ts, global ts) without anchor rebuild. - Direct Timestamp -> EPUB Locator (Storyteller only): ABS audiobook timestamps on Storyteller-transcript books can now resolve to EPUB locators directly from transcript offsets, bypassing fuzzy text search.
- Storyteller Backfill Action: Added a Settings maintenance action to bulk ingest/re-ingest Storyteller transcripts for existing Storyteller-linked books and rebuild storyteller-native alignments.
- Storyteller Transcript Ingest in Forge Pipeline: Added transcript ingestion and anchored alignment generation directly in the forge workflow.
- Suggestion Discovery from Socket Events: Unknown-book Socket.IO progress events now trigger suggestion discovery to surface likely matches automatically.
- Event-Driven Real-Time Sync: Added ABS Socket.IO listener for near-instant sync. When you play/pause an audiobook in Audiobookshelf, progress automatically syncs to all configured clients (KoSync, Storyteller, Booklore, Hardcover) within ~30 seconds — no more waiting for the poll cycle. Also triggers instant sync on KoSync PUT from KOReader. Configurable via
ABS_SOCKET_ENABLEDandABS_SOCKET_DEBOUNCE_SECONDS. - Dashboard Search: Added instant client-side search filter to the dashboard. Users can now type in a "Search books..." field to filter the library by title or author in real time without a page reload.
- Sync Now & Mark Complete Actions: Added quick-action buttons to each book card — ⚡ triggers an immediate background sync cycle, and ✅ marks a book as finished across all configured platforms with an optional mapping cleanup prompt.
- Dashboard Version Badge: Cleaned up the version display badge. Dev builds now show
Build dev-Nand official releases showvX.Y.Zwithout redundant prefixes.
Bug Fixes
- Settings Save Not Restarting: Fixed a critical bug where saving settings from the UI did not actually restart the application. The restart function called
sys.exit(0)from a background thread, which in Python only raisesSystemExitin that thread — the main process kept running with stale configuration. All service singletons (Booklore, Storyteller, ABS socket, etc.) retained their old URLs, credentials, and settings until the container was fully rebuilt. Replaced withos.kill(SIGTERM)to properly signal the main process. - Booklore Refresh Retry Storm: Fixed an infinite retry loop when Booklore is slow or unreachable. Failed cache refreshes left the cache timestamp at zero, causing every subsequent sync cycle to immediately retry the full library scan — spiking CPU and flooding logs. Added a 5-minute cooldown after failed refreshes that suppresses retries while preserving normal cache TTL behavior on the happy path.
- ABS Socket.IO Auth Reliability: The socket connection was previously sending the auth token at the transport level (HTTP headers + Socket.IO CONNECT packet) in addition to the
"auth"event. On some ABS setups this caused both the primary token and the fallback to be rejected immediately. Auth is now sent exclusively via the"auth"event (the canonical ABS flow). If authentication fails, the listener disconnects cleanly and the bridge automatically falls back to the standard poll cycle — sync continues uninterrupted. - Storyteller Filename Prefix Compatibility: Ingestion now accepts both
00000-xxxxx.jsonand00001-xxxxx.jsonchapter prefixes. - Storyteller Format Guardrails: Backfill/ingest now validates chapter JSON shape (
dictwithwordTimeline) before ingesting, preventing invalid files from failing alignment after copy. - ABS Sync Lag with Storyteller Transcripts: Fixed delayed ABS synchronization behavior for Storyteller-transcript-backed books.
- Tri-Link Drift and Storyteller Jump Detection: Corrected drift handling and jump-detection logic to prevent incorrect position propagation.
- Storyteller Backfill and BookLore Reset Fallback: Fixed backfill messaging/flow and BookLore clear/reset fallback behavior.
- KOSync Hash Mismatch: Resolved a hash mismatch issue that occurred when the device epub differs from the bridge epub, preventing stale progress lookups.
- KOSync Shadow Documents: Fixed an issue where stale shadow documents could be returned in GET progress responses, causing incorrect sync positions.
- KOSync Admin Endpoints: Corrected auth handling on admin endpoints to allow dashboard access while keeping sensitive operations protected.
- Booklore Double Search: Fixed a redundant double-search issue in Booklore book lookups, improving match performance.
- Database Schema: Consolidated schema repair into a single clean Alembic migration, reducing startup migration time and preventing edge-case schema conflicts.
- Mark Complete Crash: Fixed a
TypeErrorin themark_completeendpoint caused by invalidLocatorResultkeyword arguments. - LRUCache Thread Safety: Added
threading.Lockto theLRUCacheclass inebook_utils.py. The cache is accessed concurrently by the sync daemon, forge background jobs, and web server requests, butOrderedDict.move_to_end()andpopitem()are not thread-safe for concurrent mutation. - Forge Service Audio Copying: Fixed an indentation error in the audio file copying logic that prevented files from being copied when found via exact path or suffix matching.
- ABS Socket.IO Feedback Loop: Fixed a self-triggering sync loop where BookBridge's own ABS progress writes fired a
user_item_progress_updatedsocket event, which the listener then treated as a real user change and scheduled another sync cycle. A module-level write-suppression tracker now stamps each book after a write; any socket event arriving within 60 seconds of that stamp is silently dropped. A single real progress change now produces exactly one sync cycle instead of three. - Booklore Full Library Scan on Progress Update: Fixed
update_progress()calling_refresh_book_cache()after every successful write, which fetched all books from the Booklore API on every sync cycle. Progress is now applied to the cached entry in-place. Full library scans still occur on initial load and the hourly staleness check.
Maintenance
- Comment Cleanup: Removed reflective/speculative inline comments for clearer, more maintainable code.