platform.tsx 3.0 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192
  1. import { createSimpleContext } from "@opencode-ai/ui/context"
  2. import { AsyncStorage, SyncStorage } from "@solid-primitives/storage"
  3. import type { Accessor } from "solid-js"
  4. export type Platform = {
  5. /** Platform discriminator */
  6. platform: "web" | "desktop"
  7. /** Desktop OS (Tauri only) */
  8. os?: "macos" | "windows" | "linux"
  9. /** App version */
  10. version?: string
  11. /** Open a URL in the default browser */
  12. openLink(url: string): void
  13. /** Open a local path in a local app (desktop only) */
  14. openPath?(path: string, app?: string): Promise<void>
  15. /** Restart the app */
  16. restart(): Promise<void>
  17. /** Navigate back in history */
  18. back(): void
  19. /** Navigate forward in history */
  20. forward(): void
  21. /** Send a system notification (optional deep link) */
  22. notify(title: string, description?: string, href?: string): Promise<void>
  23. /** Open directory picker dialog (native on Tauri, server-backed on web) */
  24. openDirectoryPickerDialog?(opts?: { title?: string; multiple?: boolean }): Promise<string | string[] | null>
  25. /** Open native file picker dialog (Tauri only) */
  26. openFilePickerDialog?(opts?: { title?: string; multiple?: boolean }): Promise<string | string[] | null>
  27. /** Save file picker dialog (Tauri only) */
  28. saveFilePickerDialog?(opts?: { title?: string; defaultPath?: string }): Promise<string | null>
  29. /** Storage mechanism, defaults to localStorage */
  30. storage?: (name?: string) => SyncStorage | AsyncStorage
  31. /** Check for updates (Tauri only) */
  32. checkUpdate?(): Promise<{ updateAvailable: boolean; version?: string }>
  33. /** Install updates (Tauri only) */
  34. update?(): Promise<void>
  35. /** Fetch override */
  36. fetch?: typeof fetch
  37. /** Get the configured default server URL (platform-specific) */
  38. getDefaultServerUrl?(): Promise<string | null> | string | null
  39. /** Set the default server URL to use on app startup (platform-specific) */
  40. setDefaultServerUrl?(url: string | null): Promise<void> | void
  41. /** Get the configured WSL integration (desktop only) */
  42. getWslEnabled?(): Promise<boolean>
  43. /** Set the configured WSL integration (desktop only) */
  44. setWslEnabled?(config: boolean): Promise<void> | void
  45. /** Get the preferred display backend (desktop only) */
  46. getDisplayBackend?(): Promise<DisplayBackend | null> | DisplayBackend | null
  47. /** Set the preferred display backend (desktop only) */
  48. setDisplayBackend?(backend: DisplayBackend): Promise<void>
  49. /** Parse markdown to HTML using native parser (desktop only, returns unprocessed code blocks) */
  50. parseMarkdown?(markdown: string): Promise<string>
  51. /** Webview zoom level (desktop only) */
  52. webviewZoom?: Accessor<number>
  53. /** Check if an editor app exists (desktop only) */
  54. checkAppExists?(appName: string): Promise<boolean>
  55. /** Read image from clipboard (desktop only) */
  56. readClipboardImage?(): Promise<File | null>
  57. }
  58. export type DisplayBackend = "auto" | "wayland"
  59. export const { use: usePlatform, provider: PlatformProvider } = createSimpleContext({
  60. name: "Platform",
  61. init: (props: { value: Platform }) => {
  62. return props.value
  63. },
  64. })