| ... | ... | @@ -50,6 +50,8 @@ const ROOT_DIR = Path.resolve(__dirname, "../../.."); |
| 50 | 50 | const isDevelopment = Boolean(process.env.VITE_DEV_SERVER_URL); |
| 51 | 51 | const APP_DISPLAY_NAME = isDevelopment ? "T3 Code (Dev)" : "T3 Code (Alpha)"; |
| 52 | 52 | const APP_USER_MODEL_ID = "com.t3tools.t3code"; |
| 53 | const USER_DATA_DIR_NAME = isDevelopment ? "t3code-dev" : "t3code"; |
| 54 | const LEGACY_USER_DATA_DIR_NAME = isDevelopment ? "T3 Code (Dev)" : "T3 Code (Alpha)"; |
| 53 | 55 | const COMMIT_HASH_PATTERN = /^[0-9a-f]{7,40}$/i; |
| 54 | 56 | const COMMIT_HASH_DISPLAY_LENGTH = 12; |
| 55 | 57 | const LOG_DIR = Path.join(STATE_DIR, "logs"); |
| ... | ... | @@ -593,6 +595,34 @@ function resolveIconPath(ext: "ico" | "icns" | "png"): string | null { |
| 593 | 595 | return resolveResourcePath(`icon.${ext}`); |
| 594 | 596 | } |
| 595 | 597 | |
| 598 | /** |
| 599 | * Resolve the Electron userData directory path. |
| 600 | * |
| 601 | * Electron derives the default userData path from `productName` in |
| 602 | * package.json, which currently produces directories with spaces and |
| 603 | * parentheses (e.g. `~/.config/T3 Code (Alpha)` on Linux). This is |
| 604 | * unfriendly for shell usage and violates Linux naming conventions. |
| 605 | * |
| 606 | * We override it to a clean lowercase name (`t3code`). If the legacy |
| 607 | * directory already exists we keep using it so existing users don't |
| 608 | * lose their Chromium profile data (localStorage, cookies, sessions). |
| 609 | */ |
| 610 | function resolveUserDataPath(): string { |
| 611 | const appDataBase = |
| 612 | process.platform === "win32" |
| 613 | ? process.env.APPDATA || Path.join(OS.homedir(), "AppData", "Roaming") |
| 614 | : process.platform === "darwin" |
| 615 | ? Path.join(OS.homedir(), "Library", "Application Support") |
| 616 | : process.env.XDG_CONFIG_HOME || Path.join(OS.homedir(), ".config"); |
| 617 | |
| 618 | const legacyPath = Path.join(appDataBase, LEGACY_USER_DATA_DIR_NAME); |
| 619 | if (FS.existsSync(legacyPath)) { |
| 620 | return legacyPath; |
| 621 | } |
| 622 | |
| 623 | return Path.join(appDataBase, USER_DATA_DIR_NAME); |
| 624 | } |
| 625 | |
| 596 | 626 | function configureAppIdentity(): void { |
| 597 | 627 | app.setName(APP_DISPLAY_NAME); |
| 598 | 628 | const commitHash = resolveAboutCommitHash(); |
| ... | ... | @@ -1187,6 +1217,11 @@ function createWindow(): BrowserWindow { |
| 1187 | 1217 | return window; |
| 1188 | 1218 | } |
| 1189 | 1219 | |
| 1220 | // Override Electron's userData path before the `ready` event so that |
| 1221 | // Chromium session data uses a filesystem-friendly directory name. |
| 1222 | // Must be called synchronously at the top level — before `app.whenReady()`. |
| 1223 | app.setPath("userData", resolveUserDataPath()); |
| 1224 | |
| 1190 | 1225 | configureAppIdentity(); |
| 1191 | 1226 | |
| 1192 | 1227 | async function bootstrap(): Promise<void> { |