mirror of
https://github.com/RooVetGit/Roo-Code.git
synced 2026-09-26 01:11:20 +00:00
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
7.5 KiB
7.5 KiB
OpenTUI Feature Parity Matrix
Issue: #11705
Date: 2026-02-22
Scope: All Ink primitives, components, and hooks used in apps/cli/src/ui/ (69 files, ~10,619 LOC)
Summary
| Category | Ink Components Used | OpenTUI Equivalent Available | Gap |
|---|---|---|---|
| Layout | 5 | 3 (partial) | 2 |
| Text | 4 | 2 (partial) | 2 |
| Input | 4 | 1 (partial) | 3 |
| Selection | 2 | 1 (partial) | 1 |
| Lifecycle | 2 | 0 | 2 |
| Measurement | 2 | 0 | 2 |
| Testing | 1 | 0 | 1 |
| Total | 20 | 7 | 13 |
Ink Primitives (from ink)
| # | Ink API | Usage Count | Files Using | OpenTUI Equivalent | Status | Notes |
|---|---|---|---|---|---|---|
| 1 | Box |
28 | 25 | View / flexbox container |
Partial | OpenTUI uses different prop names for flexbox |
| 2 | Text |
30 | 27 | Text |
Partial | Ink Text supports color, bold, italic, dimColor; OpenTUI text styling differs |
| 3 | Newline |
2 | 1 | \n in text |
Yes | Trivial mapping |
| 4 | useInput |
7 | 7 | Key event handler | Partial | OpenTUI uses different key event model |
| 5 | useApp |
2 | 2 | App context | Gap | No direct equivalent; need custom exit handling |
| 6 | DOMElement |
2 | 1 | N/A | Gap | Ink-specific type for DOM node references |
| 7 | measureElement |
2 | 1 | N/A | Gap | No equivalent measurement API in OpenTUI |
| 8 | Key (type) |
1 | 1 | N/A | Gap | Ink-specific key type definition |
| 9 | TextProps (type) |
1 | 1 | N/A | Partial | Type can be recreated |
@inkjs/ui Components
| # | Component | Usage Count | Files Using | OpenTUI Equivalent | Status | Notes |
|---|---|---|---|---|---|---|
| 10 | Select |
2 | 2 | Custom select | Gap | Need custom implementation; used in App.tsx, OnboardingScreen.tsx |
| 11 | Spinner |
1 | 1 | Custom spinner | Gap | Used in LoadingText.tsx; need frame-based animation |
Custom Components (Ink-dependent)
| # | Component | File | Ink APIs Used | Migration Complexity | Notes |
|---|---|---|---|---|---|
| 12 | App |
App.tsx | Box, Text, useApp, useInput, Select | High | Main app shell; 450+ LOC, orchestrates all state |
| 13 | ChatHistoryItem |
ChatHistoryItem.tsx | Box, Newline, Text | Medium | Message rendering with tool results |
| 14 | Header |
Header.tsx | Text, Box | Low | Status bar display |
| 15 | HorizontalLine |
HorizontalLine.tsx | Text | Low | Decorative separator |
| 16 | Icon |
Icon.tsx | Box, Text, TextProps | Low | Unicode icon rendering |
| 17 | LoadingText |
LoadingText.tsx | Spinner (@inkjs/ui) | Medium | Animated loading indicator |
| 18 | MetricsDisplay |
MetricsDisplay.tsx | Text, Box | Low | Token/cost metrics |
| 19 | MultilineTextInput |
MultilineTextInput.tsx | Box, Text, useInput, Key | High | Complex cursor management, line editing |
| 20 | ProgressBar |
ProgressBar.tsx | Text | Low | Visual progress indicator |
| 21 | ScrollArea |
ScrollArea.tsx | Box, DOMElement, measureElement, Text, useInput | High | Virtual scrolling with measurement |
| 22 | ScrollIndicator |
ScrollIndicator.tsx | Box, Text | Low | Scroll position indicator |
| 23 | ToastDisplay |
ToastDisplay.tsx | Text, Box | Low | Toast notification rendering |
| 24 | TodoChangeDisplay |
TodoChangeDisplay.tsx | Box, Text | Low | Todo diff display |
| 25 | TodoDisplay |
TodoDisplay.tsx | Box, Text | Low | Todo list rendering |
| 26 | AutocompleteInput |
AutocompleteInput.tsx | useInput | High | Keyboard-driven autocomplete |
| 27 | PickerSelect |
PickerSelect.tsx | Box, Text, useInput | Medium | Filterable selection list |
| 28 | OnboardingScreen |
OnboardingScreen.tsx | Box, Text, Select | Medium | First-run setup wizard |
Custom Hooks (Ink-dependent)
| # | Hook | File | Ink APIs Used | Migration Complexity | Notes |
|---|---|---|---|---|---|
| 29 | useExtensionHost |
useExtensionHost.ts | useApp | Medium | Exit handling via Ink's app context |
| 30 | useFocusManagement |
useFocusManagement.ts | None (pure state) | Low | Focus toggle logic; no Ink dependency |
| 31 | useGlobalInput |
useGlobalInput.ts | useInput | Medium | Global keyboard shortcuts |
| 32 | useInputHistory |
useInputHistory.ts | None (pure state) | Low | Input history navigation |
| 33 | useFollowupCountdown |
useFollowupCountdown.ts | None (pure state) | Low | Timer-based countdown |
| 34 | useMessageHandlers |
useMessageHandlers.ts | None (pure state) | Low | Message processing logic |
| 35 | usePickerHandlers |
usePickerHandlers.ts | None (pure state) | Low | Picker interaction logic |
| 36 | useTaskSubmit |
useTaskSubmit.ts | None (pure state) | Low | Task submission logic |
| 37 | useTerminalSize |
useTerminalSize.ts | None (process.stdout) | Low | Terminal dimensions |
| 38 | useToast |
useToast.ts | None (pure state) | Low | Toast state management |
Tool Components
| # | Component | File | Ink APIs Used | Migration Complexity |
|---|---|---|---|---|
| 39 | CommandTool |
CommandTool.tsx | Box, Text | Low |
| 40 | CompletionTool |
CompletionTool.tsx | Box, Text | Low |
| 41 | FileReadTool |
FileReadTool.tsx | Box, Text | Low |
| 42 | FileWriteTool |
FileWriteTool.tsx | Box, Text | Low |
| 43 | GenericTool |
GenericTool.tsx | Box, Text | Low |
| 44 | ModeTool |
ModeTool.tsx | Box, Text | Low |
| 45 | SearchTool |
SearchTool.tsx | Box, Text | Low |
Autocomplete Triggers
| # | Component | File | Ink APIs Used | Migration Complexity |
|---|---|---|---|---|
| 46 | FileTrigger |
FileTrigger.tsx | Box, Text | Low |
| 47 | HelpTrigger |
HelpTrigger.tsx | Box, Text | Low |
| 48 | HistoryTrigger |
HistoryTrigger.tsx | Box, Text | Low |
| 49 | ModeTrigger |
ModeTrigger.tsx | Box, Text | Low |
| 50 | SlashCommandTrigger |
SlashCommandTrigger.tsx | Box, Text | Low |
State Management
| # | File | Ink Dependency | Migration Complexity | Notes |
|---|---|---|---|---|
| 51 | store.ts |
None (Zustand) | None | Pure Zustand store; framework-agnostic |
| 52 | uiStateStore.ts |
None (Zustand) | None | UI state; framework-agnostic |
Testing Infrastructure
| # | Item | Current | OpenTUI Equivalent | Gap |
|---|---|---|---|---|
| 53 | ink-testing-library |
Used in 10 test files | N/A | Full gap -- need custom test renderer |
| 54 | Component snapshot tests | Ink render output | N/A | Need new snapshot format |
Migration Complexity Summary
| Complexity | Count | Percentage |
|---|---|---|
| None (framework-agnostic) | 12 | 22% |
| Low | 24 | 44% |
| Medium | 8 | 15% |
| High | 4 | 7% |
| Full gap (needs custom impl) | 6 | 11% |
| Total tracked items | 54 | 100% |
Critical Path Items
The following items are on the critical path for any migration and should be addressed first:
- ScrollArea -- Uses
measureElementandDOMElementwhich have no OpenTUI equivalent - MultilineTextInput -- Complex cursor/key handling tightly coupled to Ink's
useInput - AutocompleteInput -- Keyboard-driven interaction depends on Ink's input model
- App (main shell) -- Orchestrates all components; highest coupling to Ink lifecycle
- Testing infrastructure --
ink-testing-libraryhas no OpenTUI counterpart - Select component --
@inkjs/uiSelect used in onboarding and main app