Commit Graph
100 Commits
Author SHA1 Message Date
sjgandClaude Sonnet 4.6 57e88b3590 [fix](trx-rds): tune RDS parameters for maximum sensitivity
- RRC_ALPHA 0.75→0.50: narrower noise BW, ~0.6 dB SNR gain
- COSTAS_KI 3.5e-7: maintain ζ≈0.68 (1e-6 caused loop instability)
- Soft confidence: use biphase_i.abs() instead of full vector magnitude
  so OSD confidence is aligned with bit-decision sign; suppresses
  false groups under noise with residual Costas phase error
- OSD(2) in locked mode: corrects ≤2-bit errors after block sync
- Search mode: hard decode only for Block A; OSD(1) in search yielded
  ~13% false Block A rate per bit, letting wrong clock candidates
  accumulate false groups as fast as the correct candidate
- Incumbent candidate tracking (best_candidate_idx): the winning
  candidate updates best_state at equal score; challengers need strictly
  higher score; best_score tracks incumbent even on no-state-change
  groups so challengers can't leapfrog on a single false group
- blocks_to_chips: add NRZI (NRZ-Mark) pre-encoding so the differential
  biphase decoder recovers actual data bits rather than XOR-of-pairs
- Add blocks_to_chips_round_trips_all_groups test: verifies all 16 blocks
  across 4 PS segments round-trip correctly without BPSK modulation

[fix](trx-backend-soapysdr): lower pilot lock threshold for weak-signal RDS

- PILOT_LOCK_THRESHOLD 0.25→0.20, add PILOT_LOCK_ONSET=0.30 constant
- Pilot reference engages at coherence ≥0.36 (was ≥0.45)

WIP: end_to_end_clean_signal_decodes_ps still failing (13/15 pass).
Decoder skips segment 2 due to ISI from rectangular test chips through
RRC receive filter. chips_to_rds_signal needs RRC pulse shaping.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Signed-off-by: Stan Grams <sjg@haxx.space>
2026-03-27 01:46:01 +01:00
sjgandClaude Sonnet 4.6 8b310c184b [fix](trx-backend-soapysdr): lower pilot lock threshold for weak-signal RDS
Lower PILOT_LOCK_THRESHOLD 0.5 -> 0.25 so the accurate 57 kHz pilot-derived
carrier reference is handed to the RDS decoder even with a weaker pilot tone.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Signed-off-by: Stan Grams <sjg@haxx.space>
2026-03-27 00:01:10 +01:00
sjgandClaude Sonnet 4.6 42b7dcaa42 [fix](trx-rds): improve weak-signal sensitivity
- Add single-bit flip fallback in search mode (push_bit_soft) so Block A
  can be acquired with one bit error, matching locked-mode OSD(1) behaviour
- Lower MIN_PUBLISH_QUALITY 0.38 -> 0.20 for earlier publish on noisy signals

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Signed-off-by: Stan Grams <sjg@haxx.space>
2026-03-27 00:01:04 +01:00
sjgandClaude Sonnet 4.6 d1703f6b0a [fix](trx-rds): replace ring-buffer FIR with FFT overlap-save, tune constants
- Replace FirFilter (ring-buffer FIR) with FftRrcFilter using overlap-save
  FFT convolution; I and Q are processed together as a single complex FFT,
  halving filter cost (~10x fewer operations than direct convolution)
- Reduce PHASE_CANDIDATES 16 -> 8 (reasonable, double the original)
- Lower MIN_PUBLISH_QUALITY 0.55 -> 0.38 (more permissive acquisition)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Signed-off-by: Stan Grams <sjg@haxx.space>
2026-03-26 23:53:53 +01:00
sjgandClaude Sonnet 4.6 032ff2a735 [fix](trx-rds): tune acquisition speed vs false-positive tradeoff
- Increase phase candidates 4 -> 16 for faster clock-phase lock
- Lower MIN_PUBLISH_QUALITY 0.65 -> 0.55 for earlier decode on weaker signals

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Signed-off-by: Stan Grams <sjg@haxx.space>
2026-03-26 23:36:45 +01:00
sjgandClaude Sonnet 4.6 32e090f927 [fix](trx-backend-soapysdr): preserve RDS subcarrier with narrow WFM bandwidth
The IQ prefilter cutoff was audio_bandwidth_hz/2, so any setting below
~120 kHz would cut off the 57 kHz RDS subcarrier before FM demod.

- Clamp IQ prefilter cutoff to >= 60 kHz for WFM in both new() and
  rebuild_filters() — audio quality is unaffected since WfmStereoDecoder
  applies its own 18 kHz lowpass internally
- Ensure pipeline target rate >= 120 kHz for WFM so the decimated IQ
  sample rate can represent the 60 kHz cutoff

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Signed-off-by: Stan Grams <sjg@haxx.space>
2026-03-26 23:31:54 +01:00
sjgandClaude Sonnet 4.6 1994534b4d [fix](trx-rds): reduce false positives and cpu usage
- Downgrade OSD from distance-2 to distance-1 (removes 325-iteration
  double-bit flip loop per block, main source of both false positives
  and excess CPU)
- Reduce phase candidates from 8 to 4 (halves per-sample work)
- Raise MIN_PUBLISH_QUALITY from 0.45 to 0.65 (requires stronger
  signal confidence before emitting decoded state)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Signed-off-by: Stan Grams <sjg@haxx.space>
