import { homedir } from "node:os"; import { join, resolve } from "node:path"; import { fileURLToPath } from "node:url"; const settings = process.platform === "darwin" ? join(homedir(), "Library", "Application Support", "Ace") : join(process.env.XDG_CONFIG_HOME || join(homedir(), ".config"), "ace"); /** Capture host configuration before credentials leave the process environment. */ export const config = { home: resolve(process.env.ACE_HOME || join(homedir(), ".local", "state", "ace")), settings: resolve(process.env.ACE_CONFIG_HOME || settings), keychain: process.env.ACE_KEYCHAIN_SERVICE || "ace", user: process.env.ACE_USER, model: process.env.ACE_MODEL, port: Number(process.env.ACE_PORT || 4140), /** HTTPS for browsers on the tailnet; defaults to port + 1000. */ webPort: process.env.ACE_WEB_PORT ? Number(process.env.ACE_WEB_PORT) : undefined, peerPort: process.env.ACE_PEER_PORT ? Number(process.env.ACE_PEER_PORT) : undefined, app: process.env.ACE_APP_DIR || fileURLToPath(new URL("../../app/dist", import.meta.url)), appUrl: process.env.ACE_APP_URL, helper: false, worker: [ process.execPath, "--no-env-file", process.env.ACE_WORKER || fileURLToPath(new URL("./worker.ts", import.meta.url)), ] as [string, ...string[]], }; const ports: Record = { dev: 4141, canary: 4142 }; /** * Canary, the installed development app, and each checkout's development build own separate * channels, settings, credentials, and listeners, derived from the app's bundle identifier. * Returns the checkout's build suffix, whose app must not manage Ace Helper. */ export function desktop(identifier: string): string | undefined { const name = identifier.slice("dev.ace.desktop.".length).replaceAll(".", "-"); if (!name) return; const lane = /^dev-([a-f0-9]{8})$/.exec(name)?.[1]; // A profile exported for another app must never point a checkout's build at that app's data. if (lane || !process.env.ACE_HOME) { config.home = join(homedir(), ".local", "state", `ace-${name}`); } if (lane || !process.env.ACE_CONFIG_HOME) config.settings = `${settings}-${name}`; if (lane || !process.env.ACE_KEYCHAIN_SERVICE) config.keychain = `ace-${name}`; if (!process.env.ACE_PORT) { config.port = ports[name] || 4200 + Number.parseInt(lane || "0", 16) % 800; } return lane; }