kmdr's banner
kmdr's profile picture

kmdr

@kmdrfx6,586 subscribers

opentui/opencode @anomalyco Staff Software Chef, Father, husband

Shorts

Working on OpenCode is unique. I have seen a world that no man should see

Working on OpenCode is unique. I have seen a world that no man should see

85,861 Aufrufe

Anthrorpic wtf.

Anthrorpic wtf.

82,452 Aufrufe

Videos

kmdrfx's profile picture

OpenTUI Keymap is a host agnostic key/cmd engine for DOM like apps. It allows extreme customisation of a generic core, from key stroke syntax parsing to to command resolution and dispatch behaviour. It composes layers of bindings and commands into a single adaptive dispatch model. Demo link in the replies. There are many such systems, most of which stop at the key binding part. Apps often are expected to implement their own command layer on top of these. This disconnects the bindings from the actual command registry. Looking for a proper solution usable in OpenCode I couldn't find anything that fulfilled the need of being extremely extensible to allow plugins to fully control key mapping and command behaviour. I wanted it to always be able to know exactly which keys and commands are reachable at any point in time, no matter from where and how the mappings are manipulated. The main driver was enabling a which-key like plugin and vim like bindings in a mostly declarative way. While any other plugin could extend the keymap even further with a custom config syntax for key strokes for example. So addons for it are mostly composable and it comes with a variety of addons providing common behaviour. It can also power other discovery features directly from live state. Help views, command palettes and graph/debug UIs can all ask the engine what is active, reachable, shadowed, pending, or dispatchable instead of rebuilding that knowledge separately. The core is intentionally very much generic: hosts adapt focus, hierarchy, input events, and lifecycle, while addons extend parsing, tokens, sequence patterns, command metadata, resolvers, interceptors, and event matching. The result is a keymap that plugins can compose with rather than work around. This could all be built directly into OpenCode and just be app specific. Working on OpenTUI though I want applications to have an out-of-the-box solution to build keyboard-first apps easily. Well, at least agents can. It is extremely over-engineered. And I love it. I hope some of you will too.

kmdr

90,709 Aufrufe • vor 29 Tagen

kmdrfx's profile picture

"Please fix Markdown tables!" Okay: text-only, wrapping, columnar selection, proper border conjunctions, fill full width, in opencode beta now. "What took so long?" Here's a writeup: OpenTUI uses yoga layout and has elements called Renderables. Boxes with borders, plain text, code with tree-sitter backed highlighting and other primitives. Organised in a tree structure resembling somewhat of a DOM. Approaching a table naively, given the primitives are there, one would think to just stack box and text elements the right way in a flex-box layout to visually represent a table. Boxes support borders. Problem solved. This is what an LLM would one-shot in a working state, given OpenTUI's API surface. Ignoring the fact that just using box local borders don't handle border conjunctions properly. Benchmarking something like that quickly shows that instantiating an average table takes >70ms and incremental updates become expensive. Hugely due to yoga-layout via wasm having a painful price on yoga API calls. The whole ordeal becomes memory hungry, because a Text element handles more than just plain text. A simple 4x6 table needs a Box and Text per cell, ending up with 48 heavy nodes that yoga must lay out. "But that's just OpenTUI being slow" - you might say. Yes, but no. Yoga should be integrated in the zig native binary core of OpenTUI. It is on the roadmap to do so, which will speed up render passes by 2-5x. Yoga-layout has an open PR to support CSS Grids, which would greatly ease building something like a table. We will use that for fully laid out tables when it gets there. Below the typescript core level Renderables, there are lower level primitives like TextBuffers and TextBufferViews, bound via FFI and completely handled in Zig. I was stuck expecting a table primitive to handle a full layout like a table in the browser does. For Markdown all we need is a text-only table. So we had to come up with a better idea, something that is feasible now. A table layout is pretty straight forward. No need to have yoga deal with that. Using TextBufferViews for cells directly gives lower level control and eliminates some overhead that Boxes and Text renderables have. A simple native method to draw a grid with proper conjunctions is a nice library method. It will surely be used for other cases, so that's what we added. Using this simplified approach we were able to bring down initial instantiation to <1ms, more than 70x improvement. With a far smaller memory footprint. Given all the low level primitives are known and implementing a text-only table like this is possible, Codex was of great help to carve out the PoC, setup the benchmarks and tests. That's only a fraction of what was needed though. The table needs options to span the full available width, render different border styles, show/hide borders, padding, selection etc. So many iterations later OpenTUI now has a text-only, performant and relatively cheap TextTable that we can leverage to render Markdown tables in a streaming/incremental manner. Efficiently and properly.

kmdr

205,115 Aufrufe • vor 3 Monaten

kmdrfx's profile picture

Got flash banged by OpenCode recently? Yeah, that was me. Here's what happened: OpenCode/OpenTUI detects terminal theme mode (light or dark) by querying OSC 10/11 for the terminal’s foreground/background colors and deriving the mode from those values. OpenTUI also enables DEC Private Mode 2031 to receive theme-change notifications. When that mode is enabled, terminals can send CSI 997 when the system theme changes. OpenTUI treated the 997 payload as authoritative and let it override the OSC 10/11-derived result. That turned out to be wrong. In some terminals, the 997 payload is simply unreliable: it can report light while the queried terminal colors clearly indicate a dark theme. That’s what caused the flash bangs. The fix seemed straightforward: stop trusting the 997 payload as the actual theme mode and use it only as a trigger to re-query OSC 10/11, then derive the mode from the returned foreground/background colors. That works great. Except OpenTUI had also started using OSC 11 to set the terminal’s default background color, so the terminal gutter around the drawn TUI matched the app background instead of the terminal’s own default background. This was introduced recently in OpenTUI. That created a new problem: if you use OSC 11 to override the terminal background, then later query OSC 11, you are just reading back your own override instead of the terminal’s real theme background. No problem. Reset the terminal background with OSC 111, query OSC 10/11, derive the mode, then restore the renderer background again. Oh wait. Turns out Ghostty has a bug. Once this background reset/override path is used, later OSC 11 background reporting can get stuck and stop tracking system theme changes correctly. Even though theme-change notifications still fire and OSC 10 foreground updates continue. This would cause further issues where the OSC 10/11 derivation would be wrong again. So for now: no using OSC 11 to set the terminal background color just to fill the gutter. TL;DR: OpenTUI must treat CSI 997 only as a hint that the terminal theme may have changed and rely exclusively on OSC 10/11 color queries for actual theme mode detection, while avoiding terminal background mutation via OSC 11/111 because that breaks correctness in some terminals like Ghostty.

kmdr

29,509 Aufrufe • vor 1 Monat

Keine weiteren Inhalte verfügbar