2026-03-26 23:31:45 +01:00
sjgandClaude Sonnet 4.6 bb5beb79da [feat](trx-client): freeze only the disconnected rig's view in multi-rig mode
Track per-rig server connection state in `rig_server_connected` so that when
one trx-server drops, only the rig(s) it serves are marked disconnected. Other
rigs with active connections remain fully interactive. The SSE `server_connected`
field is now resolved from the per-rig map for the session's active rig, falling
back to the global flag for backward compatibility.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Signed-off-by: Stan Grams <sjg@haxx.space>
2026-03-26 23:22:07 +01:00
sjgandClaude Sonnet 4.6 ba2fbed7c3 [feat](trx-rds): improve RDS robustness with 9 DSP techniques
Tech 1: replace one-pole baseband LPF with FIR RRC matched filter
(alpha=0.75, 4-chip span) — largest single measured improvement per
empirical comparison (gr-rds RRC vs plain FIR: 32/38 vs 18/38 stations).
Tech 2: 19 kHz pilot x3 -> 57 kHz coherent carrier reference via the
triple-angle formula; fed from the WFM pilot Costas PLL when
pilot_lock_level > 0.5, clearing to NCO fallback otherwise.
Tech 3/7/8: OSD(2) soft-decision block decoder replaces hard CRC check.
Per-bit soft magnitudes accumulated in Candidate::block_soft[26].
decode_block_soft() searches Hamming distance 0/1/2 (352 trials total)
and returns the minimum Euclidean-cost valid codeword; ~2-3 dB gain.
Tech 4: 8th-order 57 kHz BPF (4 cascaded biquads at Q=5) in wfm.rs
replaces the previous single Q=10 biquad; ~6x steeper ACI stopband.
Tech 5: Costas loop with tanh soft phase detector drives the RDS carrier
NCO when no pilot reference is available (P+I, B_L ~20 Hz).
Tech 6: Block A PI field LLR accumulation — signed per-bit LLR summed
over 3 independent Block A observations before committing the PI value,
correcting weak-signal false locks without delaying strong-signal lock.
Tech 9: 8-tap complex CMA blind equalizer applied to IQ samples before
FM discrimination; constant-modulus error (|y|^2 - R^2) drives tap
adaptation without a training sequence, suppressing adjacent-channel
interference at the source.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Signed-off-by: Stan Grams <sjg@haxx.space>
2026-03-26 23:10:42 +01:00
sjgandClaude Opus 4.6 27489c3745 [feat](trx-rs): rename AMC (AM C-QUAM) to SAM (Stereo AM) with stereo width and carrier sync controls
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Signed-off-by: Stan Grams <sjg@haxx.space>
2026-03-26 21:50:53 +01:00
sjgandClaude Opus 4.6 20a22622e7 [fix](trx-frontend-http): hide scheduler controls in main view when scheduler disabled
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Signed-off-by: Stan Grams <sjg@haxx.space>
2026-03-26 21:35:06 +01:00
sjgandClaude Opus 4.6 79fcb1ba9c [feat](trx-frontend-http): add Client sub-tab to About page
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Signed-off-by: Stan Grams <sjg@haxx.space>
2026-03-26 21:23:47 +01:00
sjgandClaude Opus 4.6 999d2c0436 [fix](trx-server): prevent capacity overflow panic in audio history replay
Use saturating CAS loop in adjust_total_count to prevent AtomicUsize underflow, and cap history estimate at 500k entries.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Signed-off-by: Stan Grams <sjg@haxx.space>
2026-03-26 21:20:15 +01:00
sjgandClaude Opus 4.6 dd8d2a4bfa [fix](trx-frontend-http): hide duplicate spectrum waterfall, use overview waterfall only
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Signed-off-by: Stan Grams <sjg@haxx.space>
2026-03-26 21:06:36 +01:00
sjgandClaude Opus 4.6 d99ce62562 [fix](trx-frontend-http): swap spectrum layout — waterfall on top, waveform on bottom
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Signed-off-by: Stan Grams <sjg@haxx.space>
2026-03-26 21:01:12 +01:00
sjgandClaude Opus 4.6 a82541e24e [fix](trx-frontend-http): drop peak labels, equalize spectrum/waterfall split
Remove overkill peak frequency labels from spectrum view. Set waterfall
height to match spectrum height (1:1 split) instead of fixed 120px.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Signed-off-by: Stan Grams <sjg@haxx.space>
2026-03-26 20:53:50 +01:00
sjg 49657fa68b Merge branch 'feat/ux' 2026-03-26 20:53:36 +01:00
36be58a537 [feat](trx-frontend-http): spectrum view UI/UX improvements
Add 8 enhancements to the spectrum display:

1. Noise floor reference line — dashed horizontal line at estimated
   noise floor (15th-percentile heuristic)
2. Peak frequency labels — top 5 strongest peaks labeled with
   frequency text on the spectrum canvas
3. Crosshair lines — vertical + horizontal guide lines follow
   cursor on hover for precise frequency/dB reading
4. Zoom indicator + minimap — shows current zoom level (e.g. "4.0x")
   and a minimap showing the visible window within the full span
5. dB range control — new Range input alongside Floor, with Auto
   button updating both; allows direct control of vertical span
6. Keyboard shortcuts — Arrow Left/Right to pan, +/- to zoom,
   0 to reset zoom; documented in hint bar
7. Full waterfall panel — WebGL waterfall canvas below the spectrum
   plot, synchronized with zoom/pan, with scroll/click/drag support
8. Signal overlay extended — overlay height now includes waterfall
   canvas for consistent BW/bookmark/freq marker coverage

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Signed-off-by: Stan Grams <sjg@haxx.space>
2026-03-26 20:48:30 +01:00
sjgandClaude Opus 4.6 36325a2eef [feat](trx-frontend-http): spectrum view UI/UX improvements
Add 8 enhancements to the spectrum display:

