fix(settings,layout): import keeps the local OSC target; inline layouts export as JSON, not the stale default preset - #135
Conversation
…ts export as JSON, not the default preset
|
I'll fix CI failures and address comments from users with write access. I'll skip comments containing "(aside)".
|
|
Review complete. 🟠 1 high 💬 Inline comments (1)
🧹 Nitpicks (1) — 🟢 1 low
This change hardens the portable project export/import path so importing a bundle onto a machine that already has a project no longer clobbers hardware-local state, and adds a JSON-based env-var path for loading layout config.
Reviewed commit: a5320f0 |
There was a problem hiding this comment.
Improves portable project export/import fidelity by preserving machine-local OSC targets on overwrite and adds env-driven layout loading via JSON parsing.
Key findings
- 🟠 Empty
osc: {}bundle wipes local OSC target — portable.ts:151
| // with no target must not wipe the one configured here. | ||
| let config = bundle.config; | ||
| let keptLocalOsc = false; | ||
| if (hasProject(paths, project) && config.osc == null) { |
There was a problem hiding this comment.
🟠 bug · high
Empty osc: {} bundle wipes local OSC target
On overwrite, importProject preserves a machine's local OSC target only when config.osc == null (packages/settings/src/portable.ts:151). But the canonical "no target" form saved by wavegrid projects osc clear is config.osc = {} (packages/cli/src/commands/osc.ts:174), which exportProject ships verbatim, so an empty object fails the == null test and the branch is skipped.
The locally configured BEYOND/FB4/routing target is then silently overwritten with the bundle's empty block — exactly the cross-machine wipe this PR exists to prevent. Reuse the empty-object semantics already applied to the local side at line 153 on the bundle side.
📋 Prompt for AI Agents
In packages/settings/src/portable.ts at line 151, change the overwrite guard so an empty osc object is treated as "bundle had no target": replace config.osc == null with (config.osc == null || Object.keys(config.osc).length === 0). The local-keep branch at lines 152-157 then fires for a bundle whose config carries osc: {} (the shape persisted by wavegrid projects osc clear), preventing the import from wiping this machine's configured BEYOND/FB4/routing hardware target on overwrite. Short-circuiting keeps Object.keys safe for null/undefined, and any non-object osc yields zero keys, preserving the local target.
Summary
Two issues found while syncing the Grace receiver laptop to the 28-fixture brain (both flagged by the laptop-side assistant, reproduced here).
1.
importProject --overwritewiped the machine's OSC target. A bundle exported from the brain has nooscblock (the brain sends nowhere), so re-importing it over the laptop'sgraceproject replaced the config wholesale and dropped the BEYOND host/port. The OSC target is a fact about the hardware next to this machine, not portable project state:A bundle that does carry
oscstill wins.ImportResult/ImportSummarygainkeptLocalOsc, surfaced in the CLI import output and the desktop import dialog.2.
WAVEGRID_LAYOUTleakedgrid-7x7for inline layouts.configEnvMapexportedconfig.layout.preset, but a store layer with{kind:'rings', …}is merged overDEFAULT_CONFIG, sopreset:'grid-7x7'survives underneathkind.resolveLayoutpreferskind, so the running process was right, butwavegrid env export/ receiver env handed a 49-cannon preset to anything reading the env. Now:and
envLayeraccepts either form ({-prefixed →JSON.parseasLayoutSpec, else preset id), so the value round-trips: the test exports the inline grace-28 rings and reloads it to 28 cannons.Tests: layout 108, settings 87, desktop 99, cli 147 passing; tsc clean.
Link to Devin session: https://app.devin.ai/sessions/c4872c2982734093bdee80d04a7d5ceb
Open in Devin Desktop: https://app.devin.ai/desktop/session/c4872c2982734093bdee80d04a7d5ceb?variant=devin
Requested by: @pyramation