build(deps): bump the opentui-opencode group with 3 updates

Closed
DE
5d ago
+35-35

Bumps the opentui-opencode group with 3 updates: @opentui/core, @opentui/solid and @opencode/plugin.

Updates @opentui/core from 0.7.0 to 0.8.1

Release notes

Sourced from @​opentui/core's releases.

Release v0.8.1

OpenTUI 0.8.1 can play video. VideoRenderable, and <video> in React and Solid, plays an MP4 file with H.264 video and AAC audio. Native code does the decoding, the media clock, the audio, and the drawing. Frames draw like an ImageRenderable, with Kitty, Sixel, or Unicode blocks:

const video = new VideoRenderable(renderer, {
  source: "./clip.mp4",
  width: 60,
  height: 20,
  autoplay: true,
  loop: true,
  onError: console.error,
})
renderer.root.add(video)

To show only part of a clip, you could make a node the size of the whole board and let its parent clip it. That gets expensive quickly. Nine such tiles of one 1080p clip used 2.3 cores and sent 58 MB of Kitty data per frame, which is far over the output limit. The new crop option selects a region in source pixels, and the decoder scales and copies only that region. The same nine tiles use 0.93 cores and 5.1 MB per frame. There is a second cost: each player of a clip with audio opens its own audio device, even when it is muted. Set audio: false on every tile except the one that plays sound:

// The top-left quarter of a 1920x1080 clip, with no audio device.
const tile = new VideoRenderable(renderer, {
  source: "./clip.mp4",
  crop: { left: 0, top: 0, width: 960, height: 540 },
  audio: false,
  width: 30,
  height: 10,
})

ImageRenderable takes the same crop. To decode video, the native library now statically links a decode-only LGPL build of FFmpeg 9.0.2. This makes each stripped library 2.6 to 3.5 MB larger. On linux-x64 it grows from 5.20 MB to 8.40 MB.

Over a slow link such as ssh, the terminal reads frames more slowly than OpenTUI writes them. Once the pty and the link filled up, the JavaScript thread waited inside write(2), and keys and timers waited behind it. On a 48 KB/s link it spent 79% of its time there, and the median key wait was 123.7 ms. In 0.8.1, on Linux and macOS when stdout is a terminal, a native thread owned by the Session does the write. On the same link, the JavaScript thread spends no time in write(2), and the median key wait is 0.1 ms. The screen still lags by the size of the link's buffers. The app also uses more CPU per run, because it now does the updates that it used to skip while it waited. Set OTUI_STDOUT_THREAD=0 to write on the JavaScript thread as before.

A slow link also made exit unreliable. In 0.8.0, the close gave up after one second and cancelled the session before it wrote the restore sequence. A 40-row quit at 16 KB/s left the terminal in the alternate screen with mouse reporting on. Now the close waits as long as output keeps moving. If nothing is written for one second, or if the close has run for ten seconds, the renderer stops waiting. It lets the write in progress finish, drops the queued output, writes the restore, and rejects closed as late.

The Session writes at most 8 MiB in one frame. In 0.8.0, a larger frame failed, and the repaint after it was just as large. The screen froze, but input still worked. Three 1000x700 Kitty images were enough to cause it. Now a frame sends its cells and the images that fit, and later frames send the rest. If one image is too large for a frame on its own, OpenTUI sends a copy at the size it is shown. A 1272x2015 photo shown at 880x1400 pixels sends 6.6 MB instead of 13.7 MB. The image draws as blocks only if that copy is too large as well. If a frame's cells alone are too large, the new frame:dropped event reports it once for each content. In 0.8.0, console.error reported it on every frame:

renderer.on(CliRenderEvents.FRAME_DROPPED, ({ bytes, limit }) => {
  console.warn(`dropped a frame of ${bytes} bytes (limit ${limit})`)
})

One layout change can show in existing apps. When Yoga gives a node zero width or height, OpenTUI used to paint and hit-test it as one cell, on top of its siblings. A common case is a one-row header above a ScrollBox with flexGrow. Once the list is taller than the screen, Yoga shrinks the header to zero rows. The header and the first list row then mixed into one line. Now the header is not drawn at all. To keep it, give the header flexShrink: 0, or give the ScrollBox flexBasis: 0:

const column = new BoxRenderable(renderer, { flexDirection: "column", height: "100%" })
column.add(new TextRenderable(renderer, { content: "filter: (type)", flexShrink: 0 }))
column.add(new ScrollBoxRenderable(renderer, { flexGrow: 1, minHeight: 0 }))

... (truncated)

