import { createSimpleContext } from "@opencode-ai/ui/context" import type { AsyncStorage, SyncStorage } from "@solid-primitives/storage" import type { Accessor } from "solid-js" import type { DesktopMenuAction } from "../desktop-menu" import { ServerConnection } from "./server" import type { WslServersPlatform } from "../wsl/types" import type { UpdaterPlatform } from "../updater" type PickerPaths = string | string[] | null type OpenDirectoryPickerOptions = { title?: string; multiple?: boolean } type OpenAttachmentPickerOptions = { title?: string multiple?: boolean accept?: string[] extensions?: string[] defaultPath?: string } type SaveFilePickerOptions = { title?: string; defaultPath?: string } type PlatformName = "web" | "desktop" type DesktopOS = "macos" | "windows" | "linux" export type FatalRendererErrorLog = { error: string url: string version?: string platform: PlatformName os?: DesktopOS } type PlatformBase = { /** App version */ version?: string /** Open a URL in the default browser */ openLink(url: string): void /** Open a local path in a local app (desktop only) */ openPath?(path: string, app?: string): Promise /** Reveal a local path in the system file manager; false when the path does not exist (desktop only) */ revealPath?(path: string): Promise /** Restart the app */ restart(): Promise /** Navigate back in history */ back(): void /** Navigate forward in history */ forward(): void /** Send a system notification (optional deep link) */ notify(title: string, description?: string, href?: string): Promise /** Open a native attachment picker and read selected files sequentially (desktop only) */ openAttachmentPickerDialog?( opts: OpenAttachmentPickerOptions, onFile: (file: File) => Promise, ): Promise /** Resolve the native source path for a desktop File. */ getPathForFile?(file: File): string /** Open a native save file picker dialog (desktop only) */ saveFilePickerDialog?(opts?: SaveFilePickerOptions): Promise /** Storage mechanism, defaults to localStorage */ storage?: (name?: string) => SyncStorage | AsyncStorage /** Stable platform window identity for window-scoped persistence */ windowID?: string /** Application-global desktop updater */ updater?: UpdaterPlatform /** Fetch override */ fetch?: typeof fetch /** Get the configured default server URL (platform-specific) */ getDefaultServer?(): Promise /** Set the default server URL to use on app startup (platform-specific) */ setDefaultServer?(url: ServerConnection.Key | null): Promise | void /** Manage WSL sidecar servers (Electron on Windows only) */ wslServers?: WslServersPlatform /** Get the preferred display backend (desktop only) */ getDisplayBackend?(): Promise | DisplayBackend | null /** Set the preferred display backend (desktop only) */ setDisplayBackend?(backend: DisplayBackend): Promise /** Parse markdown to HTML using native parser (desktop only, returns unprocessed code blocks) */ parseMarkdown?(markdown: string): Promise /** Webview zoom level (desktop only) */ webviewZoom?: Accessor /** Get whether native pinch/Ctrl-scroll zoom gestures are enabled (desktop only) */ getPinchZoomEnabled?(): Promise | boolean /** Allow native pinch/Ctrl-scroll zoom gestures (desktop only) */ setPinchZoomEnabled?(enabled: boolean): Promise | void /** Run a desktop-only menu action from the app chrome */ runDesktopMenuAction?(action: DesktopMenuAction): Promise | void /** Check if an editor app exists (desktop only) */ checkAppExists?(appName: string): Promise /** Read image from clipboard (desktop only) */ readClipboardImage?(): Promise /** Export collected diagnostic logs (desktop only) */ exportDebugLogs?(): Promise /** Record a fatal renderer error in platform logs (desktop only) */ recordFatalRendererError?(error: FatalRendererErrorLog): Promise } export type Platform = PlatformBase & ( | { platform: "web"; os?: never } | { platform: "desktop" os?: DesktopOS openDirectoryPickerDialog(opts?: OpenDirectoryPickerOptions): Promise } ) export type DisplayBackend = "auto" | "wayland" export const { use: usePlatform, provider: PlatformProvider } = createSimpleContext({ name: "Platform", init: (props: { value: Platform }) => { return props.value }, })