polish(desktop): rename userData folder to Backspace with first-launch migration

Electron derived userData from package.json's `@backspace/desktop` name, leaking
the monorepo's pnpm scope into ~/Library/Application Support/. Now `app.setName`
runs at module load before any userData consumer, and a one-shot migration
atomically moves the historical folder to <appData>/Backspace, cleaning the
empty @backspace/ parent. Conservative on conflict — never clobbers an existing
populated target. EXDEV fallback to recursive copy. Smoke-recovery path flipped
back to Backspace.
This commit is contained in:
Jannis Braun
2026-05-03 14:36:34 +02:00
parent 309484dca9
commit 2b0f93ec62
5 changed files with 203 additions and 1 deletions
+23
View File
@@ -37,6 +37,29 @@ import {
buildAppMenuTemplate,
type RecoveryState,
} from './recovery';
import { migrateUserData } from './userDataMigration';
// Override Electron's package.json-derived app name so userData lives at
// "<appData>/Backspace" instead of leaking the monorepo's "@backspace/desktop"
// package name. Must run before any app.getPath('userData') consumer.
app.setName('Backspace');
// One-time migration from the historical scoped path. After the move the old
// folder is gone, so subsequent launches hit the old-missing no-op branch.
{
const appDataDir = app.getPath('appData');
const oldParent = path.join(appDataDir, '@backspace');
const result = migrateUserData({
oldDir: path.join(oldParent, 'desktop'),
newDir: path.join(appDataDir, 'Backspace'),
oldParent,
});
if (result.kind === 'migrated') {
console.log(`[userData] migrated ${result.from}${result.to}`);
} else if (result.kind === 'failed') {
console.error('[userData] migration failed:', result.error);
}
}
let mainWindow: BrowserWindow | null = null;
const keybindManager = new KeybindManager();