diff --git a/packages/ui-mac/src/main/alpha-auth.ts b/packages/ui-mac/src/main/alpha-auth.ts index fbfd06c8d2e6..43dba3d4ae33 100644 --- a/packages/ui-mac/src/main/alpha-auth.ts +++ b/packages/ui-mac/src/main/alpha-auth.ts @@ -19,6 +19,7 @@ import { join } from "node:path" import { safeStorage, shell, type BrowserWindow } from "electron" import type { AuthMode, AuthState } from "../preload/types" import { getLogger } from "./logging" +import { ALPHA_ENDPOINTS, ALPHA_PATHS } from "../shared/alpha-config" type StoredAuth = { mode: AuthMode @@ -42,11 +43,12 @@ const CLIENT_ID = "alpha-code" const REDIRECT_URI = "alpha-code://auth/callback" const AUTH_FILE = "alpha-auth.json" -// Endpoints default to alphacodeone.com (subdomain split) and are env-overridable for dev/staging. -// ALPHA_WEB_URL = alpha-web (C, identity authority — login/token); ALPHA_PLATFORM_URL = -// alpha-platform (B, model proxy at /v1 + MCP gateway at /mcp). -const webBase = () => (process.env.ALPHA_WEB_URL ?? "https://auth.alphacodeone.com").replace(/\/+$/, "") -const platformBase = () => (process.env.ALPHA_PLATFORM_URL ?? "https://api.alphacodeone.com").replace(/\/+$/, "") +// Endpoint defaults live in shared/alpha-config (single source of truth — change a domain THERE, +// not here). This layer only adds the env overrides for dev/staging: ALPHA_WEB_URL = alpha-web +// (C, identity authority — login/token); ALPHA_PLATFORM_URL = alpha-platform (B, model proxy /v1 + +// MCP gateway /mcp). +const webBase = () => (process.env.ALPHA_WEB_URL ?? ALPHA_ENDPOINTS.web).replace(/\/+$/, "") +const platformBase = () => (process.env.ALPHA_PLATFORM_URL ?? ALPHA_ENDPOINTS.platform).replace(/\/+$/, "") let userDataPath = "" let getWindow: () => BrowserWindow | null = () => null @@ -133,9 +135,9 @@ export function applyAuthEnv() { const token = devToken || (loggedInPlatform ? stored.accessToken : undefined) const base = platformBase() if (!token || !base) return - if (!process.env.ALPHA_BASE_URL) process.env.ALPHA_BASE_URL = `${base}/v1` + if (!process.env.ALPHA_BASE_URL) process.env.ALPHA_BASE_URL = `${base}${ALPHA_PATHS.modelProxy}` if (!process.env.ALPHA_API_KEY) process.env.ALPHA_API_KEY = token - if (!process.env.ALPHA_CLOUD_MCP_URL) process.env.ALPHA_CLOUD_MCP_URL = `${base}/mcp` + if (!process.env.ALPHA_CLOUD_MCP_URL) process.env.ALPHA_CLOUD_MCP_URL = `${base}${ALPHA_PATHS.mcpGateway}` if (!process.env.ALPHA_CLOUD_TOKEN) process.env.ALPHA_CLOUD_TOKEN = token } @@ -168,7 +170,7 @@ export async function startAuth(): Promise { const challenge = base64url(createHash("sha256").update(verifier).digest()) const state = randomUUID() pkce = { verifier, state } - const url = new URL(`${webBase()}/auth/authorize`) + const url = new URL(`${webBase()}${ALPHA_PATHS.authorize}`) url.searchParams.set("response_type", "code") url.searchParams.set("client_id", CLIENT_ID) url.searchParams.set("redirect_uri", REDIRECT_URI) @@ -227,7 +229,7 @@ async function completeAuth(parsed: URL) { } async function exchangeCode(code: string, verifier: string): Promise { - const res = await fetch(`${webBase()}/auth/token`, { + const res = await fetch(`${webBase()}${ALPHA_PATHS.token}`, { method: "POST", headers: { "content-type": "application/json" }, body: JSON.stringify({ diff --git a/packages/ui-mac/src/renderer/sidebar/alpha-sidebar.tsx b/packages/ui-mac/src/renderer/sidebar/alpha-sidebar.tsx index 46969e2b94cb..ba8c2d7d86b9 100644 --- a/packages/ui-mac/src/renderer/sidebar/alpha-sidebar.tsx +++ b/packages/ui-mac/src/renderer/sidebar/alpha-sidebar.tsx @@ -14,6 +14,7 @@ import { Icon } from "@opencode-ai/ui/v2/icon" import { useTheme } from "@opencode-ai/ui/theme/context" import { t } from "../i18n" import { Mark } from "../logo-alpha" +import { ALPHA_ENDPOINTS, ALPHA_PATHS } from "../../shared/alpha-config" import { base64UrlDecode, homeHref, newSessionHref, projectLabel, sessionHref } from "./route" import { clearHiddenProjects, @@ -107,7 +108,7 @@ export function AlphaSidebar(props: { server: Accessor } { k: "dark", l: "深色" }, { k: "system", l: "系统" }, ] as const - const billingUrl = "https://auth.alphacodeone.com/billing" + const billingUrl = `${ALPHA_ENDPOINTS.web}${ALPHA_PATHS.billing}` const MenuCommon = () => ( <> diff --git a/packages/ui-mac/src/shared/alpha-config.ts b/packages/ui-mac/src/shared/alpha-config.ts new file mode 100644 index 000000000000..a2eee8e40928 --- /dev/null +++ b/packages/ui-mac/src/shared/alpha-config.ts @@ -0,0 +1,27 @@ +// Single source of truth for alpha's backend endpoint defaults. Change a domain HERE — not in +// individual pages/modules. Main-process callers layer env overrides on top (ALPHA_WEB_URL / +// ALPHA_PLATFORM_URL) for dev/staging; the renderer imports these defaults directly (it has no +// process.env). Pure constants only — NO electron/node imports — so both the main and renderer +// bundles can import this module. + +export const ALPHA_ENDPOINTS = { + /** alpha-web (C): identity / login / token / billing portal. */ + web: "https://auth.tidelabs.click", + /** alpha-platform (B): model proxy (/v1) + MCP gateway (/mcp). */ + platform: "https://api.tidelabs.click", +} as const + +// Path segments appended to the hosts above — the full alpha↔backend URL contract in one place. +// Change a route here (e.g. /v1 → /openai/v1) instead of editing inline template strings. +export const ALPHA_PATHS = { + /** web: OAuth authorize page. */ + authorize: "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/auth/authorize", + /** web: PKCE code → token exchange. */ + token: "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/auth/token", + /** web: billing portal. */ + billing: "/billing", + /** platform: model proxy base → ALPHA_BASE_URL. */ + modelProxy: "/v1", + /** platform: MCP tool gateway → ALPHA_CLOUD_MCP_URL. */ + mcpGateway: "/mcp", +} as const