rooibos 0.6.2 → 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 (217) hide show
  1. checksums.yaml +4 -4
  2. data/LICENSES/BSD-2-Clause.txt +9 -0
  3. data/REUSE.toml +5 -0
  4. data/exe/.gitkeep +0 -0
  5. data/lib/rooibos/cli/commands/new.rb +24 -0
  6. data/lib/rooibos/command/batch.rb +10 -0
  7. data/lib/rooibos/command/bubble.rb +34 -0
  8. data/lib/rooibos/command/custom.rb +3 -2
  9. data/lib/rooibos/command/deliver.rb +50 -0
  10. data/lib/rooibos/command/http.rb +1 -1
  11. data/lib/rooibos/command/lifecycle.rb +3 -1
  12. data/lib/rooibos/command/outlet.rb +19 -9
  13. data/lib/rooibos/command.rb +107 -3
  14. data/lib/rooibos/configuration.rb +29 -0
  15. data/lib/rooibos/message/bubbled.rb +29 -0
  16. data/lib/rooibos/message.rb +24 -6
  17. data/lib/rooibos/router/action.rb +36 -0
  18. data/lib/rooibos/router/flow/dispatch.rb +39 -0
  19. data/lib/rooibos/router/flow/inward.rb +41 -0
  20. data/lib/rooibos/router/flow/outward.rb +44 -0
  21. data/lib/rooibos/router/guard.rb +56 -0
  22. data/lib/rooibos/router/predicate.rb +65 -0
  23. data/lib/rooibos/router/registry/actions.rb +41 -0
  24. data/lib/rooibos/router/registry/forwards.rb +58 -0
  25. data/lib/rooibos/router/registry/observes.rb +57 -0
  26. data/lib/rooibos/router/registry/otherwises.rb +29 -0
  27. data/lib/rooibos/router/registry/receives.rb +57 -0
  28. data/lib/rooibos/router/registry/routes.rb +59 -0
  29. data/lib/rooibos/router/registry.rb +26 -0
  30. data/lib/rooibos/router/route.rb +42 -0
  31. data/lib/rooibos/router/router_update.rb +53 -0
  32. data/lib/rooibos/router/rule/forward.rb +39 -0
  33. data/lib/rooibos/router/rule/observe.rb +22 -0
  34. data/lib/rooibos/router/rule/otherwise.rb +26 -0
  35. data/lib/rooibos/router/rule/receive.rb +22 -0
  36. data/lib/rooibos/router/rule.rb +40 -0
  37. data/lib/rooibos/router.rb +424 -438
  38. data/lib/rooibos/runtime.rb +37 -52
  39. data/lib/rooibos/test_helper.rb +22 -0
  40. data/lib/rooibos/transition.rb +92 -0
  41. data/lib/rooibos/version.rb +1 -1
  42. data/lib/rooibos.rb +2 -57
  43. data/sig/rooibos/cli.rbs +1 -0
  44. data/sig/rooibos/command.rbs +44 -0
  45. data/sig/rooibos/configuration.rbs +20 -0
  46. data/sig/rooibos/message.rbs +12 -0
  47. data/sig/rooibos/router/action.rbs +33 -0
  48. data/sig/rooibos/router/actions.rbs +27 -0
  49. data/sig/rooibos/router/flow/dispatch.rbs +29 -0
  50. data/sig/rooibos/router/flow/inward.rbs +37 -0
  51. data/sig/rooibos/router/flow/outward.rbs +36 -0
  52. data/sig/rooibos/router/forward.rbs +35 -0
  53. data/sig/rooibos/router/forwards.rbs +34 -0
  54. data/sig/rooibos/router/guard.rbs +21 -0
  55. data/sig/rooibos/router/observe.rbs +20 -0
  56. data/sig/rooibos/router/observes.rbs +38 -0
  57. data/sig/rooibos/router/otherwise.rbs +22 -0
  58. data/sig/rooibos/router/otherwises.rbs +20 -0
  59. data/sig/rooibos/router/predicate.rbs +51 -0
  60. data/sig/rooibos/router/receive.rbs +20 -0
  61. data/sig/rooibos/router/receives.rbs +38 -0
  62. data/sig/rooibos/router/registry.rbs +24 -0
  63. data/sig/rooibos/router/route.rbs +46 -0
  64. data/sig/rooibos/router/router_update.rbs +33 -0
  65. data/sig/rooibos/router/routes.rbs +41 -0
  66. data/sig/rooibos/router/rule.rbs +36 -0
  67. data/sig/rooibos/router.rbs +216 -161
  68. data/sig/rooibos/runtime.rbs +0 -1
  69. data/sig/rooibos/test_helper.rbs +6 -0
  70. data/sig/rooibos/transition.rbs +33 -0
  71. data/sig/rooibos.rbs +0 -10
  72. metadata +144 -198
  73. data/.builds/ruby-3.2.yml +0 -55
  74. data/.builds/ruby-3.3.yml +0 -55
  75. data/.builds/ruby-3.4.yml +0 -55
  76. data/.builds/ruby-4.0.0.yml +0 -55
  77. data/.pre-commit-config.yaml +0 -16
  78. data/.rubocop.yml +0 -8
  79. data/AGENTS.md +0 -108
  80. data/CHANGELOG.md +0 -308
  81. data/README.md +0 -183
  82. data/README.rdoc +0 -374
  83. data/Rakefile +0 -16
  84. data/Steepfile +0 -13
  85. data/doc/best_practices/forms_and_validation.md +0 -20
  86. data/doc/best_practices/http_workflows.md +0 -20
  87. data/doc/best_practices/index.md +0 -26
  88. data/doc/best_practices/lists_and_tables.md +0 -20
  89. data/doc/best_practices/modal_dialogs.md +0 -20
  90. data/doc/best_practices/no_stateful_widgets.md +0 -184
  91. data/doc/best_practices/orchestration.md +0 -20
  92. data/doc/best_practices/streaming_data.md +0 -20
  93. data/doc/contributors/design/commands_and_outlets.md +0 -214
  94. data/doc/contributors/design/mvu_tea_implementations_research.md +0 -373
  95. data/doc/contributors/documentation_plan.md +0 -616
  96. data/doc/contributors/documentation_stub_audit.md +0 -112
  97. data/doc/contributors/documentation_style.md +0 -275
  98. data/doc/contributors/e2e_pty.md +0 -168
  99. data/doc/contributors/maybe_stateful_router.md +0 -56
  100. data/doc/contributors/specs/earliest_tutorial_steps_per_story.md +0 -70
  101. data/doc/contributors/specs/file_browser.md +0 -789
  102. data/doc/contributors/specs/file_browser_stories.md +0 -784
  103. data/doc/contributors/specs/tutorials_to_stories.rb +0 -167
  104. data/doc/contributors/todo/scrollbar.md +0 -118
  105. data/doc/contributors/tutorial_old/01_project_setup.md +0 -20
  106. data/doc/contributors/tutorial_old/02_hello_world.md +0 -24
  107. data/doc/contributors/tutorial_old/03_adding_state.md +0 -26
  108. data/doc/contributors/tutorial_old/06_organizing_your_code.md +0 -20
  109. data/doc/contributors/tutorial_old/07_your_first_command.md +0 -21
  110. data/doc/contributors/tutorial_old/08_the_preview_pane.md +0 -20
  111. data/doc/contributors/tutorial_old/09_loading_states.md +0 -20
  112. data/doc/contributors/tutorial_old/10_testing_your_app.md +0 -20
  113. data/doc/contributors/tutorial_old/11_polish_and_refine.md +0 -20
  114. data/doc/contributors/tutorial_old/12_going_further.md +0 -20
  115. data/doc/contributors/tutorial_old/index.md +0 -20
  116. data/doc/custom.css +0 -22
  117. data/doc/essentials/commands.md +0 -20
  118. data/doc/essentials/index.md +0 -31
  119. data/doc/essentials/messages.md +0 -21
  120. data/doc/essentials/models.md +0 -21
  121. data/doc/essentials/shortcuts.md +0 -19
  122. data/doc/essentials/the_elm_architecture.md +0 -24
  123. data/doc/essentials/the_runtime.md +0 -21
  124. data/doc/essentials/update_functions.md +0 -20
  125. data/doc/essentials/views.md +0 -22
  126. data/doc/getting_started/for_go_developers.md +0 -16
  127. data/doc/getting_started/for_python_developers.md +0 -16
  128. data/doc/getting_started/for_rails_developers.md +0 -17
  129. data/doc/getting_started/for_ratatui_ruby_developers.md +0 -17
  130. data/doc/getting_started/for_react_developers.md +0 -17
  131. data/doc/getting_started/index.md +0 -52
  132. data/doc/getting_started/install.md +0 -20
  133. data/doc/getting_started/quickstart.md +0 -20
  134. data/doc/getting_started/ruby_primer.md +0 -19
  135. data/doc/getting_started/why_rooibos.md +0 -20
  136. data/doc/images/verify_readme_usage.png +0 -0
  137. data/doc/images/widget_cmd_exec.png +0 -0
  138. data/doc/index.md +0 -93
  139. data/doc/scaling_up/async_patterns.md +0 -20
  140. data/doc/scaling_up/command_composition.md +0 -20
  141. data/doc/scaling_up/custom_commands.md +0 -21
  142. data/doc/scaling_up/fractal_architecture.md +0 -20
  143. data/doc/scaling_up/index.md +0 -30
  144. data/doc/scaling_up/message_routing.md +0 -20
  145. data/doc/scaling_up/ractor_safety.md +0 -20
  146. data/doc/scaling_up/testing.md +0 -21
  147. data/doc/troubleshooting/common_errors.md +0 -20
  148. data/doc/troubleshooting/debugging.md +0 -21
  149. data/doc/troubleshooting/index.md +0 -23
  150. data/doc/troubleshooting/performance.md +0 -20
  151. data/doc/tutorial/01_project_setup.md +0 -44
  152. data/doc/tutorial/02_hello_world.md +0 -45
  153. data/doc/tutorial/03_static_file_list.md +0 -44
  154. data/doc/tutorial/04_arrow_navigation.md +0 -47
  155. data/doc/tutorial/05_real_files.md +0 -45
  156. data/doc/tutorial/06_safe_refactoring.md +0 -21
  157. data/doc/tutorial/07_red_first_tdd.md +0 -26
  158. data/doc/tutorial/08_file_metadata.md +0 -42
  159. data/doc/tutorial/09_text_preview.md +0 -44
  160. data/doc/tutorial/10_directory_tree.md +0 -42
  161. data/doc/tutorial/11_pane_focus.md +0 -40
  162. data/doc/tutorial/12_sorting.md +0 -41
  163. data/doc/tutorial/13_filtering.md +0 -43
  164. data/doc/tutorial/14_toggle_hidden.md +0 -41
  165. data/doc/tutorial/15_text_input_widget.md +0 -43
  166. data/doc/tutorial/16_rename_files.md +0 -42
  167. data/doc/tutorial/17_confirmation_dialogs.md +0 -43
  168. data/doc/tutorial/18_progress_indicators.md +0 -43
  169. data/doc/tutorial/19_atomic_operations.md +0 -42
  170. data/doc/tutorial/20_external_editor.md +0 -42
  171. data/doc/tutorial/21_modal_overlays.md +0 -41
  172. data/doc/tutorial/22_error_handling.md +0 -43
  173. data/doc/tutorial/23_terminal_capabilities.md +0 -53
  174. data/doc/tutorial/24_mouse_events.md +0 -43
  175. data/doc/tutorial/25_resize_events.md +0 -43
  176. data/doc/tutorial/26_loading_states.md +0 -42
  177. data/doc/tutorial/27_performance.md +0 -43
  178. data/doc/tutorial/28_color_schemes.md +0 -47
  179. data/doc/tutorial/29_configuration.md +0 -124
  180. data/doc/tutorial/30_going_further.md +0 -17
  181. data/doc/tutorial/index.md +0 -17
  182. data/examples/app_fractal_dashboard/README.md +0 -60
  183. data/examples/app_fractal_dashboard/app.rb +0 -63
  184. data/examples/app_fractal_dashboard/dashboard/base.rb +0 -73
  185. data/examples/app_fractal_dashboard/dashboard/update_helpers.rb +0 -86
  186. data/examples/app_fractal_dashboard/dashboard/update_manual.rb +0 -87
  187. data/examples/app_fractal_dashboard/dashboard/update_router.rb +0 -43
  188. data/examples/app_fractal_dashboard/fragments/custom_shell_input.rb +0 -81
  189. data/examples/app_fractal_dashboard/fragments/custom_shell_modal.rb +0 -82
  190. data/examples/app_fractal_dashboard/fragments/custom_shell_output.rb +0 -90
  191. data/examples/app_fractal_dashboard/fragments/disk_usage.rb +0 -47
  192. data/examples/app_fractal_dashboard/fragments/network_panel.rb +0 -45
  193. data/examples/app_fractal_dashboard/fragments/ping.rb +0 -47
  194. data/examples/app_fractal_dashboard/fragments/stats_panel.rb +0 -45
  195. data/examples/app_fractal_dashboard/fragments/system_info.rb +0 -47
  196. data/examples/app_fractal_dashboard/fragments/uptime.rb +0 -47
  197. data/examples/tutorial/01/app.rb +0 -50
  198. data/examples/tutorial/02/app.rb +0 -64
  199. data/examples/tutorial/03/app.rb +0 -91
  200. data/examples/tutorial/06_safe_refactoring/app.rb +0 -124
  201. data/examples/verify_readme_usage/README.md +0 -54
  202. data/examples/verify_readme_usage/app.rb +0 -47
  203. data/examples/verify_website_first_app/app.rb +0 -85
  204. data/examples/verify_website_hello_mvu/app.rb +0 -31
  205. data/examples/widget_command_system/README.md +0 -70
  206. data/examples/widget_command_system/app.rb +0 -134
  207. data/generate_tutorial_stubs.rb +0 -126
  208. data/mise.toml +0 -8
  209. data/rbs_collection.lock.yaml +0 -108
  210. data/rbs_collection.yaml +0 -15
  211. data/tasks/example_viewer.html.erb +0 -172
  212. data/tasks/install.rake +0 -29
  213. data/tasks/resources/build.yml.erb +0 -55
  214. data/tasks/resources/index.html.erb +0 -44
  215. data/tasks/resources/rubies.yml +0 -7
  216. data/tasks/steep.rake +0 -11
  217. /data/{vendor/goodcop/base.yml → lib/rooibos/rubocop.yml} +0 -0
data/README.md DELETED
@@ -1,183 +0,0 @@
1
- <!--
2
- SPDX-FileCopyrightText: 2026 Kerrick Long <me@kerricklong.com>
3
- SPDX-License-Identifier: CC-BY-SA-4.0
4
- -->
5
- # rooibos
6
-
7
- [![
8
- builds.sr.ht status](https://builds.sr.ht/~kerrick/rooibos.svg)](https://builds.sr.ht/~kerrick/rooibos?) [![
9
- License](https://img.shields.io/badge/dynamic/regex?url=https%3A%2F%2Fgit.sr.ht%2F~kerrick%2Frooibos%2Fblob%2Fstable%2Frooibos.gemspec&search=spec%5C.license%20%3D%20%22(.*)%22&replace=%241&label=License&color=a2c93e)](https://spdx.org/licenses/LGPL-3.0-or-later.html) [![
10
- Gem Total Downloads](https://img.shields.io/gem/dt/rooibos)](https://rubygems.org/gems/rooibos) [![
11
- Gem Version](https://img.shields.io/gem/v/rooibos)](https://rubygems.org/gems/rooibos) [![
12
- Mailing List: Discussion](https://img.shields.io/badge/mailing_list-discussion-5865F2.svg?logo=data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIyNCIgaGVpZ2h0PSIyNCIgdmlld0JveD0iMCAwIDI0IDI0IiBmaWxsPSJub25lIiBzdHJva2U9IiNmZmZmZmYiIHN0cm9rZS13aWR0aD0iMiIgc3Ryb2tlLWxpbmVjYXA9InJvdW5kIiBzdHJva2UtbGluZWpvaW49InJvdW5kIiBjbGFzcz0iaWNvbiBpY29uLXRhYmxlciBpY29ucy10YWJsZXItb3V0bGluZSBpY29uLXRhYmxlci1tYWlsIj48cGF0aCBzdHJva2U9Im5vbmUiIGQ9Ik0wIDBoMjR2MjRIMHoiIGZpbGw9Im5vbmUiLz48cGF0aCBkPSJNMyA3YTIgMiAwIDAgMSAyIC0yaDE0YTIgMiAwIDAgMSAyIDJ2MTBhMiAyIDAgMCAxIC0yIDJoLTE0YTIgMiAwIDAgMSAtMiAtMnYtMTB6IiAvPjxwYXRoIGQ9Ik0zIDdsOSA2bDkgLTYiIC8+PC9zdmc+Cg==)](https://lists.sr.ht/~kerrick/ratatui_ruby-discuss) [![
13
- Mailing List: Development](https://img.shields.io/badge/mailing_list-development-4954d5.svg?logo=data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIyNCIgaGVpZ2h0PSIyNCIgdmlld0JveD0iMCAwIDI0IDI0IiBmaWxsPSJub25lIiBzdHJva2U9IiNmZmZmZmYiIHN0cm9rZS13aWR0aD0iMiIgc3Ryb2tlLWxpbmVjYXA9InJvdW5kIiBzdHJva2UtbGluZWpvaW49InJvdW5kIiBjbGFzcz0iaWNvbiBpY29uLXRhYmxlciBpY29ucy10YWJsZXItb3V0bGluZSBpY29uLXRhYmxlci1tYWlsIj48cGF0aCBzdHJva2U9Im5vbmUiIGQ9Ik0wIDBoMjR2MjRIMHoiIGZpbGw9Im5vbmUiLz48cGF0aCBkPSJNMyA3YTIgMiAwIDAgMSAyIC0yaDE0YTIgMiAwIDAgMSAyIDJ2MTBhMiAyIDAgMCAxIC0yIDJoLTE0YTIgMiAwIDAgMSAtMiAtMnYtMTB6IiAvPjxwYXRoIGQ9Ik0zIDdsOSA2bDkgLTYiIC8+PC9zdmc+Cg==)](https://lists.sr.ht/~kerrick/ratatui_ruby-devel) [![
14
- Mailing List: Announcements](https://img.shields.io/badge/mailing_list-announcements-3b44ac.svg?logo=data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIyNCIgaGVpZ2h0PSIyNCIgdmlld0JveD0iMCAwIDI0IDI0IiBmaWxsPSJub25lIiBzdHJva2U9IiNmZmZmZmYiIHN0cm9rZS13aWR0aD0iMiIgc3Ryb2tlLWxpbmVjYXA9InJvdW5kIiBzdHJva2UtbGluZWpvaW49InJvdW5kIiBjbGFzcz0iaWNvbiBpY29uLXRhYmxlciBpY29ucy10YWJsZXItb3V0bGluZSBpY29uLXRhYmxlci1tYWlsIj48cGF0aCBzdHJva2U9Im5vbmUiIGQ9Ik0wIDBoMjR2MjRIMHoiIGZpbGw9Im5vbmUiLz48cGF0aCBkPSJNMyA3YTIgMiAwIDAgMSAyIC0yaDE0YTIgMiAwIDAgMSAyIDJ2MTBhMiAyIDAgMCAxIC0yIDJoLTE0YTIgMiAwIDAgMSAtMiAtMnYtMTB6IiAvPjxwYXRoIGQ9Ik0zIDdsOSA2bDkgLTYiIC8+PC9zdmc+Cg==)](https://lists.sr.ht/~kerrick/ratatui_ruby-announce)
15
-
16
-
17
- ## Introduction
18
-
19
- **rooibos** is a gem in the [RatatuiRuby ecosystem](https://sr.ht/~kerrick/ratatui_ruby/).
20
- **ratatui_ruby** is a community wrapper that is not affiliated with [the Ratatui team](https://github.com/orgs/ratatui/people).
21
-
22
- > [!WARNING]
23
- > **rooibos** is currently in **BETA**. The API may change with minor versions.
24
-
25
- **[Why RatatuiRuby?](https://man.sr.ht/~kerrick/ratatui_ruby/why.md)** — Native Rust performance, zero runtime overhead, and Ruby's expressiveness. [See how we compare](https://man.sr.ht/~kerrick/ratatui_ruby/why.md) to CharmRuby, raw Rust, and Go.
26
-
27
- Please join the **announce** mailing list at https://lists.sr.ht/~kerrick/ratatui_ruby-announce to stay up-to-date on new releases and announcements. See the [`trunk` branch](https://git.sr.ht/~kerrick/rooibos/tree/trunk) for pre-release updates.
28
-
29
- ---
30
-
31
- ## Quick Links
32
-
33
- ### The Ecosystem
34
-
35
- **RatatuiRuby:** [Core engine](https://git.sr.ht/~kerrick/ratatui_ruby) • **Tea:** [MVU architecture](https://git.sr.ht/~kerrick/rooibos) • **Kit:** [Component architecture](https://git.sr.ht/~kerrick/ratatui_ruby-kit) (Planned) • **DSL:** [Glimmer syntax](https://sr.ht/~kerrick/ratatui_ruby/#chapter-4-the-syntax) (Planned) • **Framework:** [Omakase framework](https://git.sr.ht/~kerrick/ratatui_ruby-framework) (Planned) • **UI:** [Polished widgets](https://git.sr.ht/~kerrick/ratatui_ruby-ui) (Planned) • **UI Pro:** [More polished widgets](https://sr.ht/~kerrick/ratatui_ruby#chapter-6-licensing) (Planned)
36
-
37
- ### For App Developers
38
-
39
- **Get Started:** [Quickstart](https://git.sr.ht/~kerrick/ratatui_ruby/tree/stable/item/doc/getting_started/quickstart.md) • [Examples](https://git.sr.ht/~kerrick/ratatui_ruby/tree/stable/item/examples) ⸺ **Stay Informed:** [Announce List](https://lists.sr.ht/~kerrick/ratatui_ruby-announce) • [FAQ](https://man.sr.ht/~kerrick/ratatui_ruby/troubleshooting.md) ⸺ **Reach Out:** [Discuss List](https://lists.sr.ht/~kerrick/ratatui_ruby-discuss) • [Bug Tracker](https://todo.sr.ht/~kerrick/ratatui_ruby)
40
-
41
- ### For Contributors
42
-
43
- **Get Started:** [Contributing Guide](https://man.sr.ht/~kerrick/ratatui_ruby/contributing.md) • [Code of Conduct](https://man.sr.ht/~kerrick/ratatui_ruby/code_of_conduct.md) ⸺ **Stay Informed:** [Announce List](https://lists.sr.ht/~kerrick/ratatui_ruby-announce) • [Project History](https://man.sr.ht/~kerrick/ratatui_ruby/history/index.md) ⸺ **Reach Out:** [Development List](https://lists.sr.ht/~kerrick/ratatui_ruby-devel) • [Bug Tracker](https://todo.sr.ht/~kerrick/ratatui_ruby)
44
-
45
- ---
46
-
47
- ## Compatibility
48
-
49
- **rooibos** is designed to run on [everything Ruby does](https://www.ruby-lang.org/en/documentation/installation/), including:
50
-
51
- - GNU/Linux, macOS, Windows, OpenBSD, and FreeBSD; and
52
- - x86_64 (AMD, Intel) and ARM (Apple Silicon, Raspberry Pi).
53
-
54
- We support the latest minor version of every
55
- [non-eol Ruby version](https://www.ruby-lang.org/en/downloads/branches/),
56
- including Ruby 4.
57
-
58
-
59
- ## Installation
60
-
61
- Add this line to your application's Gemfile:
62
-
63
- <!-- SPDX-SnippetBegin -->
64
- <!--
65
- SPDX-FileCopyrightText: 2026 Kerrick Long
66
- SPDX-License-Identifier: MIT-0
67
- -->
68
- ```ruby
69
- gem "rooibos"
70
- ```
71
- <!-- SPDX-SnippetEnd -->
72
-
73
- And then execute:
74
-
75
- <!-- SPDX-SnippetBegin -->
76
- <!--
77
- SPDX-FileCopyrightText: 2026 Kerrick Long
78
- SPDX-License-Identifier: MIT-0
79
- -->
80
- ```bash
81
- bundle install
82
- ```
83
- <!-- SPDX-SnippetEnd -->
84
-
85
- Or install it yourself with:
86
-
87
- <!-- SPDX-SnippetBegin -->
88
- <!--
89
- SPDX-FileCopyrightText: 2026 Kerrick Long
90
- SPDX-License-Identifier: MIT-0
91
- -->
92
- ```bash
93
- gem install rooibos
94
- ```
95
- <!-- SPDX-SnippetEnd -->
96
-
97
-
98
- ## Usage
99
-
100
- **rooibos** uses the Model-View-Update (MVU) pattern. You provide an immutable model, a view function, and an update function.
101
-
102
- <!-- SPDX-SnippetBegin -->
103
- <!--
104
- SPDX-FileCopyrightText: 2026 Kerrick Long
105
- SPDX-License-Identifier: MIT-0
106
- -->
107
- <!-- SYNC:START:examples/verify_readme_usage/app.rb:mvu -->
108
- ```ruby
109
- Model = Data.define(:text)
110
-
111
- Init = -> do
112
- Model.new(text: "Hello, Ratatui! Press 'q' to quit.")
113
- end
114
-
115
- View = -> (model, tui) do
116
- tui.paragraph(
117
- text: model.text,
118
- alignment: :center,
119
- block: tui.block(
120
- title: "My Ruby TUI App",
121
- borders: [:all],
122
- border_style: { fg: "cyan" }
123
- )
124
- )
125
- end
126
-
127
- Update = -> (msg, model) do
128
- if msg.q? || msg.ctrl_c?
129
- Rooibos::Command.exit
130
- else
131
- model
132
- end
133
- end
134
-
135
- def run
136
- Rooibos.run(VerifyReadmeUsage)
137
- end
138
- ```
139
- <!-- SYNC:END -->
140
- <!-- SPDX-SnippetEnd -->
141
-
142
- ![Hello Ratatui](./doc/images/verify_readme_usage.png)
143
-
144
- For a full tutorial, see [the Quickstart](./doc/getting_started/quickstart.md). For an explanation of the application architecture, see [Application Architecture](./doc/concepts/application_architecture.md).
145
-
146
-
147
- ## Features
148
-
149
- _Because this gem is in alpha, it lacks documentation. Please check the source files._
150
-
151
-
152
- ## Documentation
153
-
154
- | Resource | Description |
155
- |----------|-------------|
156
- | [Quickstart](./doc/getting_started/quickstart.md) | Get running in 5 minutes |
157
- | [Application Architecture](./doc/concepts/application_architecture.md) | Patterns for scaling your app |
158
- | [Guides](./doc/index.md) | Tutorials, examples, and more |
159
- | API Reference | To generate full RDoc documentation, run `bundle exec rake rdoc` |
160
- | [Wiki](https://man.sr.ht/~kerrick/ratatui_ruby) | Learn more about the RatatuiRuby ecosystem |
161
-
162
-
163
- ## Contributing
164
-
165
- Bug reports and pull requests are welcome on [sourcehut](https://sourcehut.org) at https://sr.ht/~kerrick/ratatui_ruby/. This project is intended to be a safe, productive collaboration, and contributors are expected to adhere to the [Code of Conduct](https://man.sr.ht/~kerrick/ratatui_ruby/code_of_conduct.md).
166
-
167
-
168
- Want to help develop **rooibos**? Check out the [contribution guide on the wiki](https://man.sr.ht/~kerrick/ratatui_ruby/contributing.md).
169
-
170
- **Note**: Active development happens on the `trunk` branch. Use `trunk` if you are a contributor or want the latest cutting-edge features. `stable` is for stable releases only.
171
-
172
-
173
- ## Copyright & License
174
-
175
- **rooibos** is copyright 2026, Kerrick Long.
176
-
177
- The library is [LGPL-3.0-or-later](./LICENSES/LGPL-3.0-or-later.txt): you can use it in proprietary applications, but you must share changes you make to **rooibos** itself. Documentation snippets and widget examples are [MIT-0](./LICENSES/MIT-0.txt): copy and use them without attribution.
178
-
179
- Documentation is [CC-BY-SA-4.0](./LICENSES/CC-BY-SA-4.0.txt). Build tooling and full app examples are [LGPL-3.0-or-later](./LICENSES/LGPL-3.0-or-later.txt). See each file's SPDX comment for specifics.
180
-
181
- Some parts of this program are copied from other sources under appropriate reuse licenses, and the copyright belongs to their respective owners. See the [REUSE Specification – Version 3.3](https://reuse.software/spec-3.3/) for details.
182
-
183
- This program was created with significant assistance from multiple LLMs. The process was human-controlled through creative prompts, with human contributions to each commit. See commit footers for model attribution. [declare-ai.org](https://declare-ai.org/1.0.0/creative.html)
data/README.rdoc DELETED
@@ -1,374 +0,0 @@
1
- == Confidently Build Terminal Apps
2
-
3
- Rooibos[https://rooibos.run] helps you build interactive terminal applications.
4
- Keep your code understandable and testable as it scales. Rooibos handles
5
- keyboard, mouse, and async work so you can focus on behavior and user experience.
6
-
7
- gem install rooibos
8
-
9
- <i>Currently in beta. APIs may change before 1.0.</i>
10
-
11
- === Get Started in Seconds
12
-
13
- rooibos new my_app
14
- cd my_app
15
- rooibos run
16
-
17
- That's it. You have a working app with keyboard navigation, mouse support,
18
- and clickable buttons. Open <tt>lib/my_app.rb</tt> to make it your own.
19
-
20
-
21
- ---
22
-
23
- === The Pattern
24
-
25
- \Rooibos uses Model-View-Update, the architecture behind
26
- Elm[https://guide.elm-lang.org/architecture/],
27
- Redux[https://redux.js.org/], and {Bubble
28
- Tea}[https://github.com/charmbracelet/bubbletea].
29
- State lives in one place. Updates flow in one direction. The runtime handles
30
- rendering and runs background work for you.
31
-
32
- ---
33
-
34
- === Hello, MVU
35
-
36
- The simplest \Rooibos app. Press any key to increment the counter. Press
37
- <tt>Ctrl</tt>+<tt>C</tt> to quit.
38
-
39
- require "rooibos"
40
-
41
- module Counter
42
- # Init: How do you create the initial model?
43
- Init = -> { 0 }
44
-
45
- # View: What does the user see?
46
- View = -> (model, tui) { tui.paragraph(text: <<~END) }
47
- Current count: #{model}.
48
- Press any key to increment.
49
- Press Ctrl+C to quit.
50
- END
51
-
52
- # Update: What happens when things change?
53
- Update = -> (message, model) {
54
- if message.ctrl_c?
55
- Rooibos::Command.exit
56
- elsif message.key?
57
- model + 1
58
- end
59
- }
60
- end
61
-
62
- Rooibos.run(Counter)
63
-
64
- That's the whole pattern: Model holds state, Init creates it, View renders it,
65
- and Update changes it. The runtime handles everything else.
66
-
67
-
68
- ---
69
-
70
- === Your First Real Application
71
-
72
- A file browser in sixty lines. It opens files, navigates directories, handles
73
- errors, styles directories and hidden files differently, and supports vim-style
74
- keyboard shortcuts. If you can do this much with this little code, imagine how
75
- easy _your_ app will be to build.
76
-
77
- require "rooibos"
78
-
79
- module FileBrowser
80
- # Model: What state does your app need?
81
- Model = Data.define(:path, :entries, :selected, :error)
82
-
83
- Init = -> {
84
- path = Dir.pwd
85
- entries = Entries[path]
86
- Ractor.make_shareable( # Ensures thread safety
87
- Model.new(path:, entries:, selected: entries.first, error: nil))
88
- }
89
-
90
- View = -> (model, tui) {
91
- tui.block(
92
- titles: [model.error || model.path,
93
- { content: KEYS, position: :bottom, alignment: :right}],
94
- borders: [:all],
95
- border_style: if model.error then tui.style(fg: :red) else nil end,
96
- children: [tui.list(items: model.entries.map(&ListItem[model, tui]),
97
- selected_index: model.entries.index(model.selected),
98
- highlight_symbol: "",
99
- highlight_style: tui.style(modifiers: [:reversed]))]
100
- )
101
- }
102
-
103
- Update = -> (message, model) {
104
- return model.with(error: ERROR) if message.error?
105
- model = model.with(error: nil) if model.error && message.key?
106
-
107
- if message.ctrl_c? || message.q? then Rooibos::Command.exit
108
- elsif message.home? || message.g? then model.with(selected: model.entries.first)
109
- elsif message.end? || message.G? then model.with(selected: model.entries.last)
110
- elsif message.up_arrow? || message.k? then Select[:-, model]
111
- elsif message.down_arrow? || message.j? then Select[:+, model]
112
- elsif message.enter? then Open[model]
113
- elsif message.escape? then Navigate[File.dirname(model.path), model]
114
- end
115
- }
116
-
117
- private # Lines below this are implementation details
118
-
119
- KEYS = "↑/↓/Home/End: Select | Enter: Open | Esc: Navigate Up | q: Quit"
120
- ERROR = "Sorry, opening the selected file failed."
121
-
122
- ListItem = -> (model, tui) { -> (name) {
123
- modifiers = name.start_with?(".") ? [:dim] : []
124
- fg = :blue if name.end_with?("/")
125
- tui.list_item(content: name, style: tui.style(fg:, modifiers:))
126
- } }
127
-
128
- Select = -> (operator, model) {
129
- new_index = model.entries.index(model.selected).public_send(operator, 1)
130
- model.with(selected: model.entries[new_index.clamp(0, model.entries.length - 1)])
131
- }
132
-
133
- Open = -> (model) {
134
- full = File.join(model.path, model.selected.delete_suffix("/"))
135
- model.selected.end_with?("/") ? Navigate[full, model] : Rooibos::Command.open(full)
136
- }
137
-
138
- Navigate = -> (path, model) {
139
- entries = Entries[path]
140
- model.with(path:, entries:, selected: entries.first, error: nil)
141
- }
142
-
143
- Entries = -> (path) {
144
- Dir.children(path).map { |name|
145
- File.directory?(File.join(path, name)) ? "#{name}/" : name
146
- }.sort_by { |name| [name.end_with?("/") ? 0 : 1, name.downcase] }
147
- }
148
- end
149
-
150
- Rooibos.run(FileBrowser)
151
-
152
-
153
- ---
154
-
155
- === Batteries Included
156
-
157
- ==== Commands
158
-
159
- Applications fetch data, run shell commands, and set timers. \Rooibos Commands
160
- run off the main thread and send results back as messages.
161
-
162
- <b>HTTP requests:</b>
163
-
164
- Update = -> (message, model) {
165
- case message
166
- in :fetch_users
167
- [model.with(loading: true), Rooibos::Command.http(:get, "/api/users", :got_users)]
168
- in { type: :http, envelope: :got_users, status: 200, body: }
169
- model.with(loading: false, users: JSON.parse(body))
170
- in { type: :http, envelope: :got_users, status: }
171
- model.with(error: "HTTP #{status}")
172
- end
173
- }
174
-
175
- <b>Shell commands:</b>
176
-
177
- Update = -> (message, model) {
178
- case message
179
- in :list_files
180
- Rooibos::Command.system("ls -la", :listed_files)
181
- in { type: :system, envelope: :listed_files, stdout:, status: 0 }
182
- model.with(files: stdout.lines.map(&:chomp))
183
- in { type: :system, envelope: :listed_files, stderr:, status: }
184
- model.with(error: stderr)
185
- end
186
- }
187
-
188
- <b>Timers:</b>
189
-
190
- Update = -> (message, model) {
191
- case message
192
- in { type: :timer, envelope: :tick, elapsed: }
193
- [model.with(frame: model.frame + 1), Rooibos::Command.wait(1.0 / 24, :tick)]
194
- end
195
- }
196
-
197
- <b>And more!</b> \Rooibos includes <tt>all</tt>, <tt>batch</tt>, <tt>cancel</tt>,
198
- <tt>custom</tt>, <tt>exit</tt>, <tt>http</tt>, <tt>map</tt>, <tt>open</tt>,
199
- <tt>system</tt>, <tt>tick</tt>, and <tt>wait</tt> commands. You can also define
200
- your own custom commands for complex orchestration.
201
-
202
- Every command produces a message, and Update handles it the same way.
203
-
204
- ==== Testing
205
-
206
- \Rooibos makes TUIs so easy to test, you'll save more time by writing tests than
207
- by not testing.
208
-
209
- <b>Unit test Update, View, and Init.</b> No terminal needed. Test helpers included.
210
-
211
- def test_moves_selection_down_with_j
212
- model = Ractor.make_shareable(FileBrowser::Model.new(
213
- path: "/", entries: %w[bin exe lib], selected: "bin", error: nil))
214
- message = RatatuiRuby::Event::Key.new(code: "j")
215
-
216
- result = FileBrowser::Update.call(message, model)
217
-
218
- assert_equal "exe", result.selected
219
- end
220
-
221
- <b>Style assertions.</b> Draw to a headless terminal, verify colors and modifiers.
222
-
223
- def test_directories_are_blue
224
- with_test_terminal(60, 10) do
225
- model = Ractor.make_shareable(FileBrowser::Model.new(
226
- path: "/", entries: %w[file.txt subdir/], selected: "file.txt", error: nil))
227
- widget = FileBrowser::View.call(model, RatatuiRuby::TUI.new)
228
-
229
- RatatuiRuby.draw { |frame| frame.render_widget(widget, frame.area) }
230
-
231
- assert_blue(1, 2) # "subdir/" at column 1, row 2
232
- end
233
- end
234
-
235
- <b>System tests.</b> Inject events, run the full app, snapshot the result.
236
-
237
- def test_selection_moves_down
238
- with_test_terminal(120, 30) do
239
- Dir.mktmpdir do |dir|
240
- FileUtils.touch(File.join(dir, "a"))
241
- FileUtils.touch(File.join(dir, "b"))
242
- FileUtils.touch(File.join(dir, "c"))
243
-
244
- inject_key(:down)
245
- inject_key(:ctrl_c)
246
-
247
- # Tests use explicit params to inject deterministic initial state.
248
- Rooibos.run(
249
- model: Ractor.make_shareable(FileBrowser::Model.new(
250
- path: dir, entries: %w[a b c], selected: "a", error: nil)),
251
- view: FileBrowser::View,
252
- update: FileBrowser::Update
253
- )
254
-
255
- assert_snapshots("selection_moved_down") do |lines|
256
- title = "┌/tmp/test#{'─' * 107}┐"
257
- lines.map do |l|
258
- l.gsub(/┌#{Regexp.escape(dir)}[^┐]*┐/, title)
259
- end
260
- end
261
- end
262
- end
263
- end
264
-
265
- Snapshots record both plain text and ANSI colors. Normalization blocks mask
266
- dynamic content (timestamps, temp paths) for cross-platform reproducibility.
267
- Run <tt>UPDATE_SNAPSHOTS=1 rake test</tt> to regenerate baselines.
268
-
269
- ==== Scale Up
270
-
271
- Large applications decompose into fragments. Each fragment has its own Model,
272
- View, Update, and Init. Parents compose children. The pattern scales.
273
-
274
- The Router DSL eliminates boilerplate:
275
-
276
- module Dashboard
277
- include Rooibos::Router
278
-
279
- route :stats, to: StatsPanel
280
- route :network, to: NetworkPanel
281
-
282
- keymap do
283
- key :ctrl_c, -> { Rooibos::Command.exit }
284
- only when: -> (model) { !model.modal_open } do
285
- key :q, -> { Rooibos::Command.exit }
286
- key :s, -> { StatsPanel.fetch_command }
287
- key :p, -> { NetworkPanel.ping_command }
288
- end
289
- end
290
-
291
- Update = from_router
292
-
293
- # ... Model, Init, View below
294
- end
295
-
296
- Declare routes and keymaps. The router generates Update for you. Use guards to
297
- ignore keys when needed.
298
-
299
- ==== CLI
300
-
301
- The <tt>rooibos</tt> command scaffolds projects and runs applications.
302
-
303
- rooibos new my_app # Generate project structure
304
- rooibos run # Run the app in current directory
305
-
306
- Generated apps include tests, type signatures, and a working welcome
307
- screen with keyboard and mouse support.
308
-
309
-
310
- ---
311
-
312
- === The Ecosystem
313
-
314
- \Rooibos builds on RatatuiRuby[https://www.ratatui-ruby.dev], a Rubygem built on
315
- Ratatui[https://ratatui.rs]. You get native performance with the joy of Ruby.
316
- \Rooibos is one way to manage state and composition. Kit is another.
317
-
318
- ==== Rooibos[https://git.sr.ht/~kerrick/rooibos]
319
-
320
- Model-View-Update architecture. Inspired by Elm, Bubble Tea, and React +
321
- Redux. Your UI is a pure function of state.
322
-
323
- - Functional programming with MVU
324
- - Commands work off the main thread
325
- - Messages, not callbacks, drive updates
326
-
327
- ==== {Kit}[https://sr.ht/~kerrick/ratatui_ruby/#chapter-3-the-object-path--kit] (Coming Soon)
328
-
329
- Component-based architecture. Encapsulate state, input handling, and
330
- rendering in reusable pieces.
331
-
332
- - OOP with stateful components
333
- - Separate UI state from domain logic
334
- - Built-in focus management & click handling
335
-
336
- Both use the same widget library and rendering engine. Pick the paradigm
337
- that fits your brain.
338
-
339
-
340
- ---
341
-
342
- === Links
343
-
344
- [Get Started]
345
- {Getting Started}[https://git.sr.ht/~kerrick/rooibos/tree/trunk/item/doc/getting_started/index.md],
346
- {Tutorial}[https://git.sr.ht/~kerrick/rooibos/tree/trunk/item/doc/tutorial/index.md],
347
- {Examples}[https://git.sr.ht/~kerrick/rooibos/tree/trunk/item/examples]
348
-
349
- [Coming From...]
350
- {React/Redux}[https://git.sr.ht/~kerrick/rooibos/tree/trunk/item/doc/getting_started/for_react_developers.md],
351
- {BubbleTea}[https://git.sr.ht/~kerrick/rooibos/tree/trunk/item/doc/getting_started/for_go_developers.md],
352
- {Textual}[https://git.sr.ht/~kerrick/rooibos/tree/trunk/item/doc/getting_started/for_python_developers.md]
353
-
354
- [Learn More]
355
- {Essentials}[https://git.sr.ht/~kerrick/rooibos/tree/trunk/item/doc/essentials/index.md],
356
- {Scaling Up}[https://git.sr.ht/~kerrick/rooibos/tree/trunk/item/doc/scaling_up/index.md],
357
- {Best Practices}[https://git.sr.ht/~kerrick/rooibos/tree/trunk/item/doc/best_practices/index.md],
358
- {Troubleshooting}[https://git.sr.ht/~kerrick/rooibos/tree/trunk/item/doc/troubleshooting/index.md]
359
-
360
- [Community]
361
- {Discuss}[https://lists.sr.ht/~kerrick/ratatui_ruby-discuss],
362
- {Announcements}[https://lists.sr.ht/~kerrick/ratatui_ruby-announce],
363
- {Bug Tracker}[https://todo.sr.ht/~kerrick/ratatui_ruby],
364
- {Contribution Guide}[https://man.sr.ht/~kerrick/ratatui_ruby/contributing.md],
365
- {Code of Conduct}[https://man.sr.ht/~kerrick/ratatui_ruby/code_of_conduct.md]
366
-
367
-
368
- ---
369
-
370
- [Website] https://rooibos.run
371
- [Source] https://git.sr.ht/~kerrick/rooibos
372
- [RubyGems] https://rubygems.org/gems/rooibos
373
-
374
- © 2026 Kerrick Long · Library: LGPL-3.0-or-later · Website: CC-BY-NC-ND-4.0 · Snippets: MIT-0
data/Rakefile DELETED
@@ -1,16 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- #--
4
- # SPDX-FileCopyrightText: 2026 Kerrick Long <me@kerricklong.com>
5
- # SPDX-License-Identifier: LGPL-3.0-or-later
6
- #++
7
-
8
- require "bundler/gem_tasks"
9
- require "ratatui_ruby/devtools"
10
-
11
- RatatuiRuby::Devtools.install!
12
-
13
- # Import project-specific tasks
14
- Dir.glob("tasks/*.rake").each { |r| import r }
15
-
16
- task default: %w[lint:fix install:force test lint reuse steep]
data/Steepfile DELETED
@@ -1,13 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- # SPDX-FileCopyrightText: 2026 Kerrick Long <me@kerricklong.com>
4
- # SPDX-License-Identifier: LGPL-3.0-or-later
5
-
6
- target :lib do
7
- signature "sig"
8
- check "lib"
9
-
10
- library "open3"
11
-
12
- collection_config "rbs_collection.yaml"
13
- end
@@ -1,20 +0,0 @@
1
- <!--
2
- SPDX-FileCopyrightText: 2026 Kerrick Long <me@kerricklong.com>
3
- SPDX-License-Identifier: CC-BY-SA-4.0
4
- -->
5
-
6
- # Forms and Validation
7
-
8
-
9
- By the end of this guide, you will:
10
-
11
- - Collect multi-field user input in your Model
12
- - Validate input and store error messages
13
- - Display inline validation feedback
14
- - Submit form data via Commands
15
-
16
- > ⚠️ **This page is a stub.** Help us write it! See the [Documentation Plan](../contributors/documentation_plan.md) and [Style Guide](../contributors/documentation_style.md).
17
-
18
- ---
19
-
20
- **Best Practices:** [Modal Dialogs](./modal_dialogs.md) | [Lists and Tables](./lists_and_tables.md) | [HTTP Workflows](./http_workflows.md) | [Streaming Data](./streaming_data.md) | [Orchestration](./orchestration.md)
@@ -1,20 +0,0 @@
1
- <!--
2
- SPDX-FileCopyrightText: 2026 Kerrick Long <me@kerricklong.com>
3
- SPDX-License-Identifier: CC-BY-SA-4.0
4
- -->
5
-
6
- # HTTP Workflows
7
-
8
-
9
- By the end of this guide, you will:
10
-
11
- - Model loading/success/error states for HTTP requests
12
- - Implement retry logic with exponential backoff
13
- - Cache responses to avoid redundant fetches
14
- - Handle offline/error states gracefully
15
-
16
- > ⚠️ **This page is a stub.** Help us write it! See the [Documentation Plan](../contributors/documentation_plan.md) and [Style Guide](../contributors/documentation_style.md).
17
-
18
- ---
19
-
20
- **Best Practices:** [Modal Dialogs](./modal_dialogs.md) | [Forms and Validation](./forms_and_validation.md) | [Lists and Tables](./lists_and_tables.md) | [Streaming Data](./streaming_data.md) | [Orchestration](./orchestration.md)
@@ -1,26 +0,0 @@
1
- <!--
2
- SPDX-FileCopyrightText: 2026 Kerrick Long <me@kerricklong.com>
3
- SPDX-License-Identifier: CC-BY-SA-4.0
4
- -->
5
-
6
- # Best Practices
7
-
8
- Common UI patterns and recipes for Rooibos applications.
9
-
10
- ---
11
-
12
- ## UI Patterns
13
-
14
- - [**Modal Dialogs**](./modal_dialogs.md) — Overlays, focus capture, result routing
15
- - [**Forms and Validation**](./forms_and_validation.md) — Multi-field input, error display
16
- - [**Lists and Tables**](./lists_and_tables.md) — Scrolling, selection, pagination
17
-
18
- ## Data Patterns
19
-
20
- - [**HTTP Workflows**](./http_workflows.md) — Loading states, retries, caching
21
- - [**Streaming Data**](./streaming_data.md) — SSE, websockets, incremental updates
22
- - [**Orchestration**](./orchestration.md) — Parallel commands, sequential flows
23
-
24
- ---
25
-
26
- **Having trouble?** Check out [Troubleshooting](../troubleshooting/common_errors.md).
@@ -1,20 +0,0 @@
1
- <!--
2
- SPDX-FileCopyrightText: 2026 Kerrick Long <me@kerricklong.com>
3
- SPDX-License-Identifier: CC-BY-SA-4.0
4
- -->
5
-
6
- # Lists and Tables
7
-
8
-
9
- By the end of this guide, you will:
10
-
11
- - Implement keyboard-navigable scrolling lists
12
- - Track selection state in your Model
13
- - Support pagination for large datasets
14
- - Link to RatatuiRuby List and Table widgets
15
-
16
- > ⚠️ **This page is a stub.** Help us write it! See the [Documentation Plan](../contributors/documentation_plan.md) and [Style Guide](../contributors/documentation_style.md).
17
-
18
- ---
19
-
20
- **Best Practices:** [Modal Dialogs](./modal_dialogs.md) | [Forms and Validation](./forms_and_validation.md) | [HTTP Workflows](./http_workflows.md) | [Streaming Data](./streaming_data.md) | [Orchestration](./orchestration.md)