1. Noise floor reference line — dashed horizontal line at estimated
   noise floor (15th-percentile heuristic)
2. Peak frequency labels — top 5 strongest peaks labeled with
   frequency text on the spectrum canvas
3. Crosshair lines — vertical + horizontal guide lines follow
   cursor on hover for precise frequency/dB reading
4. Zoom indicator + minimap — shows current zoom level (e.g. "4.0x")
   and a minimap showing the visible window within the full span
5. dB range control — new Range input alongside Floor, with Auto
   button updating both; allows direct control of vertical span
6. Keyboard shortcuts — Arrow Left/Right to pan, +/- to zoom,
   0 to reset zoom; documented in hint bar
7. Full waterfall panel — WebGL waterfall canvas below the spectrum
   plot, synchronized with zoom/pan, with scroll/click/drag support
8. Signal overlay extended — overlay height now includes waterfall
   canvas for consistent BW/bookmark/freq marker coverage

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Signed-off-by: Stan Grams <sjg@haxx.space>
2026-03-26 20:44:08 +01:00
sjgandClaude Opus 4.6 caa7603489 [fix](trx-rs): frost main view on trx-server disconnect
Nudge state watch when server_connected goes false so SSE delivers the change. Frontend applies a desaturated frost + banner instead of a blocking overlay, keeping the last-known state visible.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Signed-off-by: Stan Grams <sjg@haxx.space>
2026-03-26 20:28:56 +01:00
sjgandClaude Opus 4.6 c8de54d85e [feat](trx-rs): show audio bitrate and active stream count on About page
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Signed-off-by: Stan Grams <sjg@haxx.space>
2026-03-26 20:18:19 +01:00
sjgandClaude Opus 4.6 f31fbecca6 [fix](trx-core): default cw_decode_enabled to false
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Signed-off-by: Stan Grams <sjg@haxx.space>
2026-03-26 20:13:46 +01:00
sjgandClaude Opus 4.6 25338710ee [feat](trx-frontend-http): rework About page with grouped cards and new info
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Signed-off-by: Stan Grams <sjg@haxx.space>
2026-03-26 20:07:33 +01:00
sjgandClaude Opus 4.6 5be4019c04 [feat](trx-frontend-http): rename Decoders tab to Digital modes and filter by active rig
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Signed-off-by: Stan Grams <sjg@haxx.space>
2026-03-26 19:44:01 +01:00
sjgandClaude Opus 4.6 1a744e427a [feat](trx-frontend-http): draw radio path from each receiver location
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Signed-off-by: Stan Grams <sjg@haxx.space>
2026-03-26 18:57:41 +01:00
sjgandClaude Opus 4.6 10b1512d75 [style](trx-backend): fix trailing blank line in dummy.rs
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Signed-off-by: Stan Grams <sjg@haxx.space>
2026-03-26 18:57:34 +01:00
sjgandClaude Opus 4.6 ab0003b08d [feat](trx-frontend-http): show receiver/locator on map panel stat cards
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Signed-off-by: Stan Grams <sjg@haxx.space>
2026-03-26 18:36:08 +01:00
sjgandClaude Opus 4.6 7b07feb725 [fix](trx-backend): remove stale filter_state test from DummyRig
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Signed-off-by: Stan Grams <sjg@haxx.space>
2026-03-26 18:36:02 +01:00
sjg f3bc5bc34d [docs](trx-rs): update docs
Signed-off-by: Stan Grams <sjg@haxx.space>
2026-03-26 17:38:25 +01:00
sjgandClaude Opus 4.6 6eff023271 [fix](trx-frontend-http): reduce decoder overlay opacity in spectrum screenshots
Decoder bar overlays (AIS, VDES, FT8, APRS, RDS) use backdrop-filter
blur for a frosted-glass look in the browser, but this can't be
replicated on canvas — resulting in opaque blocks covering the spectrum
in screenshots. Cap their background alpha to 0.35 when rendering to
the snapshot canvas.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Signed-off-by: Stan Grams <sjg@haxx.space>
2026-03-25 23:11:51 +01:00
sjgandClaude Opus 4.6 d11f7b4876 [feat](trx-frontend-http): add F1 keyboard shortcuts overlay
Press F1 to toggle a help overlay listing available keyboard shortcuts.
Dismiss with F1, Escape, or clicking the backdrop. Refactored the
global keydown handler to route all shortcuts through one listener.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Signed-off-by: Stan Grams <sjg@haxx.space>
2026-03-25 23:11:50 +01:00
sjgandClaude Opus 4.6 892533bdc2 [feat](trx-configurator): add --check flag for config validation
Validates existing TOML config files for syntax correctness, unknown
keys, and structural issues. Auto-detects config type (server, client,
combined) and checks known sections against expected schema.

Validates: log levels, coordinate ranges, port ranges, access types,
lat/lon pairing, and unknown key warnings.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Signed-off-by: Stan Grams <sjg@haxx.space>
2026-03-25 23:11:50 +01:00
sjgandClaude Opus 4.6 81486fa147 [feat](trx-configurator): add interactive configuration generator
New binary crate that generates trx-server.toml, trx-client.toml, or
trx-rs.toml via interactive prompts or --defaults mode. Produces
commented TOML using toml_edit with per-field descriptions.

