Files
feedBack-desktop/src/renderer/settings.html
T
5188aab938 feat(config): real config reset/repair + migration framework (drop manual-delete) (#38)
Eliminates the fragile "delete the config folder before upgrading" tester
instruction, which was wrong-by-OS because the userData folder name was
derived inconsistently per platform (fee[dB]ack on macOS, slopsmith-desktop
on Linux/Windows).

A. Deterministic paths + migration framework
- Pin the userData name on every OS via app.setName('feedback-desktop') +
  build.extraMetadata.name; brand (productName 'fee[dB]ack') unchanged.
- One-time userData migration copies a legacy folder into the new one so
  upgraded users don't start fresh (atomic copy-then-rename, fail-soft).
  Runs before the single-instance lock / crashReporter, which would otherwise
  create userData and defeat the "new dir doesn't exist" gate.
- config-migrations.ts: versioned, ordered, idempotent, fail-soft migration
  runner stamped in CONFIG_DIR/config_version.json; logs the active CONFIG_DIR
  at startup (closes the Linux ~/.local/share/slopsmith shared-config gap).

B. In-app "Reset / repair configuration" (Settings panel)
- Granular options: reset app settings & caches, clear plugin state & cached
  Python deps, and full reset with default-OFF opt-ins for installed plugins /
  song library / ML caches.
- config-paths.ts is the single source of truth for per-OS path enumeration;
  the song library, installed plugins and ML caches are structurally confined
  to optInExtras and never wiped by the safe/full categories.
- Reset stops the backend, deletes immediate paths, includes SQLite WAL/SHM
  sidecars + the migration stamp on full reset, and defers Chromium/Crashpad
  state to next launch (consumed before any window reopens it). ML caches honor
  TORCH_HOME/HF_HOME. Empty selection is a no-op (backend left running).
- SECURITY: destructive resets require a native main-process confirmation
  dialog — the renderer bridge is reachable by plugin scripts, so a
  renderer-only confirm is not a sufficient gate.

Tests: node:test suites for path enumeration (per-OS + library/plugins
preserved), migration idempotency/fail-soft, reset delete pipeline guarantees,
userData migration, and deferred-deletion schedule/consume. `npm test` green
(adds a test script). codex review --base origin/main clean.

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-26 22:13:24 +02:00

165 lines
10 KiB
HTML

<div class="space-y-3">
<div id="ae-updates-section" class="border border-slate-700 rounded-lg p-3 bg-slate-800/30">
<div class="text-xs font-semibold text-slate-300 mb-2">Updates</div>
<div class="grid grid-cols-1 md:grid-cols-2 gap-3">
<div>
<label class="block text-xs text-slate-400 mb-1" for="update-channel">Update channel</label>
<select id="update-channel" class="w-full bg-slate-700 border border-slate-600 rounded px-3 py-1.5 text-sm">
<option value="stable">Stable</option>
<option value="rc">Release candidate</option>
<option value="beta">Beta</option>
<option value="alpha">Alpha</option>
</select>
<p class="text-xs text-slate-500 mt-1">Pre-release channels (alpha/beta/rc) opt you into early builds.</p>
</div>
<div class="flex flex-col">
<label class="block text-xs text-slate-400 mb-1">Manual check</label>
<button id="update-check-now" class="px-3 py-1.5 rounded bg-blue-600 hover:bg-blue-500 text-sm font-medium disabled:opacity-50">
Check for updates
</button>
</div>
</div>
<p id="update-status" class="text-xs text-slate-400 mt-3">Loading updater status…</p>
<p id="update-linux-note" class="hidden text-xs text-amber-300 mt-2">
Auto-update is not available on Linux —
<a id="update-releases-link" href="https://github.com/got-feedback/feedback-desktop/releases"
target="_blank" rel="noopener" class="underline hover:text-amber-200">download new versions from GitHub Releases</a>.
</p>
</div>
<div>
<label class="block text-xs text-slate-400 mb-1">Audio Sync Offset</label>
<div class="flex items-center gap-3">
<input type="range" id="ae-sync-offset" min="-0.2" max="0.5" step="0.005" value="0.2"
class="flex-1 accent-blue-500">
<span id="ae-sync-offset-label" class="text-sm text-slate-300 w-16 text-right">200ms</span>
</div>
<p class="text-xs text-slate-500 mt-1">Compensates for audio latency. Increase if music leads the tab, decrease if tab leads the music.</p>
</div>
<div>
<label class="block text-xs text-slate-400 mb-1">Audio Quality (Guitar Pro → audio rendering)</label>
<div class="space-y-2">
<label class="flex items-start gap-2 text-sm text-slate-300 cursor-pointer">
<input type="radio" name="ae-sf-quality" value="default" id="ae-sf-default" class="mt-1 accent-blue-500">
<span>
<span class="block">Default — GeneralUser GS (~32 MB, bundled)</span>
<span class="block text-xs text-slate-500">Good quality for practice-reference audio. Ships with the installer.</span>
</span>
</label>
<label class="flex items-start gap-2 text-sm text-slate-300 cursor-pointer">
<input type="radio" name="ae-sf-quality" value="high" id="ae-sf-high" class="mt-1 accent-blue-500" disabled>
<span>
<span class="block">High — FluidR3_GM (~142 MB, downloaded)</span>
<span id="ae-sf-high-status" class="block text-xs text-slate-500">Not downloaded yet.</span>
</span>
</label>
</div>
<div class="mt-2 flex items-center gap-2">
<button id="ae-sf-download" class="px-3 py-1.5 rounded bg-slate-600 hover:bg-slate-500 text-sm">Download 142 MB</button>
<button id="ae-sf-cancel" class="hidden px-3 py-1.5 rounded bg-slate-700 hover:bg-slate-600 text-sm">Cancel</button>
<span id="ae-sf-progress-label" class="hidden text-xs text-slate-400"></span>
</div>
<progress id="ae-sf-progress" class="hidden w-full mt-2 h-1.5" max="100" value="0"></progress>
<p id="ae-sf-message" class="hidden text-xs mt-2"></p>
</div>
<div>
<label class="block text-xs text-slate-400 mb-1">DLC Folder</label>
<div class="flex gap-2">
<input type="text" id="ae-dlc-path" class="flex-1 bg-slate-700 border border-slate-600 rounded px-3 py-1.5 text-sm">
<button id="ae-pick-dlc" class="px-3 py-1.5 rounded bg-slate-600 hover:bg-slate-500 text-sm">Browse</button>
</div>
</div>
<div>
<label class="block text-xs text-slate-400 mb-1">NAM Models Folder</label>
<div class="flex gap-2">
<input type="text" id="ae-nam-path" class="flex-1 bg-slate-700 border border-slate-600 rounded px-3 py-1.5 text-sm">
<button id="ae-pick-nam" class="px-3 py-1.5 rounded bg-slate-600 hover:bg-slate-500 text-sm">Browse</button>
</div>
</div>
<div>
<label class="block text-xs text-slate-400 mb-1">Cabinet IRs Folder</label>
<div class="flex gap-2">
<input type="text" id="ae-ir-path" class="flex-1 bg-slate-700 border border-slate-600 rounded px-3 py-1.5 text-sm">
<button id="ae-pick-ir" class="px-3 py-1.5 rounded bg-slate-600 hover:bg-slate-500 text-sm">Browse</button>
</div>
</div>
<div>
<label class="block text-xs text-slate-400 mb-1">Saved Presets</label>
<div id="ae-preset-list" class="space-y-1 max-h-40 overflow-y-auto"></div>
</div>
<div id="ae-tone-automation" class="border-t border-slate-700 pt-3">
<div class="text-xs font-semibold text-slate-300 mb-1">Tone Automation</div>
<p class="text-xs text-slate-500 mb-3">
Configure keyword filters and preset targets here. Turn Tone Automation on or off from the Chain panel (Mode → Tone Automation).
</p>
<p class="text-xs text-slate-500 mb-3">
Selects a target preset based on keywords found in song titles, tone names, or text inputs.
Precedence: <span class="text-slate-400">SOLO &gt; DIST &gt; OD &gt; CLEAN &gt; BASS &gt; ACOUSTIC &gt; MOD</span>.
If no keyword matches, the Idle Target is loaded.
</p>
<div class="mb-3">
<div class="text-xs text-slate-400 mb-2">Auto Classifier Filters</div>
<div id="ae-ta-filters" class="space-y-2"></div>
</div>
<div>
<div class="text-xs text-slate-400 mb-2">Target Mapping</div>
<div id="ae-ta-targets" class="space-y-1.5"></div>
</div>
</div>
<div id="maint-section" class="border border-slate-700 rounded-lg p-3 bg-slate-800/30">
<div class="text-xs font-semibold text-slate-300 mb-2">Reset / repair configuration</div>
<p class="text-xs text-slate-500 mb-2">
Fixes a broken or stale configuration after an upgrade — you no longer need to delete any folders by hand.
Your song library and installed plugins are kept unless you explicitly opt in under Full reset.
</p>
<p id="maint-config-dir" class="text-xs text-slate-500 mb-1 break-all"></p>
<p id="maint-shared-warning" class="hidden text-xs text-amber-300 mb-2"></p>
<div class="space-y-2">
<div class="flex items-start justify-between gap-3">
<div>
<div class="text-sm text-slate-200">Reset app settings &amp; caches</div>
<div class="text-xs text-slate-500">Audio device settings, soundfont state, window/UI prefs and Electron caches. Safe — rebuilt on next launch.</div>
</div>
<button id="maint-reset-app" class="shrink-0 px-3 py-1.5 rounded bg-slate-600 hover:bg-slate-500 text-sm">Reset</button>
</div>
<div class="flex items-start justify-between gap-3">
<div>
<div class="text-sm text-slate-200">Clear plugin state &amp; cached Python deps</div>
<div class="text-xs text-slate-500">Enabled/disabled state, plugin data, and plugin-installed Python packages. Does not remove installed plugins.</div>
</div>
<button id="maint-reset-plugins" class="shrink-0 px-3 py-1.5 rounded bg-slate-600 hover:bg-slate-500 text-sm">Clear</button>
</div>
<div class="border-t border-slate-700 pt-2">
<div class="text-sm text-rose-300">Full reset</div>
<div class="text-xs text-slate-500 mb-2">
Everything above plus the backend databases and config. By default your song library and installed
plugins are preserved — opt in below only if you really want to delete them.
</div>
<div class="space-y-1 mb-2">
<label class="flex items-start gap-2 text-xs text-slate-300 cursor-pointer">
<input type="checkbox" id="maint-opt-plugins" class="mt-0.5 accent-rose-500">
<span>Also remove installed plugins</span>
</label>
<label class="flex items-start gap-2 text-xs text-slate-300 cursor-pointer">
<input type="checkbox" id="maint-opt-library" class="mt-0.5 accent-rose-500">
<span>Also delete the song library <span id="maint-library-path" class="text-slate-500 break-all"></span></span>
</label>
<label class="flex items-start gap-2 text-xs text-slate-300 cursor-pointer">
<input type="checkbox" id="maint-opt-ml" class="mt-0.5 accent-rose-500">
<span>Also clear ML model caches (torch / huggingface)</span>
</label>
</div>
<button id="maint-reset-full" class="px-3 py-1.5 rounded bg-rose-700 hover:bg-rose-600 text-sm">Full reset…</button>
</div>
</div>
<p class="text-xs text-slate-500 mt-2">You'll be asked to confirm in a system dialog before anything is deleted.</p>
<p id="maint-status" class="hidden text-xs mt-3"></p>
<button id="maint-restart" class="hidden mt-2 px-3 py-1.5 rounded bg-blue-600 hover:bg-blue-500 text-sm font-medium">Restart now</button>
</div>
</div>