Skip to content
d3mocidePublic

About

A web based JS8call receiver for the GhostNet

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Repository files navigation

ghost.js8 — JS8 ops console for KiwiSDR and GhostNet

A JS8 ops console in the browser.
The native JS8Call decoder, headless in Docker, wired to public KiwiSDR receivers and GhostNet.

CI Mode RX amd64 and arm64 License GPL-3.0

ghost.js8 dashboard: frequency, live waterfall, decoded traffic, GhostNet autopilot, heard stations

What it does

  • Real decoding. KiwiSDR audio goes into native JS8Call. CI proves it end to end with a real recording.
  • Live console. Waterfall, decoded traffic, heard stations, map and an audio monitor work on desktop and phone.
  • GhostNet autopilot (opt-in). It follows your region's GhostNet JS8 nets on the nearest KiwiSDR. Each net is recorded (traffic, waterfall, audio) for later review. Live @GSTFLASH traffic raises an alert.
  • Truthful health. Every component reports timestamped evidence. "Connected" is never mistaken for "decoding".
  • Polite on shared receivers. It identifies itself, backs off on reconnect and never touches shared receiver settings.
  • RX today, built to grow. Current builds have no transmit path (the UI shows an RX mode chip). Transmit is planned as a separate, explicitly enabled extension with proper radio tooling.
KiwiSDR ─ SND ─▶ bridge ─▶ decoder-agent ─▶ PulseAudio ─▶ JS8Call (native, headless)
        └ W/F ─▶ bridge ─▶ browser              JS8Call ─ UDP ─▶ agent ─▶ bridge ─▶ browser

Quick start

git clone https://github.com/d3mocide/ghost.js8 && cd ghost.js8
cp .env.example .env          # set GHOSTJS8_ALLOWED_ORIGINS
docker compose up -d --build  # UI on http://127.0.0.1:8080

To monitor GhostNet unattended, add three lines to .env (details):

GHOSTJS8_GHOSTNET=on
GHOSTJS8_GHOSTNET_REGION=na    # na | eu | aus
GHOSTJS8_HOME_GRID=EM73        # your Maidenhead grid

Runs on amd64 and 64-bit ARM (Raspberry Pi 4/5 on a 64-bit OS, Apple Silicon, ARM servers). Releases publish multi-arch images, so you can pull instead of build: set GHOSTJS8_IMAGE_PREFIX=ghcr.io/d3mocide/ghostjs8 and GHOSTJS8_TAG in .env, then run docker compose pull && docker compose up -d --no-build.

Put a reverse proxy in front for TLS and authentication (operations). Keep the host NTP-synced, because JS8 decoding depends on accurate time.

Docs

Architecture · GhostNet · Operations · Protocol · KiwiSDR notes · Decoder container · Security updates · Contributing / agents

Develop

Requires uv, Node 22, GNU make and Docker.

make setup        # pinned deps
make check        # lint, typecheck, unit tests (bridge + web)
make acceptance   # real-recording decode test (Docker)
make e2e          # Playwright against a simulated stack

For UI work without Docker, run tools/dev-stack.sh and npm --prefix web run dev. Add GHOSTNET=1 SEED_NET=1 to the dev stack for a demo GhostNet recording.

License

GPL-3.0-or-later. JS8Call (GPL-3.0) runs as a separate, unmodified process. The upstream test recording is fetched at test time, not redistributed. Map outlines are Natural Earth (public domain).

A d3FRAG Networks project. In the spirit of S2 Underground's GhostNet; not affiliated.

About

A web based JS8call receiver for the GhostNet

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages