Roo-Code/docs/opentui-implementation-plan.md
Roo Code e5c2a97af5 docs: add Wave 0 OpenTUI migration deliverables (ADR, parity matrix, baseline, implementation plan)
Addresses Issue #11705 Wave 0 Discovery acceptance criteria:
- ADR: Node.js-first with opt-in Bun experimental strategy
- Feature parity matrix: 54 items cataloged across Ink components, hooks, and tools
- Performance baseline: startup, latency, render cadence, memory benchmarks
- Implementation plan: 8-week roadmap across 60 tasks in 5 waves
- Terminal compatibility matrix for cross-platform validation
2026-02-22 18:20:38 +00:00

9.7 KiB

OpenTUI Migration Implementation Plan

Issue: #11705 Date: 2026-02-22 Duration: ~8 weeks (60 tasks across 5 waves) ADR: docs/adr/cli-opentui-runtime.md

Overview

This plan covers the full migration path from Ink to OpenTUI for the Roo CLI terminal UI. Per the ADR, the strategy is Node.js-first with opt-in experimental OpenTUI support. Each wave builds on the previous one and includes a go/no-go checkpoint.

Wave 0: Discovery (Complete)

Duration: 1 week | Status: Complete

# Task Deliverable Status
1 Inventory Ink UI capabilities Parity Matrix Done
2 Build feature parity matrix Parity Matrix Done
3 Validate OpenTUI runtime constraints ADR Done
4 Write ADR for runtime strategy ADR Done
5 Define MVP scope and non-goals This document (Wave 1 scope) Done
6 Instrument current CLI UX timings Performance Baseline Done
7 Define terminal compatibility matrix Performance Baseline Done

Wave 1: Foundation (2 weeks)

Goal: Scaffolding, dual-renderer architecture, minimal rendering.

Go/No-Go Criteria: OpenTUI can render a static text screen in Node.js behind the --ui opentui flag.

# Task Description Estimate Dependencies
8 Add OpenTUI dependency Vendor or git-dep OpenTUI source into apps/cli 2h None
9 Create tsconfig.ui-next.json TypeScript config for OpenTUI/SolidJS compilation 1h #8
10 Create build script for ui-next apps/cli/scripts/build-ui-next.ts 2h #9
11 Add --ui flag to CLI Extend commander options in run.ts 1h None
12 Create renderer selection logic Switch in run.ts based on --ui flag 2h #11
13 Create ui-next/main.tsx OpenTUI app entry point 2h #8, #12
14 Create ui-next/app.tsx Root component with basic layout 4h #13
15 Implement view-model contracts Define interfaces for UI state consumed by both renderers 4h None
16 Create adapter layer Bridge between Zustand stores and OpenTUI reactive state 4h #15
17 Add error boundary with fallback Catch OpenTUI errors, fall back to plain text output 2h #14
18 Wire exit/lifecycle hooks Process exit, SIGINT handling for OpenTUI context 2h #14
19 Add smoke test for ui-next Vitest test that OpenTUI app initializes without crash 2h #14
20 Update CI to build ui-next Add build step for OpenTUI target 1h #10

Wave 2: Core Components (2 weeks)

Goal: Port essential display components for basic chat interaction.

Go/No-Go Criteria: Can display a streaming chat message and show the header/footer.

# Task Description Estimate Dependencies
21 Port Text styling helpers Color, bold, dim, italic text rendering 2h Wave 1
22 Port Box layout equivalent Flexbox container with padding/margin/border 4h Wave 1
23 Port Header component Status bar with mode, model, metrics 2h #21, #22
24 Port HorizontalLine Separator component 1h #21
25 Port Icon component Unicode icon rendering 1h #21
26 Port LoadingText / Spinner Frame-based animation without @inkjs/ui 4h #21
27 Port ProgressBar Visual progress indicator 2h #21
28 Port ChatHistoryItem Message rendering with markdown/code blocks 8h #21, #22
29 Port MetricsDisplay Token count and cost display 2h #21, #22
30 Port ToastDisplay Toast notification component 2h #21, #22
31 Port TodoDisplay Checklist rendering 2h #21, #22
32 Port TodoChangeDisplay Todo diff display 2h #21, #22
33 Port tool display components (7) CommandTool, FileReadTool, FileWriteTool, etc. 8h #21, #22
34 Create component test helpers Test utilities replacing ink-testing-library 4h Wave 1
35 Add component unit tests Tests for ported components 8h #34

Wave 3: Input and Interaction (2 weeks)

Goal: Port input handling, autocomplete, and selection components.

