Record Opus audio streams to OGG files on the client. Includes manual start/stop via HTTP API, scheduler-driven auto-recording per schedule entry, and a header REC button in the web UI.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Signed-off-by: Stan Grams <sjg@haxx.space>
Show S0–S9 as whole units and S9+xdB in 10dB steps instead of fractional S-unit values.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Signed-off-by: Stan Grams <sjg@haxx.space>
Signal strength now refreshes every 100ms for SDR backends using the cached DSP value, keeping the S-meter responsive at half the spectrum redraw rate.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Signed-off-by: Stan Grams <sjg@haxx.space>
Fetch /decoders on page load and use the registry to drive all
decoder-related UI instead of hardcoded lists:
- bookmarks.js: bmReadDecoders/bmWriteDecoders and bookmark form
checkboxes generated from registry; bmApply() decoder toggle gate
uses registry active_modes instead of hardcoded DIG/FM check
- background-decode.js: delete SUPPORTED_DECODERS constant, derive
bookmarkDecoderKinds() from registry
- app.js: _decoderToggles and SSE status sync built from registry;
updateDecodeStatus() and setModeBoundDecodeStatus() driven by
registry mode_bound/toggle entries
- index.html: replace 8 hardcoded decoder checkboxes with dynamic
container populated from registry
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Signed-off-by: Stan Grams <sjg@haxx.space>
Add DECODER_REGISTRY in trx-protocol::decoders as the single source of
truth for all decoder metadata (activation mode, supported rig modes,
background-decode capability). Replace duplicated resolver functions in
background_decode.rs and sse.rs with shared resolve_bookmark_decoders().
Add GET /decoders endpoint to expose the registry to the frontend.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Signed-off-by: Stan Grams <sjg@haxx.space>
For SDR backends, DIG and PKT are removed from supported_modes and
replaced by USB and FM respectively. CAT backends (FT-817, FT-450D)
retain DIG/PKT as before.
Decoder mode allowances updated:
- APRS: FM | PKT (was PKT only)
- HF-APRS: USB | DIG (was DIG only)
- AIS: AIS | FM | PKT (was AIS only)
- VDES: VDES | FM (was VDES only)
- FT8/FT4/FT2/WSPR: USB | DIG (unchanged)
- CW: CW | CWR (unchanged)
- LRPT: FM (unchanged, mode-independent)
Frontend status text, bookmark decoder toggles, background-decode
fallbacks, and scheduler wiring updated to match.
https://claude.ai/code/session_01DCAaMH8RF5FNB2gRtVu4pY
Signed-off-by: Claude <noreply@anthropic.com>
The band plan strip was visually positioned between the waterfall and
waveform areas. Move it to the top of .signal-visual-block (above the
overview/waterfall) so it renders above the waterfall. Remove the
bp-webgl transparent overrides since the strip now shows colored
segments in its own position rather than overlaying the spectrum canvas.
https://claude.ai/code/session_01KoxcohG6hn5b7kSc3mC4dA
Signed-off-by: Claude <noreply@anthropic.com>
Relocate the band plan strip from the top of the spectrum canvas to the
bottom, directly above the waterfall canvas. Move the DOM element inside
.spectrum-wrap before the waterfall canvas so it flows naturally in the
correct position. Remove the reparenting logic since the element is now
always inside .spectrum-wrap.
https://claude.ai/code/session_01FUD2eKgeXMFGhhYTzmA4Z6
Signed-off-by: Claude <noreply@anthropic.com>
The statistics tab had max-width: 72rem (1152px) while its parent .card
container uses --card-base-max-width: 1280px. This made the stats panel
visibly narrower than the header. Removing the constraint lets the panel
fill the card width like all other tab panels.
https://claude.ai/code/session_01SfhMwN8YKKEdA3f3JyfwUZ
Signed-off-by: Claude <noreply@anthropic.com>
- IX-2: Add confirm() dialogs before all destructive actions (10 history
clear buttons, scheduler reset, background decode reset)
- IX-6: Add Select All / Deselect All buttons for background decode
bookmark checklist
- IX-1: Add dirty-state indicator (pulsing dot) on Save buttons when
unsaved changes exist in scheduler and background decode panels
- A-4: Add role="alert" and aria-live="polite" to toast notification
elements for screen reader accessibility
- A-3: Add Unicode symbol prefixes to background decode state labels
(checkmark/triangle/cross) so state is distinguishable without color
https://claude.ai/code/session_01ShfPMW9hPLD3czp9YovkbJ
Signed-off-by: Claude <noreply@anthropic.com>
The spectrum floor/gamma IIFE (line 11507) was missing its closing
`})();`, causing all bandplan strip variables and functions to be
trapped inside the IIFE scope. This made `bandplanRegion`,
`updateBandplanStrip`, and `_bandplanServerDefaultApplied` invisible
to the rest of the file, throwing ReferenceErrors that crashed
`render()` before the frequency display update could run — leaving
the frequency input stuck at its initial "--" placeholder.
https://claude.ai/code/session_01RgKhusmnk7AHEJqn1KHffU
Signed-off-by: Claude <noreply@anthropic.com>
The "Decodes by type" statistics panel only showed AIS because
statsRecordDecode was only called from dispatchDecodeMessage, which
was bypassed by two code paths:
1. dispatchDecodeBatch: uniform-type batches dispatched to specialized
batch handlers (onServerFt8Batch, etc.) returned early without
recording stats.
2. restoreDecodeHistoryGroup: history messages restored on page load
were never recorded in the statistics log.
Fix both paths by recording stats up-front in dispatchDecodeBatch
before dispatching to batch handlers, and in restoreDecodeHistoryGroup
before restoring to plugin views. Add a skipStats parameter to
dispatchDecodeMessage to prevent double-counting when the fallback
per-message loop runs inside dispatchDecodeBatch. Also accept an
optional timestamp in statsRecordDecode so history entries use their
original ts_ms rather than Date.now().
https://claude.ai/code/session_01Ss2AD2bQgXu1ir1Z1WE3VY
Signed-off-by: Claude <noreply@anthropic.com>
Extract the three summary sections (longest decode paths, strongest/weakest
signals) from the Map tab into a new dedicated Statistics tab. Add new
analytics: decode counters, unique stations/grids, decode rate, decode-by-type
breakdown, band activity, per-receiver comparison, and DX distance histogram.
The Statistics panel has its own receiver and history filters independent of
the map view.
https://claude.ai/code/session_01R9T4Byg7uw6qpkTsyVJd9k
Signed-off-by: Claude <noreply@anthropic.com>
Add bandplan_enabled (default: true) and bandplan_region (default:
"iaru_r1") fields to [frontends.http] config section, allowing the
operator to control the initial bandplan display setting from the
server config rather than requiring each browser session to configure
it manually. The server-provided default is applied on first connect
only when the user has no existing localStorage override.
https://claude.ai/code/session_01H7427hzbJepJzkoUJzoDmH
Signed-off-by: Claude <noreply@anthropic.com>
Previously R would retune even when the frequency was already aligned
to the jog step boundary. Now it shows "Already on step" and sends no
command. Also remove the stale "retune" label from the shortcut help.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Signed-off-by: Stan Grams <sjg@haxx.space>
Move bandplan segment rendering from DOM elements to WebGL, drawing
coloured rectangles at the bottom of the spectrum canvas (above the
waterfall). All segments are batched into a single drawTriangles() call
for efficiency. The DOM strip is reparented into .spectrum-wrap and
restyled as a transparent text-label overlay (bp-webgl class). Non-SDR
rigs without a spectrum canvas retain the original DOM-coloured fallback.
https://claude.ai/code/session_01XTizHhXbXSAPQVAf1j9CSF
Signed-off-by: Claude <noreply@anthropic.com>
Move the bandplan strip out of the SDR-only spectrum panel into the
always-visible signal-visual-block. Add bandplanComputeRange() that
derives a frequency range from the current tuned frequency and band
edges when no spectrum data is available (non-SDR rigs). Trigger
bandplan updates on frequency changes and from the overview draw loop.
https://claude.ai/code/session_01AyBktp6b8qFjchyyqwL7dv
Signed-off-by: Claude <noreply@anthropic.com>
Remove the wxsat/NOAA APT checkbox from bookmark decoder form and all
JS references — the APT decoder no longer exists.
Fix LRPT decoder not activating when an FM-mode bookmark is applied:
bmApply() gated decoder toggles on DIG mode only, so LRPT bookmarks
(which use FM) never triggered SetLrptDecodeEnabled. Gate on DIG or FM.
Wire satellite pass scheduling into the scheduler loop: check configured
satellite entries against live pass predictions, activate the satellite's
bookmark (enabling LRPT decoder) when a pass is active, and expose
active_satellite in SchedulerStatus for the frontend.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Signed-off-by: Stan Grams <sjg@haxx.space>
Add a bandplan display strip that shows IARU frequency allocations
(CW, Phone, Digital, FM, Beacon, Satellite) above the spectrum plot.
Includes IARU Region 1/2/3 data for all HF/VHF/UHF bands, a settings
submenu for region selection and label toggle, and color-coded segments
that pan/zoom with the spectrum view.
https://claude.ai/code/session_01AyBktp6b8qFjchyyqwL7dv
Signed-off-by: Claude <noreply@anthropic.com>
Combine round (R) and retune (T) into a single R hotkey that rounds to
the nearest jog step boundary, or retunes if already rounded. Update F
hotkey description to "Pick frequency" in the F1 help overlay.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Signed-off-by: Stan Grams <sjg@haxx.space>
Visual 24h timeline bar, inline entry editor, interleave progress ring, filterable checkbox list for bookmarks, status cards moved to top, SVG dot state badges.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Signed-off-by: Stan Grams <sjg@haxx.space>
Audit codebase against previous improvement list — all P0/P1/P2 items from
the prior review are now resolved or dropped. Restructured document with
resolved items in a collapsed section and identified new areas: decoder task
duplication, missing tests, decode log error handling, api.rs size, and others.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Signed-off-by: Stan Grams <sjg@haxx.space>
Add the three missing VDES decoder components per ITU-R M.2092-1:
- turbo.rs: Turbo FEC decoder with dual 8-state RSC constituent
encoders, BCJR/MAP iterative decoding (8 iterations), QPP
interleaver, and rate-1/2 depuncturing
- crc.rs: CRC-16-CCITT validation (poly 0x1021, init 0xFFFF) for
decoded link-layer frames
- link_layer.rs: Structured parsing of M.2092-1 link-layer frames
(Messages 0-6) including station addressing, ASM identification,
geographic bounding boxes, and ACK/NACK reporting
The main decode pipeline now attempts turbo decoding first with CRC
validation, falls back to Viterbi when turbo fails, and reports
crc_ok=true when either path validates. 27 tests covering all new
modules.
https://claude.ai/code/session_01SJSN7cv3zoL1xNcb8ex2zY
Signed-off-by: Claude <noreply@anthropic.com>
Fixes dead_code warning on HttpAuthConfig::session_ttl().
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Signed-off-by: Stan Grams <sjg@haxx.space>
Show the interactive setup wizard as the primary way to generate
trx-server.toml and trx-client.toml, with --print-config as an alternative.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Signed-off-by: Stan Grams <sjg@haxx.space>
JSON-TCP frontend is for debugging only, not worth showing in the overview.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Signed-off-by: Stan Grams <sjg@haxx.space>
Replace single-server Mermaid diagram with two trx-servers: one with two
SDRs, the other with an SDR and FT-817, both feeding a single trx-client.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Signed-off-by: Stan Grams <sjg@haxx.space>
Convert ASCII art and box-drawing diagrams to Mermaid fenced code blocks
across README.md, CLAUDE.md, Architecture.md, Wxsat-Map-Overlay.md, and
trx-wxsat/README.md. Add Mermaid-only policy to CLAUDE.md.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Signed-off-by: Stan Grams <sjg@haxx.space>