7d8d06e2e5
The native layer now emits one JSON object per report, so the service parses each into a sealed Iperf3Event — start, interval, end, error — and publishes those instead of opaque lines. Interval samples carry bytes, bits per second, retransmits and per-stream socket/cwnd/rtt detail; the end event carries sent and received totals and CPU utilisation. None of that was available while the output was scraped text. Anything unrecognised — non-JSON, malformed JSON, an event name a future iperf3 adds — becomes an Iperf3LogLine rather than being dropped, so unexpected output still reaches the user. Failures arrive as an `error` event rather than a non-zero return from iperf_run_client, so that event is what now marks a run as failed. The result's rawOutput keeps the JSON lines verbatim, since that is what the native layer actually produced. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>