Without a SetReadDeadline, a silently dead WebSocket (e.g. Cloudflare
dropping the connection without a close frame) would block readLoop
forever. The daemon would appear connected but never receive tasks,
and never fall back to HTTP polling.
- Send RFC 6455 pings every 30s (resets Cloudflare's idle timer)
- SetReadDeadline of 45s, refreshed on every pong and text message
- SetWriteDeadline of 10s on all writes to prevent blocked sends
- On timeout, readLoop emits "disconnected" → HybridTransport falls
back to HTTP and starts WS reconnection loop
- Go deps: cobra 1.10.2, fatih/color 1.19, tablewriter 1.1.4,
anacrolix/torrent 1.61, charmbracelet/huh 1.0, pion/webrtc 4.2.11
- GitHub Actions: checkout v6, setup-go v6, golangci-lint-action v9,
codecov-action v5, ghaction-upx v4, goreleaser-action v7
- CI matrix: drop Go 1.22, test on 1.24 + 1.25
- Migrate tablewriter API from v0 to v1 (breaking change)
- Fix data race in WSTransport.readLoop (pass conn as parameter)
- Add file.Sync() before close in debrid and usenet downloaders
- Improve progress tracker: dedup MarkDone, re-mark dirty on flush error