Skip to content

fix(desktop): the show's receiver gets the selected project's OSC target - #111

Merged
pyramation merged 1 commit into
mainfrom
feat/desktop-receiver-osc-target
Aug 19, 2026
Merged

fix(desktop): the show's receiver gets the selected project's OSC target#111
pyramation merged 1 commit into
mainfrom
feat/desktop-receiver-osc-target

Conversation

@pyramation

Copy link
Copy Markdown
Contributor

Summary

Starting a show from the desktop app painted fine over the WebSocket but drove nothing, while Advanced → OSC controlled the lasers. Cause: startReceiver picks its outputs from process.env (BEYOND_HOST / FB4_HOST / ROUTING_CONFIG), never from the ResolvedConfig it is handed — and the desktop app only set state/log/device vars, so the receiver came up with ConsoleOutput alone and reported no error.

The config→env projection that the CLI already had (configEnvMap) moves into @wavegrid/layout next to the loader that parses it back, and the desktop app applies it before starting the receiver:

// brain.start()
store.setActiveProject(project);                 // appstash is the source of truth
const resolved = resolveProjectConfig();         // loads from ambient env, not env we wrote
applyReceiverEnv(store, project, resolved);      // ← new: projects osc.* into env
receiver = startReceiver(resolved);

resetConfigEnv(config, ambient) rather than applyConfigToEnv, because the Electron process outlives project switches: for every config-derived key it restores the operator's process-start value if there was one, else the new project's value, else deletes it — so a console-only project can't keep firing at the previous project's BEYOND host. resolveProjectConfig() loads against a snapshot of the ambient env taken at module load for the same reason.

Projects that configure osc.routing (a spec, not a file) now get a per-device routing file generated into the project's state dir and ROUTING_CONFIG pointed at it; an invalid spec throws with the validation problems instead of silently leaving the show targetless.

So a dark rig is visible rather than inferred, ReceiverHandle now exposes the labels it already logs, and the UI reads them:

receiverOutputs: ['Console', 'BEYOND OSC → 10.0.0.5:8000 (row-major, rgb)']
hasOscOutput(status) === false   // ['Console'] alone → show is running, lasers stay dark

Show screen warns "Console only — no OSC output" in that case; Advanced → OSC additionally warns when the project you're debugging isn't the project the running show is driving, so the debugger and the show path can no longer disagree without saying so.

Link to Devin session: https://app.devin.ai/sessions/ec43152136134467a853ec0bbf783ea9
Requested by: @pyramation

The receiver reads BEYOND_HOST/FB4_HOST/ROUTING_CONFIG from process.env only,
which the desktop app never set: paint reached the brain over the WebSocket and
nothing reached BEYOND, while the OSC debugger (which reads the store directly)
drove the lasers fine.

Share the CLI's config-to-env projection from @wavegrid/layout, apply it before
starting the in-process receiver, and reset config-derived keys per start so a
project switch cannot keep firing at the previous project's target. Surface the
receiver's outputs so a console-only show says so instead of looking healthy.
@pyramation pyramation self-assigned this Aug 19, 2026
@devin-ai-integration

Copy link
Copy Markdown
Contributor

🤖 Devin AI Engineer

I'll be helping with this pull request! Here's what you should know:

✅ I will automatically:

  • Address comments on this PR. Add '(aside)' to your comment to have me ignore it.
  • Look at CI failures and help fix them

Note: I can only respond to comments from users who have write access to this repository.

⚙️ Control Options:

  • Disable automatic comment, CI, and merge conflict monitoring

@pyramation
pyramation merged commit aaf71eb into main Aug 19, 2026
5 checks passed
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.

1 participant