import { createSimpleContext } from "@opencode/ui/context" import type { AsyncStorage, SyncStorage } from "@solid-primitives/storage" import type { Accessor } from "solid-js" import type { DesktopMenuAction } from "@/shell/commands/desktop-menu" import { ServerConnection } from "@/runtime/server/registry" import type { WslServersPlatform } from "@/servers/wsl/types" import type { SshPlatform } from "@/servers/ssh/types" import type { UpdaterPlatform } from "@/shell/updates/types" import type { DraftStore } from "@/runtime/persistence/drafts" import type { BrowserPanePlatform } from "./browser-pane" 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 PairingInfo = { readonly urls: readonly string[] readonly username: "opencode" readonly password: string } export type FatalRendererErrorLog = { error: string url: string version?: string platform: PlatformName os?: DesktopOS } type PlatformBase = { /** App version */ version?: string /** Open a web or mail URL in the default system application */ openExternal(url: string): void /** Open a local path in a local app (desktop only) */ openPath?(path: string, app?: string): Promise /** Open a local file URL in its default app (desktop only) */ openLocalFile?(url: string): void /** 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 /** Send a system notification */ notify(title: string, description?: string, onClick?: () => void): 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 /** Observe native drag cancellation that does not reach the renderer event loop. */ onDragCancel?(callback: () => void): () => void /** Open a native save file dialog and write content to the selected path (desktop only) */ saveFile?(opts: SaveFilePickerOptions, content: string): Promise /** Storage mechanism, defaults to localStorage */ storage?: (name?: string) => SyncStorage | AsyncStorage /** Prompt drafts, history, and their blobs. */ draftStore?: DraftStore /** 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 sshServers?: SshPlatform /** Webview zoom level (desktop only) */ webviewZoom?: Accessor /** Whether the native desktop window is fullscreen */ windowFullscreen?: 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 /** Prevent the local display from sleeping while the desktop app is running. */ getKeepScreenActive?(): Promise setKeepScreenActive?(enabled: boolean): Promise /** 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 /** Write text to the native clipboard (desktop only) */ writeClipboardText?(text: string): Promise /** Export collected diagnostic logs (desktop only) */ exportDebugLogs?(): Promise /** Force focus styles on interactive elements through desktop devtools (desktop only) */ setForceFocus?(enabled: boolean): Promise /** Record a fatal renderer error in platform logs (desktop only) */ recordFatalRendererError?(error: FatalRendererErrorLog): Promise /** Native browser pane hosted by the platform (desktop only). */ browserPane?: BrowserPanePlatform /** Pair another device with the local desktop server. */ pair?: { info(): Promise } } export type Platform = PlatformBase & ( | { platform: "web"; os?: never; windowID?: never } | { platform: "desktop" os?: DesktopOS /** Stable platform window identity for window-scoped persistence */ windowID: string openDirectoryPickerDialog(opts?: OpenDirectoryPickerOptions): Promise } ) export const { use: usePlatform, provider: PlatformProvider } = createSimpleContext({ name: "Platform", init: (props: { value: Platform }) => { return props.value }, })