Supports server config (general, rig, listen, audio, behavior) and
client config (general, remote, frontends). Hardware detection is
stubbed for future iteration.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Signed-off-by: Stan Grams <sjg@haxx.space>
2026-03-25 23:11:50 +01:00
sjgandClaude Opus 4.6 0828f197a8 [chore](trx-rs): add workflow to sync docs submodule on wiki edits
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Signed-off-by: Stan Grams <sjg@haxx.space>
2026-03-25 21:17:58 +01:00
sjgandClaude Opus 4.6 8bd5167209 [docs](trx-rs): update docs submodule and README links for renamed pages
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Signed-off-by: Stan Grams <sjg@haxx.space>
2026-03-25 21:16:41 +01:00
sjgandClaude Opus 4.6 4ffdc12334 [docs](trx-rs): update docs submodule (Home page)
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Signed-off-by: Stan Grams <sjg@haxx.space>
2026-03-25 20:48:04 +01:00
sjgandClaude Opus 4.6 83c96518a2 [docs](trx-rs): consolidate documentation into docs/ wiki
Move scattered documentation into the docs/ submodule (GitHub wiki):
- OVERVIEW.md → docs/ARCHITECTURE.md
- SCHEDULER.md, aidocs/CONFIGURATION.md, aidocs/AUTH.md → docs/MANUAL.md
- OPTIMIZATION.md → docs/OPTIMIZATION_GUIDELINES.md
- RECORDER.md → docs/NEXT.md
- Remove aidocs/ (content migrated or obsolete)
- Update README.md documentation links

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Signed-off-by: Stan Grams <sjg@haxx.space>
2026-03-25 20:45:50 +01:00
sjg 6eb0f3a116 [fix](trx-frontend-http): preserve bookmark bandwidth
Order bookmark mode and bandwidth updates so WFM bookmarks do\nnot race against the backend mode default.\n\nAlso apply saved bookmark bandwidth in the scheduler path so\nscheduled bookmark replays keep the configured filter width.\n\nTested with:\n- cargo test -p trx-frontend-http\n\nCo-authored-by: OpenAI Codex <codex@openai.com>

