0.3.1
Highlights
-
Reading-progress tracking &
read_statefiltering. Substack exposes per-post reading progress (read_progress/max_read_progress/is_viewed) on both unified and legacy reader APIs. They are now stored as columns and surfaced viaread_statefilters (unread/in_progress/finished/started) onlist_posts/search_postsand MCP tools, with sorting byread_progressandminutes_remaining(word_count * (1 - max_read_progress)).is_fully_readandminutes_remainingare derived at read time from the high-water markmax_read_progressagainst a configurableSUBSTACK_SAVED_FULLY_READ_THRESHOLD(default0.95, envSUBSTACK_SAVED_FULLY_READ_THRESHOLD).get_statusnow reportsposts_unread/posts_in_progress/posts_fully_read/minutes_remaining_total.upsert_postnow preserves0.0progress values (previously lost toor-coalescing). -
inspect-networkstability fixes. Removes thecontext.route("**/*")→route.fetch()→route.fulfill()interception that caused cross-tab stalls, CORS breakage, andcontent-encoding: gzipdouble-decompression (React feed failed to render). Replaced with a passivecontext.on("response")listener so every page asset and API call loads natively. Scopes the browser launch with--disable-blink-features=AutomationControlled, a desktop Chrome user-agent and1280×800viewport to pass Cloudflare Turnstile / cookie-banner checks. -
Rate-limit resilience. Raises reader-API
max_retriesfrom 3→5 (withRetry-After-aware capped exponential backoff, 2–30 s) across all three cursor-paginated fetchers (legacy posts, unified posts, notes). Adds a 15 s cooldown between posts and notes phases ofsyncwhen the posts phase was truncated by rate-limiting, so the notes phase no longer immediately re-trips the same bucket. -
Sync warning hygiene. Explicit
api_context.dispose()infinallyblocks for all Playwright request contexts (_fetch_saved_posts_page_impl,_fetch_saved_notes_page_impl,probe_api) suppressesTask was destroyed but it is pending!/TargetClosedErrornoise on sync completion after a mid-pagination 429.