Commits
  • 9a09079 Release v0.8.1
  • 7303776 core: bound the whole close and restore at the limit (#1893)
  • 4b10d91 core: make the TypeScript tests faster and fix two test-order flakes (#1895)
  • 85b015d native: draw frames that are larger than the output limit (#1890)
  • 269db3e build: migrate to Zig 0.17 (#1586)
  • 9b7d5fb native: show a source region on video and image nodes (#1888)
  • 6a1264e native: pad video RGBA rows for swscale's SIMD stores (#1889)
  • 1823930 native: add an audio option to play video without a device (#1884)
  • 3091d20 native: enable the stdout writer on macOS (#1881)
  • 75e0d0a core: accept program status until the terminal closes (#1871)
  • Additional commits viewable in compare view

Updates @opentui/solid from 0.7.0 to 0.8.1

Release notes

Sourced from @​opentui/solid's releases.

Release v0.8.1

OpenTUI 0.8.1 can play video. VideoRenderable, and <video> in React and Solid, plays an MP4 file with H.264 video and AAC audio. Native code does the decoding, the media clock, the audio, and the drawing. Frames draw like an ImageRenderable, with Kitty, Sixel, or Unicode blocks:

const video = new VideoRenderable(renderer, {
  source: "./clip.mp4",
  width: 60,
  height: 20,
  autoplay: true,
  loop: true,
  onError: console.error,
})
renderer.root.add(video)

To show only part of a clip, you could make a node the size of the whole board and let its parent clip it. That gets expensive quickly. Nine such tiles of one 1080p clip used 2.3 cores and sent 58 MB of Kitty data per frame, which is far over the output limit. The new crop option selects a region in source pixels, and the decoder scales and copies only that region. The same nine tiles use 0.93 cores and 5.1 MB per frame. There is a second cost: each player of a clip with audio opens its own audio device, even when it is muted. Set audio: false on every tile except the one that plays sound:

// The top-left quarter of a 1920x1080 clip, with no audio device.
const tile = new VideoRenderable(renderer, {
  source: "./clip.mp4",
  crop: { left: 0, top: 0, width: 960, height: 540 },
  audio: false,
  width: 30,
  height: 10,
})

ImageRenderable takes the same crop. To decode video, the native library now statically links a decode-only LGPL build of FFmpeg 9.0.2. This makes each stripped library 2.6 to 3.5 MB larger. On linux-x64 it grows from 5.20 MB to 8.40 MB.

Over a slow link such as ssh, the terminal reads frames more slowly than OpenTUI writes them. Once the pty and the link filled up, the JavaScript thread waited inside write(2), and keys and timers waited behind it. On a 48 KB/s link it spent 79% of its time there, and the median key wait was 123.7 ms. In 0.8.1, on Linux and macOS when stdout is a terminal, a native thread owned by the Session does the write. On the same link, the JavaScript thread spends no time in write(2), and the median key wait is 0.1 ms. The screen still lags by the size of the link's buffers. The app also uses more CPU per run, because it now does the updates that it used to skip while it waited. Set OTUI_STDOUT_THREAD=0 to write on the JavaScript thread as before.

A slow link also made exit unreliable. In 0.8.0, the close gave up after one second and cancelled the session before it wrote the restore sequence. A 40-row quit at 16 KB/s left the terminal in the alternate screen with mouse reporting on. Now the close waits as long as output keeps moving. If nothing is written for one second, or if the close has run for ten seconds, the renderer stops waiting. It lets the write in progress finish, drops the queued output, writes the restore, and rejects closed as late.

The Session writes at most 8 MiB in one frame. In 0.8.0, a larger frame failed, and the repaint after it was just as large. The screen froze, but input still worked. Three 1000x700 Kitty images were enough to cause it. Now a frame sends its cells and the images that fit, and later frames send the rest. If one image is too large for a frame on its own, OpenTUI sends a copy at the size it is shown. A 1272x2015 photo shown at 880x1400 pixels sends 6.6 MB instead of 13.7 MB. The image draws as blocks only if that copy is too large as well. If a frame's cells alone are too large, the new frame:dropped event reports it once for each content. In 0.8.0, console.error reported it on every frame:

renderer.on(CliRenderEvents.FRAME_DROPPED, ({ bytes, limit }) => {
  console.warn(`dropped a frame of ${bytes} bytes (limit ${limit})`)
})

One layout change can show in existing apps. When Yoga gives a node zero width or height, OpenTUI used to paint and hit-test it as one cell, on top of its siblings. A common case is a one-row header above a ScrollBox with flexGrow. Once the list is taller than the screen, Yoga shrinks the header to zero rows. The header and the first list row then mixed into one line. Now the header is not drawn at all. To keep it, give the header flexShrink: 0, or give the ScrollBox flexBasis: 0:

const column = new BoxRenderable(renderer, { flexDirection: "column", height: "100%" })
column.add(new TextRenderable(renderer, { content: "filter: (type)", flexShrink: 0 }))
column.add(new ScrollBoxRenderable(renderer, { flexGrow: 1, minHeight: 0 }))

... (truncated)

Commits
  • 9a09079 Release v0.8.1
  • 4b10d91 core: make the TypeScript tests faster and fix two test-order flakes (#1895)
  • 9b7d5fb native: show a source region on video and image nodes (#1888)
  • 1823930 native: add an audio option to play video without a device (#1884)
  • b8032e2 native: add a video player node (#1800)
  • 60b7ce7 core: fix ScrollBox Markdown collapse and selection listener leak (#1863)
  • 738067f Release v0.8.0
  • 2dbd917 core: make ScrollBox a facade over the native scroll control (#1805)
  • 6c56a69 core: share one animation clock between components (#1803)
  • 577d67e solid: update Solid to resolve security warnings and allow compatible solid u...
  • See full diff in compare view

Updates @opencode/plugin from 2.2.0 to 2.2.5

Release notes

Sourced from @​opencode/plugin's releases.

v2.2.5

Highlights

  • Worktree and Shell Mode Shortcuts: Press ⌘⌥O on macOS or Ctrl+Alt+O on Windows and Linux to choose a worktree, and ⌘⌥B or Ctrl+Alt+B to choose its base branch. ⌘⇧X or Ctrl+Shift+X now toggles shell mode in the composer. (#60713)
  • Send Quotes From the Comment Popup: Hold ⌘ or Ctrl in the quote popup to turn its checkmark into send, or press ⌘Enter or Ctrl+Enter, to send just that quote and comment while leaving the rest of the composer untouched. (#60640)
  • Percentage Compaction Buffer: Set "compaction": { "buffer": "20%" } in opencode.json to keep a share of each model's context window free, so one setting fits models with small and large windows. Token counts still work. (#60647)

Core

Improvements

  • compaction.buffer accepts a percentage of the model's context window, such as "20%", in addition to a token count. (#60647)
  • When read misses because a folder is missing, the error names that folder and the nearest one that exists. (#60688)
  • When edit can't find oldString, the error shows the file's closest lines, or says the change is already there. (#60689)
  • Calls to a tool named bash now run as shell instead of failing, with the same permissions. A plugin tool actually named bash still takes precedence. (#60687)

Bug fixes

  • MCP servers that send stdio messages larger than 10 MiB no longer get disconnected, and large messages are read much faster. (#60694)
  • Idle locations no longer restart their MCP servers right after shutting down. (#60668)
  • Compaction now caps its prompt at the model's context window when the input limit is larger. (#60660)
  • LiteLLM context window errors now trigger compaction instead of stopping the session. (#60692)
  • Reasoning is no longer turned into plain text when you switch models or resume an interrupted response, which caused request errors on some providers. (#60498)

TUI

Bug fixes

  • The connect menu no longer lists MCP servers, which are managed in their own place. (#60675)

Desktop

Improvements

  • Added keyboard shortcuts to choose a worktree and its base branch, shown in tooltips, and a shortcut to toggle shell mode. The worktree path can be selected to copy the full directory. (#60713)
  • Hold ⌘ or Ctrl in the quote popup to send a quote and its comment directly. (#60640)
  • Added flat input surfaces and a compact input size. (#60598)

Bug fixes

  • The connect menu no longer lists MCP servers. (#60675)
  • Added the missing top inset to the search field in the recently closed menu. (#60652)

v2.2.4

Highlights

  • Persistent Desktop Terminals: Desktop terminals now belong to the session, survive server restarts with their scrollback, and stay synchronized with the TUI and other windows. Renamed terminals also keep their names across restarts. (#60346)
  • Publish Interactive Artifacts: Enable "experimental": { "artifacts": true } in opencode.json to let agents publish, update, and serve HTML or static artifacts through the built-in local provider or plugin-provided storage. (#60351)
  • Guided Claude Agent Setup: Select Claude Agent from the provider picker to copy claude auth login, install Claude Code, and verify the connection before continuing to model selection. (#60603)
  • Choose a Base Branch Quickly: While creating a worktree, open Choose base branch with ⌘⌥. on macOS or Ctrl+Alt+. on Windows and Linux. The command is also available in the command palette and Settings › Shortcuts. (#60579)

... (truncated)

Changelog

Sourced from @​opencode/plugin's changelog.

v2.2.5 — 2026-10-30

Highlights

  • Worktree and Shell Mode Shortcuts: Press ⌘⌥O on macOS or Ctrl+Alt+O on Windows and Linux to choose a worktree, and ⌘⌥B or Ctrl+Alt+B to choose its base branch. ⌘⇧X or Ctrl+Shift+X now toggles shell mode in the composer. (#60713)
  • Send Quotes From the Comment Popup: Hold ⌘ or Ctrl in the quote popup to turn its checkmark into send, or press ⌘Enter or Ctrl+Enter, to send just that quote and comment while leaving the rest of the composer untouched. (#60640)
  • Percentage Compaction Buffer: Set "compaction": { "buffer": "20%" } in opencode.json to keep a share of each model's context window free, so one setting fits models with small and large windows. Token counts still work. (#60647)

Core

Improvements

  • compaction.buffer accepts a percentage of the model's context window, such as "20%", in addition to a token count. (#60647)
  • When read misses because a folder is missing, the error names that folder and the nearest one that exists. (#60688)
  • When edit can't find oldString, the error shows the file's closest lines, or says the change is already there. (#60689)
  • Calls to a tool named bash now run as shell instead of failing, with the same permissions. A plugin tool actually named bash still takes precedence. (#60687)

Bug fixes

  • MCP servers that send stdio messages larger than 10 MiB no longer get disconnected, and large messages are read much faster. (#60694)
  • Idle locations no longer restart their MCP servers right after shutting down. (#60668)
  • Compaction now caps its prompt at the model's context window when the input limit is larger. (#60660)
  • LiteLLM context window errors now trigger compaction instead of stopping the session. (#60692)
  • Reasoning is no longer turned into plain text when you switch models or resume an interrupted response, which caused request errors on some providers. (#60498)

TUI

Bug fixes

  • The connect menu no longer lists MCP servers, which are managed in their own place. (#60675)

Desktop

Improvements

  • Added keyboard shortcuts to choose a worktree and its base branch, shown in tooltips, and a shortcut to toggle shell mode. The worktree path can be selected to copy the full directory. (#60713)
  • Hold ⌘ or Ctrl in the quote popup to send a quote and its comment directly. (#60640)
  • Added flat input surfaces and a compact input size. (#60598)

Bug fixes

  • The connect menu no longer lists MCP servers. (#60675)
  • Added the missing top inset to the search field in the recently closed menu. (#60652)

v2.2.4 — 2026-10-30

Highlights

  • Persistent Desktop Terminals: Desktop terminals now belong to the session, survive server restarts with their scrollback, and stay synchronized with the TUI and other windows. Renamed terminals also keep their names across restarts. (#60346)
  • Publish Interactive Artifacts: Enable "experimental": { "artifacts": true } in opencode.json to let agents publish, update, and serve HTML or static artifacts through the built-in local provider or plugin-provided storage. (#60351)

... (truncated)

Commits

Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting @dependabot rebase.


Dependabot commands and options

You can trigger Dependabot actions by commenting on this PR:

  • @dependabot rebase will rebase this PR
  • @dependabot recreate will recreate this PR, overwriting any edits that have been made to it
  • @dependabot show <dependency name> ignore conditions will show all of the ignore conditions of the specified dependency
  • @dependabot ignore <dependency name> major version will close this group update PR and stop Dependabot creating any more for the specific dependency's major version (unless you unignore this specific dependency's major version or upgrade to it yourself)
  • @dependabot ignore <dependency name> minor version will close this group update PR and stop Dependabot creating any more for the specific dependency's minor version (unless you unignore this specific dependency's minor version or upgrade to it yourself)
  • @dependabot ignore <dependency name> will close this group update PR and stop Dependabot creating any more for the specific dependency (unless you unignore this specific dependency or upgrade to it yourself)
  • @dependabot unignore <dependency name> will remove all of the ignore conditions of the specified dependency
  • @dependabot unignore <dependency name> <ignore condition> will remove the ignore condition of the specified dependency and ignore conditions

Summary by cubic

Bumps @opentui/core and @opentui/solid from 0.7.0 to 0.8.1 and @opencode/plugin from 2.2.0 to 2.2.5 in packages/opencode.

Migration

  • OpenTUI 0.8.1 no longer paints or hit-tests nodes with zero width or height; give collapsing headers flexShrink: 0 to keep them visible.