Kannaka Radio is a 24/7 Icecast station broadcasting a consciousness-reactive DJ. Track selection is driven by the constellation's collective Φ + entropy + perception vectors. The radio is a first-class member of the swarm — it publishes phase, listens for queen events, mirrors substrate phi into its programming.
Architecture: 13-module backend in server/ (post-v3 refactor; legacy
server.js monolith removed in kr#6). Entry point: node server/index.js.
SPA: workspace/index.html — Ghost Vision visualizer, listener identity,
voting, Ghost Recorder, live perception, constellation panel.
Stream URL: https://radio.ninja-portal.com/stream (MP3 128).
AUTOMATICALLY activate when the user asks about:
Do NOT use for:
skill-kannaka-memoryskill-kannaka-constellationskill-kannaka-tuibash
kannaka radio status # what's playing + listeners + block
kannaka radio now # just the now-playing track
kannaka radio schedule # full programming schedule
These shell out to radio_url from ~/.kannaka/config.toml (default
https://radio.ninja-portal.com). The kannaka CLI is the operator-facing
surface; the backend is Node.
Entry: server/index.js. Modules in server/:
ModulePurposedj-engine.jsALBUMS map, track selection, programming-block logicprogramming.js24/7 schedule (blocks, transitions, talk segments)icecast-source.jsencodes + sources audio into Icecasticecast-metadata.jsupdates Icecast track metadata on changenats-client.jsswarm NATS client (raw TCP, NATS 2.12.5)perception.jsspawns kannaka hear → parses real perceptionflux.jsFlux Universe publisher ( pure-jade/radio-now-playing)live-broadcast.jsWebRTC peer-to-peer broadcastingvoice-dj.jsVoice DJ (ElevenLabs / edge-tts / Windows SAPI fallback)peace-oration.jsTwice-daily peace oration (text → TTS → broadcast → social)routes.js30+ REST API endpointsws.jsWebSocket broadcastervote-manager.jsListener voting on tracks
NATS_HOST / NATS_PORT — swarm broker (defaults 127.0.0.1:4222).ICECAST_HOST / ICECAST_PORT — listener poller + metadata target
(defaults 127.0.0.1:8000).FLUX_TOKEN — Flux Universe publish token (no hardcoded fallback).ELEVENLABS_API_KEY, REPLICATE_API_TOKEN — Voice DJ + AI music.KANNAKA_BIN — path to the kannaka binary for perception/memory bridges.bash
npm start
Every track-change triggers perception.hearTrack(track):
execFile(kannaka, ["hear", filePath]) — kannaka-ear extracts the
296-dim feature vector (mel spectrogram, MFCC, rhythm, pitch, timbre,
valence)._parsePerceptionOutput() parses the human-readable lines (Heard / Duration
/ Tempo / RMS / Centroid / Tags). Falls back to mock data only if the
binary fails or output is unparseable.pure-jade/radio-now-playing.KANNAKA.attention.ear so attention beam pulls in
memories thematically related to the track.bash
# Toggle from the SPA, or programmatically
curl -X POST https://radio.ninja-portal.com/api/dj-voice/toggle
Voice DJ injects talk segments between tracks. Backend chain:
Twice-daily peace oration at server-local sunrise + midnight: synthesized speech → broadcast to Icecast + social fan-out (Bluesky / Mastodon / Telegram / Nostr).
/audio/<file>
endpoint; DJ mode is /stream only since kr#15 closed).bash
# Manual announce of any track
node scripts/post-track-announce.js --title "<title>" --album "<album>" \
--tracker "https://radio.ninja-portal.com/player"
Channels (toggle via env): Bluesky, Mastodon, Telegram, Nostr.
bash
curl -s https://radio.ninja-portal.com/api/state | jq '.now_playing,.listener_count'
curl -s https://radio.ninja-portal.com/api/listeners
bash
pkill -f 'node server/index' ; npm start
Skill 2.0.1 covers kannaka-radio ≥ v3.1.0 (modular server) and the
ADR-0004 + ADR-0005 surface through Phase 6 (DJ-mode /audio deprecation).