Go/No-Go Criteria: Can type a message, use autocomplete, and submit to the agent.

# Task Description Estimate Dependencies
36 Create input event handler Replace Ink's useInput with OpenTUI key events 8h Wave 2
37 Port MultilineTextInput Full cursor management and line editing 12h #36
38 Port ScrollArea Scrollable container (without measureElement) 12h #22, #36
39 Port ScrollIndicator Scroll position display 2h #38
40 Port AutocompleteInput Keyboard-driven autocomplete overlay 8h #36, #37
41 Port PickerSelect Filterable selection list 6h #36, #22
42 Port autocomplete triggers (5) File, Help, History, Mode, SlashCommand triggers 8h #40
43 Port OnboardingScreen First-run wizard with Select replacement 4h #41
44 Port useGlobalInput hook Global keyboard shortcut handling 4h #36
45 Port useFocusManagement Focus toggle between scroll area and input 4h #36
46 Integration test: full chat flow End-to-end test of message input, display, scroll 8h #37-#45

Wave 4: Polish and Evaluation (2 weeks)

Goal: Performance testing, cross-platform validation, go/no-go decision.

# Task Description Estimate Dependencies
47 Run performance benchmarks Collect all metrics from baseline doc 4h Wave 3
48 Compare startup time Ink vs OpenTUI cold/warm start 2h #47
49 Compare input latency Ink vs OpenTUI keypress-to-render 2h #47
50 Compare memory usage Heap profiles under load 2h #47
51 Compare render cadence FPS during streaming 2h #47
52 Test on iTerm2 macOS validation 2h Wave 3
53 Test on Terminal.app macOS fallback validation 2h Wave 3
54 Test on GNOME Terminal Linux validation 2h Wave 3
55 Test on Windows Terminal Windows validation 2h Wave 3
56 Test on tmux Multiplexer validation 2h Wave 3
57 Test on VS Code terminal IDE terminal validation 1h Wave 3
58 Document findings Update ADR with results 4h #47-#57
59 Write go/no-go recommendation Based on all collected data 2h #58
60 Present to team Summary of findings and recommendation 2h #59

MVP Scope (Wave 1)

In Scope

  • Static text rendering (header, messages, status)
  • --ui opentui flag for opt-in
  • Error boundary with plain-text fallback
  • Basic layout (vertical stacking, padding)
  • Process lifecycle management

Out of Scope (Deferred)

  • Input handling (Wave 3)
  • Autocomplete (Wave 3)
  • Scroll virtualization (Wave 3)
  • Mouse support
  • Custom themes
  • Animation beyond spinner
  • Accessibility features
  • Plugin/extension API

Non-Goals

These items are explicitly not part of this migration effort:

  1. Changing the non-TUI modes -- --print and --output-format stream-json are unaffected
  2. Modifying the agent/core -- Only apps/cli/src/ui* and run.ts are in scope
  3. Removing Ink -- Ink remains the default renderer; OpenTUI is experimental
  4. Requiring Bun -- Node.js compatibility is mandatory per the ADR
  5. Changing the build system -- tsup remains the bundler; ui-next gets its own tsconfig

Risk Register

# Risk Probability Impact Mitigation Owner
R1 OpenTUI cannot run on Node.js Medium Critical Validate in Wave 1 task #13; abort if fails CLI team
R2 ScrollArea cannot be ported without measureElement Medium High Implement custom measurement using ANSI escape sequences CLI team
R3 Input latency regression Low High Benchmark in Wave 4; revert to Ink if >2x slower CLI team
R4 Test coverage drops significantly Medium Medium Build test helpers in Wave 2 (#34); maintain parity CLI team
R5 Cross-terminal rendering inconsistencies Medium Medium Test matrix in Wave 4; document known issues CLI team
R6 OpenTUI API breaks during migration Low Medium Pin to specific commit/version; vendor if needed CLI team

Effort Summary

Wave Duration Tasks Estimated Hours
Wave 0 (Discovery) 1 week 7 20h
Wave 1 (Foundation) 2 weeks 13 29h
Wave 2 (Core Components) 2 weeks 15 53h
Wave 3 (Input/Interaction) 2 weeks 11 76h
Wave 4 (Polish/Evaluation) 2 weeks 14 32h
Total ~8 weeks 60 ~210h

Decision Points

  1. After Wave 1: Can OpenTUI render anything on Node.js? If no, abort.
  2. After Wave 2: Is component porting feasible at acceptable quality? If not, abort.
  3. After Wave 3: Does the full interaction model work? If critical gaps exist, pause.
  4. After Wave 4: Performance and compatibility results drive final go/no-go.

References