Signed-off-by: Stan Grams <sjg@haxx.space>
2026-03-24 23:04:35 +01:00
sjgandClaude Opus 4.6 c93e855f0d [fix](trx-frontend-http): draw radio paths from actual receiver, improve mobile spectrum controls
Radio paths now originate from the rig that decoded the message rather
than the currently selected rig. Bookmark locators no longer draw radio
paths. Rig switch no longer tears down decode pipeline since it is
rig-independent. Mobile spectrum controls use flex-wrap for better layout.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Signed-off-by: Stan Grams <sjg@haxx.space>
2026-03-24 22:34:43 +01:00
sjgandClaude Opus 4.6 a5e443a224 [feat](trx-frontend-http): show all rig locations on map, load decode history for all remotes
Add latitude/longitude to /rigs API response. Map now displays receiver
markers for all configured rigs, de-duplicated by location. Decode history
is no longer filtered to the active rig so all remotes contribute to the map.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Signed-off-by: Stan Grams <sjg@haxx.space>
2026-03-24 22:26:48 +01:00
sjgandClaude Opus 4.6 a32560a9ab [feat](trx-frontend-http): restore rig selector on map with All as default
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Signed-off-by: Stan Grams <sjg@haxx.space>
2026-03-24 22:15:55 +01:00
sjgandClaude Opus 4.6 4b387457af [fix](trx-frontend-http): show general bookmarks in scheduler bookmark selector
Use the merged bookmarks endpoint instead of separate fetches so general
bookmarks are always visible alongside rig-specific ones.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Signed-off-by: Stan Grams <sjg@haxx.space>
2026-03-24 22:03:00 +01:00
sjgandClaude Opus 4.6 d88eb89e16 [feat](trx-frontend-http): add WASM Opus decoder fallback for Safari/iPadOS audio
WebCodecs AudioDecoder does not support Opus on Safari. Fall back to
opus-decoder WASM library (loaded from CDN) for browsers without
WebCodecs Opus support.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Signed-off-by: Stan Grams <sjg@haxx.space>
2026-03-24 21:52:09 +01:00
sjgandClaude Opus 4.6 69fcc4b068 [fix](trx-frontend-http): show all decodes on map regardless of selected rig
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Signed-off-by: Stan Grams <sjg@haxx.space>
2026-03-24 21:27:15 +01:00
sjgandClaude Opus 4.6 6b043d76be [feat](trx-frontend-http): swap play icon to pause when audio is active
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Signed-off-by: Stan Grams <sjg@haxx.space>
2026-03-24 21:15:34 +01:00
sjgandClaude Opus 4.6 127da19856 [fix](trx-frontend-http): unify Delete Selected button styling with other toolbar buttons
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Signed-off-by: Stan Grams <sjg@haxx.space>
2026-03-24 21:14:58 +01:00
sjgandClaude Opus 4.6 65c59e55e4 [fix](trx-frontend-http): separate bookmark overlay list from editor list
Scope picker filters the bookmarks table for editing. Spectrum and map
always show merged general + active rig bookmarks via bmOverlayList.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Signed-off-by: Stan Grams <sjg@haxx.space>
2026-03-24 21:12:59 +01:00
sjgandClaude Opus 4.6 a00b1d216a [fix](trx-frontend-http): show trx-client version in header, remove version info from footer
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Signed-off-by: Stan Grams <sjg@haxx.space>
2026-03-24 21:08:41 +01:00
sjgandClaude Opus 4.6 68449425be [fix](trx-frontend-http): always list rig-specific and general bookmarks together
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Signed-off-by: Stan Grams <sjg@haxx.space>
2026-03-24 21:05:47 +01:00
sjgandClaude Opus 4.6 e52d276198 [fix](trx-frontend-http): use display names in header rig picker
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Signed-off-by: Stan Grams <sjg@haxx.space>
2026-03-24 21:04:15 +01:00
sjgandClaude Opus 4.6 eb798ad79f [feat](trx-frontend-http): merge general bookmarks into rig view, fix button styling, improve rig display names
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Signed-off-by: Stan Grams <sjg@haxx.space>
2026-03-24 21:02:08 +01:00
sjgandClaude Opus 4.6 de5f27f75e [feat](trx-frontend-http): add Select All bookmarks across pages, fix move wrap styling
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Signed-off-by: Stan Grams <sjg@haxx.space>
2026-03-24 20:52:01 +01:00
sjgandClaude Opus 4.6 abe8529332 [feat](trx-frontend-http): add batch move bookmarks between scopes
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Signed-off-by: Stan Grams <sjg@haxx.space>
2026-03-24 20:47:32 +01:00
sjgandClaude Opus 4.6 8c44a1b5f2 [fix](trx-frontend-http): scope server-lost overlay to content area, keep header accessible
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Signed-off-by: Stan Grams <sjg@haxx.space>
2026-03-24 20:43:15 +01:00
sjgandClaude Opus 4.6 dc271c1fdb chore(trx-rs): remove WIP.md, all items implemented
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Signed-off-by: Stan Grams <sjg@haxx.space>
2026-03-24 20:31:56 +01:00
sjgandClaude Opus 4.6 55266bf83e [fix](trx-frontend-http): add Default impl for BookmarkStoreMap, merge bookmarks in scheduler
Fix clippy warning by adding Default impl for BookmarkStoreMap. Scheduler
bookmark picker now fetches both general and rig-specific bookmarks and
merges them so all available bookmarks are shown.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Signed-off-by: Stan Grams <sjg@haxx.space>
2026-03-24 20:26:55 +01:00
sjgandClaude Opus 4.6 55688a27b2 [feat](trx-frontend-http): per-rig bookmarks, scheduler, and decode filtering
Two-tier bookmark system: general bookmarks shared across all rigs plus
rig-specific bookmarks with scope picker in the Bookmarks tab. Scheduler
storage split into per-rig files with migration from legacy single file.
Decode history tagged with rig_id and filterable via ?remote= on
/decode/history endpoint. Decode SSE reconnects on rig switch to refresh
filtered history.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Signed-off-by: Stan Grams <sjg@haxx.space>
2026-03-24 20:24:49 +01:00
sjg b50c6bca96 chore(trx-rs): add WIP.md
Signed-off-by: Stan Grams <sjg@haxx.space>
2026-03-24 08:52:01 +01:00
sjgandClaude Opus 4.6 e46189e9ac [fix](trx-client): use send_replace for per-rig audio stream info
watch::Sender::send() silently discards the value when receiver_count
is zero.  The per-rig info channel is created with watch::channel().0
which drops the only Receiver, so the first send(Some(info)) after TCP
connect returns early without storing the value.  Later subscribers
see None forever.  send_replace() stores unconditionally.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Signed-off-by: Stan Grams <sjg@haxx.space>
2026-03-24 08:39:29 +01:00
sjgandClaude Opus 4.6 7e447ab1f6 [fix](trx-frontend-http): drop global info_rx fallback for vchan audio
Use only the per-rig stream info when a remote is specified on the
channel audio path; do not fall back to the global channel.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Signed-off-by: Stan Grams <sjg@haxx.space>
2026-03-24 08:03:07 +01:00
sjgandClaude Opus 4.6 723e3ad7cb [fix](trx-client): preserve per-rig stream info across audio reconnects
The audio client was clearing per_rig_info_tx to None every time the
TCP connection dropped, even during transient reconnect cycles.  This
caused WebSocket clients subscribing to per-rig audio to stall
indefinitely waiting for stream info that would only arrive after the
next successful reconnect.

Move the None send to the permanent shutdown path only.  The last-known
stream info remains valid for the same rig across reconnects.

Also revert the global info_rx fallback from 6e4c5e3 since the root
cause is now fixed.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Signed-off-by: Stan Grams <sjg@haxx.space>
2026-03-24 08:00:13 +01:00
sjgandClaude Opus 4.6 6e4c5e3c72 [fix](trx-frontend-http): fall back to global stream info for per-rig audio
Per-rig info_rx watch channel is transiently None when the rig's audio
TCP connection is between reconnect cycles.  This caused the WebSocket
handler to hang indefinitely waiting for stream info that might never
arrive, regressed in 7d76606.

Prefer the per-rig info_rx when it holds a value, otherwise fall back to
the global info channel (the pre-regression behaviour).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Signed-off-by: Stan Grams <sjg@haxx.space>
2026-03-24 07:55:09 +01:00
sjgandClaude Opus 4.6 cfc8407c3a [chore](trx-frontend-http): add debug logging to audio WebSocket handler
Trace per-rig audio subscription lookup, stream info availability, and
session lifecycle to diagnose multi-rig audio regression.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Signed-off-by: Stan Grams <sjg@haxx.space>
2026-03-24 07:50:14 +01:00
sjgandOpenAI Codex 80ed1155f5 [fix](trx-frontend-http): scope channel audio by remote
Send the selected remote together with virtual-channel audio requests and use per-rig stream info when /audio is opened with channel_id.

This keeps browser channel audio aligned with the requested remote after the recent multi-rig client changes.

Add coverage for parsing channel_id together with remote.

