OpenTUI 0.5.11

npmGitHub release

Added

  • core: audio.playStream() accepts format: "pcm" with the sampleFormat, sampleRate, and channels options. PCM uses the same stream worker as MP3 and FLAC. Writes go to a bounded 256 KiB input queue and are validated asynchronously. PCM reconnect is not supported. See Streaming audio. (#1481)
  • core: CliRenderer.getLinkAt(x, y) returns the URL at a cell, and CliRenderer.getLinkIdAt(x, y) returns its link ID. See Renderer. (#1442)
  • core: TextBufferRenderable.getLineSources() and CodeRenderable.getLineSources() return the source IDs of a range of visual lines. detectLinks() and ChunkRenderContext accept optional sourceRanges. See Code. (#1442, #1462)
  • core: CodeRenderable.updateStreamingPreview(content, initialStyledText) updates streamed code with a styled preview. See Code. (#1442)
  • native: Line wrapping can break between CJK characters. (#1453)
  • core: Bun 1.4 is supported. See Runtime and platform support. (#1400)

Changed

  • core: Markdown named links and bare links are clickable in terminals that support OSC 8, and the link destination is not shown. Other terminals show the visible URL. Links stay intact across formatting, streaming, wrapping, and late terminal capability detection. See Markdown. (#1442)
  • core: Large diffs paint and highlight only the rows that reach the screen. Applying syntax highlights to 5,000 JSON fields takes 164 ms instead of 5,973 ms. See Diff. (#1462)

Removed

  • core: DiffRenderable.onResize() is no longer a protected method. Diff alignment rebuilds when the width of a pane changes. Subclasses that override or call onResize() must use another resize hook. See Diff. (#1463)

Fixed

  • core: EmbeddedTerminalRenderable keeps the active-layout key when it encodes Kitty keyboard input. With a Dvorak layout, Ctrl+U and Ctrl+D no longer reach the child process as Ctrl+F and Ctrl+H. See Embedded terminal. (#1477)
  • core: Split diffs realign after the viewer changes between split and unified views or is resized. Scrolling to the end no longer shows blank rows in place of the removed and added line tails. See Diff. (#1463)

API changes#

@opentui/core#

Added

  • const MAX_LINK_URL_BYTES = 512
  • method CliRenderer.getLinkAt(x: number, y: number): string | null
  • method CliRenderer.getLinkIdAt(x: number, y: number): number
  • method CodeRenderable.getLineSources(startLine: number, lineCount: number): number[]
  • method CodeRenderable.updateStreamingPreview(content: string, initialStyledText: StyledText): void
  • method LineInfoProvider.getLineSources?(startLine: number, lineCount: number): number[]
  • protected method MarkdownRenderable.destroySelf(): void
  • method TextBufferRenderable.getLineSources(startLine: number, lineCount: number): number[]
  • protected method TextBufferRenderable.needsLineInfoFallback(owner: object): boolean
  • method TextBufferView.getLineSources(startLine: number, lineCount: number): number[]
  • property AudioStreamOptions.channels?: 1 | 2
  • property AudioStreamOptions.sampleFormat?: "f32le"
  • property AudioStreamOptions.sampleRate?: number
  • property ChunkRenderContext.sourceRanges?: Array<{ start: number; end: number; }>
  • property RenderLib.linkGetUrl: (linkId: number, maxLen?: number) => string
  • property RenderLib.textBufferViewGetLineSources: (view: TextBufferViewHandle, startLine: number, lineCount: number) => number[]

Changed

  • const NativeAudioStreamFormat: { readonly Mp3: 1; readonly Flac: 2; }const NativeAudioStreamFormat: { readonly Mp3: 1; readonly Flac: 2; readonly Pcm: 3; }
  • function detectLinks(chunks: TextChunk[], context: { content: string; highlights: SimpleHighlight[]; }): TextChunk[]function detectLinks(chunks: TextChunk[], context: { content: string; highlights: SimpleHighlight[]; sourceRanges?: Array<{ start: number; end: number; }>; }): TextChunk[]
  • type AudioStreamCreateOptions = { capacityMs: number; startupMs: number; resumeMs: number; volume: number; pan: number; groupId: number; maxProbeBytes: number; format: NativeAudioStreamFormat; }type AudioStreamCreateOptions = { capacityMs: number; startupMs: number; resumeMs: number; volume: number; pan: number; groupId: number; maxProbeBytes: number; format: NativeAudioStreamFormat; sampleRate?: number; channels?: number; }
  • type AudioStreamFormat = "mp3" | "flac"type AudioStreamFormat = "mp3" | "flac" | "pcm"

Removed

  • protected method DiffRenderable.onResize(width: number, height: number): void