Desktop bridge for Soundnode. Describe a sound, build a VIRGINIA/BeatStars mission with XUNIA SOUNDS, or save SoundCloud media you own or are allowed to save.
+
+
+ BEGINNER FLOW
+ YOU DESCRIBE → XUNIA SOUNDS BUILDS THE PLAN → CLAUDE/BEATSTARS DISCOVERY → REVIEW LICENSE → OPTIONAL SOUNDCLOUDOPEN SAVE
+
+
+
Checking SoundCloudOpen…
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
The save button does not bypass SoundCloud permissions. Use it only for audio you own, downloads SoundCloud permits, or material you otherwise have permission to save.
+
Ready.
+
+
+
+
From 3090c240ef2d4399d3a8e75ac4f8ccda8ec129c8 Mon Sep 17 00:00:00 2001
From: Doug Brown <60854716+sonoxo@users.noreply.github.com>
Date: Wed, 26 Aug 2026 19:15:06 -0400
Subject: [PATCH 3/9] feat(agent-ui): wire XUNIA desktop controls to Electron
IPC
---
app/public/js/xuniaSoundCloudOpen.js | 97 ++++++++++++++++++++++++++++
1 file changed, 97 insertions(+)
create mode 100644 app/public/js/xuniaSoundCloudOpen.js
diff --git a/app/public/js/xuniaSoundCloudOpen.js b/app/public/js/xuniaSoundCloudOpen.js
new file mode 100644
index 00000000..c79cda50
--- /dev/null
+++ b/app/public/js/xuniaSoundCloudOpen.js
@@ -0,0 +1,97 @@
+'use strict';
+
+const { ipcRenderer } = require('electron');
+
+function byId(id) {
+ return document.getElementById(id);
+}
+
+function value(id) {
+ return byId(id).value.trim();
+}
+
+function missionPayload(promptOnly) {
+ return {
+ prompt: value('prompt'),
+ genre: value('genre'),
+ mood: value('mood'),
+ bpm: value('bpm'),
+ count: value('count'),
+ useCase: value('useCase'),
+ format: value('format'),
+ soundcloudUrl: value('soundcloudUrl'),
+ promptOnly: !!promptOnly
+ };
+}
+
+function downloadPayload() {
+ return {
+ url: value('soundcloudUrl'),
+ format: value('format'),
+ browser: value('browser'),
+ output: value('output')
+ };
+}
+
+function showOutput(payload) {
+ const node = byId('outputView');
+ node.textContent = typeof payload === 'string' ? payload : JSON.stringify(payload, null, 2);
+}
+
+function setStatus(message, good) {
+ const status = byId('status');
+ status.textContent = message;
+ status.className = `status ${good === true ? 'good' : good === false ? 'bad' : ''}`;
+}
+
+async function check() {
+ setStatus('Checking SoundCloudOpen…');
+ try {
+ const result = await ipcRenderer.invoke('xunia:check');
+ if (result.ready) {
+ setStatus(`READY — ${result.xunia.version} / ${result.downloader.version}`, true);
+ } else {
+ setStatus('NOT READY — install SoundCloudOpen 1.2+ on this computer.', false);
+ }
+ showOutput(result);
+ } catch (error) {
+ setStatus(error.message, false);
+ showOutput({ error: error.message });
+ }
+}
+
+async function buildMission(promptOnly) {
+ showOutput(promptOnly ? 'Building Claude discovery prompt…' : 'Building XUNIA mission…');
+ try {
+ const result = await ipcRenderer.invoke('xunia:mission', missionPayload(promptOnly));
+ showOutput(result);
+ } catch (error) {
+ showOutput({ error: error.message });
+ }
+}
+
+async function saveAuthorizedMedia() {
+ const url = value('soundcloudUrl');
+ if (!url) {
+ showOutput({ error: 'Add an authorized SoundCloud track or playlist URL first.' });
+ return;
+ }
+
+ const confirmed = window.confirm('Save this SoundCloud media only if you own it, SoundCloud permits the download, or you otherwise have permission. Continue?');
+ if (!confirmed) return;
+
+ showOutput('Starting SoundCloudOpen…');
+ try {
+ const result = await ipcRenderer.invoke('xunia:download', downloadPayload());
+ showOutput(result);
+ } catch (error) {
+ showOutput({ error: error.message });
+ }
+}
+
+byId('check').addEventListener('click', check);
+byId('mission').addEventListener('click', () => buildMission(false));
+byId('promptOnly').addEventListener('click', () => buildMission(true));
+byId('save').addEventListener('click', saveAuthorizedMedia);
+
+check();
From 983d8a900404358fb03c628439965b869292a72a Mon Sep 17 00:00:00 2001
From: Doug Brown <60854716+sonoxo@users.noreply.github.com>
Date: Wed, 26 Aug 2026 19:15:31 -0400
Subject: [PATCH 4/9] feat(agent-bridge): expose SoundCloudOpen through
Electron IPC
---
main.js | 56 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 56 insertions(+)
diff --git a/main.js b/main.js
index dfc195ac..0b6e2257 100644
--- a/main.js
+++ b/main.js
@@ -10,6 +10,7 @@ const {
} = require('electron');
const windowStateKeeper = require('electron-window-state');
const configuration = require('./app/public/js/common/configLocation');
+const soundCloudOpenBridge = require('./integrations/soundcloudopenBridge');
// custom constants
const clientId = '342b8a7af638944906dcdb46f9d56d98';
@@ -18,6 +19,7 @@ const SCconnect = `https://soundcloud.com/connect?&client_id=${clientId}&redirec
let mainWindow;
let authenticationWindow;
+let xuniaWindow;
app.on('ready', () => {
checkUserConfig();
@@ -124,6 +126,42 @@ function initMainWindow() {
menuBar();
}
+function openXuniaWindow() {
+ if (xuniaWindow && !xuniaWindow.isDestroyed()) {
+ xuniaWindow.show();
+ xuniaWindow.focus();
+ return;
+ }
+
+ xuniaWindow = new BrowserWindow({
+ width: 980,
+ height: 780,
+ minWidth: 720,
+ minHeight: 600,
+ title: 'XUNIA SOUNDS + SoundCloudOpen',
+ webPreferences: {
+ nodeIntegration: true
+ }
+ });
+
+ xuniaWindow.loadURL(`file://${__dirname}/app/xunia.html`);
+ xuniaWindow.on('closed', () => {
+ xuniaWindow = null;
+ });
+}
+
+ipcMain.handle('xunia:check', async () => {
+ return soundCloudOpenBridge.checkAvailability();
+});
+
+ipcMain.handle('xunia:mission', async (_event, payload) => {
+ return soundCloudOpenBridge.buildMission(payload || {});
+});
+
+ipcMain.handle('xunia:download', async (_event, payload) => {
+ return soundCloudOpenBridge.saveAuthorizedMedia(payload || {});
+});
+
app.on('will-quit', () => {
// Unregister all shortcuts.
globalShortcut.unregisterAll()
@@ -207,6 +245,24 @@ function menuBar() {
role: 'editMenu',
label: 'Soundnode'
},
+ {
+ label: 'XUNIA SOUNDS',
+ submenu: [
+ {
+ label: 'Open XUNIA SOUNDS + SoundCloudOpen',
+ accelerator: 'CmdOrCtrl+Shift+X',
+ click() {
+ openXuniaWindow();
+ }
+ },
+ {
+ label: 'SoundCloudOpen on GitHub',
+ click() {
+ require('electron').shell.openExternal('https://github.com/sonoxo/soundcloudopen')
+ }
+ }
+ ]
+ },
{
role: 'view',
label: 'View',
From cf384d4896360f2a19a31ab512e89101b56336a4 Mon Sep 17 00:00:00 2001
From: Doug Brown <60854716+sonoxo@users.noreply.github.com>
Date: Wed, 26 Aug 2026 19:15:44 -0400
Subject: [PATCH 5/9] test(agent-verify): cover SoundCloudOpen desktop bridge
---
tests/xunia-soundcloudopen.test.js | 67 ++++++++++++++++++++++++++++++
1 file changed, 67 insertions(+)
create mode 100644 tests/xunia-soundcloudopen.test.js
diff --git a/tests/xunia-soundcloudopen.test.js b/tests/xunia-soundcloudopen.test.js
new file mode 100644
index 00000000..f0e917af
--- /dev/null
+++ b/tests/xunia-soundcloudopen.test.js
@@ -0,0 +1,67 @@
+'use strict';
+
+const assert = require('assert');
+const bridge = require('../integrations/soundcloudopenBridge');
+
+function testMissionArgs() {
+ const args = bridge.buildMissionArgs({
+ prompt: 'dark melodic trap',
+ genre: 'trap',
+ mood: 'cold',
+ bpm: 90,
+ count: 4,
+ useCase: 'album',
+ format: 'wav',
+ soundcloudUrl: 'https://soundcloud.com/example/owned-track'
+ });
+
+ assert.strictEqual(args[0], 'dark melodic trap');
+ assert.ok(args.includes('--genre'));
+ assert.ok(args.includes('trap'));
+ assert.ok(args.includes('--mood'));
+ assert.ok(args.includes('cold'));
+ assert.ok(args.includes('--bpm'));
+ assert.ok(args.includes('90'));
+ assert.ok(args.includes('--count'));
+ assert.ok(args.includes('4'));
+ assert.ok(args.includes('--use-case'));
+ assert.ok(args.includes('album'));
+ assert.ok(args.includes('--format'));
+ assert.ok(args.includes('wav'));
+ assert.ok(args.includes('--soundcloud'));
+}
+
+function testPromptOnly() {
+ const args = bridge.buildMissionArgs({ prompt: 'warm soul', promptOnly: true });
+ assert.ok(args.includes('--prompt-only'));
+}
+
+function testDownloadArgs() {
+ const args = bridge.buildDownloadArgs({
+ url: 'https://soundcloud.com/example/sets/owned-playlist',
+ format: 'flac',
+ browser: 'none',
+ output: '/tmp/xunia',
+ saveJson: true
+ });
+
+ assert.strictEqual(args[0], 'https://soundcloud.com/example/sets/owned-playlist');
+ assert.deepStrictEqual(args.slice(1, 5), ['--format', 'flac', '--browser', 'none']);
+ assert.ok(args.includes('--output'));
+ assert.ok(args.includes('/tmp/xunia'));
+ assert.ok(args.includes('--save-json'));
+}
+
+function testValidation() {
+ assert.throws(() => bridge.buildMissionArgs({ prompt: '' }), /Describe the sound/);
+ assert.throws(() => bridge.buildMissionArgs({ prompt: 'x', bpm: 0 }), /BPM/);
+ assert.throws(() => bridge.buildMissionArgs({ prompt: 'x', count: 11 }), /Candidate count/);
+ assert.throws(() => bridge.buildDownloadArgs({ url: 'https://example.com/file.mp3' }), /soundcloud.com/);
+ assert.throws(() => bridge.buildDownloadArgs({ url: 'https://soundcloud.com/example/x', format: 'exe' }), /Unsupported audio format/);
+}
+
+testMissionArgs();
+testPromptOnly();
+testDownloadArgs();
+testValidation();
+console.log('XUNIA SoundCloudOpen bridge tests: PASS');
From 08c7a2e4dbd04ab87d7e7b632a6c0fa59b099577 Mon Sep 17 00:00:00 2001
From: Doug Brown <60854716+sonoxo@users.noreply.github.com>
Date: Wed, 26 Aug 2026 19:16:03 -0400
Subject: [PATCH 6/9] test(agent-verify): add XUNIA bridge verification scripts
---
package.json | 12 +++++++-----
1 file changed, 7 insertions(+), 5 deletions(-)
diff --git a/package.json b/package.json
index 09d077a0..bf718460 100644
--- a/package.json
+++ b/package.json
@@ -1,11 +1,11 @@
{
"name": "Soundnode",
- "version": "7.0.0",
+ "version": "7.1.0",
"main": "main.js",
- "description": "Soundnode App is the Soundcloud for desktop",
+ "description": "Soundnode desktop with XUNIA SOUNDS and SoundCloudOpen integration",
"repository": {
"type": "git",
- "url": "git://github.com/Soundnode/soundnode-app.git"
+ "url": "git://github.com/sonoxo/soundnode-app-xunia.git"
},
"scripts": {
"prestart": "npm run watch",
@@ -20,9 +20,11 @@
"package:osx": "electron-packager ./ Soundnode --platform=darwin --out ./dist/Soundnode --electron-version 8.0.1 --overwrite --icon ./app/soundnode.ico",
"package:linux": "electron-packager ./ Soundnode --platform=linux --out ./dist/Soundnode --electron-version 8.0.1 --overwrite --icon ./app/soundnode.icns",
"package:win32": "electron-packager ./ Soundnode --platform=win32 --out ./dist/Soundnode --electron-version 8.0.1 --overwrite --icon ./app/soundnode.icns",
- "package:all": "npm run package:osx && npm run package:linux && npm run package:win32"
+ "package:all": "npm run package:osx && npm run package:linux && npm run package:win32",
+ "test:xunia": "node tests/xunia-soundcloudopen.test.js",
+ "check:xunia": "node --check integrations/soundcloudopenBridge.js && node --check app/public/js/xuniaSoundCloudOpen.js && node tests/xunia-soundcloudopen.test.js"
},
- "author": "Michael Lancaster",
+ "author": "Michael Lancaster / XUNIA integration by sonoxo",
"license": "GPL-3.0",
"devDependencies": {
"babel-core": "6.26.3",
From 7e2f78cfa51740bb8040953961866fd837135d3b Mon Sep 17 00:00:00 2001
From: Doug Brown <60854716+sonoxo@users.noreply.github.com>
Date: Wed, 26 Aug 2026 19:16:10 -0400
Subject: [PATCH 7/9] ci(agent-verify): verify XUNIA bridge across desktop
platforms
---
.github/workflows/xunia-soundcloudopen.yml | 26 ++++++++++++++++++++++
1 file changed, 26 insertions(+)
create mode 100644 .github/workflows/xunia-soundcloudopen.yml
diff --git a/.github/workflows/xunia-soundcloudopen.yml b/.github/workflows/xunia-soundcloudopen.yml
new file mode 100644
index 00000000..bab7d796
--- /dev/null
+++ b/.github/workflows/xunia-soundcloudopen.yml
@@ -0,0 +1,26 @@
+name: XUNIA SoundCloudOpen Bridge
+
+on:
+ push:
+ branches:
+ - master
+ - feature/xunia-soundcloudopen-desktop-bridge
+ pull_request:
+ branches:
+ - master
+
+jobs:
+ verify:
+ strategy:
+ fail-fast: false
+ matrix:
+ os: [ubuntu-latest, macos-latest, windows-latest]
+ node: [18, 20]
+ runs-on: ${{ matrix.os }}
+ steps:
+ - uses: actions/checkout@v4
+ - uses: actions/setup-node@v4
+ with:
+ node-version: ${{ matrix.node }}
+ - name: Verify XUNIA + SoundCloudOpen bridge
+ run: npm run check:xunia
From 672abb73429f482b838eafbf13e064cdfa15926d Mon Sep 17 00:00:00 2001
From: Doug Brown <60854716+sonoxo@users.noreply.github.com>
Date: Wed, 26 Aug 2026 19:16:28 -0400
Subject: [PATCH 8/9] docs(agent-verify): document Soundnode + SoundCloudOpen
integration
---
doc/XUNIA_SOUNDCLOUDOPEN.md | 79 +++++++++++++++++++++++++++++++++++++
1 file changed, 79 insertions(+)
create mode 100644 doc/XUNIA_SOUNDCLOUDOPEN.md
diff --git a/doc/XUNIA_SOUNDCLOUDOPEN.md b/doc/XUNIA_SOUNDCLOUDOPEN.md
new file mode 100644
index 00000000..403a1c47
--- /dev/null
+++ b/doc/XUNIA_SOUNDCLOUDOPEN.md
@@ -0,0 +1,79 @@
+# XUNIA SOUNDS + SoundCloudOpen Desktop Bridge
+
+## Beginner version
+
+This fork turns Soundnode into a desktop front end for the creator-owned SoundCloudOpen workflow.
+
+**PLAY / BROWSE IN SOUNDNODE → OPEN XUNIA SOUNDS → DESCRIBE A SOUND → BUILD A VIRGINIA + BEATSTARS DISCOVERY MISSION → REVIEW THE BEAT/LiCENSE → OPTIONALLY SAVE SOUNDCLOUD MEDIA YOU OWN OR ARE ALLOWED TO SAVE**
+
+The original Soundnode player remains intact. The new integration lives beside it.
+
+## What each part does
+
+| Part | Job |
+|---|---|
+| Soundnode | Desktop SoundCloud listening/browsing interface |
+| XUNIA SOUNDS panel | Beginner desktop control surface |
+| `integrations/soundcloudopenBridge.js` | Shell-safe bridge from Electron to the SoundCloudOpen CLI |
+| `xunia-sounds` | Builds the VIRGINIA / 3LM CLAUDE / BeatStars discovery mission |
+| `soundcloudopen` | Saves authorized SoundCloud tracks/playlists with the existing SoundCloudOpen rules |
+| BeatStars MCP | Discovery tool provider used through Claude |
+
+## Install the companion CLI
+
+Soundnode does not embed Python. Install SoundCloudOpen 1.2+ on the same computer:
+
+```bash
+python3 -m pip install git+https://github.com/sonoxo/soundcloudopen.git
+```
+
+Then verify:
+
+```bash
+soundcloudopen --version
+xunia-sounds --version
+```
+
+## Open the desktop panel
+
+Start Soundnode, then use:
+
+**XUNIA SOUNDS → Open XUNIA SOUNDS + SoundCloudOpen**
+
+Keyboard shortcut:
+
+```text
+Cmd/Ctrl + Shift + X
+```
+
+The panel can:
+
+1. check whether both SoundCloudOpen commands are available;
+2. build a structured XUNIA SOUNDS mission;
+3. build only the Claude/BeatStars natural-language prompt;
+4. pass an optional authorized SoundCloud URL into the mission; and
+5. run the existing SoundCloudOpen save command for authorized media.
+
+## Security boundary
+
+The Electron bridge never constructs a shell command string. It calls child processes with an executable plus an argument array and `shell: false`.
+
+SoundCloudOpen remains responsible for its existing URL validation, dependency checks, browser-cookie selection, metadata handling, and yt-dlp/FFmpeg execution.
+
+The desktop panel also validates SoundCloud hostnames before execution and asks for confirmation before starting a save.
+
+## Verification
+
+The integration has a dependency-free Node test lane:
+
+```bash
+npm run check:xunia
+```
+
+CI runs that verification on:
+
+- Windows / Node 18 and 20
+- macOS / Node 18 and 20
+- Ubuntu / Node 18 and 20
+
+This focused lane intentionally does not install the legacy Electron 8 / node-sass dependency tree just to verify the new bridge.
From d345333afca8efc4a681e6063d776396743d5fc5 Mon Sep 17 00:00:00 2001
From: Doug Brown <60854716+sonoxo@users.noreply.github.com>
Date: Wed, 26 Aug 2026 19:16:45 -0400
Subject: [PATCH 9/9] docs(agent-verify): surface SoundCloudOpen desktop bridge
---
README.md | 41 +++++++++++++++++++++++++++++++++++++++++
1 file changed, 41 insertions(+)
diff --git a/README.md b/README.md
index 24a13b7c..921fc0b8 100644
--- a/README.md
+++ b/README.md
@@ -1,3 +1,44 @@
+# SOUNDNODE APP — XUNIA DESKTOP
+
+## XUNIA SOUNDS + SoundCloudOpen
+
+This fork now includes a focused desktop bridge to [SoundCloudOpen](https://github.com/sonoxo/soundcloudopen).
+
+**Soundnode plays/browses → XUNIA SOUNDS builds the creator mission → 3LM CLAUDE can use BeatStars discovery → SoundCloudOpen handles authorized SoundCloud saving.**
+
+Open it from the desktop menu:
+
+**XUNIA SOUNDS → Open XUNIA SOUNDS + SoundCloudOpen**
+
+Shortcut: `Cmd/Ctrl + Shift + X`
+
+The new panel supports:
+
+- SoundCloudOpen/XUNIA CLI readiness checks;
+- VIRGINIA + BeatStars mission creation;
+- BPM, genre, mood, use-case, candidate-count, and optional SoundCloud source controls;
+- Claude prompt-only output;
+- authorized SoundCloud track/playlist saving through the existing SoundCloudOpen CLI; and
+- shell-safe process execution with argument arrays instead of command-string interpolation.
+
+Install the companion CLI on the same computer:
+
+```bash
+python3 -m pip install git+https://github.com/sonoxo/soundcloudopen.git
+soundcloudopen --version
+xunia-sounds --version
+```
+
+Focused verification:
+
+```bash
+npm run check:xunia
+```
+
+Full integration guide: [doc/XUNIA_SOUNDCLOUDOPEN.md](doc/XUNIA_SOUNDCLOUDOPEN.md)
+
+---
+
[](https://gitter.im/Soundnode/soundnode-app?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
Soundnode App