refactor: expose local server through app platform

This commit is contained in:
LukeParkerDev 2026-04-16 14:37:21 +10:00
parent c575415ec4
commit df635562e9
3 changed files with 115 additions and 1 deletions

View file

@ -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<LocalServerState>
setConfig(config: LocalServerConfig): Promise<void>
runStep(step: LocalServerStep): Promise<void>
cancelJob(): Promise<void>
installWsl(): Promise<void>
installDistro(name: string): Promise<void>
openTerminal(): Promise<void>
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> | void
/** Manage the desktop Local Server lifecycle (desktop only) */
localServer?: LocalServerPlatform
/** Get the configured WSL integration (desktop only) */
getWslEnabled?(): Promise<boolean>

View file

@ -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"

View file

@ -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)
},