Skip to content

Staging#25

Merged
MichaelWheeley merged 16 commits intoMichaelWheeley:feature/thai-language-devfrom
accius:Staging
Mar 25, 2026
Merged

Staging#25
MichaelWheeley merged 16 commits intoMichaelWheeley:feature/thai-language-devfrom
accius:Staging

Conversation

@MichaelWheeley
Copy link
Copy Markdown
Owner

What does this PR do?

Type of change

  • Bug fix
  • New feature
  • Performance improvement
  • Refactor / code cleanup
  • Documentation
  • Translation
  • Map layer plugin

How to test

Checklist

  • App loads without console errors
  • Tested in Dark, Light, and Retro themes
  • Responsive at different screen sizes (desktop + mobile)
  • If touching server.js: caches have TTLs and size caps (we serve 2,000+ concurrent users)
  • If adding an API route: includes caching and error handling
  • If adding a panel: wired into Modern, Classic, and Dockable layouts
  • No hardcoded colors — uses CSS variables (var(--accent-cyan), etc.)
  • No .bak, .old, console.log debug lines, or test scripts included

Screenshots (if visual change)

accius and others added 16 commits March 25, 2026 12:22
…Phase 2)

Config now lives in ~/.config/openhamclock/ (Linux/macOS) or
%APPDATA%/openhamclock/ (Windows) so updates never overwrite it.

- Auto-migrates legacy config from rig-bridge/ dir to external path
- configVersion field tracks schema changes
- Deep-merge preserves user values while adding new defaults
- Logs new keys on migration: "Schema migrated v1 → v2: added ..."
- Config path shown in startup banner and /health endpoint

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- New server route /api/rig-bridge/status proxies health check to
  rig-bridge, avoiding CORS — browser never needs direct access
- /api/rig-bridge/start spawns rig-bridge as detached child process
- /api/rig-bridge/stop sends SIGTERM to managed process
- RigContext runs server-side health check on SSE failure to diagnose:
  auth required but no token, rig-bridge not reachable, etc.
- New error banners: "needs-token", "not-reachable" with actionable text

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Moved apiToken declaration above checkRigBridgeHealth useCallback
that references it. The minifier exposed the temporal dead zone error
as "Cannot access 'f' before initialization".

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…835 Phase 3)

Phase 3a/3d of rig-bridge unification:

- New shared library: rig-bridge/lib/wsjtx-protocol.js
  - WSJTXReader (parser) + WSJTXWriter (serializer)
  - Message builders: buildReply, buildHaltTx, buildFreeText,
    buildHighlightCallsign, buildSwitchConfig
  - Single source of truth for WSJT-X/MSHV/JTDX binary protocol

- Updated wsjtx-relay plugin:
  - Uses shared protocol library (removes 200+ lines of duplicated code)
  - Tracks remote WSJT-X address/port from incoming packets
  - New send() method for bidirectional UDP communication
  - New API endpoints: POST /wsjtx/reply, /halt, /freetext, /highlight

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…Phase 3)

Completes Phase 3b/3c — all four digital mode apps now have
bidirectional rig-bridge plugins:

- New shared factory: digital-mode-base.js generates a full plugin
  (UDP listener, remote tracking, send(), API endpoints) from config
- MSHV plugin (port 2239) — multi-stream decode support
- JTDX plugin (port 2238) — enhanced JT65/JT9/FT8 decoding
- JS8Call plugin (port 2242) — JS8 messaging protocol

Each plugin exposes: /api/{id}/status, /reply, /halt, /freetext, /highlight
All use the shared wsjtx-protocol.js library for parsing and serialization.
Config version bumped to 3 with new mshv/jtdx/js8call sections.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Phase 4a: Local APRS TNC plugin (aprs-tnc)
- KISS protocol library: frame encode/decode, AX.25 parse/build
- Connects to Direwolf via KISS TCP or hardware TNC via serial
- Receives APRS packets over RF (no internet dependency)
- Sends position beacons, messages, and acknowledgments
- SSE stream of raw packets for real-time monitoring
- Endpoints: POST /aprs/beacon, /message, /ack; GET /aprs/stream

Phase 4b: Winlink gateway plugin (winlink-gateway)
- Gateway discovery via api.winlink.org (requires API key)
- Pat client integration for inbox/outbox/compose/connect
- Endpoints: GET /winlink/gateways, /inbox, /outbox;
  POST /winlink/compose, /connect

