These docs describe the main branch, including unreleased changes. Read the 0.6.0 docs.

OpenTUI 0.5.2

npmGitHub release

Added

  • core: createClipboard() combines the host clipboard and the terminal clipboard behind one ClipboardService with read(), writeText(), clear(), and dispose(). createHostClipboard() reads and changes the clipboard of the machine that runs the process. createRendererClipboardAdapter() writes or clears the terminal user’s clipboard with OSC 52. writeText() and clear() take a destination of "terminal-only", "host-only", "best-available", or "all-available". See Clipboard. (#1271)
  • core: ImageRenderable accepts a NativeImage as source (ImageRenderableSource) without decoding it again. NativeImage.retain() returns a new handle, so the caller can dispose its own handle at once. NativeImage.ensureEncodedPng() encodes the image as PNG on request. See Image and NativeImage. (#1356)

Changed

  • core: Unicode 17 data is now used for character width and grapheme handling. (#1286)
  • core: Automatic terminal detection forwards the SSH and mosh markers, so remote sessions do not inherit the capabilities of the host terminal. (#1286)
  • native: libopentui now links Ghostty VT statically. Native packages are one self-contained library and include the Ghostty, uucode, and Unicode notices. (#1317)

Fixed

  • core: CodeRenderable no longer creates unbounded Tree-sitter worker work during streaming. It runs one highlight at a time and keeps only the latest pending content. Highlight settlement now includes queued reruns, so rendered output and scrollback match the current content. CodeRenderable.destroy() is now exported. See Code. (#1331)
  • core: A failed one-shot Tree-sitter highlight request now rejects instead of staying unresolved. TreeSitterWorkerResponse errors carry an optional messageId. See Syntax highlighting with Tree-sitter. (#1331)

API changes#

@opentui/core#

Added

  • const createClipboard: ({ host, terminal }: ClipboardOptions) => ClipboardService
  • const createHostClipboard: (options?: HostClipboardOptions) => HostClipboardService
  • const createRendererClipboardAdapter: (renderer: RendererClipboardBoundary) => TerminalClipboardAdapter
  • enum NativeClipboardCancelStatus
  • enum NativeClipboardCopyStatus
  • enum NativeClipboardDestroyStatus
  • enum NativeClipboardOperationStatus
  • enum NativeClipboardShutdownStatus
  • enum NativeClipboardStartStatus
  • interface ClipboardClearResult
  • interface ClipboardOptions
  • interface ClipboardReadOptions
  • interface ClipboardRepresentation
  • interface ClipboardService
  • interface ClipboardWriteOptions
  • interface ClipboardWriteResult
  • interface HostClipboardBackend
  • interface HostClipboardOperationOptions
  • interface HostClipboardOptions
  • interface HostClipboardReadOptions
  • interface HostClipboardService
  • interface HostClipboardWriteOptions
  • interface RendererClipboardBoundary
  • interface TerminalClipboardAdapter
  • interface TerminalClipboardOperationResult
  • method CodeRenderable.destroy(): void
  • method NativeImage.ensureEncodedPng(): void
  • method NativeImage.retain(): NativeImage
  • property RenderLib.clipboardClearOperationStart: (service: ClipboardServiceHandle, selection: number, timeoutMs: number) => { status: NativeClipboardStartStatus; operation: ClipboardOperationHandle | null; }
  • property RenderLib.clipboardOperationCancel: (operation: ClipboardOperationHandle) => NativeClipboardCancelStatus
  • property RenderLib.clipboardOperationDestroy: (operation: ClipboardOperationHandle) => NativeClipboardDestroyStatus
  • property RenderLib.clipboardOperationPoll: (operation: ClipboardOperationHandle) => NativeClipboardOperationStatus
  • property RenderLib.clipboardOperationResultDataCopy: (operation: ClipboardOperationHandle, output: Uint8Array) => NativeClipboardCopyStatus
  • property RenderLib.clipboardOperationResultDataLength: (operation: ClipboardOperationHandle) => { status: NativeClipboardCopyStatus; length: number; }
  • property RenderLib.clipboardOperationResultDiagnosticCopy: (operation: ClipboardOperationHandle, output: Uint8Array) => NativeClipboardCopyStatus
  • property RenderLib.clipboardOperationResultDiagnosticLength: (operation: ClipboardOperationHandle) => { status: NativeClipboardCopyStatus; length: number; }
  • property RenderLib.clipboardOperationResultErrorCode: (operation: ClipboardOperationHandle) => { status: NativeClipboardCopyStatus; errorCode: number; }
  • property RenderLib.clipboardOperationResultMimeCopy: (operation: ClipboardOperationHandle, output: Uint8Array) => NativeClipboardCopyStatus
  • property RenderLib.clipboardOperationResultMimeLength: (operation: ClipboardOperationHandle) => { status: NativeClipboardCopyStatus; length: number; }
  • property RenderLib.clipboardReadOperationStart: (service: ClipboardServiceHandle, request: Uint8Array, selection: number, maxBytes: number, maxImagePixels: number, maxConversionBytes: number, timeoutMs: number) => { status: NativeClipboardStartStatus; operation: ClipboardOperationHandle | null; }
  • property RenderLib.clipboardServiceBeginShutdown: (service: ClipboardServiceHandle) => NativeClipboardShutdownStatus
  • property RenderLib.clipboardServiceCreate: (maxConcurrentOperations: number, maxProviderTransfers: number, waylandSeat?: string) => ClipboardServiceHandle | null
  • property RenderLib.clipboardServiceDestroy: (service: ClipboardServiceHandle) => NativeClipboardDestroyStatus
  • property RenderLib.clipboardServiceDrain: (service: ClipboardServiceHandle) => number
  • property RenderLib.clipboardServicePollShutdown: (service: ClipboardServiceHandle) => NativeClipboardShutdownStatus
  • property RenderLib.clipboardWriteOperationStart: (service: ClipboardServiceHandle, textUtf8: Uint8Array, selection: number, timeoutMs: number) => { status: NativeClipboardStartStatus; operation: ClipboardOperationHandle | null; }
  • property RenderLib.imageEnsureEncodedPng: (image: ImageHandle) => number
  • property RenderLib.imageRetain: (image: ImageHandle) => { status: number; handle: ImageHandle | null; }
  • type ClipboardOperationHandle = number & { readonly __nativeHandle: "clipboard_operation"; }
  • type ClipboardReadResult = { readonly status: "read"; readonly representation: ClipboardRepresentation; } | { readonly status: "empty" | "unsupported" | "cancelled" | "timed-out" | "limit-exceeded"; } | { readonly status: "failed"; readonly error: Error; }
  • type ClipboardSelection = "clipboard" | "primary"
  • type ClipboardServiceHandle = number & { readonly __nativeHandle: "clipboard_service"; }
  • type ClipboardWriteDestination = "terminal-only" | "host-only" | "best-available" | "all-available"
  • type HostClipboardClearResult = { readonly status: "cleared" | "unsupported" | "cancelled" | "timed-out"; } | { readonly status: "failed"; readonly error: Error; }
  • type HostClipboardWriteResult = { readonly status: "written" | "unsupported" | "cancelled" | "timed-out"; } | { readonly status: "failed"; readonly error: Error; }
  • type ImageRenderableSource = ImageSource | NativeImage

Changed

  • property ImageRenderable.source: ImageSource | undefinedproperty ImageRenderable.source: ImageRenderableSource | undefined
  • property ImageRenderableOptions.source?: ImageSourceproperty ImageRenderableOptions.source?: ImageRenderableSource
  • type TreeSitterWorkerResponse = { type: "INIT_RESPONSE"; error?: string; } | { type: "PARSER_INIT_RESPONSE"; bufferId: number; messageId: string; hasParser: boolean; warning?: string; error?: string; } | { type: "HIGHLIGHT_RESPONSE"; bufferId: number; version: number; highlights: HighlightResponse[]; } | { type: "PRELOAD_PARSER_RESPONSE"; messageId: string; hasParser: boolean; } | { type: "BUFFER_DISPOSED"; bufferId: number; } | { type: "PERFORMANCE_RESPONSE"; performance: PerformanceStats; messageId: string; } | { type: "ONESHOT_HIGHLIGHT_RESPONSE"; messageId: string; hasParser: boolean; highlights?: SimpleHighlight[]; warning?: string; error?: string; } | { type: "UPDATE_DATA_PATH_RESPONSE"; messageId: string; error?: string; } | { type: "CLEAR_CACHE_RESPONSE"; messageId: string; error?: string; } | { type: "WARNING"; bufferId?: number; warning: string; } | { type: "ERROR"; bufferId?: number; error: string; } | { type: "WORKER_LOG"; logType: TreeSitterWorkerLogType; data: unknown[]; }type TreeSitterWorkerResponse = { type: "INIT_RESPONSE"; error?: string; } | { type: "PARSER_INIT_RESPONSE"; bufferId: number; messageId: string; hasParser: boolean; warning?: string; error?: string; } | { type: "HIGHLIGHT_RESPONSE"; bufferId: number; version: number; highlights: HighlightResponse[]; } | { type: "PRELOAD_PARSER_RESPONSE"; messageId: string; hasParser: boolean; } | { type: "BUFFER_DISPOSED"; bufferId: number; } | { type: "PERFORMANCE_RESPONSE"; performance: PerformanceStats; messageId: string; } | { type: "ONESHOT_HIGHLIGHT_RESPONSE"; messageId: string; hasParser: boolean; highlights?: SimpleHighlight[]; warning?: string; error?: string; } | { type: "UPDATE_DATA_PATH_RESPONSE"; messageId: string; error?: string; } | { type: "CLEAR_CACHE_RESPONSE"; messageId: string; error?: string; } | { type: "WARNING"; bufferId?: number; warning: string; } | { type: "ERROR"; bufferId?: number; messageId?: string; error: string; } | { type: "WORKER_LOG"; logType: TreeSitterWorkerLogType; data: unknown[]; }