Ankit c cloud tui poc a2bc - #905
Open
ankit-thesys wants to merge 12 commits into
Open
Conversation
examples/openui-tui-chat: a terminal chat client that streams OpenUI Lang from an OpenAI-compatible model and renders it as an interactive Ink TUI. Reuses @openuidev/lang-core (streaming parser + runtime) and @openuidev/react-headless (chat store + streaming adapter); adds an Ink component library, tree walker, and keyboard focus/action handling. Includes vitest + ink-testing-library tests for rendering and interactivity. Co-authored-by: Ankit Das <www.das5471@gmail.com>
ChatProvider from react-headless resolved the workspace's react@19 while Ink's reconciler uses react@18, causing a dual-React 'invalid hook call' crash. Drop ChatProvider/useThread and add a small local chat store (src/chat.ts) that runs on Ink's own React while still reusing react-headless's DOM-free streaming pipeline (processStreamedMessage + openAIReadableStreamAdapter). Co-authored-by: Ankit Das <www.das5471@gmail.com>
- Preserve full conversation history via Ink <Static> (completed turns are emitted once to scrollback), fixing the tall-output/composer-scroll issue and keeping the composer anchored at the bottom. - Split interactive components into interactive vs display-only variants (via a context flag) so finalized turns don't pollute keyboard focus. - Add chat framing: header bar, user bubbles, assistant labels, welcome/empty state, an animated streaming spinner, and a bordered composer with hints. - Add a test covering display-only (finalized) rendering. Co-authored-by: Ankit Das <www.das5471@gmail.com>
The dropdown required arrow-then-Enter and gave no immediate visual feedback (the (•) only appeared after focus moved away), so selection felt broken. Now arrow keys select immediately (radio-group style) and a local state bump guarantees an instant repaint even when the cursor index is unchanged. Also initialize the cursor to the current selection and add a form usage hint. Co-authored-by: Ankit Das <www.das5471@gmail.com>
Options are numbered (1., 2., …) and pressing the matching digit selects that option directly — no arrow navigation or Enter required. Arrow keys and Enter still work. Updates the focused-select and form hints accordingly. Co-authored-by: Ankit Das <www.das5471@gmail.com>
Adds a click-only SGR mouse layer (src/genui/mouse.tsx): enables ?1000/?1006 once at the root, parses left-button presses, and hit-tests them against the bottom-anchored live region via Yoga layout offsets (offset recomputed per click so it adapts as content changes). Clicking selects a dropdown option, activates a button/follow-up, or focuses a text field. Text inputs and the composer now filter escape/mouse sequences out of stdin so mouse bytes don't leak into fields. Keyboard remains the primary, fully-portable interaction. Co-authored-by: Ankit Das <www.das5471@gmail.com>
Mouse clicks were only landing when the conversation had filled the screen; a short/fresh form rendered near the top, but hit-testing assumed the live region was bottom-anchored, so clicks missed. Give the live region the full terminal height with justifyContent=flex-end so it always fills the screen (top at row 0). The click offset then computes to 0 and zone positions equal screen coordinates, so clicks land correctly regardless of content length. Co-authored-by: Ankit Das <www.das5471@gmail.com>
…tic> The full-height live region plus <Static> made Ink repaint and scroll the whole screen on every keystroke (flicker + jumping). Render the current exchange in a single fixed full-height frame instead: Ink updates it in place without scrolling, so typing is stable, and because the frame fills the screen from the top, mouse clicks still map 1:1 to screen rows. Trade-off: only the current exchange is shown on screen (no scrollback history of prior turns). Co-authored-by: Ankit Das <www.das5471@gmail.com>
Co-authored-by: Ankit Das <www.das5471@gmail.com>
Bring back the multi-turn history that was dropped when fixing the flicker. Render finished turns via Ink <Static> (terminal scrollback) with a small natural-height live region — the combination that was smooth in earlier versions. Trade-off: mouse hit-testing becomes best-effort (reliable once the conversation fills the screen); keyboard works everywhere. Documented the history-vs-mouse trade-off in the README. Co-authored-by: Ankit Das <www.das5471@gmail.com>
- Full-screen: render on the terminal alternate screen (cli.tsx) with a single full-height frame showing the current exchange (no scrollback history). This gives reliable pixel-perfect mouse (offset 0) and minimal flicker. - Richer visuals via the Ink ecosystem: a self-contained truecolor GradientText (gradient.tsx) on the header, headings, chart bars and the assistant label; ink-spinner for the streaming indicator; ink-big-text for the welcome splash. - New OpenUI components: Callout (colored banner) and TagBlock (colored pills), wired into the library so the model can emit them. Tests strip ANSI and cover the new components. Co-authored-by: Ankit Das <www.das5471@gmail.com>
…me + DSR) A form taller than the terminal broke the fixed-height/alt-screen layout (overflow corrupted the frame; Ink can't reliably clip). Render the exchange at natural height instead, so long content scrolls in the terminal's native scrollback and the layout stays intact. Removed the alternate screen (native scrollback is needed for long forms) and the DSR cursor-position probe (its responses leaked into the composer as garbage). Mouse hit-testing bottom-anchors to the live region, which is correct for screen-filling content incl. long forms. Co-authored-by: Ankit Das <www.das5471@gmail.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
Describe the change and why it is needed.
Changes
Test Plan
Describe how you validated this change.
Checklist