- Stream[T]: Send(v T) type-safe; message type recovered from the
instantiated Send signature (reflect has no type-args API)
- method signatures reduced to (error), (T, error), (*Stream[T], error);
the (T, *Stream, error) first-message form is gone — send it via Send
- return T and stream message T now run checkType at bind time
(Stream[any] remains the explicit untyped escape hatch)
- generated clients: TS onMessage: (data: T); Go <-chan T
- fix vacuous panic assertions (fmt.Sprint(nil) -> "<nil>") in
hardening/route test catch helpers
Generated with [Devin](https://devin.ai)
Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
- handle.go: stream writer emits a blank-line heartbeat every 25s while
the business sends nothing; invisible to NDJSON parsers but resets
NAT/CDN idle timers (mobile CGNAT ~60s, Bunny ~120s)
- template_ts.go: split stream() into retry loop + streamOnce()
- dto accepts a factory re-evaluated per attempt (cursor resume)
- retry only on transport failures (status 4/5); opt-in via
StreamOptions.retry, exponential backoff with jitter, abortable
- idle watchdog (idleTimeoutMs) built on AbortSignal.timeout; no
setTimeout in generated code (simplicity gate)
- docs: README.zh.md version table for v1.3.6
- request interceptor now receives the mutable per-request state map (token injection)
- response interceptor may return a replacement result (central token swap / error handling)
- fetch failures normalized to result status=4 (network error) instead of throwing
- stream requests also pass through request interceptors with state copy