Co-authored-by: OpenAI Codex <noreply@openai.com>
Signed-off-by: Stan Grams <sjg@haxx.space>
2026-03-24 07:29:57 +01:00
sjgandOpenAI Codex db5fa26bd9 [fix](trx-frontend-http): start browser audio on user gesture
Create and resume the RX AudioContext from the audio button click so Chromium does not leave playback suspended until a later interaction.

Reuse that context when stream metadata arrives instead of recreating it from the WebSocket message path.

Co-authored-by: OpenAI Codex <noreply@openai.com>
Signed-off-by: Stan Grams <sjg@haxx.space>
2026-03-23 22:52:28 +01:00
sjgandOpenAI Codex 32e1618384 [fix](trx-frontend-http): drop rig_id http aliases
Remove the remaining legacy rig_id aliases across the HTTP frontend and use remote consistently for scheduler and audio requests.

Disable browser caching for the HTML, CSS, and JS assets so clients pick up the parameter rename immediately instead of running stale frontend code.

Co-authored-by: OpenAI Codex <noreply@openai.com>
Signed-off-by: Stan Grams <sjg@haxx.space>
2026-03-23 22:49:01 +01:00
sjgandOpenAI Codex 7d76606927 [fix](trx-frontend-http): accept remote on audio endpoint
Parse the renamed `remote` query parameter on `/audio` while keeping
`rig_id` as a compatibility alias, and use per-rig stream info for
rig-scoped audio subscriptions.

Add tests covering both query names.

Co-authored-by: OpenAI Codex <noreply@openai.com>
Signed-off-by: Stan Grams <sjg@haxx.space>
2026-03-23 22:31:04 +01:00
sjgandOpenAI Codex b8ce05d41e [fix](trx-client): isolate selected state per server group
Keep global state and spectrum updates scoped to the server group that
owns the selected short name, so other servers cannot overwrite the UI
or clear the active spectrum stream.

Add regression tests for cross-server selection and spectrum ownership.

Co-authored-by: OpenAI Codex <noreply@openai.com>
Signed-off-by: Stan Grams <sjg@haxx.space>
2026-03-23 22:23:22 +01:00
sjgandOpenAI Codex fad63be247 [fix](trx-client): keep multi-server rigs in audio cache
Merge per-server GetRigs updates into the shared remote rig cache
instead of replacing it, so audio tasks from other servers are not
torn down on each poll cycle.

Add a regression test covering the multi-server cache update path.

Co-authored-by: OpenAI Codex <noreply@openai.com>
Signed-off-by: Stan Grams <sjg@haxx.space>
2026-03-23 22:18:50 +01:00
sjgandOpenAI Codex e09f14d2d3 [feat](trx-client): support audio URL overrides
Use full audio endpoint URLs for trx-server audio connections while
preserving server-advertised ports and legacy port-based fallback for
backward compatibility.

Add `server_url` and per-remote `rig_urls` config entries, plus
validation and tests for audio URL parsing and address resolution.

Co-authored-by: OpenAI Codex <noreply@openai.com>
Signed-off-by: Stan Grams <sjg@haxx.space>
2026-03-23 22:04:14 +01:00
sjgandOpenAI Codex d8444f35f6 [refactor](trx-frontend-http): rename rig_id API fields to remote
Rename HTTP query params, JSON fields, and scheduler payloads to
use remote names consistently while still accepting legacy `rig_id`
inputs through serde aliases.

Co-authored-by: OpenAI Codex <noreply@openai.com>
Signed-off-by: Stan Grams <sjg@haxx.space>
2026-03-23 21:54:45 +01:00
sjgandOpenAI Codex 2db13da706 [fix](trx-client): use default remote name in config
Use the remote short name for the HTTP frontend default selection and
keep `default_rig_id` as a serde alias for backward compatibility.

Co-authored-by: OpenAI Codex <noreply@openai.com>
Signed-off-by: Stan Grams <sjg@haxx.space>
2026-03-23 21:54:37 +01:00
sjgandClaude Opus 4.6 9cd172ce64 [feat](trx-client): support multiple trx-servers from a single client
Introduce [[remotes]] config array where each entry maps a user-chosen
short name to a (server URL, rig_id) pair. Short names replace raw
rig_ids as the universal key throughout frontends, audio routing, and
state management, allowing rig_ids to safely collide across servers.

Entries sharing the same server URL and token share a single TCP
connection. A request routing dispatcher forwards frontend commands to
the correct per-server channel based on the short name.

