summaryrefslogtreecommitdiffhomepage
path: root/packages/desktop-electron/src/main/migrate.ts
diff options
context:
space:
mode:
authorBrendan Allan <[email protected]>2026-03-04 15:12:34 +0800
committerGitHub <[email protected]>2026-03-04 15:12:34 +0800
commit5cf235fa6cf7b4c890c68f8ff68a96fcae992abf (patch)
tree25fdfd8ce95ad048fb097822995dcf060e8d6d8b /packages/desktop-electron/src/main/migrate.ts
parente4f0825c56300286ec0aa82b1006e4006a17e1e1 (diff)
downloadopencode-5cf235fa6cf7b4c890c68f8ff68a96fcae992abf.tar.gz
opencode-5cf235fa6cf7b4c890c68f8ff68a96fcae992abf.zip
desktop: add electron version (#15663)
Diffstat (limited to 'packages/desktop-electron/src/main/migrate.ts')
-rw-r--r--packages/desktop-electron/src/main/migrate.ts91
1 files changed, 91 insertions, 0 deletions
diff --git a/packages/desktop-electron/src/main/migrate.ts b/packages/desktop-electron/src/main/migrate.ts
new file mode 100644
index 000000000..bad1349ee
--- /dev/null
+++ b/packages/desktop-electron/src/main/migrate.ts
@@ -0,0 +1,91 @@
+import { app } from "electron"
+import log from "electron-log/main.js"
+import { existsSync, readdirSync, readFileSync } from "node:fs"
+import { homedir } from "node:os"
+import { join } from "node:path"
+import { CHANNEL } from "./constants"
+import { getStore, store } from "./store"
+
+const TAURI_MIGRATED_KEY = "tauriMigrated"
+
+// Resolve the directory where Tauri stored its .dat files for the given app identifier.
+// Mirrors Tauri's AppLocalData / AppData resolution per OS.
+function tauriDir(id: string) {
+ switch (process.platform) {
+ case "darwin":
+ return join(homedir(), "Library", "Application Support", id)
+ case "win32":
+ return join(process.env.APPDATA ?? join(homedir(), "AppData", "Roaming"), id)
+ default:
+ return join(process.env.XDG_DATA_HOME ?? join(homedir(), ".local", "share"), id)
+ }
+}
+
+// The Tauri app identifier changes between dev/beta/prod builds.
+const TAURI_APP_IDS: Record<string, string> = {
+ dev: "ai.opencode.desktop.dev",
+ beta: "ai.opencode.desktop.beta",
+ prod: "ai.opencode.desktop",
+}
+function tauriAppId() {
+ return app.isPackaged ? TAURI_APP_IDS[CHANNEL] : "ai.opencode.desktop.dev"
+}
+
+// Migrate a single Tauri .dat file into the corresponding electron-store.
+// `opencode.settings.dat` is special: it maps to the `opencode.settings` store
+// (the electron-store name without the `.dat` extension). All other .dat files
+// keep their full filename as the electron-store name so they match what the
+// renderer already passes via IPC (e.g. `"default.dat"`, `"opencode.global.dat"`).
+function migrateFile(datPath: string, filename: string) {
+ let data: Record<string, unknown>
+ try {
+ data = JSON.parse(readFileSync(datPath, "utf-8"))
+ } catch (err) {
+ log.warn("tauri migration: failed to parse", filename, err)
+ return
+ }
+
+ // opencode.settings.dat → the electron settings store ("opencode.settings").
+ // All other .dat files keep their full filename as the store name so they match
+ // what the renderer passes via IPC (e.g. "default.dat", "opencode.global.dat").
+ const storeName = filename === "opencode.settings.dat" ? "opencode.settings" : filename
+ const target = getStore(storeName)
+ const migrated: string[] = []
+ const skipped: string[] = []
+
+ for (const [key, value] of Object.entries(data)) {
+ // Don't overwrite values the user has already set in the Electron app.
+ if (target.has(key)) {
+ skipped.push(key)
+ continue
+ }
+ target.set(key, value)
+ migrated.push(key)
+ }
+
+ log.log("tauri migration: migrated", filename, "→", storeName, { migrated, skipped })
+}
+
+export function migrate() {
+ if (store.get(TAURI_MIGRATED_KEY)) {
+ log.log("tauri migration: already done, skipping")
+ return
+ }
+
+ const dir = tauriDir(tauriAppId())
+ log.log("tauri migration: starting", { dir })
+
+ if (!existsSync(dir)) {
+ log.log("tauri migration: no tauri data directory found, nothing to migrate")
+ store.set(TAURI_MIGRATED_KEY, true)
+ return
+ }
+
+ for (const filename of readdirSync(dir)) {
+ if (!filename.endsWith(".dat")) continue
+ migrateFile(join(dir, filename), filename)
+ }
+
+ log.log("tauri migration: complete")
+ store.set(TAURI_MIGRATED_KEY, true)
+}