Config version bumped to 4 with aprs + winlink sections.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…gin (#835)

Phase 5: Deprecate legacy tools
- rig-listener: deprecation banner on startup pointing to rig-bridge
- rig-control: deprecation warning on startup
- wsjtx-relay: notice that local installs should use rig-bridge

Phase 6: Reliability & observability
- /health endpoint now includes integration plugin status, freq, mode, ptt
- Plugin registry exposes getIntegrations() for health reporting
- All integration plugins report their status via getStatus()

Phase 7: Extended hardware
- New rotator plugin (rotctld/Hamlib) with AZ/EL control
  - Endpoints: GET /api/rotator/status, POST /position, /stop, /park
  - Auto-reconnect, position polling, target tracking
- Config version bumped to 5

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Message Logging (Phase 4c):
- JSON Lines (.jsonl) file-based logger — no dependencies
- Query by callsign, type, time range
- Export as CSV or plain text (ICS-213 format for EmComm)
- Auto-pruning by age (default 7 days) and count (max 10k)
- API: GET /api/messages, /messages/export, /messages/stats

Cloud Relay Plugin:
- Local agent that proxies all rig-bridge features to cloud OHC
- Pushes rig state (freq/mode/PTT) on change
- Polls cloud for pending commands (tune, mode, PTT)
- Enables click-to-tune, PTT, etc. for cloud-hosted users
- Config: cloudRelay.url, apiKey, session, push/poll intervals

Config version bumped to 6.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
New "Rig Bridge" tab in Settings panel with:
- Connection settings (host, port, API token) — moved from Station tab
- Click-to-tune and auto-mode toggles
- Direct link to Rig Bridge setup UI
- Plugin overview showing all available integrations (radio, digital,
  packet, hardware, cloud)

The old rig control section in Station Settings still works for
backwards compatibility but the new tab is the primary location.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Completes the cloud relay circuit — cloud-hosted OHC users can now
control their local radio via rig-bridge over HTTPS.

Server-side relay endpoints:
- POST /api/rig-bridge/relay/state — rig-bridge pushes state here
- GET  /api/rig-bridge/relay/state — browser polls for rig state
- POST /api/rig-bridge/relay/command — browser queues commands
- GET  /api/rig-bridge/relay/commands — rig-bridge picks up commands
- GET  /api/rig-bridge/relay/credentials — browser gets relay key
- POST /api/rig-bridge/relay/configure — one-click: pushes cloud
  relay config to local rig-bridge

Per-session state and command queuing (50 sessions max, 1hr TTL).
Auth via RIG_BRIDGE_RELAY_KEY env var (falls back to WSJTX_RELAY_KEY).

Settings UI: "Connect Cloud Relay" button in Rig Bridge tab —
auto-configures the local rig-bridge with server URL and credentials.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Build script (rig-bridge/build.js) for creating pkg standalone binaries
- Download endpoints: GET /api/rig-bridge/download/:platform
  - Windows: .bat installer that checks for Node, clones rig-bridge,
    installs deps, and starts it
  - Mac/Linux: .sh installer with same flow
- Settings tab: download buttons for all 3 platforms + Open Setup UI
  link, replacing the single setup UI link

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
New "Plugins" tab in the rig-bridge setup UI (localhost:5555) with:
- Toggle switches to enable/disable each plugin
- Inline config fields shown when a plugin is enabled
- Changes saved via /api/config (requires restart to activate)

Plugins manageable from the UI:
- MSHV (port 2239)
- JTDX (port 2238)
- JS8Call (port 2242)
- APRS TNC (KISS protocol, host, port, callsign, beacon interval)
- Rotator (rotctld host/port)
- Winlink (API key, Pat client host/port)
- Cloud Relay (server URL, API key, session, intervals)

No more editing JSON to enable plugins.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
The xcopy source path was relative (rig-bridge\*) instead of absolute
(%RIG_DIR%\repo\rig-bridge), so files weren't copied to the install
directory. Also added /I flag for directory target, hardcoded git URL
instead of string-replacing the server URL, and replaced deprecated
--production with --omit=dev. Same fixes applied to Mac/Linux script.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Rewrites the OpenHamClock connection section with three scenarios:
1. Local install (same machine)
2. LAN setup (Pi in shack, laptop in office)
3. Cloud relay (openhamclock.com + radio at home)

Also adds documentation for:
- Plugin manager UI
- All digital mode plugins (MSHV, JTDX, JS8Call)
- APRS TNC plugin with Direwolf setup
- Rotator plugin with rotctld
- Winlink plugin (gateway discovery + Pat)
- Cloud relay architecture diagram
- Config file location by OS

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
The server can't reach localhost:5555 when cloud-hosted (localhost is
the cloud server, not the user's machine). Fixed by splitting the flow:

1. Browser asks OHC server for relay credentials (key, session, URL)
2. Browser pushes the config directly to the user's local rig-bridge
   (browser IS on the user's machine, so localhost works)

This is the same pattern used for WSJT-X relay credential fetch.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
When cloudRelaySession is configured, RigContext switches to cloud mode:
- State: polls /api/rig-bridge/relay/state every 2s (same origin, no CORS)
- Commands: routes setFreq/setMode/setPTT through /api/rig-bridge/relay/command
  instead of POSTing directly to localhost:5555

This completes the cloud relay data path:
  rig-bridge → pushes state → OHC server ← polls ← browser
  browser → pushes command → OHC server ← polls ← rig-bridge → radio

Session ID saved to rigControl.cloudRelaySession in config on setup.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@MichaelWheeley MichaelWheeley merged commit bea3c1c into MichaelWheeley:feature/thai-language-dev Mar 25, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants