Commit Graph

1205 Commits

Author SHA1 Message Date
github-actions[bot] d42c803f91 [chore](trx-rs): sync docs submodule with wiki 2026-03-26 06:10:47 +00:00
Claude 74eb755858 [chore](trx-rs): update Cargo.lock
https://claude.ai/code/session_01XzurkeuUmamBuhQwxVy7T4
Signed-off-by: Claude <noreply@anthropic.com>
2026-03-26 07:02:46 +01:00
Claude 22ad90b2ba [fix](trx-server): release mutex before serialization in flush_all
Clone history data out under the lock, then drop the guard before
calling save_key, so serialization never blocks concurrent readers.

https://claude.ai/code/session_01XzurkeuUmamBuhQwxVy7T4
Signed-off-by: Claude <noreply@anthropic.com>
2026-03-26 07:02:46 +01:00
Claude d7c8eed44f [feat](trx-frontend-http): add per-IP login rate limiting
Implement LoginRateLimiter that tracks failed login attempts per IP,
enforcing a cooldown (10 attempts per 60s window) to mitigate brute-
force attacks on the /auth/login endpoint.

https://claude.ai/code/session_01XzurkeuUmamBuhQwxVy7T4
Signed-off-by: Claude <noreply@anthropic.com>
2026-03-26 07:02:46 +01:00
Claude c299e9a2d2 [fix](trx-server): truncate raw JSON in error logs to 128 chars
Prevent potential information disclosure by truncating raw client input
in log messages instead of logging the full payload.

https://claude.ai/code/session_01XzurkeuUmamBuhQwxVy7T4
Signed-off-by: Claude <noreply@anthropic.com>
2026-03-26 07:02:46 +01:00
Claude edf16b63d6 [fix](trx-core): log invalid state machine transitions
Add debug-level tracing for rejected state transitions instead of
silently returning false, aiding debugging of unexpected rig behavior.

https://claude.ai/code/session_01XzurkeuUmamBuhQwxVy7T4
Signed-off-by: Claude <noreply@anthropic.com>
2026-03-26 07:02:46 +01:00
Claude 9cf66fc04a [fix](trx-app): add plugin loading validation and disable toggle
Reject world-writable plugin files on Unix to prevent loading tampered
libraries. Add TRX_PLUGINS_DISABLED env var to disable plugin loading
entirely.

https://claude.ai/code/session_01XzurkeuUmamBuhQwxVy7T4
Signed-off-by: Claude <noreply@anthropic.com>
2026-03-26 07:02:46 +01:00
Claude cbe22bd7b6 [refactor](trx-frontend-http): replace string-level JSON splice with serde(flatten)
Use a StateWithMeta wrapper struct with #[serde(flatten)] for merging
rig state with frontend meta, replacing the manual string manipulation.
Also add Serialize derive and skip_serializing_if to FrontendMeta.

https://claude.ai/code/session_01XzurkeuUmamBuhQwxVy7T4
Signed-off-by: Claude <noreply@anthropic.com>
2026-03-26 07:02:46 +01:00
Claude 635a1214d0 [refactor](trx-client): switch VChanAudioCmd to bounded channels (cap 256)
Replace unbounded_channel with channel(256) for VChanAudioCmd to prevent
unlimited memory accumulation under backpressure. Use try_send in
synchronous contexts.

https://claude.ai/code/session_01XzurkeuUmamBuhQwxVy7T4
Signed-off-by: Claude <noreply@anthropic.com>
2026-03-26 07:02:46 +01:00
Claude c3abc5ff5b [refactor](trx-frontend): add DecodeHistory type alias and use bounded channels
Introduce DecodeHistory<T> alias for the repeated
Arc<Mutex<VecDeque<(Instant, Option<String>, T)>>> pattern (9 fields).
Also switch VChanAudioCmd channel senders from UnboundedSender to Sender
to prevent unbounded memory growth under backpressure.

https://claude.ai/code/session_01XzurkeuUmamBuhQwxVy7T4
Signed-off-by: Claude <noreply@anthropic.com>
2026-03-26 07:02:46 +01:00
Claude 449b877694 [refactor](trx-ftx): use HashSet for candidate deduplication
Replace Vec::contains() with HashSet::insert() for O(1) dedup lookups
instead of O(n), significantly reducing comparisons during decode.

https://claude.ai/code/session_01XzurkeuUmamBuhQwxVy7T4
Signed-off-by: Claude <noreply@anthropic.com>
2026-03-26 07:02:46 +01:00
Claude 99d95c8eb6 [refactor](trx-frontend-rigctl): adapt to Cow-returning mode_to_string
Update rig_mode_to_str to call .into_owned() on the new Cow return.

https://claude.ai/code/session_01XzurkeuUmamBuhQwxVy7T4
Signed-off-by: Claude <noreply@anthropic.com>
2026-03-26 07:02:46 +01:00
Claude 019f12e3fc [refactor](trx-protocol): return Cow<'static, str> from mode_to_string
Eliminates per-call String allocations for standard modes by returning
borrowed static strings. Only the Other variant allocates.

https://claude.ai/code/session_01XzurkeuUmamBuhQwxVy7T4
Signed-off-by: Claude <noreply@anthropic.com>
2026-03-26 07:02:46 +01:00
sjg 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
sjg 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
sjg 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
sjg 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
github-actions[bot] ac751bd82d [chore](trx-rs): sync docs submodule with wiki 2026-03-25 22:11:27 +00:00
github-actions[bot] ff81bc64c0 [chore](trx-rs): sync docs submodule with wiki 2026-03-25 20:34:31 +00:00
sjg 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
sjg 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
sjg 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
sjg 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
sjg 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
sjg 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
sjg 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
sjg 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
sjg 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
sjg 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
sjg 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
sjg 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
sjg 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
sjg 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
sjg 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
sjg 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
sjg 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
sjg 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
sjg 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
sjg 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
sjg 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
sjg 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
sjg 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
sjg 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
sjg 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
sjg 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
sjg 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
sjg 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
sjg 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