Skip to content

chore(tui): upgrade OpenTUI to 0.6.2 - #55083

Merged
simonklee merged 1 commit into
devfrom
oc-ot-native
Oct 13, 2026
Merged

simonklee merged 1 commit into
devfrom
oc-ot-native

Conversation

@simonklee

@simonklee simonklee commented Oct 13, 2026 •

Copy link
Copy Markdown
Member

Move the TUI and its OpenTUI consumers to the 0.6.2 native renderer.

  • Draw custom renderables in renderSelf(), size them with the native layout, and release owned buffers in destroySelf().
  • Read owned scratch buffers through withBuffers(); 0.6 throws on direct buffer access, which broke ShimmerText and FadeInText.
  • Pass renderer.nativeScene as the owner of syntax styles and buffers.
  • Await terminal transitions and renderer.closed, and ignore a rejected closed during teardown, when nothing is left to restore.
  • Apply retry-provider opacity in mergeStyles(); 0.6 no longer calls gatherWithInheritedStyle() while rendering.
  • Compute prompt editor offsets with OpenTUI's measureEditText and the renderer's width method instead of JavaScript string widths or string lengths. Editors now show control characters as Vim notation and give a tab its tab width, so mention triggers, mention and paste ranges, appended prompts, and history and draft cursors landed in the wrong place after a tab, a control character, or wide text. The prompt helpers stay pure functions of the text and the width method.
  • Strip escape sequences from text pasted into the prompt, as the mini prompt and forms already did.
  • Replace opentui-spinner, which 0.6 broke, with an in-house spinner renderable advanced by OpenTUI frame updates, and remove the dependency, its patch, and cli-spinners.

Added by the opencode bot (AI-generated).

Public API: raises @opencode/plugin peer deps to @opentui/core and @opentui/solid >=0.6.2 (not backwards compatible for plugins on OpenTUI 0.5)

@opencode-agent opencode-agent Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I recommend changes before merging: with this PR the TUI crashes on startup under opencode-drive.

I ran the base and this PR with opencode-drive and the simulated model. With default config the PR's TUI never becomes ready. It shows "OpenCode crashed: ot_session_control failed: InvalidPhase", thrown from renderer.setTerminalTitle in the terminal-title effect in app.tsx.

I checked OpenTUI 0.6.2 directly:

  • The test renderer rejects setTerminalTitle every time, so the drive/simulation frontend can't start the full TUI.
  • A real CliRenderer also throws InvalidPhase while it is suspended. That could crash the TUI if the title effect runs while $EDITOR is open or during ctrl+z. Example: the session title arrives after the first message while the external editor is open. mini/runtime.lifecycle.ts's setTitle has the same exposure.

Could the title calls go through a guarded helper that skips when the renderer can't take session control? Alternatively, the simulation renderer could stub it. Either way, a test that mounts the app on the simulation renderer would catch this.

With terminal.title: false everything else worked in drive: replies render and the @ mention autocomplete matches the base (screenshots below). packages/tui typecheck and tests pass, apart from two dialog-shell-output failures that also fail on the base. packages/simulation tests and packages/cli typecheck pass.

Public API: the @opencode/plugin peer dependencies move from @opentui/core/@opentui/solid >=0.5.17 to >=0.6.2. TUI plugins that render with OpenTUI need 0.6, which is not backwards compatible with plugins built on 0.5 renderer APIs. The private @opencode/tui export ./component/register-spinner is replaced by ./component/spinner-renderable. Nothing else outside code depends on changes.

One inline note on mini shutdown.

Before

After

Move the TUI and its OpenTUI consumers to the 0.6.2 native renderer.

- Draw custom renderables in renderSelf(), size them with the native
  layout, and release owned buffers in destroySelf().
- Read owned scratch buffers through withBuffers(); 0.6 throws on
  direct buffer access, which broke ShimmerText and FadeInText.
- Pass renderer.nativeScene as the owner of syntax styles and buffers.
- Await terminal transitions and renderer.closed, and ignore a rejected
  closed during teardown, when nothing is left to restore.
- Skip terminal title updates while the renderer is suspended or
  destroyed; 0.6 rejects terminal control from suspend() until
  resume() completes, which crashed the TUI when a session title
  arrived while $EDITOR was open. The simulation renderer now sets up
  its terminal, as production does, so drive can set the title.
- Apply retry-provider opacity in mergeStyles(); 0.6 no longer calls
  gatherWithInheritedStyle() while rendering.
- Compute prompt editor offsets with OpenTUI's measureEditText and the
  renderer's width method instead of JavaScript string widths or string
  lengths. Editors now show control characters as Vim notation and give
  a tab its tab width, so mention triggers, mention and paste ranges,
  appended prompts, and history and draft cursors landed in the wrong
  place after a tab, a control character, or wide text. The prompt
  helpers stay pure functions of the text and the width method.
- Strip escape sequences from text pasted into the prompt, as the mini
  prompt and forms already did.
- Replace opentui-spinner, which 0.6 broke, with an in-house spinner
  renderable advanced by OpenTUI frame updates, and remove the
  dependency, its patch, and cli-spinners.
@simonklee
simonklee merged commit 65f8907 into dev Oct 13, 2026
9 of 10 checks passed
@simonklee
simonklee deleted the oc-ot-native branch October 13, 2026 12:59
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant