ratatui_ruby 0.6.0 → 0.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (171) hide show
  1. checksums.yaml +4 -4
  2. data/.builds/ruby-3.2.yml +1 -1
  3. data/.builds/ruby-3.3.yml +1 -1
  4. data/.builds/ruby-3.4.yml +1 -1
  5. data/.builds/ruby-4.0.0.yml +1 -1
  6. data/AGENTS.md +4 -4
  7. data/CHANGELOG.md +35 -0
  8. data/README.md +26 -1
  9. data/doc/application_architecture.md +16 -16
  10. data/doc/application_testing.md +1 -1
  11. data/doc/contributors/architectural_overhaul/chat_conversations.md +4952 -0
  12. data/doc/contributors/architectural_overhaul/implementation_plan.md +60 -0
  13. data/doc/contributors/architectural_overhaul/task.md +37 -0
  14. data/doc/contributors/design/ruby_frontend.md +277 -81
  15. data/doc/contributors/design/rust_backend.md +349 -55
  16. data/doc/contributors/developing_examples.md +5 -5
  17. data/doc/contributors/index.md +7 -5
  18. data/doc/contributors/v1.0.0_blockers.md +1729 -0
  19. data/doc/index.md +11 -6
  20. data/doc/interactive_design.md +2 -2
  21. data/doc/quickstart.md +66 -97
  22. data/doc/v0.7.0_migration.md +236 -0
  23. data/doc/why.md +93 -0
  24. data/examples/app_all_events/README.md +6 -4
  25. data/examples/app_all_events/app.rb +1 -1
  26. data/examples/app_all_events/model/app_model.rb +1 -1
  27. data/examples/app_all_events/model/msg.rb +1 -1
  28. data/examples/app_all_events/update.rb +1 -1
  29. data/examples/app_all_events/view/app_view.rb +1 -1
  30. data/examples/app_all_events/view/controls_view.rb +1 -1
  31. data/examples/app_all_events/view/counts_view.rb +1 -1
  32. data/examples/app_all_events/view/live_view.rb +1 -1
  33. data/examples/app_all_events/view/log_view.rb +1 -1
  34. data/examples/app_color_picker/README.md +7 -5
  35. data/examples/app_color_picker/app.rb +1 -1
  36. data/examples/app_login_form/README.md +2 -0
  37. data/examples/app_stateful_interaction/README.md +2 -0
  38. data/examples/app_stateful_interaction/app.rb +1 -1
  39. data/examples/verify_quickstart_dsl/README.md +4 -3
  40. data/examples/verify_quickstart_dsl/app.rb +1 -1
  41. data/examples/verify_quickstart_layout/README.md +1 -1
  42. data/examples/verify_quickstart_lifecycle/README.md +3 -3
  43. data/examples/verify_quickstart_lifecycle/app.rb +2 -2
  44. data/examples/verify_readme_usage/README.md +1 -1
  45. data/examples/widget_barchart_demo/README.md +2 -1
  46. data/examples/widget_block_demo/README.md +2 -0
  47. data/examples/widget_box_demo/README.md +3 -3
  48. data/examples/widget_calendar_demo/README.md +3 -3
  49. data/examples/widget_calendar_demo/app.rb +5 -1
  50. data/examples/widget_canvas_demo/README.md +3 -3
  51. data/examples/widget_cell_demo/README.md +3 -3
  52. data/examples/widget_center_demo/README.md +3 -3
  53. data/examples/widget_chart_demo/README.md +3 -3
  54. data/examples/widget_gauge_demo/README.md +3 -3
  55. data/examples/widget_layout_split/README.md +3 -3
  56. data/examples/widget_line_gauge_demo/README.md +3 -3
  57. data/examples/widget_list_demo/README.md +3 -3
  58. data/examples/widget_map_demo/README.md +3 -3
  59. data/examples/widget_map_demo/app.rb +2 -2
  60. data/examples/widget_overlay_demo/README.md +36 -0
  61. data/examples/widget_popup_demo/README.md +3 -3
  62. data/examples/widget_ratatui_logo_demo/README.md +3 -3
  63. data/examples/widget_ratatui_logo_demo/app.rb +1 -1
  64. data/examples/widget_ratatui_mascot_demo/README.md +3 -3
  65. data/examples/widget_rect/README.md +3 -3
  66. data/examples/widget_render/README.md +3 -3
  67. data/examples/widget_render/app.rb +3 -3
  68. data/examples/widget_rich_text/README.md +3 -3
  69. data/examples/widget_scroll_text/README.md +3 -3
  70. data/examples/widget_scrollbar_demo/README.md +3 -3
  71. data/examples/widget_sparkline_demo/README.md +3 -3
  72. data/examples/widget_style_colors/README.md +3 -3
  73. data/examples/widget_table_demo/README.md +3 -3
  74. data/examples/widget_table_demo/app.rb +19 -4
  75. data/examples/widget_tabs_demo/README.md +3 -3
  76. data/examples/widget_text_width/README.md +3 -3
  77. data/examples/widget_text_width/app.rb +8 -1
  78. data/ext/ratatui_ruby/Cargo.lock +1 -1
  79. data/ext/ratatui_ruby/Cargo.toml +1 -1
  80. data/ext/ratatui_ruby/src/frame.rs +6 -5
  81. data/ext/ratatui_ruby/src/lib.rs +3 -2
  82. data/ext/ratatui_ruby/src/rendering.rs +22 -21
  83. data/ext/ratatui_ruby/src/text.rs +12 -3
  84. data/ext/ratatui_ruby/src/widgets/canvas.rs +5 -5
  85. data/ext/ratatui_ruby/src/widgets/table.rs +81 -36
  86. data/lib/ratatui_ruby/buffer/cell.rb +168 -0
  87. data/lib/ratatui_ruby/buffer.rb +15 -0
  88. data/lib/ratatui_ruby/frame.rb +8 -8
  89. data/lib/ratatui_ruby/layout/constraint.rb +95 -0
  90. data/lib/ratatui_ruby/layout/layout.rb +106 -0
  91. data/lib/ratatui_ruby/layout/rect.rb +118 -0
  92. data/lib/ratatui_ruby/layout.rb +19 -0
  93. data/lib/ratatui_ruby/list_state.rb +2 -2
  94. data/lib/ratatui_ruby/schema/layout.rb +1 -1
  95. data/lib/ratatui_ruby/schema/row.rb +66 -0
  96. data/lib/ratatui_ruby/schema/table.rb +10 -10
  97. data/lib/ratatui_ruby/schema/text.rb +27 -2
  98. data/lib/ratatui_ruby/style/style.rb +81 -0
  99. data/lib/ratatui_ruby/style.rb +15 -0
  100. data/lib/ratatui_ruby/table_state.rb +1 -1
  101. data/lib/ratatui_ruby/test_helper/snapshot.rb +24 -0
  102. data/lib/ratatui_ruby/test_helper/style_assertions.rb +1 -1
  103. data/lib/ratatui_ruby/tui/buffer_factories.rb +20 -0
  104. data/lib/ratatui_ruby/tui/canvas_factories.rb +44 -0
  105. data/lib/ratatui_ruby/tui/core.rb +38 -0
  106. data/lib/ratatui_ruby/tui/layout_factories.rb +74 -0
  107. data/lib/ratatui_ruby/tui/state_factories.rb +33 -0
  108. data/lib/ratatui_ruby/tui/style_factories.rb +20 -0
  109. data/lib/ratatui_ruby/tui/text_factories.rb +44 -0
  110. data/lib/ratatui_ruby/tui/widget_factories.rb +195 -0
  111. data/lib/ratatui_ruby/tui.rb +75 -0
  112. data/lib/ratatui_ruby/version.rb +1 -1
  113. data/lib/ratatui_ruby/widgets/bar_chart/bar.rb +47 -0
  114. data/lib/ratatui_ruby/widgets/bar_chart/bar_group.rb +25 -0
  115. data/lib/ratatui_ruby/widgets/bar_chart.rb +239 -0
  116. data/lib/ratatui_ruby/widgets/block.rb +192 -0
  117. data/lib/ratatui_ruby/widgets/calendar.rb +84 -0
  118. data/lib/ratatui_ruby/widgets/canvas.rb +231 -0
  119. data/lib/ratatui_ruby/widgets/cell.rb +47 -0
  120. data/lib/ratatui_ruby/widgets/center.rb +59 -0
  121. data/lib/ratatui_ruby/widgets/chart.rb +185 -0
  122. data/lib/ratatui_ruby/widgets/clear.rb +54 -0
  123. data/lib/ratatui_ruby/widgets/cursor.rb +42 -0
  124. data/lib/ratatui_ruby/widgets/gauge.rb +72 -0
  125. data/lib/ratatui_ruby/widgets/line_gauge.rb +80 -0
  126. data/lib/ratatui_ruby/widgets/list.rb +127 -0
  127. data/lib/ratatui_ruby/widgets/list_item.rb +43 -0
  128. data/lib/ratatui_ruby/widgets/overlay.rb +43 -0
  129. data/lib/ratatui_ruby/widgets/paragraph.rb +99 -0
  130. data/lib/ratatui_ruby/widgets/ratatui_logo.rb +31 -0
  131. data/lib/ratatui_ruby/widgets/ratatui_mascot.rb +36 -0
  132. data/lib/ratatui_ruby/widgets/row.rb +68 -0
  133. data/lib/ratatui_ruby/widgets/scrollbar.rb +143 -0
  134. data/lib/ratatui_ruby/widgets/shape/label.rb +68 -0
  135. data/lib/ratatui_ruby/widgets/sparkline.rb +134 -0
  136. data/lib/ratatui_ruby/widgets/table.rb +141 -0
  137. data/lib/ratatui_ruby/widgets/tabs.rb +85 -0
  138. data/lib/ratatui_ruby/widgets.rb +40 -0
  139. data/lib/ratatui_ruby.rb +23 -39
  140. data/sig/examples/app_all_events/view.rbs +1 -1
  141. data/sig/examples/app_all_events/view_state.rbs +1 -1
  142. data/sig/ratatui_ruby/schema/row.rbs +22 -0
  143. data/sig/ratatui_ruby/schema/table.rbs +1 -1
  144. data/sig/ratatui_ruby/schema/text.rbs +1 -0
  145. data/sig/ratatui_ruby/session.rbs +29 -49
  146. data/sig/ratatui_ruby/tui/buffer_factories.rbs +10 -0
  147. data/sig/ratatui_ruby/tui/canvas_factories.rbs +14 -0
  148. data/sig/ratatui_ruby/tui/core.rbs +14 -0
  149. data/sig/ratatui_ruby/tui/layout_factories.rbs +19 -0
  150. data/sig/ratatui_ruby/tui/state_factories.rbs +12 -0
  151. data/sig/ratatui_ruby/tui/style_factories.rbs +10 -0
  152. data/sig/ratatui_ruby/tui/text_factories.rbs +14 -0
  153. data/sig/ratatui_ruby/tui/widget_factories.rbs +39 -0
  154. data/sig/ratatui_ruby/tui.rbs +19 -0
  155. data/tasks/autodoc.rake +1 -35
  156. data/tasks/sourcehut.rake +4 -1
  157. metadata +62 -15
  158. data/doc/contributors/dwim_dx.md +0 -366
  159. data/doc/contributors/examples_audit/p1_high.md +0 -21
  160. data/doc/contributors/examples_audit/p2_moderate.md +0 -81
  161. data/doc/contributors/examples_audit.md +0 -41
  162. data/doc/images/app_analytics.png +0 -0
  163. data/doc/images/app_custom_widget.png +0 -0
  164. data/doc/images/app_mouse_events.png +0 -0
  165. data/doc/images/widget_table_flex.png +0 -0
  166. data/lib/ratatui_ruby/session/autodoc.rb +0 -482
  167. data/lib/ratatui_ruby/session.rb +0 -178
  168. data/tasks/autodoc/inventory.rb +0 -63
  169. data/tasks/autodoc/notice.rb +0 -26
  170. data/tasks/autodoc/rbs.rb +0 -38
  171. data/tasks/autodoc/rdoc.rb +0 -45
data/doc/index.md CHANGED
@@ -7,13 +7,18 @@
7
7
 
8
8
  ## Documentation for Users
9
9
 
10
- - [README](../README.md)
11
- - [Quickstart](./quickstart.md)
12
- - [Application Architecture](./application_architecture.md)
13
- - [Testing Your Application](./application_testing.md)
10
+ - [README](../README.md): Project overview and installation
11
+ - [Why RatatuiRuby?](./why.md): Philosophy, comparisons, and what makes us different
12
+ - [Quickstart](./quickstart.md): Build your first TUI app
13
+ - [Application Architecture](./application_architecture.md): Lifecycle patterns and API choices
14
+ - [Event Handling](./event_handling.md): Keyboard, mouse, and terminal events
15
+ - [Interactive Design](./interactive_design.md): Cached layout pattern for hit testing
16
+ - [Terminal Limitations](./terminal_limitations.md): Platform quirks and workarounds
17
+ - [Testing Your Application](./application_testing.md): Snapshot testing and style assertions
18
+ - [Migrating to v0.7.0](./v0.7.0_migration.md): Namespace changes and upgrade guide
14
19
 
15
20
 
16
21
  ## Documentation for Contributors
17
22
 
18
- - [Contributing Guidelines](https://man.sr.ht/~kerrick/ratatui_ruby/contributing.md)
19
- - [More Documentation for Contributors](./contributors/index.md)
23
+ - [Contributing Guidelines](https://man.sr.ht/~kerrick/ratatui_ruby/contributing.md): How to contribute patches and features
24
+ - [More Documentation for Contributors](./contributors/index.md): Internal design docs and style guides
@@ -103,10 +103,10 @@ end
103
103
 
104
104
  ## Layout.split
105
105
 
106
- `Layout.split` computes layout geometry without rendering. It returns an array of `Rect` objects. While you can call `RatatuiRuby::Layout.split` directly, we recommend using the `Session` helper (`tui.layout_split`) for cleaner application code.
106
+ `Layout.split` computes layout geometry without rendering. It returns an array of `Rect` objects. While you can call `RatatuiRuby::Layout.split` directly, we recommend using the `TUI` helper (`tui.layout_split`) for cleaner application code.
107
107
 
108
108
  ```ruby
109
- # Preferred (Session API)
109
+ # Preferred (TUI API)
110
110
  left, right = tui.layout_split(area, constraints: [...])
111
111
 
112
112
  # Manual (Core API)
data/doc/quickstart.md CHANGED
@@ -8,25 +8,7 @@ Welcome to **ratatui_ruby**! This guide will help you get up and running with yo
8
8
 
9
9
  ## Installation
10
10
 
11
- Add this line to your application's Gemfile:
12
-
13
- ```ruby
14
- gem "ratatui_ruby"
15
- ```
16
-
17
-
18
- And then execute:
19
-
20
- ```bash
21
- bundle install
22
- ```
23
-
24
-
25
- Or install it yourself as:
26
-
27
- ```bash
28
- gem install ratatui_ruby
29
- ```
11
+ See [Installation in the README](../README.md#installation) for setup instructions.
30
12
 
31
13
 
32
14
  ## Tutorials
@@ -45,10 +27,10 @@ begin
45
27
  loop do
46
28
  # 2. Create your UI (Immediate Mode)
47
29
  # We define a Paragraph widget inside a Block with a title and borders.
48
- view = RatatuiRuby::Paragraph.new(
30
+ view = RatatuiRuby::Widgets::Paragraph.new(
49
31
  text: "Hello, Ratatui! Press 'q' to quit.",
50
32
  alignment: :center,
51
- block: RatatuiRuby::Block.new(
33
+ block: RatatuiRuby::Widgets::Block.new(
52
34
  title: "My Ruby TUI App",
53
35
  title_alignment: :center,
54
36
  borders: [:all],
@@ -77,7 +59,7 @@ end
77
59
  ```
78
60
  <!-- SYNC:END -->
79
61
 
80
- ![quickstart_lifecycle](./images/verify_quickstart_lifecycle.png)
62
+ [![quickstart_lifecycle](./images/verify_quickstart_lifecycle.png)](../examples/verify_quickstart_lifecycle/README.md)
81
63
 
82
64
  #### How it works
83
65
 
@@ -87,12 +69,13 @@ end
87
69
  4. **`RatatuiRuby.poll_event`**: Returns a typed `Event` object with predicates like `key?`, `mouse?`, `resize?`, etc. Returns `RatatuiRuby::Event::None` if no events are pending. Use predicates to check event type without pattern matching.
88
70
  5. **`RatatuiRuby.restore_terminal`**: Essential for leaving raw mode and returning to the shell. Always wrap your loop in `begin...ensure` to guarantee this runs.
89
71
 
90
- ### Idiomatic Session
72
+ ### Simplified API
91
73
 
92
- You can simplify your code by using `RatatuiRuby.run`. This method handles the terminal lifecycle for you, yielding a `Session` object with factory methods for widgets.
74
+ You can simplify your code by using `RatatuiRuby.run`. This method handles the terminal lifecycle for you, yielding a `TUI` object with factory methods for widgets.
93
75
 
94
76
  <!-- SYNC:START:../examples/verify_quickstart_dsl/app.rb:main -->
95
77
  ```ruby
78
+ # 1. Initialize the terminal, start the run loop, and ensure the terminal is restored.
96
79
  RatatuiRuby.run do |tui|
97
80
  loop do
98
81
  # 2. Create your UI with methods instead of classes.
@@ -128,8 +111,8 @@ end
128
111
  #### How it works
129
112
 
130
113
  1. **`RatatuiRuby.run`**: This context manager initializes the terminal before the block starts and ensures `restore_terminal` is called when the block exits (even if an error occurs).
131
- 2. **Widget Shorthand**: The block yields a `Session` object (here named `tui`). This object provides factory methods for every widget, allowing you to write `tui.paragraph(...)` instead of the more verbose `RatatuiRuby::Paragraph.new(...)`.
132
- 3. **Method Shorthand**: The session object also provides aliases for module functions of `RatatuiRuby`, allowing you to write `tui.draw(...)` instead of the more verbose `RatatuiRuby.draw(...)`.
114
+ 2. **Widget Shorthand**: The block yields a `TUI` object (here named `tui`). This object provides factory methods for every widget, allowing you to write `tui.paragraph(...)` instead of the more verbose `RatatuiRuby::Widgets::Paragraph.new(...)`.
115
+ 3. **Method Shorthand**: The `TUI` object also provides aliases for module functions of `RatatuiRuby`, allowing you to write `tui.draw(...)` instead of the more verbose `RatatuiRuby.draw(...)`.
133
116
  4. **Pattern Matching for Events**: Use `case...in` with pattern matching for elegant event dispatch. Always include an `else` clause at the end to catch unmatched event types (mouse, resize, paste, focus, etc.), otherwise Ruby raises `NoMatchingPatternError`.
134
117
 
135
118
  For a deeper dive into the available application architectures (Manual vs Managed), see [Application Architecture](./application_architecture.md).
@@ -197,95 +180,81 @@ end
197
180
 
198
181
  #### How it works
199
182
 
200
- 1. **`tui.layout_split` (`RatatuiRuby::Layout.split`)**: Takes an area (like `frame.area`) and splits it into multiple sub-areas based on constraints.
201
- 2. **`tui.constraint_*` (`RatatuiRuby::Constraint`)**: Defines how space is distributed (e.g., `percentage`, `length`, `min`, `max`).
183
+ 1. **`tui.layout_split` (`RatatuiRuby::Layout::Layout.split`)**: Takes an area (like `frame.area`) and splits it into multiple sub-areas based on constraints.
184
+ 2. **`tui.constraint_*` (`RatatuiRuby::Layout::Constraint`)**: Defines how space is distributed (e.g., `percentage`, `length`, `min`, `max`).
202
185
  3. **`Frame#render_widget(widget, rect)`**: You pass the specific area (like `top` or `bottom`) to render the widget into that exact region.
203
186
  4. **`tui.text_span` (`RatatuiRuby::Text::Span`)**: Allows for rich styling within a single line of text.
204
187
 
188
+ [![quickstart_layout](./images/verify_quickstart_layout.png)](../examples/verify_quickstart_layout/README.md)
189
+
205
190
  ## Examples
206
191
 
207
192
  These examples showcase the full power of **ratatui_ruby**. You can find their source code in the [examples directory](../examples).
208
193
 
209
- ### Sample Applications
210
-
211
- Full-featured examples demonstrating complex layouts and real-world TUI patterns.
212
-
213
-
214
-
215
- #### [All Events](../examples/app_all_events/app.rb)
216
-
217
- Handling terminal events is unpredictable. Developers need to know exactly what the terminal sends for `Ctrl+C` or a mouse drag.
218
-
219
- This app captures and visualizes every event—keys, mouse, resize, paste, and focus.
220
-
221
- Use it to debug your input handling or verify terminal behavior.
222
-
223
- **What you'll learn:**
224
-
225
- * **Proto-TEA Architecture**: Implements unidirectional data flow (Model-View-Update) with immutable state and pure functions.
226
- * **Event Handling**: Captures and distinguishes all input types, including modifiers (`Ctrl+C`) and focus changes.
227
- * **Scalable Structure**: Organizes a non-trivial application into small, focused classes instead of a monolithic script.
228
-
229
- ![all_events](./images/app_all_events.png)
230
-
231
- #### [Color Picker](https://git.sr.ht/~kerrick/ratatui_ruby/tree/main/item/examples/app_color_picker/app.rb)
232
-
233
- Interactive tools require complex state. Mapping mouse clicks to widgets and handling modal dialogs creates messy code if handled in the main loop.
234
-
235
- This app implements a full Color Picker using a "Proto-Kit (Component-Based)" pattern. Each component encapsulates its own rendering, state, and event handling.
236
-
237
- Use it to build forms, editors, and mouse-driven tools.
238
-
239
- **What you'll learn:**
240
-
241
- * **Proto-Kit Architecture**: Self-contained components with `render(tui, frame, area)` and `handle_event(event)`.
242
- * **Encapsulated Hit Testing**: Components cache their render area and check `contains?` internally.
243
- * **Modal Dialogs**: Implements overlay patterns that intercept input via Chain of Responsibility.
244
-
245
- #### [Custom Widget (Escape Hatch)](https://git.sr.ht/~kerrick/ratatui_ruby/tree/main/item/examples/app_custom_widget/app.rb)
246
-
247
- Demonstrates how to define a custom widget in pure Ruby using the `render(area, buffer)` escape hatch for low-level drawing.
194
+ ### Widget Demos
248
195
 
249
- ![custom_widget](./images/app_custom_widget.png)
196
+ Focused examples for individual widgets. Each demonstrates a single widget and its configuration options.
197
+
198
+ | Widget | What it demonstrates |
199
+ |--------|---------------------|
200
+ | [Bar Chart](../examples/widget_barchart_demo/app.rb) | Grouped bars, data visualization, custom bar styling |
201
+ | [Block](../examples/widget_block_demo/app.rb) | Borders, titles, padding, nested widgets |
202
+ | [Box](../examples/widget_box_demo/app.rb) | Block + Paragraph composition, text wrapping |
203
+ | [Calendar](../examples/widget_calendar_demo/app.rb) | Date highlighting, month display, event markers |
204
+ | [Chart](../examples/widget_chart_demo/app.rb) | Line/scatter plots, axes, legends, datasets |
205
+ | [Gauge](../examples/widget_gauge_demo/app.rb) | Progress bars, percentage display, unicode blocks |
206
+ | [Layout Split](../examples/widget_layout_split/app.rb) | Constraint types, flex modes, responsive layouts |
207
+ | [Line Gauge](../examples/widget_line_gauge_demo/app.rb) | Horizontal progress, labels, thin-style gauges |
208
+ | [List](../examples/widget_list_demo/app.rb) | Selection, scrolling, highlight styles, rich text items |
209
+ | [Map](../examples/widget_map_demo/app.rb) | Canvas widget, world map rendering, coordinates |
210
+ | [Popup](../examples/widget_popup_demo/app.rb) | Clear widget, modal dialogs, overlay composition |
211
+ | [Ratatui Logo](../examples/widget_ratatui_logo_demo/app.rb) | Decorative branding widget |
212
+ | [Ratatui Mascot](../examples/widget_ratatui_mascot_demo/app.rb) | ASCII art Ferris mascot |
213
+ | [Rect](../examples/widget_rect/app.rb) | Geometry helpers, area calculations, contains/intersection |
214
+ | [Rich Text](../examples/widget_rich_text/app.rb) | Spans, lines, inline styling, mixed colors |
215
+ | [Scrollbar](../examples/widget_scrollbar_demo/app.rb) | Orientations, thumb/track styling, scroll state |
216
+ | [Scroll Text](../examples/widget_scroll_text/app.rb) | Paragraph scrolling, viewport control, long content |
217
+ | [Sparkline](../examples/widget_sparkline_demo/app.rb) | Mini charts, time series, bar sets |
218
+ | [Style Colors](../examples/widget_style_colors/app.rb) | Named colors, RGB, indexed 256-color palette |
219
+ | [Table](../examples/widget_table_demo/app.rb) | Row selection, column widths, per-cell styling |
220
+ | [Tabs](../examples/widget_tabs_demo/app.rb) | Tab navigation, highlighting, dividers |
221
+ | [Text Width](../examples/widget_text_width/app.rb) | Unicode-aware width measurement, CJK support |
222
+ | [Canvas](../examples/widget_canvas_demo/app.rb) | Drawing shapes, markers, custom graphics |
223
+ | [Cell](../examples/widget_cell_demo/app.rb) | Buffer cell inspection, styling attributes |
224
+ | [Center](../examples/widget_center_demo/app.rb) | Centering content, horizontal/vertical alignment |
225
+ | [Overlay](../examples/widget_overlay_demo/app.rb) | Layering widgets, modal backgrounds |
226
+ | [Custom Render](../examples/widget_render/app.rb) | Low-level Draw API, escape hatch for custom widgets |
250
227
 
251
- #### [Layout Split Demo](https://git.sr.ht/~kerrick/ratatui_ruby/tree/main/item/examples/widget_layout_split/app.rb)
228
+ ### Sample Applications
252
229
 
253
- Demonstrates `Layout.split` with interactive attribute cycling. Features hotkey controls For direction (vertical/horizontal), all 7 flex modes (legacy, start, center, end, space_between, space_around, space_evenly), and constraint types (fill, length, percentage, min, ratio).
230
+ These larger examples combine widgets into complete applications, demonstrating real-world TUI patterns and architectures.
254
231
 
255
- ![widget_layout_split](./images/widget_layout_split.png)
232
+ | Application | Architecture | What you'll learn |
233
+ |-------------|--------------|-------------------|
234
+ | [All Events](../examples/app_all_events/app.rb) | Model-View-Update | Event handling, unidirectional data flow, scalable structure |
235
+ | [Color Picker](../examples/app_color_picker/app.rb) | Component-Based | Hit testing, modal dialogs, encapsulated state |
236
+ | [Login Form](../examples/app_login_form/app.rb) | Overlay + Center | Modal forms, cursor positioning, text input |
237
+ | [Stateful Interaction](../examples/app_stateful_interaction/app.rb) | State Objects | ListState/TableState, offset read-back, mouse click-to-row |
256
238
 
257
- #### [Login Form](https://git.sr.ht/~kerrick/ratatui_ruby/tree/main/item/examples/app_login_form/app.rb)
239
+ #### All Events
258
240
 
259
- Shows how to use `Overlay`, `Center`, and `Cursor` to build a modal login form with text input.
241
+ [![all_events](./images/app_all_events.png)](../examples/app_all_events/README.md)
260
242
 
261
- ![login_form](./images/app_login_form.png)
243
+ #### Color Picker
262
244
 
245
+ [![color_picker](./images/app_color_picker.png)](../examples/app_color_picker/README.md)
263
246
 
247
+ #### Login Form
264
248
 
249
+ [![login_form](./images/app_login_form.png)](../examples/app_login_form/README.md)
265
250
 
266
251
 
252
+ ## Next Steps
267
253
 
268
- ### Widget Demos
254
+ Now that you've seen what **ratatui_ruby** can do:
269
255
 
270
- These smaller, focused examples demonstrate specific widgets and their configuration options.
271
-
272
- * [Bar Chart](../examples/widget_barchart_demo/app.rb)
273
- * [Block (Interactive Demo)](../examples/widget_block_demo/app.rb)
274
- * [Box (Block/Paragraph)](../examples/widget_box_demo/app.rb)
275
- * [Calendar](../examples/widget_calendar_demo/app.rb)
276
- * [Chart](../examples/widget_chart_demo/app.rb)
277
- * [Gauge](../examples/widget_gauge_demo/app.rb)
278
- * [Line Gauge](../examples/widget_line_gauge_demo/app.rb)
279
- * [List](../examples/widget_list_demo/app.rb)
280
- * [Map (Canvas)](../examples/widget_map_demo/app.rb)
281
- * [Popup (Clear)](../examples/widget_popup_demo/app.rb)
282
- * [Rect](../examples/widget_rect/app.rb)
283
- * [Ratatui Logo](../examples/widget_ratatui_logo_demo/app.rb)
284
- * [Ratatui Mascot](../examples/widget_ratatui_mascot_demo/app.rb)
285
- * [Rich Text](../examples/widget_rich_text/app.rb)
286
- * [Scrollbar](../examples/widget_scrollbar_demo/app.rb)
287
- * [Scroll Text](../examples/widget_scroll_text/app.rb)
288
- * [Sparkline](../examples/widget_sparkline_demo/app.rb)
289
- * [Table (Selection)](../examples/widget_table_demo/app.rb)
290
- * [Tabs](../examples/widget_tabs_demo/app.rb)
291
- * [Widget Style Colors](../examples/widget_style_colors/app.rb)
256
+ - **Deep dive**: Read the [Application Architecture](./application_architecture.md) guide for scaling patterns
257
+ - **Test your TUI**: See the [Testing Guide](./application_testing.md) for snapshot and style assertions
258
+ - **Explore the API**: Browse the [full RDoc documentation](./index.md)
259
+ - **Learn the philosophy**: Read [Why RatatuiRuby?](./why.md) for comparisons and design decisions
260
+ - **Get help**: Join the [discussion mailing list](https://lists.sr.ht/~kerrick/ratatui_ruby-discuss)
@@ -0,0 +1,236 @@
1
+ <!--
2
+ SPDX-FileCopyrightText: 2025 Kerrick Long <me@kerricklong.com>
3
+ SPDX-License-Identifier: CC-BY-SA-4.0
4
+ -->
5
+
6
+ # Migrating to v0.7.0
7
+
8
+ v0.7.0 restructures the library to align with upstream Ratatui. For most users, this is a non-breaking change. For some, it is breaking.
9
+
10
+ ## Are You Affected?
11
+
12
+ **If your code looks like this, you're fine:**
13
+
14
+ ```ruby
15
+ RatatuiRuby.run do |tui|
16
+ tui.draw tui.paragraph(text: "Hello", block: tui.block(title: "Title"))
17
+ event = tui.poll_event
18
+ end
19
+ ```
20
+
21
+ The TUI API method names are unchanged. Your application works without modification.
22
+
23
+ **If your code uses `highlight_style:` on Tables, rename it:**
24
+
25
+ ```ruby
26
+ # Before (v0.6.0)
27
+ tui.table(rows: [...], highlight_style: tui.style(fg: :yellow))
28
+
29
+ # After (v0.7.0)
30
+ tui.table(rows: [...], row_highlight_style: tui.style(fg: :yellow))
31
+ ```
32
+
33
+ This change aligns with Ratatui's API naming convention.
34
+
35
+ **If your code instantiates classes directly, you have work to do:**
36
+
37
+ ```ruby
38
+ # These lines break in v0.7.0
39
+ paragraph = RatatuiRuby::Paragraph.new(text: "Hello")
40
+ style = RatatuiRuby::Style.new(fg: :red)
41
+ rect = RatatuiRuby::Rect.new(x: 0, y: 0, width: 10, height: 5)
42
+ ```
43
+
44
+ The old flat namespace no longer exists. Classes moved into modules.
45
+
46
+ ## Option 1: Use the TUI API (Recommended)
47
+
48
+ Switch to the TUI API. It hides namespace verbosity and provides IDE autocomplete.
49
+
50
+ ```ruby
51
+ RatatuiRuby.run do |tui|
52
+ # All these work exactly as before
53
+ paragraph = tui.paragraph(text: "Hello")
54
+ style = tui.style(fg: :red)
55
+ rect = tui.rect(x: 0, y: 0, width: 10, height: 5)
56
+ constraint = tui.constraint_length(20)
57
+
58
+ # New in v0.7.0
59
+ cell = tui.table_cell(content: "Error", style: tui.style(bg: :red))
60
+ row = tui.table_row(cells: ["A", "B", "C"], style: tui.style(bg: :dark_gray))
61
+ end
62
+ ```
63
+
64
+ ## Option 2: Update to New Namespaces
65
+
66
+ If you prefer direct class instantiation, update to the new paths:
67
+
68
+ | Before | After |
69
+ |--------|-------|
70
+ | `RatatuiRuby::Rect` | `RatatuiRuby::Layout::Rect` |
71
+ | `RatatuiRuby::Constraint` | `RatatuiRuby::Layout::Constraint` |
72
+ | `RatatuiRuby::Layout` | `RatatuiRuby::Layout::Layout` |
73
+ | `RatatuiRuby::Style` | `RatatuiRuby::Style::Style` |
74
+ | `RatatuiRuby::Paragraph` | `RatatuiRuby::Widgets::Paragraph` |
75
+ | `RatatuiRuby::Block` | `RatatuiRuby::Widgets::Block` |
76
+ | `RatatuiRuby::Table` | `RatatuiRuby::Widgets::Table` |
77
+ | `RatatuiRuby::List` | `RatatuiRuby::Widgets::List` |
78
+ | `RatatuiRuby::Cell` | `RatatuiRuby::Buffer::Cell` |
79
+ | *(all other widgets)* | `RatatuiRuby::Widgets::*` |
80
+
81
+ ### Bulk Migration
82
+
83
+ ```bash
84
+ find . -name "*.rb" -exec sed -i '' \
85
+ 's/RatatuiRuby::Rect/RatatuiRuby::Layout::Rect/g; \
86
+ s/RatatuiRuby::Constraint\./RatatuiRuby::Layout::Constraint./g; \
87
+ s/RatatuiRuby::Paragraph\.new/RatatuiRuby::Widgets::Paragraph.new/g; \
88
+ s/RatatuiRuby::Block\.new/RatatuiRuby::Widgets::Block.new/g; \
89
+ s/RatatuiRuby::List\.new/RatatuiRuby::Widgets::List.new/g; \
90
+ s/RatatuiRuby::Table\.new/RatatuiRuby::Widgets::Table.new/g; \
91
+ s/RatatuiRuby::Style\.new/RatatuiRuby::Style::Style.new/g; \
92
+ s/RatatuiRuby::Session/RatatuiRuby::TUI/g; \
93
+ s/highlight_style:/row_highlight_style:/g' {} \;
94
+ ```
95
+
96
+ ## Session → TUI Rename
97
+
98
+ The `Session` class is now `TUI`. If you reference it directly:
99
+
100
+ ```ruby
101
+ # Before
102
+ tui = RatatuiRuby::Session.new
103
+
104
+ # After
105
+ tui = RatatuiRuby::TUI.new
106
+ ```
107
+
108
+ Most users never reference the class directly. The `|tui|` block parameter works unchanged.
109
+
110
+ ## Table: highlight_style → row_highlight_style
111
+
112
+ The `highlight_style:` parameter on Table is now `row_highlight_style:`. This aligns with Ratatui's naming convention where `row_highlight_style`, `column_highlight_style`, and `cell_highlight_style` form a consistent trio.
113
+
114
+ ```ruby
115
+ # Before (v0.6.0)
116
+ tui.table(
117
+ rows: data,
118
+ highlight_style: tui.style(fg: :yellow)
119
+ )
120
+
121
+ # After (v0.7.0)
122
+ tui.table(
123
+ rows: data,
124
+ row_highlight_style: tui.style(fg: :yellow)
125
+ )
126
+ ```
127
+
128
+ ## Text::Line style Field
129
+
130
+ `Text::Line` now accepts a `style:` parameter for line-level styling. This matches Ratatui's `Line` struct.
131
+
132
+ ```ruby
133
+ # New in v0.7.0: Line-level styling
134
+ line = tui.text_line(
135
+ spans: [tui.text_span(content: "Hello")],
136
+ style: tui.style(bg: :dark_gray) # Applied to entire line
137
+ )
138
+ ```
139
+
140
+ Existing code without `style:` continues to work unchanged.
141
+
142
+ ## New Table Cell and Row Classes
143
+
144
+ v0.7.0 adds `Widgets::Cell` and `Widgets::Row` for table construction with per-cell styling:
145
+
146
+ ```ruby
147
+ table = tui.table(
148
+ rows: [
149
+ tui.table_row(
150
+ cells: [
151
+ tui.table_cell(content: "Name", style: tui.style(fg: :blue)),
152
+ "Value"
153
+ ],
154
+ style: tui.style(bg: :dark_gray)
155
+ )
156
+ ],
157
+ widths: [tui.constraint_length(20), tui.constraint_fill]
158
+ )
159
+ ```
160
+
161
+ ## Buffer::Cell vs Widgets::Cell
162
+
163
+ Two `Cell` classes now exist:
164
+
165
+ - **`Buffer::Cell`** — Terminal cell for inspection (returned by `get_cell_at`)
166
+ - **`Widgets::Cell`** — Table cell for construction (content + style wrapper)
167
+
168
+ ```ruby
169
+ # Buffer inspection (unchanged)
170
+ cell = RatatuiRuby.get_cell_at(0, 0) # Returns Buffer::Cell
171
+ cell.char # => "X"
172
+ cell.fg # => :red
173
+
174
+ # Table cell construction (new)
175
+ cell = tui.table_cell(content: "Error", style: tui.style(bg: :red))
176
+ ```
177
+
178
+ ## Why This Change?
179
+
180
+ The old flat namespace caused name collisions (`Cell` for buffers vs. tables) and diverged from Ratatui's module structure. The new hierarchy:
181
+
182
+ - Maps 1:1 to Ratatui documentation
183
+ - Prevents future collisions
184
+ - Enables IDE autocomplete via explicit TUI methods
185
+
186
+ ---
187
+
188
+ ## For LLMs
189
+
190
+ Copy the following prompt to your AI assistant to help migrate your `ratatui_ruby` application from v0.6.0 to v0.7.0.
191
+
192
+ ````markdown
193
+ I'm migrating a Ruby TUI application from `ratatui_ruby` v0.6.0 to v0.7.0. The library restructured its namespaces. Apply these transformations:
194
+
195
+ **Namespace Changes:**
196
+ - `RatatuiRuby::Rect` → `RatatuiRuby::Layout::Rect`
197
+ - `RatatuiRuby::Constraint` → `RatatuiRuby::Layout::Constraint`
198
+ - `RatatuiRuby::Layout` → `RatatuiRuby::Layout::Layout`
199
+ - `RatatuiRuby::Style` → `RatatuiRuby::Style::Style`
200
+ - `RatatuiRuby::Paragraph` → `RatatuiRuby::Widgets::Paragraph`
201
+ - `RatatuiRuby::Block` → `RatatuiRuby::Widgets::Block`
202
+ - `RatatuiRuby::Table` → `RatatuiRuby::Widgets::Table`
203
+ - `RatatuiRuby::List` → `RatatuiRuby::Widgets::List`
204
+ - `RatatuiRuby::Cell` → `RatatuiRuby::Buffer::Cell`
205
+ - All other widgets: `RatatuiRuby::X` → `RatatuiRuby::Widgets::X`
206
+
207
+ **Class Rename:**
208
+ - `RatatuiRuby::Session` → `RatatuiRuby::TUI`
209
+
210
+ **Parameter Rename:**
211
+ - `Table` `highlight_style:` → `row_highlight_style:`
212
+
213
+ **Preferred Approach:** Convert direct class instantiation to TUI API:
214
+ ```ruby
215
+ # Instead of:
216
+ RatatuiRuby::Widgets::Paragraph.new(text: "Hello")
217
+
218
+ # Use:
219
+ tui.paragraph(text: "Hello")
220
+ ```
221
+
222
+ **TUI API method names are unchanged.** Code using `tui.paragraph(...)`, `tui.block(...)`, `tui.style(...)` etc. works without modification.
223
+
224
+ **Cell Disambiguation:**
225
+ - `Buffer::Cell` — Terminal cell for inspection (returned by `get_cell_at`)
226
+ - `Widgets::Cell` — Table cell for construction (use `tui.table_cell`)
227
+ - The old `RatatuiRuby::Cell` is now `RatatuiRuby::Buffer::Cell`
228
+
229
+ **New in v0.7.0:**
230
+ - `tui.table_cell(content:, style:)` — styled table cells
231
+ - `tui.table_row(cells:, style:, height:)` — styled table rows
232
+ - `Text::Line` now accepts `style:` parameter
233
+
234
+ Please update my code following these rules.
235
+ ````
236
+
data/doc/why.md ADDED
@@ -0,0 +1,93 @@
1
+ <!--
2
+ SPDX-FileCopyrightText: 2025 Kerrick Long <me@kerricklong.com>
3
+ SPDX-License-Identifier: CC-BY-SA-4.0
4
+ -->
5
+ # Why RatatuiRuby?
6
+
7
+ The terminal is having a renaissance. Ruby deserves to be at the forefront.
8
+
9
+ **RatatuiRuby** is a high-performance, immediate-mode TUI engine that brings the power of Rust's [Ratatui](https://ratatui.rs) library directly into Ruby. No ports. No emulations. A native bridge to the industry-standard Rust crate.
10
+
11
+
12
+ ## The Pitch
13
+
14
+ You want to build a terminal UI. You love Ruby. Your options were:
15
+
16
+ 1. **Learn Go** for Bubble Tea
17
+ 2. **Learn Rust** for Ratatui
18
+ 3. **Use a pure-Ruby library** with limited performance
19
+
20
+ We built a fourth option: **Write Ruby. Run Rust.**
21
+
22
+ RatatuiRuby gives you Rust's layout engine, rendering speed, and battle-tested widgets — with Ruby's expressiveness, ecosystem, and joy.
23
+
24
+
25
+ ## RatatuiRuby vs. CharmRuby
26
+
27
+ [CharmRuby](https://github.com/marcoroth/charm_ruby) is an excellent project by Marco Roth. It provides Ruby bindings to Charm's Go libraries (Bubble Tea, Lipgloss). The Ruby ecosystem is better because both projects exist.
28
+
29
+ So which one should you choose?
30
+
31
+ | | CharmRuby | RatatuiRuby |
32
+ |---|-----------|-------------|
33
+ | **Backend** | Go runtime | Rust (no runtime) |
34
+ | **Architecture** | Elm Architecture (MVU) | Immediate-mode + your choice |
35
+ | **GC Behavior** | Two GCs (Ruby + Go) | One GC (Ruby only) |
36
+ | **Rendering** | String manipulation | Constraint-based layout tree |
37
+ | **Best for** | Fans of Bubble Tea, MVU | Native performance, heavy-duty apps |
38
+
39
+ **What's a runtime?** A runtime is background machinery that a language needs to run. Go has one (for goroutines and garbage collection). Rust doesn't — it compiles to plain machine code. When you use Go bindings, you're running *two* runtimes in the same process (Ruby's and Go's), which adds complexity and memory overhead. With Rust bindings, there's only Ruby.
40
+
41
+ **Choose CharmRuby** if you prefer Charm's aesthetics or are migrating existing Bubble Tea code.
42
+
43
+ **Choose RatatuiRuby** if you want zero-overhead native performance and architectural freedom. RatatuiRuby doesn't force a framework — you can build MVU, component-based, or any pattern you prefer.
44
+
45
+
46
+ ## Why Not Just Write Rust?
47
+
48
+ Rust is amazing. It's also strict.
49
+
50
+ The borrow checker enforces memory safety. That's great for systems programming. It's painful for UI iteration. Moving a sidebar, changing a color, or swapping a widget often requires refactoring ownership chains.
51
+
52
+ With RatatuiRuby, you just change the object. You get Rust's performance where it matters — rendering — and Ruby's flexibility where it counts — designing.
53
+
54
+
55
+ ## Why Not Just Write Go?
56
+
57
+ Go is pragmatic. But using Go bindings means running *two* runtimes in the same process: Ruby's and Go's. That adds complexity and memory overhead.
58
+
59
+ With RatatuiRuby, there's only Ruby. Rust compiles to plain machine code with no runtime — it integrates seamlessly.
60
+
61
+
62
+ ## Why Ruby?
63
+
64
+ [Ruby isn't just another language](https://www.ruby-lang.org/en/). It's an ecosystem:
65
+
66
+ - **[ActiveRecord](https://guides.rubyonrails.org/active_record_basics.html)** — Query your database with elegant, chainable methods
67
+ - **[RSpec](https://rspec.info/)** — Write expressive, readable tests with `describe`, `it`, and `expect`
68
+ - **[Blocks](https://ruby-doc.org/docs/ruby-doc-bundle/UsersGuide/rg/blocks.html)** — Pass behavior to methods with `do...end`, the heart of Ruby's expressiveness
69
+ - **[Metaprogramming](https://ruby-doc.org/docs/ruby-doc-bundle/UsersGuide/rg/objinitialization.html)** — Define methods dynamically, build DSLs, and write code that writes code
70
+ - **[Bundler](https://bundler.io/)** — Access 180,000+ gems with a single `bundle add`
71
+
72
+ Build a dashboard for your Rails app. Monitor your Sidekiq jobs. Create developer tools in the same language as the code they inspect.
73
+
74
+
75
+ ## The Philosophy: A Solid Foundation
76
+
77
+ RatatuiRuby is a **low-level engine**. It provides raw primitives — Layouts, Blocks, Text, Tables, Charts — to build anything.
78
+
79
+ It doesn't force a framework on you. You can use:
80
+ - **Model-View-Update** for dashboards and data displays
81
+ - **Component-based** patterns for interactive tools
82
+ - **Your own architecture** for everything else
83
+
84
+ This is the foundation for Ruby's next generation of TUI tools, dashboards, and interactive scripts.
85
+
86
+
87
+ ## Get Started
88
+
89
+ Ready to build?
90
+
91
+ - [Quickstart Guide](./quickstart.md) — Your first app in 5 minutes
92
+ - [Widget Gallery](./quickstart.md#widget-demos) — See what's possible
93
+ - [Application Architecture](./application_architecture.md) — Patterns for scaling
@@ -5,9 +5,11 @@ SPDX-License-Identifier: CC-BY-SA-4.0
5
5
 
6
6
  # App All Events Example
7
7
 
8
- This example application captures and visualizes every event supported by `ratatui_ruby`. It serves as a comprehensive reference for event handling and a demonstration of the Proto-TEA architectural pattern.
8
+ [![App All Events](../../doc/images/app_all_events.png)](app.rb)
9
9
 
10
- ## Architecture: Proto-TEA (Model-View-Update)
10
+ This example application captures and visualizes every event supported by `ratatui_ruby`. It serves as a comprehensive reference for event handling and a demonstration of the Model-View-Update architectural pattern.
11
+
12
+ ## Architecture: Model-View-Update
11
13
 
12
14
  This application demonstrates **unidirectional data flow** inspired by The Elm Architecture. This separation ensures that state management is predictable and easy to test.
13
15
 
@@ -85,7 +87,7 @@ Complex applications require structured state habits. `AppAllEvents` and the [Co
85
87
 
86
88
  ### The Dashboard Approach (AppAllEvents)
87
89
 
88
- Dashboards display data. They rarely require complex mouse interaction. Proto-TEA works best here. State is immutable. Logic is pure. Updates are predictable. This simplifies testing.
90
+ Dashboards display data. They rarely require complex mouse interaction. Model-View-Update works best here. State is immutable. Logic is pure. Updates are predictable. This simplifies testing.
89
91
 
90
92
  Use this pattern for logs, monitors, and data viewers.
91
93
 
@@ -93,7 +95,7 @@ Use this pattern for logs, monitors, and data viewers.
93
95
 
94
96
  Tools require interaction. Users click buttons and drag sliders. Each UI component needs to know where it exists on screen for hit testing.
95
97
 
96
- The Color Picker uses a "Proto-Kit (Component-Based)" pattern. Each component encapsulates its own rendering, state, and event handling. The Container routes events and coordinates cross-component effects.
98
+ The Color Picker uses a Component-Based pattern. Each component encapsulates its own rendering, state, and event handling. The Container routes events and coordinates cross-component effects.
97
99
 
98
100
  Use this pattern for forms, editors, and mouse-driven tools.
99
101
 
@@ -23,7 +23,7 @@ require_relative "view/app_view"
23
23
  #
24
24
  # === Architecture
25
25
  #
26
- # This example uses the Proto-TEA (Model-View-Update) pattern:
26
+ # This example uses the Model-View-Update pattern:
27
27
  # - **Model**: Immutable AppModel holds all state
28
28
  # - **Msg**: Semantic message types decouple events from logic
29
29
  # - **Update**: Pure function computes next state
@@ -7,7 +7,7 @@ require_relative "timestamp"
7
7
  require_relative "event_entry"
8
8
  require_relative "event_color_cycle"
9
9
 
10
- # Immutable application state for the Proto-TEA architecture.
10
+ # Immutable application state for the Model-View-Update architecture.
11
11
  #
12
12
  # The Elm Architecture requires a single immutable Model. State changes return
13
13
  # a new Model instance. This consolidates all app state into one place.
@@ -3,7 +3,7 @@
3
3
  # SPDX-FileCopyrightText: 2025 Kerrick Long <me@kerricklong.com>
4
4
  # SPDX-License-Identifier: AGPL-3.0-or-later
5
5
 
6
- # Semantic message types for the Proto-TEA architecture.
6
+ # Semantic message types for the Model-View-Update architecture.
7
7
  #
8
8
  # Raw events from the terminal are converted to semantic Msg types. This
9
9
  # decouples the Update function from the event system, making it easier