diff --git a/packages/app/src/context/platform.tsx b/packages/app/src/context/platform.tsx index 3bdc46391b..38c742301b 100644 --- a/packages/app/src/context/platform.tsx +++ b/packages/app/src/context/platform.tsx @@ -9,6 +9,96 @@ type OpenFilePickerOptions = { title?: string; multiple?: boolean; accept?: stri type SaveFilePickerOptions = { title?: string; defaultPath?: string } type UpdateInfo = { updateAvailable: boolean; version?: string } +export type LocalServerMode = "windows" | "wsl" +export type LocalServerStep = "wsl" | "distro" | "opencode" | "switch" +export type LocalServerMismatchAcknowledgement = { + path: string + version: string +} +export type LocalServerWslCheck = { + available: boolean + version: string | null + status: string | null + error: string | null +} +export type LocalServerInstalledDistro = { + name: string + state: string | null + version: number | null + isDefault: boolean +} +export type LocalServerOnlineDistro = { + name: string + label: string +} +export type LocalServerDistroProbe = { + name: string + canExecute: boolean + hasBash: boolean + hasCurl: boolean + username: string | null + isRoot: boolean | null + error: string | null +} +export type LocalServerDistroCheck = { + installed: LocalServerInstalledDistro[] + online: LocalServerOnlineDistro[] + selected: LocalServerDistroProbe | null + error: string | null +} +export type LocalServerTranscriptLine = { + stream: "stdout" | "stderr" | "system" + text: string + at: number +} +export type LocalServerConfig = { + mode: LocalServerMode + distro: string | null + onboarding: { + step: LocalServerStep | null + complete: boolean + pendingRestart: boolean + } + acknowledgements: { + root: string[] + mismatch: LocalServerMismatchAcknowledgement[] + } +} +export type LocalServerStatus = + | { kind: "idle" } + | { kind: "ready" } + | { kind: "running"; step: LocalServerStep | null } + | { kind: "failed"; step: LocalServerStep | null; message: string } +export type LocalServerState = { + config: LocalServerConfig + runtime: { + key: string + mode: LocalServerMode + distro: string | null + } + status: LocalServerStatus + job: { step: LocalServerStep | null; startedAt: number } | null + checks: { + wsl: LocalServerWslCheck | null + distro: LocalServerDistroCheck | null + } + transcript: LocalServerTranscriptLine[] +} +export type LocalServerEvent = { + type: "state" + state: LocalServerState +} +export type LocalServerPlatform = { + getState(): Promise + setConfig(config: LocalServerConfig): Promise + runStep(step: LocalServerStep): Promise + cancelJob(): Promise + installWsl(): Promise + installDistro(name: string): Promise + openTerminal(): Promise + subscribe(cb: (event: LocalServerEvent) => void): () => void +} + export type Platform = { /** Platform discriminator */ platform: "web" | "desktop" @@ -64,6 +154,9 @@ export type Platform = { /** Set the default server URL to use on app startup (platform-specific) */ setDefaultServer?(url: ServerConnection.Key | null): Promise | void + /** Manage the desktop Local Server lifecycle (desktop only) */ + localServer?: LocalServerPlatform + /** Get the configured WSL integration (desktop only) */ getWslEnabled?(): Promise diff --git a/packages/app/src/index.ts b/packages/app/src/index.ts index d80e9fffb0..4e01e764fe 100644 --- a/packages/app/src/index.ts +++ b/packages/app/src/index.ts @@ -2,6 +2,16 @@ export { AppBaseProviders, AppInterface } from "./app" export { ACCEPTED_FILE_EXTENSIONS, ACCEPTED_FILE_TYPES, filePickerFilters } from "./constants/file-picker" export { useCommand } from "./context/command" export { loadLocaleDict, normalizeLocale, type Locale } from "./context/language" -export { type DisplayBackend, type Platform, PlatformProvider } from "./context/platform" +export { + type DisplayBackend, + type LocalServerConfig, + type LocalServerEvent, + type LocalServerMode, + type LocalServerPlatform, + type LocalServerState, + type LocalServerStep, + type Platform, + PlatformProvider, +} from "./context/platform" export { ServerConnection } from "./context/server" export { handleNotificationClick } from "./utils/notification-click" diff --git a/packages/desktop-electron/src/renderer/index.tsx b/packages/desktop-electron/src/renderer/index.tsx index 9ce70e5a99..1b3c409340 100644 --- a/packages/desktop-electron/src/renderer/index.tsx +++ b/packages/desktop-electron/src/renderer/index.tsx @@ -214,6 +214,17 @@ const createPlatform = (): Platform => { await window.api.setDefaultServerUrl(url) }, + localServer: { + getState: () => window.api.localServer.getState(), + setConfig: (config) => window.api.localServer.setConfig(config), + runStep: (step) => window.api.localServer.runStep(step), + cancelJob: () => window.api.localServer.cancelJob(), + installWsl: () => window.api.localServer.installWsl(), + installDistro: (name) => window.api.localServer.installDistro(name), + openTerminal: () => window.api.localServer.openTerminal(), + subscribe: (cb) => window.api.localServer.subscribe(cb), + }, + getDisplayBackend: async () => { return window.api.getDisplayBackend().catch(() => null) },