Legacy [remote] config and CLI --url are preserved via automatic
fallback to a single-entry remotes list.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Signed-off-by: Stan Grams <sjg@haxx.space>
2026-03-23 21:00:31 +01:00
sjgandClaude Opus 4.6 1e438acaf7 [feat](trx-frontend-http): show rig name and location in page title
Include active rig display name and nearest city in the browser tab
title: "freq - rig name - city, country - trx-rs v<version>".

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Signed-off-by: Stan Grams <sjg@haxx.space>
2026-03-22 14:20:09 +01:00
sjg 6c8d294f6a [chore](docs): upgrade docs
Signed-off-by: Stan Grams <sjg@haxx.space>
2026-03-22 14:15:51 +01:00
sjg eb97d8379d [chore](trx-rs): remove MANUAL.md - moved to docs/ (wiki submodule)
Signed-off-by: Stan Grams <sjg@haxx.space>
2026-03-22 14:15:25 +01:00
sjgandClaude Opus 4.6 182240faa8 [docs](trx-rs): add threshold selection guide to MANUAL.md
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Signed-off-by: Stan Grams <sjg@haxx.space>
2026-03-22 14:14:04 +01:00
sjgandClaude Opus 4.6 a5a654d508 [docs](trx-rs): add noise blanker section to MANUAL.md
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Signed-off-by: Stan Grams <sjg@haxx.space>
2026-03-22 14:11:26 +01:00
sjgandClaude Opus 4.6 1f6e3bb142 [feat](trx-frontend-http): add noise blanker controls to SDR settings UI
Add checkbox to enable/disable NB and number input for threshold (1-100).
Controls are hidden by default and shown when the server reports NB support
via SSE filter state updates.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Signed-off-by: Stan Grams <sjg@haxx.space>
2026-03-22 14:05:14 +01:00
sjgandClaude Opus 4.6 189d27bac8 [feat](trx-rs): add configurable noise blanker for SoapySDR backend
IQ-domain impulse noise blanker using exponential-smoothing RMS tracker. Samples exceeding threshold × running RMS are replaced with the last clean sample. Configurable via [sdr.noise_blanker] in TOML config and runtime via POST /set_sdr_noise_blanker API.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Signed-off-by: Stan Grams <sjg@haxx.space>
2026-03-22 13:54:17 +01:00
sjgandClaude Opus 4.6 01a6b331f6 [fix](trx-frontend-http): invalidate bookmark colors on style change too
The bookmark color palette is derived from CSS variables (--accent-yellow,
--accent-green, etc.) which change on both dark/light theme toggle AND
palette style change (arctic, lime, etc.). The previous fix only covered
setTheme; extract invalidateBookmarkColors() and call it from setStyle
as well so bookmark chips recolour on any visual change.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Signed-off-by: Stan Grams <sjg@haxx.space>
2026-03-22 12:12:09 +01:00
sjgandClaude Opus 4.6 f9f06a1db1 [fix](trx-frontend-http): force style recalc before reading bookmark theme colors
getComputedStyle may return stale CSS variable values if the browser
has not flushed the style recalculation after changing data-theme. Force
a recalc by reading a property value first. Also clear cached bookmark
DOM keys so the next draw pass rebuilds chips from scratch.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Signed-off-by: Stan Grams <sjg@haxx.space>
2026-03-22 09:42:41 +01:00
sjgandClaude Opus 4.6 2d1f635019 [fix](trx-frontend-http): directly re-apply bookmark chip colors on theme change
Bumping bmRevision and scheduling a spectrum draw was not enough because
the spectrum draw path only runs when spectrum data is present. Instead,
directly update --bm-cat-bg/--bm-cat-fg on all existing bookmark chips
from the new theme palette so colors update immediately.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Signed-off-by: Stan Grams <sjg@haxx.space>
2026-03-22 09:29:50 +01:00
sjgandClaude Opus 4.6 4d09636793 [fix](trx-frontend-http): guard scheduleSpectrumDraw from TDZ during init
scheduleSpectrumDraw references a let-bound variable that hasn't been
initialized yet when setTheme runs at startup. Wrap in try/catch so the
early call is silently skipped.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Signed-off-by: Stan Grams <sjg@haxx.space>
2026-03-22 09:25:38 +01:00
sjgandClaude Opus 4.6 84259a01f4 [fix](trx-frontend-http): redraw bookmark colors on theme change
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Signed-off-by: Stan Grams <sjg@haxx.space>
2026-03-22 09:20:32 +01:00
sjgandClaude Opus 4.6 4ad5bf863d [fix](trx-client): update per-rig state channel on command response
send_command only updated the global state_tx watch channel, but SSE
sessions subscribe to per-rig rig_states channels. Per-rig channels were
only updated during the poll cycle (default 750ms). Now send_command also
pushes state to the per-rig channel immediately, eliminating up to 750ms
of latency for confirmed frequency/mode/state changes.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Signed-off-by: Stan Grams <sjg@haxx.space>
2026-03-22 09:09:59 +01:00
sjgandClaude Opus 4.6 3ad5f7a3b7 [fix](trx-frontend-http): make vchan wrapper fire-and-forget on freq change
The vchan setRigFrequency wrapper was awaiting vchanTakeSchedulerControl()
(HTTP PUT to /scheduler-control) and vchanSetChannelFreq() (HTTP PUT to
channel freq endpoint) before calling the original setRigFrequency. This
added a full HTTP round-trip of latency to every frequency change. Make
both fire-and-forget: optimistic local update happens first, network calls
run in background.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Signed-off-by: Stan Grams <sjg@haxx.space>
2026-03-22 08:57:50 +01:00
sjgandClaude Opus 4.6 faf86faff9 [fix](trx-frontend-http): make setRigFrequency fire-and-forget
The HTTP round-trip for set_freq blocks on the server processing the
command (mpsc → TCP → rig hardware → response). With optimistic local
updates, CSS overlay, and SSE snap-back guard already in place, there is
no reason to await the network call. All callers (jog, freq input, spectrum
click, RDS AF tune) now return immediately after the optimistic update.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Signed-off-by: Stan Grams <sjg@haxx.space>
2026-03-22 08:31:01 +01:00
sjgandClaude Opus 4.6 7f9ecad34c [fix](trx-frontend-http): prevent SSE from snapping freq back during optimistic update
When the user changes frequency, applyLocalTunedFrequency sets lastFreqHz
optimistically. But the SSE state stream could push back the old server
frequency before set_freq completes, causing the marker to snap back then
forward. Add a sequence-guarded _freqOptimisticHz that suppresses stale
SSE frequency updates while a set_freq is in flight.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Signed-off-by: Stan Grams <sjg@haxx.space>
2026-03-22 08:20:58 +01:00
sjgandClaude Opus 4.6 54df7cf0f9 [feat](trx-frontend-http): GPU-composited CSS overlay for instant freq/BW updates
Replace synchronous drawSignalOverlay() calls in freq/BW change handlers
with lightweight CSS div elements repositioned via transform: translateX().
This is GPU-composited with zero layout/paint cost, making frequency and
bandwidth changes appear instantaneous. The full WebGL overlay catches up
on the next requestAnimationFrame.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Signed-off-by: Stan Grams <sjg@haxx.space>
2026-03-22 08:09:36 +01:00
sjgandClaude Opus 4.6 dc2c8b6eb1 [fix](trx-frontend-http): instant spectrum overlay on freq/bw changes
Call drawSignalOverlay() synchronously on frequency and bandwidth changes instead of deferring entirely to requestAnimationFrame. Also make bookmark apply fire-and-forget so the click handler returns immediately after optimistic UI updates.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Signed-off-by: Stan Grams <sjg@haxx.space>
2026-03-22 07:51:30 +01:00
sjgandClaude Opus 4.6 5821531a93 [feat](trx-client): per-rig audio TCP connections
Replace single-connection relay with per-rig audio manager that spawns independent TCP connections for each rig. Each rig gets its own broadcast channel, stream info, and vchan command routing. Selected rig mirrors to global channels for backward compat. Also fix bookmark apply to update spectrum marker instantly and fire all requests in parallel.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Signed-off-by: Stan Grams <sjg@haxx.space>
2026-03-22 07:37:59 +01:00
sjgandClaude Opus 4.6 5d905bff87 [fix](trx-frontend-http): stop per-rig audio fallback to global broadcast
When ?rig_id= is specified on /audio, don't fall back to the global broadcast (which carries whichever rig is connected). Return 404 for rigs without an active audio connection instead of silently delivering the wrong rig's audio. Also create per-rig audio channels for all known rigs eagerly so connected rigs are instantly subscribable.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Signed-off-by: Stan Grams <sjg@haxx.space>
2026-03-22 07:26:26 +01:00
sjgandClaude Opus 4.6 bf754f573a [fix](trx-frontend-http): filter SSE channel events by rig and fix audio hang
Channel SSE events were broadcast to all tabs regardless of rig, causing tabs to display wrong rig's channels. Per-rig audio info_rx override caused WebSocket to hang waiting for stream info that never arrives.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Signed-off-by: Stan Grams <sjg@haxx.space>
2026-03-22 07:17:26 +01:00
sjgandClaude Opus 4.6 9900314c8c [feat](trx-client): add per-rig spectrum and audio streams
Each browser tab can now subscribe to a specific rig's spectrum and
audio independently via ?rig_id= query params on /spectrum and /audio.
The remote client polls spectrum for all rigs with active subscribers
and routes responses to per-rig watch channels. Virtual channel
commands are routed through per-rig senders with global fallback.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Signed-off-by: Stan Grams <sjg@haxx.space>
2026-03-22 06:59:54 +01:00
sjgandClaude Opus 4.6 6fb7b61c1c [feat](trx-frontend-http): auto-subscribe new sessions to primary channel
When a new tab connects and receives the initial channels event,
automatically subscribe to channel 0 (primary) so the session joins
the same tuned channel as other users on that rig. Uses a lightweight
auto-join that skips scheduler control takeover since audio isn't
started yet at this point.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Signed-off-by: Stan Grams <sjg@haxx.space>
2026-03-22 06:15:47 +01:00
sjgandClaude Opus 4.6 0e195bd3c6 [fix](trx-frontend-http): remove global state mutation from select_rig
select_rig no longer mutates remote_active_rig_id — only the per-session
mapping is updated. This eliminates cross-tab leaking entirely: each tab
carries its own rig_id via the session manager, /events?rig_id, and
/status?rig_id query params.

The global remote_active_rig_id now only serves as the startup default
for brand-new sessions that have no rig_id yet.

Also fix the About section to show the per-tab lastActiveRigId instead
of the server's global active_rig_id.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Signed-off-by: Stan Grams <sjg@haxx.space>
2026-03-22 00:20:34 +01:00
sjgandClaude Opus 4.6 f3d8d349b1 [fix](trx-frontend-http): make /status respect per-tab rig selection
pollFreshSnapshot() fetches GET /status on every SSE connect/reconnect,
but /status always returned the global selected rig's state, overwriting
the per-tab display with whichever rig was last switched to globally.

Now pollFreshSnapshot passes rig_id as a query param and the /status
endpoint uses the per-rig watch channel when provided, matching the
/events behavior for true per-tab rig isolation.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Signed-off-by: Stan Grams <sjg@haxx.space>
2026-03-22 00:14:43 +01:00
sjgandClaude Opus 4.6 0836c815e4 [fix](trx-frontend-http): restore global rig update in select_rig
The previous commit conditionally skipped updating remote_active_rig_id
when session_id was provided, but the remote client reads the global to
route commands to the correct rig on trx-server. Restore the
unconditional global update; cross-tab SSE isolation is handled by the
rig_id query param on /events and the JS-side guard in applyRigList.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Signed-off-by: Stan Grams <sjg@haxx.space>
2026-03-22 00:08:41 +01:00
sjgandClaude Opus 4.6 c332172900 [fix](trx-frontend-http): pass rig_id to SSE endpoint on reconnect
After select_rig stopped mutating the global remote_active_rig_id for
session-aware clients, SSE reconnects would fall back to the old global
default instead of the newly selected rig. Now connect() passes
lastActiveRigId as a rig_id query param to /events, and the server
prefers it over the global default when present.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Signed-off-by: Stan Grams <sjg@haxx.space>
2026-03-22 00:04:36 +01:00