rooibos 0.5.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.
- checksums.yaml +7 -0
- data/.builds/ruby-3.2.yml +51 -0
- data/.builds/ruby-3.3.yml +51 -0
- data/.builds/ruby-3.4.yml +51 -0
- data/.builds/ruby-4.0.0.yml +51 -0
- data/.pre-commit-config.yaml +16 -0
- data/.rubocop.yml +8 -0
- data/AGENTS.md +108 -0
- data/CHANGELOG.md +214 -0
- data/LICENSE +304 -0
- data/LICENSES/AGPL-3.0-or-later.txt +235 -0
- data/LICENSES/CC-BY-SA-4.0.txt +170 -0
- data/LICENSES/CC0-1.0.txt +121 -0
- data/LICENSES/LGPL-3.0-or-later.txt +304 -0
- data/LICENSES/MIT-0.txt +16 -0
- data/LICENSES/MIT.txt +18 -0
- data/README.md +183 -0
- data/REUSE.toml +24 -0
- data/Rakefile +16 -0
- data/Steepfile +13 -0
- data/doc/concepts/application_architecture.md +197 -0
- data/doc/concepts/application_testing.md +49 -0
- data/doc/concepts/async_work.md +164 -0
- data/doc/concepts/commands.md +530 -0
- data/doc/concepts/message_processing.md +51 -0
- data/doc/contributors/WIP/decomposition_strategies_analysis.md +258 -0
- data/doc/contributors/WIP/implementation_plan.md +409 -0
- data/doc/contributors/WIP/init_callable_proposal.md +344 -0
- data/doc/contributors/WIP/mvu_tea_implementations_research.md +373 -0
- data/doc/contributors/WIP/runtime_refactoring_status.md +47 -0
- data/doc/contributors/WIP/task.md +36 -0
- data/doc/contributors/WIP/v0.4.0_todo.md +468 -0
- data/doc/contributors/design/commands_and_outlets.md +214 -0
- data/doc/contributors/kit-no-outlet.md +238 -0
- data/doc/contributors/priorities.md +38 -0
- data/doc/custom.css +22 -0
- data/doc/getting_started/quickstart.md +56 -0
- data/doc/images/.gitkeep +0 -0
- data/doc/images/verify_readme_usage.png +0 -0
- data/doc/images/widget_cmd_exec.png +0 -0
- data/doc/index.md +25 -0
- data/examples/app_fractal_dashboard/README.md +60 -0
- data/examples/app_fractal_dashboard/app.rb +63 -0
- data/examples/app_fractal_dashboard/dashboard/base.rb +73 -0
- data/examples/app_fractal_dashboard/dashboard/update_helpers.rb +86 -0
- data/examples/app_fractal_dashboard/dashboard/update_manual.rb +87 -0
- data/examples/app_fractal_dashboard/dashboard/update_router.rb +43 -0
- data/examples/app_fractal_dashboard/fragments/custom_shell_input.rb +81 -0
- data/examples/app_fractal_dashboard/fragments/custom_shell_modal.rb +82 -0
- data/examples/app_fractal_dashboard/fragments/custom_shell_output.rb +90 -0
- data/examples/app_fractal_dashboard/fragments/disk_usage.rb +47 -0
- data/examples/app_fractal_dashboard/fragments/network_panel.rb +45 -0
- data/examples/app_fractal_dashboard/fragments/ping.rb +47 -0
- data/examples/app_fractal_dashboard/fragments/stats_panel.rb +45 -0
- data/examples/app_fractal_dashboard/fragments/system_info.rb +47 -0
- data/examples/app_fractal_dashboard/fragments/uptime.rb +47 -0
- data/examples/verify_readme_usage/README.md +54 -0
- data/examples/verify_readme_usage/app.rb +47 -0
- data/examples/widget_command_system/README.md +70 -0
- data/examples/widget_command_system/app.rb +132 -0
- data/exe/.gitkeep +0 -0
- data/lib/rooibos/command/all.rb +69 -0
- data/lib/rooibos/command/batch.rb +77 -0
- data/lib/rooibos/command/custom.rb +104 -0
- data/lib/rooibos/command/http.rb +192 -0
- data/lib/rooibos/command/lifecycle.rb +134 -0
- data/lib/rooibos/command/outlet.rb +157 -0
- data/lib/rooibos/command/wait.rb +80 -0
- data/lib/rooibos/command.rb +546 -0
- data/lib/rooibos/error.rb +55 -0
- data/lib/rooibos/message/all.rb +45 -0
- data/lib/rooibos/message/http_response.rb +61 -0
- data/lib/rooibos/message/system/batch.rb +61 -0
- data/lib/rooibos/message/system/stream.rb +67 -0
- data/lib/rooibos/message/timer.rb +46 -0
- data/lib/rooibos/message.rb +38 -0
- data/lib/rooibos/router.rb +403 -0
- data/lib/rooibos/runtime.rb +396 -0
- data/lib/rooibos/shortcuts.rb +49 -0
- data/lib/rooibos/test_helper.rb +56 -0
- data/lib/rooibos/version.rb +12 -0
- data/lib/rooibos.rb +121 -0
- data/mise.toml +8 -0
- data/rbs_collection.lock.yaml +108 -0
- data/rbs_collection.yaml +15 -0
- data/sig/concurrent.rbs +72 -0
- data/sig/examples/verify_readme_usage/app.rbs +19 -0
- data/sig/examples/widget_command_system/app.rbs +26 -0
- data/sig/open3.rbs +17 -0
- data/sig/rooibos/command.rbs +265 -0
- data/sig/rooibos/error.rbs +13 -0
- data/sig/rooibos/message.rbs +121 -0
- data/sig/rooibos/router.rbs +153 -0
- data/sig/rooibos/runtime.rbs +75 -0
- data/sig/rooibos/shortcuts.rbs +16 -0
- data/sig/rooibos/test_helper.rbs +10 -0
- data/sig/rooibos/version.rbs +8 -0
- data/sig/rooibos.rbs +46 -0
- data/tasks/example_viewer.html.erb +172 -0
- data/tasks/resources/build.yml.erb +53 -0
- data/tasks/resources/index.html.erb +44 -0
- data/tasks/resources/rubies.yml +7 -0
- data/tasks/steep.rake +11 -0
- data/vendor/goodcop/base.yml +1047 -0
- metadata +241 -0
checksums.yaml
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
---
|
|
2
|
+
SHA256:
|
|
3
|
+
metadata.gz: f7a4f2a869c06e70b95a34cac8915f8d8e6543283007fd7c595692cf34bf3329
|
|
4
|
+
data.tar.gz: c8c0be8e5059b55671baa49105aa7b470dfdfa17647353f4e81ebcf06ecf7f15
|
|
5
|
+
SHA512:
|
|
6
|
+
metadata.gz: 97556fd7362f24d3d5572da7b11485456b3066bc56ef77994c2448a62085aa62d54c8503c5ffa2cea4472dd556bff1328ececb1dcb0c323cf663fdd1267ac8c9
|
|
7
|
+
data.tar.gz: c02267ab34497516ee6b6fee6daab08b72fcf26f6d4499aaf5d98162df1f063ee7eeec0464361189d3371a77434cf94d72b030289acea29cbc0d4b972691f1aa
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
# SPDX-FileCopyrightText: 2026 Kerrick Long <me@kerricklong.com>
|
|
2
|
+
# SPDX-License-Identifier: LGPL-3.0-or-later
|
|
3
|
+
|
|
4
|
+
image: archlinux
|
|
5
|
+
packages:
|
|
6
|
+
- bash
|
|
7
|
+
- base-devel
|
|
8
|
+
- curl
|
|
9
|
+
- openssl
|
|
10
|
+
- libyaml
|
|
11
|
+
- zlib
|
|
12
|
+
- readline
|
|
13
|
+
- gdbm
|
|
14
|
+
- ncurses
|
|
15
|
+
- libffi
|
|
16
|
+
- clang
|
|
17
|
+
- git
|
|
18
|
+
sources:
|
|
19
|
+
- https://git.sr.ht/~kerrick/ratatui_ruby-tea
|
|
20
|
+
tasks:
|
|
21
|
+
- setup: |
|
|
22
|
+
curl https://mise.jdx.dev/install.sh | sh
|
|
23
|
+
echo 'export PATH="$HOME/.local/bin:$PATH"' >> ~/.buildenv
|
|
24
|
+
echo 'eval "$($HOME/.local/bin/mise activate bash)"' >> ~/.buildenv
|
|
25
|
+
echo 'export LANG="en_US.UTF-8"' >> ~/.buildenv
|
|
26
|
+
echo 'export LC_ALL="en_US.UTF-8"' >> ~/.buildenv
|
|
27
|
+
echo 'export BINDGEN_EXTRA_CLANG_ARGS="-include stdbool.h"' >> ~/.buildenv
|
|
28
|
+
. ~/.buildenv
|
|
29
|
+
export CI="true"
|
|
30
|
+
cd ratatui_ruby-tea
|
|
31
|
+
sed -i 's/ruby = .*/ruby = "3.2"/' mise.toml
|
|
32
|
+
mise install
|
|
33
|
+
mise x -- pip install reuse
|
|
34
|
+
mise x -- gem install bundler:4.0.3
|
|
35
|
+
mise reshim
|
|
36
|
+
mise x -- bundle config set --local frozen 'true'
|
|
37
|
+
mise x -- bundle install
|
|
38
|
+
- test: |
|
|
39
|
+
. ~/.buildenv
|
|
40
|
+
cd ratatui_ruby-tea
|
|
41
|
+
echo "Testing Ruby 3.2"
|
|
42
|
+
mise x -- bundle exec rake test
|
|
43
|
+
- lint: |
|
|
44
|
+
. ~/.buildenv
|
|
45
|
+
cd ratatui_ruby-tea
|
|
46
|
+
echo "Linting Ruby 3.2"
|
|
47
|
+
mise x -- bundle exec rake lint
|
|
48
|
+
- package: |
|
|
49
|
+
. ~/.buildenv
|
|
50
|
+
cd ratatui_ruby-tea
|
|
51
|
+
mise x -- bundle exec rake build
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
# SPDX-FileCopyrightText: 2026 Kerrick Long <me@kerricklong.com>
|
|
2
|
+
# SPDX-License-Identifier: LGPL-3.0-or-later
|
|
3
|
+
|
|
4
|
+
image: archlinux
|
|
5
|
+
packages:
|
|
6
|
+
- bash
|
|
7
|
+
- base-devel
|
|
8
|
+
- curl
|
|
9
|
+
- openssl
|
|
10
|
+
- libyaml
|
|
11
|
+
- zlib
|
|
12
|
+
- readline
|
|
13
|
+
- gdbm
|
|
14
|
+
- ncurses
|
|
15
|
+
- libffi
|
|
16
|
+
- clang
|
|
17
|
+
- git
|
|
18
|
+
sources:
|
|
19
|
+
- https://git.sr.ht/~kerrick/ratatui_ruby-tea
|
|
20
|
+
tasks:
|
|
21
|
+
- setup: |
|
|
22
|
+
curl https://mise.jdx.dev/install.sh | sh
|
|
23
|
+
echo 'export PATH="$HOME/.local/bin:$PATH"' >> ~/.buildenv
|
|
24
|
+
echo 'eval "$($HOME/.local/bin/mise activate bash)"' >> ~/.buildenv
|
|
25
|
+
echo 'export LANG="en_US.UTF-8"' >> ~/.buildenv
|
|
26
|
+
echo 'export LC_ALL="en_US.UTF-8"' >> ~/.buildenv
|
|
27
|
+
echo 'export BINDGEN_EXTRA_CLANG_ARGS="-include stdbool.h"' >> ~/.buildenv
|
|
28
|
+
. ~/.buildenv
|
|
29
|
+
export CI="true"
|
|
30
|
+
cd ratatui_ruby-tea
|
|
31
|
+
sed -i 's/ruby = .*/ruby = "3.3"/' mise.toml
|
|
32
|
+
mise install
|
|
33
|
+
mise x -- pip install reuse
|
|
34
|
+
mise x -- gem install bundler:4.0.3
|
|
35
|
+
mise reshim
|
|
36
|
+
mise x -- bundle config set --local frozen 'true'
|
|
37
|
+
mise x -- bundle install
|
|
38
|
+
- test: |
|
|
39
|
+
. ~/.buildenv
|
|
40
|
+
cd ratatui_ruby-tea
|
|
41
|
+
echo "Testing Ruby 3.3"
|
|
42
|
+
mise x -- bundle exec rake test
|
|
43
|
+
- lint: |
|
|
44
|
+
. ~/.buildenv
|
|
45
|
+
cd ratatui_ruby-tea
|
|
46
|
+
echo "Linting Ruby 3.3"
|
|
47
|
+
mise x -- bundle exec rake lint
|
|
48
|
+
- package: |
|
|
49
|
+
. ~/.buildenv
|
|
50
|
+
cd ratatui_ruby-tea
|
|
51
|
+
mise x -- bundle exec rake build
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
# SPDX-FileCopyrightText: 2026 Kerrick Long <me@kerricklong.com>
|
|
2
|
+
# SPDX-License-Identifier: LGPL-3.0-or-later
|
|
3
|
+
|
|
4
|
+
image: archlinux
|
|
5
|
+
packages:
|
|
6
|
+
- bash
|
|
7
|
+
- base-devel
|
|
8
|
+
- curl
|
|
9
|
+
- openssl
|
|
10
|
+
- libyaml
|
|
11
|
+
- zlib
|
|
12
|
+
- readline
|
|
13
|
+
- gdbm
|
|
14
|
+
- ncurses
|
|
15
|
+
- libffi
|
|
16
|
+
- clang
|
|
17
|
+
- git
|
|
18
|
+
sources:
|
|
19
|
+
- https://git.sr.ht/~kerrick/ratatui_ruby-tea
|
|
20
|
+
tasks:
|
|
21
|
+
- setup: |
|
|
22
|
+
curl https://mise.jdx.dev/install.sh | sh
|
|
23
|
+
echo 'export PATH="$HOME/.local/bin:$PATH"' >> ~/.buildenv
|
|
24
|
+
echo 'eval "$($HOME/.local/bin/mise activate bash)"' >> ~/.buildenv
|
|
25
|
+
echo 'export LANG="en_US.UTF-8"' >> ~/.buildenv
|
|
26
|
+
echo 'export LC_ALL="en_US.UTF-8"' >> ~/.buildenv
|
|
27
|
+
echo 'export BINDGEN_EXTRA_CLANG_ARGS="-include stdbool.h"' >> ~/.buildenv
|
|
28
|
+
. ~/.buildenv
|
|
29
|
+
export CI="true"
|
|
30
|
+
cd ratatui_ruby-tea
|
|
31
|
+
sed -i 's/ruby = .*/ruby = "3.4"/' mise.toml
|
|
32
|
+
mise install
|
|
33
|
+
mise x -- pip install reuse
|
|
34
|
+
mise x -- gem install bundler:4.0.3
|
|
35
|
+
mise reshim
|
|
36
|
+
mise x -- bundle config set --local frozen 'true'
|
|
37
|
+
mise x -- bundle install
|
|
38
|
+
- test: |
|
|
39
|
+
. ~/.buildenv
|
|
40
|
+
cd ratatui_ruby-tea
|
|
41
|
+
echo "Testing Ruby 3.4"
|
|
42
|
+
mise x -- bundle exec rake test
|
|
43
|
+
- lint: |
|
|
44
|
+
. ~/.buildenv
|
|
45
|
+
cd ratatui_ruby-tea
|
|
46
|
+
echo "Linting Ruby 3.4"
|
|
47
|
+
mise x -- bundle exec rake lint
|
|
48
|
+
- package: |
|
|
49
|
+
. ~/.buildenv
|
|
50
|
+
cd ratatui_ruby-tea
|
|
51
|
+
mise x -- bundle exec rake build
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
# SPDX-FileCopyrightText: 2026 Kerrick Long <me@kerricklong.com>
|
|
2
|
+
# SPDX-License-Identifier: LGPL-3.0-or-later
|
|
3
|
+
|
|
4
|
+
image: archlinux
|
|
5
|
+
packages:
|
|
6
|
+
- bash
|
|
7
|
+
- base-devel
|
|
8
|
+
- curl
|
|
9
|
+
- openssl
|
|
10
|
+
- libyaml
|
|
11
|
+
- zlib
|
|
12
|
+
- readline
|
|
13
|
+
- gdbm
|
|
14
|
+
- ncurses
|
|
15
|
+
- libffi
|
|
16
|
+
- clang
|
|
17
|
+
- git
|
|
18
|
+
sources:
|
|
19
|
+
- https://git.sr.ht/~kerrick/ratatui_ruby-tea
|
|
20
|
+
tasks:
|
|
21
|
+
- setup: |
|
|
22
|
+
curl https://mise.jdx.dev/install.sh | sh
|
|
23
|
+
echo 'export PATH="$HOME/.local/bin:$PATH"' >> ~/.buildenv
|
|
24
|
+
echo 'eval "$($HOME/.local/bin/mise activate bash)"' >> ~/.buildenv
|
|
25
|
+
echo 'export LANG="en_US.UTF-8"' >> ~/.buildenv
|
|
26
|
+
echo 'export LC_ALL="en_US.UTF-8"' >> ~/.buildenv
|
|
27
|
+
echo 'export BINDGEN_EXTRA_CLANG_ARGS="-include stdbool.h"' >> ~/.buildenv
|
|
28
|
+
. ~/.buildenv
|
|
29
|
+
export CI="true"
|
|
30
|
+
cd ratatui_ruby-tea
|
|
31
|
+
sed -i 's/ruby = .*/ruby = "4.0.0"/' mise.toml
|
|
32
|
+
mise install
|
|
33
|
+
mise x -- pip install reuse
|
|
34
|
+
mise x -- gem install bundler:4.0.3
|
|
35
|
+
mise reshim
|
|
36
|
+
mise x -- bundle config set --local frozen 'true'
|
|
37
|
+
mise x -- bundle install
|
|
38
|
+
- test: |
|
|
39
|
+
. ~/.buildenv
|
|
40
|
+
cd ratatui_ruby-tea
|
|
41
|
+
echo "Testing Ruby 4.0.0"
|
|
42
|
+
mise x -- bundle exec rake test
|
|
43
|
+
- lint: |
|
|
44
|
+
. ~/.buildenv
|
|
45
|
+
cd ratatui_ruby-tea
|
|
46
|
+
echo "Linting Ruby 4.0.0"
|
|
47
|
+
mise x -- bundle exec rake lint
|
|
48
|
+
- package: |
|
|
49
|
+
. ~/.buildenv
|
|
50
|
+
cd ratatui_ruby-tea
|
|
51
|
+
mise x -- bundle exec rake build
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
# SPDX-FileCopyrightText: 2020 Free Software Foundation Europe e.V.
|
|
2
|
+
# SPDX-License-Identifier: CC0-1.0
|
|
3
|
+
repos:
|
|
4
|
+
- repo: local
|
|
5
|
+
hooks:
|
|
6
|
+
- id: bundle-check
|
|
7
|
+
name: Check Gemfile.lock
|
|
8
|
+
entry: bundle check
|
|
9
|
+
language: system
|
|
10
|
+
files: (Gemfile|Gemfile\.lock|rooibos\.gemspec)
|
|
11
|
+
pass_filenames: false
|
|
12
|
+
- id: rake
|
|
13
|
+
name: rake
|
|
14
|
+
entry: bundle exec rake
|
|
15
|
+
language: system
|
|
16
|
+
pass_filenames: false
|
data/.rubocop.yml
ADDED
data/AGENTS.md
ADDED
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
<!--
|
|
2
|
+
SPDX-FileCopyrightText: 2026 Kerrick Long <me@kerricklong.com>
|
|
3
|
+
SPDX-License-Identifier: CC-BY-SA-4.0
|
|
4
|
+
-->
|
|
5
|
+
|
|
6
|
+
# AGENTS.md
|
|
7
|
+
|
|
8
|
+
## Project Identity
|
|
9
|
+
|
|
10
|
+
Project Name: rooibos
|
|
11
|
+
|
|
12
|
+
Description: Part of the RatatuiRuby ecosystem.
|
|
13
|
+
|
|
14
|
+
## 1. Standards
|
|
15
|
+
|
|
16
|
+
### STRICT REQUIREMENTS
|
|
17
|
+
|
|
18
|
+
- Every file MUST begin with an SPDX-compliant header. Use `LGPL-3.0-or-later` for code; `CC-BY-SA-4.0` for documentation. `reuse annotate` can help you generate the header. **For Ruby files**, wrap SPDX comments in `#--` / `#++` to hide them from RDoc output.
|
|
19
|
+
- Every line of Ruby MUST be covered by tests that would stand up to mutation testing.
|
|
20
|
+
- Tests must be meaningful and verify specific behavior or rendering output; simply verifying that code "doesn't crash" is insufficient and unacceptable.
|
|
21
|
+
- **Pre-commit:** Use `bundle exec agent_rake` to ensure commit-readiness. See Tools for detailed instructions.
|
|
22
|
+
- **Git Pager:** ALWAYS set `PAGER=cat` for ALL `git` commands (e.g., `PAGER=cat git diff`). This is mandatory.
|
|
23
|
+
|
|
24
|
+
### Tools
|
|
25
|
+
|
|
26
|
+
- **NEVER** run `bundle exec rake` directly. **NEVER** run `bundle exec ruby -Ilib:test ...` directly.
|
|
27
|
+
- **ALWAYS use `bundle exec agent_rake`** (provided by the `ratatui_ruby-devtools` gem) for running tests, linting, or checking compilation.
|
|
28
|
+
- **Usage:**
|
|
29
|
+
- Runs default task (compile + test + lint): `bundle exec agent_rake`
|
|
30
|
+
- Runs specific task: `bundle exec agent_rake test:ruby` (for example)
|
|
31
|
+
- **Setup:** `bin/setup` must handle Bundler dependencies.
|
|
32
|
+
- **Git:** ALWAYS set `PAGER=cat` with `git`. **THIS IS CRITICAL!**
|
|
33
|
+
|
|
34
|
+
### Rooibos-Specific Vocabulary
|
|
35
|
+
|
|
36
|
+
- **BANNED WORD: "component"** — Reserved for Kit.
|
|
37
|
+
- **Avoid "widget" for Rooibos units** — "Widget" refers to Engine/Ratatui render primitives. In Rooibos, call them **fragments**.
|
|
38
|
+
- **Fragment:** A module containing `Model`, `INITIAL`, `UPDATE`, and `VIEW` constants. Fragments compose: parent fragments delegate to child fragments.
|
|
39
|
+
- Use "model", "update", "view" for the MVU pattern. Use "message" (not "msg") and "command" (not "cmd").
|
|
40
|
+
|
|
41
|
+
### Ruby Standards
|
|
42
|
+
|
|
43
|
+
- Use `Data.define` for all value objects (Ruby 3.2+).
|
|
44
|
+
- Define types in `.rbs` files. Don't use `untyped` just because it's easy; be comprehensive and accurate.
|
|
45
|
+
- Every public Ruby class/method must be documented for humans in RDoc.
|
|
46
|
+
|
|
47
|
+
## 2. Committing
|
|
48
|
+
|
|
49
|
+
- Who commits: DON'T stage (DON'T `git add`) unless explicitly instructed. DON'T commit unless explicitly instructed. DO suggest a commit message when you finish.
|
|
50
|
+
- **Format:**
|
|
51
|
+
- Format: Use [Conventional Commits](https://www.conventionalcommits.org/).
|
|
52
|
+
- Body: Explanation if necessary (wrap at 72 chars).
|
|
53
|
+
- **DON'T list the files changed or the edits made in the body.**
|
|
54
|
+
- **DON'T use markdown syntax** (no backticks, no bolding, no lists, no links).
|
|
55
|
+
|
|
56
|
+
## 3. Definition of Done (DoD)
|
|
57
|
+
|
|
58
|
+
Before considering a task complete and returning control to the user, you **MUST** ensure:
|
|
59
|
+
|
|
60
|
+
0. **Production Ready:** RBS types are complete and accurate (no `untyped`), errors are handled with good DX, documentation follows guidelines, high code quality (no "pre-existing debt" excuses).
|
|
61
|
+
1. **Default Rake Task Passes:** Run `bundle exec agent_rake` (no args). Confirm it passes with ZERO errors **or warnings**.
|
|
62
|
+
- You will save time if you run `bundle exec agent_rake rubocop:autocorrect` first.
|
|
63
|
+
- If you think the rake is looking for deleted files, STOP EVERYTHING and tell the user.
|
|
64
|
+
2. **Documentation Updated:** If public APIs or observable behavior changed, update relevant RDoc, rustdoc, `doc/` files, `README.md`, and/or `ratatui_ruby-wiki` files.
|
|
65
|
+
3. **Changelog Updated:** If public APIs, observable behavior, or gemspec dependencies have changed, update [CHANGELOG.md](CHANGELOG.md)'s **Unreleased** section.
|
|
66
|
+
4. **Commit Message Suggested:** You **MUST** ensure the final message to the user includes a suggested commit message block. This is NOT optional.
|
|
67
|
+
- You MUST also check `git log -n1` to see the current standard AI footer ("Generated with" and "Co-Authored-By") and include it in your suggested message.
|
|
68
|
+
|
|
69
|
+
## 4. Committing
|
|
70
|
+
|
|
71
|
+
- Who commits: DON'T stage (DON'T `git add`) unless explicitly instructed. DON'T commit unless explicitly instructed. DO suggest a commit message when you finish, even if not instructed..
|
|
72
|
+
- When: Before reporting the task as complete to the user, suggest the commit message.
|
|
73
|
+
- What: Consider not what you remember, but EVERYTHING in the `git diff` and `git diff --cached`.
|
|
74
|
+
- **Format:**
|
|
75
|
+
- Format: Use [Conventional Commits](https://www.conventionalcommits.org/).
|
|
76
|
+
- Body: Explanation if necessary (wrap at 72 chars).
|
|
77
|
+
- Explain why this is the implementation, as opposed to other possible implementations.
|
|
78
|
+
- Skip the body entirely if it's rote, a duplication of the diff, or otherwise unhelpful.
|
|
79
|
+
- **DON'T list the files changed or the edits made in the body.** Don't provide a bulleted list of changes. Use prose to explain the problem and the solution.
|
|
80
|
+
- **DON'T use markdown syntax** (no backticks, no bolding, no lists, no links). The commit message must be plain text.
|
|
81
|
+
- **Type conventions by directory:**
|
|
82
|
+
- `lib/`, `ext/`, `sig/`: Use `feat`, `fix`, `refactor`, `perf` as appropriate.
|
|
83
|
+
- `bin/`, `tasks/`, `.builds/`, CI/CD: Use `chore` for tooling internal to developing this gem. Use `feat`/`fix` for user-facing executables or changes that affect downstream users.
|
|
84
|
+
- `examples/`: Always `docs` (documentation by example).
|
|
85
|
+
- `test/`: Use `test` for new/changed tests, or match the type of the code being tested.
|
|
86
|
+
- `doc/`: Always `docs`.
|
|
87
|
+
|
|
88
|
+
### 5. Changelog
|
|
89
|
+
|
|
90
|
+
- Follow [Semantic Versioning](https://semver.org/)
|
|
91
|
+
- Follow the [Keep a Changelog](https://keepachangelog.com/en/1.1.0/) specification.
|
|
92
|
+
- **What belongs in CHANGELOG:** Only changes that affect **application developers** or **higher-level library developers** who use or depend on `ratatui_ruby`:
|
|
93
|
+
- New public APIs or widget parameters
|
|
94
|
+
- Backwards-incompatible type signature changes, or behavioral additions to type signature changes
|
|
95
|
+
- Observable behavior changes (rendering, styling, layout)
|
|
96
|
+
- Deprecations and removals
|
|
97
|
+
- Breaking changes
|
|
98
|
+
- **What does NOT belong in CHANGELOG:** Internal or non-behavioral changes that don't affect downstream users:
|
|
99
|
+
- Test additions or improvements
|
|
100
|
+
- Documentation updates, RDoc fixes, markdown clarifications
|
|
101
|
+
- Refactors of internal code
|
|
102
|
+
- New or modified example code
|
|
103
|
+
- Internal tooling, CI/CD, or build configuration changes
|
|
104
|
+
- Code style or linting changes
|
|
105
|
+
- Performance improvements that affect applications
|
|
106
|
+
- Changelogs should be useful to downstream developers (both app and library developers), not simple restatements of diffs or commit messages.
|
|
107
|
+
- The Unreleased section MUST be considered "since the last git tag". Therefore, if a change was done in one commit and undone in another (both since the last tag), the second commit should remove its changelog entry.
|
|
108
|
+
- **Location:** New entries ALWAYS go in `## [Unreleased]`. Never edit past version sections (e.g., `## [0.4.0]`)—those are frozen history.
|
data/CHANGELOG.md
ADDED
|
@@ -0,0 +1,214 @@
|
|
|
1
|
+
<!--
|
|
2
|
+
SPDX-FileCopyrightText: 2026 Kerrick Long <me@kerricklong.com>
|
|
3
|
+
SPDX-License-Identifier: CC-BY-SA-4.0
|
|
4
|
+
-->
|
|
5
|
+
|
|
6
|
+
# Changelog
|
|
7
|
+
|
|
8
|
+
All notable changes to this project will be documented in this file.
|
|
9
|
+
|
|
10
|
+
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
|
|
11
|
+
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
## [Unreleased]
|
|
15
|
+
|
|
16
|
+
### Added
|
|
17
|
+
|
|
18
|
+
### Changed
|
|
19
|
+
|
|
20
|
+
### Fixed
|
|
21
|
+
|
|
22
|
+
### Removed
|
|
23
|
+
|
|
24
|
+
## [0.5.0] - 2026-01-16
|
|
25
|
+
|
|
26
|
+
### Added
|
|
27
|
+
|
|
28
|
+
### Changed
|
|
29
|
+
|
|
30
|
+
- **BREAKING: Rebrand to Rooibos**: The gem is now named `rooibos` and the module is top-level `Rooibos` instead of `RatatuiRuby::Tea`. Update your code, including:
|
|
31
|
+
- `require "ratatui_ruby/tea"` → `require "rooibos"`
|
|
32
|
+
- `RatatuiRuby::Tea::*` → `Rooibos::*`
|
|
33
|
+
- If you need a full migration guide, reach out to [the mailing list](https://lists.sr.ht/~kerrick/ratatui_ruby-discuss)
|
|
34
|
+
|
|
35
|
+
### Fixed
|
|
36
|
+
|
|
37
|
+
### Removed
|
|
38
|
+
|
|
39
|
+
## [0.4.0] - 2026-01-16
|
|
40
|
+
|
|
41
|
+
### Added
|
|
42
|
+
|
|
43
|
+
- **Timer Commands**: `Command.wait(seconds, tag)` and `Command.tick(seconds, tag)` for timed events. After the duration, sends `tag` to the update function. Responds to cancellation cooperatively — sends `Command.cancel(self)` when cancelled so you can handle it. Uses `Concurrent::Cancellation.timeout` internally. `Command.tick` is an alias for `Command.wait`; the "recurring tick" pattern is achieved by re-dispatching in the update function.
|
|
44
|
+
|
|
45
|
+
- **Command.uncancellable Factory**: Creates a fresh `Concurrent::Cancellation` that never fires. Use for commands wrapping non-cancellable blocking I/O (e.g., `Net::HTTP` requests).
|
|
46
|
+
|
|
47
|
+
- **Command.batch**: Fire-and-forget parallel execution. `Command.batch(cmd1, cmd2)` or `Command.batch([cmds])` runs children in parallel; each child sends its own messages independently. On cancellation, emits `Command.cancel(self)` so you can detect the batch was stopped. Child errors surface as `Command::Error` so you can handle failures in your update function. One failing child does not stop the others. Requires all child commands to be Ractor-shareable.
|
|
48
|
+
|
|
49
|
+
- **Command.all**: Aggregating parallel execution. `Command.all(:tag, cmd1, cmd2)` or `Command.all(:tag, [cmds])` runs children in parallel and waits for all to complete, then sends a single aggregated message. Array syntax produces `[:tag, [results]]`; variadic syntax splats results as `[:tag, result1, result2]`. On cancellation, emits `Command.cancel(self)`. Child errors surface as `Command::Error`. Requires all child commands to be Ractor-shareable.
|
|
50
|
+
|
|
51
|
+
- **Outlet#source**: Command composition for multi-step workflows. `out.source(child_command, token, timeout: 30.0)` runs a child command synchronously within a custom command, returning its result (or `nil` if cancelled/timed out). Exceptions from failed children propagate to the caller. Use this to orchestrate sequential API calls, conditional fetches, or any workflow that needs one result before starting the next.
|
|
52
|
+
|
|
53
|
+
- **Command.http**: Native HTTP client for API calls. Supports GET, POST, PUT, PATCH, DELETE with DWIM syntax: `Command.http(get: 'url')`, `Command.http(:get, 'url', :tag)`, etc. Returns hash-based `HttpResponse` with `deconstruct_keys` for pattern matching: `{ type: :http, envelope:, status:, body:, headers: }` or `{ type: :http, envelope:, error: }`. Optional `parser:` keyword invokes a callable on the response body for JSON, YAML, CSV, or custom parsing. SSL, default 10s timeout, and cancellation-before-request are supported. Parsers and parsed results must be Ractor-shareable.
|
|
54
|
+
|
|
55
|
+
- **Streaming Command Data Loss Fix**: Fixed race condition in `Command.system(stream: true)` where fast commands could lose stdout/stderr data. Reader threads now `join` instead of `kill` to ensure all output is processed before completion.
|
|
56
|
+
|
|
57
|
+
- **Message::Predicates Mixin**: Include in custom message types for safe predicate calls. Returns `false` for any unknown predicate method (ending in `?`). Enables pattern matching workflows where messages can respond to predicates like `msg.http?` or `msg.timer?` without raising `NoMethodError`. Includes `respond_to_missing?` for introspection parity.
|
|
58
|
+
|
|
59
|
+
- **Message::Timer**: Predicate-rich response type for timer commands (`Command.wait`, `Command.tick`). Includes `timer?` predicate and `deconstruct_keys` for pattern matching with `type: :timer` discriminator. Contains `envelope` (routing symbol) and `elapsed` (actual wait time in seconds).
|
|
60
|
+
|
|
61
|
+
- **Message::HttpResponse**: Moved from `Command::HttpResponse` to `Message::HttpResponse` with added predicates. Includes `http?`, `success?`, and `error?` predicates. Implements `deconstruct_keys` for pattern matching with `type: :http` discriminator.
|
|
62
|
+
|
|
63
|
+
- **Message::System::Batch**: Response type for `Command.system` (batch mode). Includes `system?`, `success?` (exit 0), and `error?` (non-zero exit) predicates. Contains `envelope`, `stdout`, `stderr`, and `status`. Implements `deconstruct_keys` for pattern matching.
|
|
64
|
+
|
|
65
|
+
- **Message::System::Stream**: Response type for `Command.system(..., stream: true)`. Includes `system?`, `stdout?`, `stderr?`, and `complete?` predicates. Contains `envelope`, `stream` type (`:stdout`, `:stderr`, `:complete`), `content` (for output lines), and `status` (for completion). Implements conditional `deconstruct_keys` based on stream type.
|
|
66
|
+
|
|
67
|
+
- **Message::All**: Response type for `Command.all` aggregating parallel execution. Includes `all?` predicate. Contains `envelope`, `results` array, and `nested` boolean. Implements `deconstruct_keys` for pattern matching.
|
|
68
|
+
|
|
69
|
+
- **Command Parameter Rename**: Renamed `tag` parameter to `envelope` across all commands for consistency: `Command.wait`, `Command.tick`, `Command.system`, and `Command.all`. These now use `envelope:` in their data definitions. Messages emit with `envelope:` for pattern matching.
|
|
70
|
+
|
|
71
|
+
- **Dependencies**: Added `concurrent-ruby` (~> 1.3) and `concurrent-ruby-edge` (~> 0.7) for robust concurrency primitives.
|
|
72
|
+
|
|
73
|
+
- **Rooibos.normalize_init Helper**: New `Rooibos.normalize_init(result)` normalizes Init callable returns. Accepts the output of a `Fragment.Init` callable and always returns `[model, command]`. Use when composing child fragment initialization in parent fragments.
|
|
74
|
+
|
|
75
|
+
### Changed
|
|
76
|
+
|
|
77
|
+
- **Terminology: "Bag" → "Fragment"**: Renamed Fractal Architecture units from "bags" to "fragments" throughout the codebase. A fragment is a module containing `Model`, `INITIAL`, `UPDATE`, and `VIEW` constants. Parent fragments compose child fragments via routing. The `examples/app_fractal_dashboard/bags/` directory is now `examples/app_fractal_dashboard/fragments/`. All API documentation, code comments, and examples updated to reflect this terminology change.
|
|
78
|
+
|
|
79
|
+
- **Runtime API Signature (Breaking)**: `Rooibos.run` signature changed:
|
|
80
|
+
- Fragment parameter is now **positional** instead of keyword: `Rooibos.run(MyApp)` instead of `Rooibos.run(fragment: MyApp)`
|
|
81
|
+
- Removed `argv:` and `env:` parameters - Runtime now automatically uses `ARGV` and `ENV` globals
|
|
82
|
+
- Added `fps:` parameter (default 60) for configurable frame rate
|
|
83
|
+
- Renamed `init:` parameter to `command:` in explicit parameters API for clarity
|
|
84
|
+
|
|
85
|
+
- **Fragment Convention Rename (Breaking)**: Fragment constants have new naming conventions:
|
|
86
|
+
- `INITIAL` constant → `Init` callable. The runtime calls `Init.()` to get the initial model.
|
|
87
|
+
- `UPDATE` constant → `Update` callable (capitalized).
|
|
88
|
+
- `VIEW` constant → `View` callable (capitalized).
|
|
89
|
+
- Init is now a lambda/callable instead of a frozen constant. This enables parameterized initialization and returning `[model, command]` tuples for initial commands.
|
|
90
|
+
|
|
91
|
+
- **Internal Method Rename (Breaking)**: `Runtime.normalize_update_result` renamed to `Runtime.normalize_update_return` for clarity. Only affects code calling private Runtime internals.
|
|
92
|
+
|
|
93
|
+
- **Command.custom Ractor Validation (Breaking)**: `Command.custom(callable)` now validates in debug mode that the callable is Ractor-shareable. Callables that capture mutable state will raise `Invariant`. Define callables at module level or use `Ractor.make_shareable`.
|
|
94
|
+
|
|
95
|
+
- **Model Validation Timing (Breaking)**: Runtime now validates model Ractor-shareability **immediately after Init returns**, not just during the Update cycle. This catches mutable models earlier, enforcing immutability at startup. Models must be frozen (`.freeze`) or use immutable data structures (`Data.define`). This is a good breaking change that prevents subtle concurrency bugs.
|
|
96
|
+
|
|
97
|
+
- **CancellationToken Replaced (Breaking)**: Custom commands now receive `Concurrent::Cancellation` instead of `CancellationToken`. The method to check cancellation changes from `token.cancelled?` (British) to `token.canceled?` (American).
|
|
98
|
+
|
|
99
|
+
- **Outlet Accepts Channel (Breaking)**: `Outlet.new` now accepts a `Concurrent::Promises::Channel` instead of `Thread::Queue`.
|
|
100
|
+
|
|
101
|
+
- **Outlet#put (Breaking)**: `out.put(msg)`, the common case now sends `msg` directly instead of `[msg]`; `out.put(a, b, c)` sends `[a, b, c]`. Previously all calls wrapped arguments in an array. Update functions that matched `when Array` may need adjustment.
|
|
102
|
+
|
|
103
|
+
- **Command.all Output (Breaking)**: `Command.all` now emits `Message::All` objects instead of raw arrays. Previously emitted `[:tag, [results]]` (nested) or `[:tag, result1, result2]` (variadic). Now emits `Message::All` with `envelope`, `results`, and `nested` fields. Use hash pattern matching: `in { type: :all, envelope:, results:, nested: }`.
|
|
104
|
+
|
|
105
|
+
### Fixed
|
|
106
|
+
|
|
107
|
+
- **Streaming Command Data Loss**: Fixed race condition where fast commands (e.g., `echo hello`) could lose stdout/stderr messages. The streaming reader threads were being killed immediately after the child process exited, before they could finish reading buffered output. Now the runtime joins the reader threads to ensure all data is processed before sending `:complete`.
|
|
108
|
+
|
|
109
|
+
### Removed
|
|
110
|
+
|
|
111
|
+
- **CancellationToken Class**: Removed in favor of `Concurrent::Cancellation` from concurrent-ruby-edge.
|
|
112
|
+
- **CancellationToken::NONE**: Removed. Use `Command.uncancellable` factory instead.
|
|
113
|
+
|
|
114
|
+
## [0.3.1] - 2026-01-11
|
|
115
|
+
|
|
116
|
+
### Added
|
|
117
|
+
|
|
118
|
+
- **CancellationToken**: Cooperative cancellation mechanism for long-running custom commands. Commands check `cancelled?` periodically and stop gracefully when `cancel!` is called. Includes `CancellationToken::NONE` null object for commands that ignore cancellation.
|
|
119
|
+
|
|
120
|
+
- **Command::Custom Mixin**: Include in your class to mark it as a custom command. Provides `rooibos_command?` brand predicate and `rooibos_cancellation_grace_period` (default 2.0 seconds) for configuring cleanup time after cancellation.
|
|
121
|
+
|
|
122
|
+
- **Command::Outlet**: Messaging gateway for custom commands. Use `put(tag, *payload)` to send results back to the update function. Validates Ractor-shareability in debug mode.
|
|
123
|
+
|
|
124
|
+
- **Custom Command Dispatch**: Runtime now dispatches custom commands (objects with `rooibos_command?` returning true) in background threads. Commands receive an `Outlet` for messaging and a `CancellationToken` for cooperative shutdown.
|
|
125
|
+
|
|
126
|
+
- **Command.custom Factory**: Wraps lambdas/procs to give them unique identity for dispatch tracking. Each `Command.custom(callable)` call produces a distinct wrapper, enabling targeted cancellation. Accepts optional `grace_period:` to override the default 2.0 second cleanup window.
|
|
127
|
+
|
|
128
|
+
- **Command.cancel Factory**: Request cancellation of a running command. Returns a `Command::Cancel` sentinel that the runtime routes to the appropriate command's CancellationToken.
|
|
129
|
+
|
|
130
|
+
- **Runtime Cancellation Dispatch**: The runtime now handles `Command::Cancel` by signaling the target command's `CancellationToken`, enabling cooperative cancellation of long-running commands. Respects `rooibos_cancellation_grace_period`: waits for the grace period, then force-kills unresponsive threads. Use `Float::INFINITY` to never force-kill.
|
|
131
|
+
|
|
132
|
+
- **Graceful Shutdown**: On exit, runtime signals all active commands then respects each command's grace period. Commands with `Float::INFINITY` grace are waited on indefinitely (user has SIGKILL). Final queue messages are processed before returning.
|
|
133
|
+
|
|
134
|
+
- **Automatic Error Propagation**: Custom commands that raise unhandled exceptions now produce a `Command::Error` message instead of corrupting the TUI display. The runtime catches exceptions and pushes `Command::Error.new(command:, exception:)` to the queue. Pattern match on `Command::Error` in your update function to handle failures uniformly. Factory method `Command.error(command, exception)` is available for testing.
|
|
135
|
+
|
|
136
|
+
- **Command::System Cancellation**: Streaming shell commands now respect cooperative cancellation. When cancelled, sends `SIGTERM` for graceful shutdown, then `SIGKILL` if the child process doesn't exit. Prevents orphaned child processes from lingering after app exit.
|
|
137
|
+
|
|
138
|
+
### Changed
|
|
139
|
+
|
|
140
|
+
### Fixed
|
|
141
|
+
|
|
142
|
+
- **Ractor Enforcement is Debug-Only**: The Ractor-shareability check now only runs in debug mode (and automated tests). Production skips this check for performance, matching the original specification. Previously, the check ran unconditionally.
|
|
143
|
+
|
|
144
|
+
### Removed
|
|
145
|
+
|
|
146
|
+
## [0.3.0] - 2026-01-08
|
|
147
|
+
|
|
148
|
+
### Added
|
|
149
|
+
|
|
150
|
+
- **Router DSL**: New `Rooibos::Router` module provides declarative routing for Fractal Architecture:
|
|
151
|
+
- `route :prefix, to: ChildBag` — declares a child bag route
|
|
152
|
+
- `keymap { key "q", -> { Command.exit } }` — declares keyboard handlers
|
|
153
|
+
- `keymap { key "x", handler, when: -> (m) { m.ready? } }` — guards (also: `if:`, `only:`, `guard:`, `unless:`, `except:`, `skip:`)
|
|
154
|
+
- `keymap { only when: guard do ... end }` — nested guard blocks apply to all keys within (also: `skip when: ...`)
|
|
155
|
+
- `mousemap { click -> (x, y) { ... } }` — declares mouse handlers
|
|
156
|
+
- `action :name, handler` — declares reusable actions for key/mouse handlers
|
|
157
|
+
- `from_router` — generates an UPDATE lambda from routes and handlers
|
|
158
|
+
|
|
159
|
+
- **Composition Helpers**: New helper methods for Fractal Architecture reduce boilerplate:
|
|
160
|
+
- `Rooibos.route(command, :prefix)` — wraps a command to route results to a child bag
|
|
161
|
+
- `Rooibos.delegate(message, :prefix, child_update, child_model)` — dispatches prefixed messages to child bags
|
|
162
|
+
|
|
163
|
+
- **Command Mapping**: `Command.map(inner_command, &mapper)` wraps a child command and transforms its result message. Essential for parent bags routing child command results.
|
|
164
|
+
|
|
165
|
+
- **Shortcuts Module**: `require "rooibos/shortcuts"` and `include Rooibos::Shortcuts` for short aliases:
|
|
166
|
+
- `Cmd.exit` — alias for `Command.exit`
|
|
167
|
+
- `Cmd.sh(command, tag)` — alias for `Command.system`
|
|
168
|
+
- `Cmd.map(command, &block)` — alias for `Command.map`
|
|
169
|
+
|
|
170
|
+
- **Sync Event Integration**: Runtime now handles `Event::Sync` from `RatatuiRuby::SyntheticEvents`. When a Sync event is received, the runtime waits for all pending async threads and processes their results before continuing. Use `inject_sync` in tests for deterministic async verification.
|
|
171
|
+
|
|
172
|
+
- **Streaming Command Output**: `Command.system` now accepts a `stream:` keyword argument. When `stream: true`, the runtime sends incremental messages (`[:tag, :stdout, line]`, `[:tag, :stderr, line]`) as output arrives, followed by `[:tag, :complete, {status:}]` when the command finishes. Invalid commands send `[:tag, :error, {message:}]`. Default behavior (`stream: false`) remains unchanged.
|
|
173
|
+
|
|
174
|
+
- **Custom Shell Modal Example**: Added `examples/app_fractal_dashboard/bags/custom_shell_modal.rb` demonstrating a 3-bag fractal architecture for a modal that runs arbitrary shell commands with streaming output. Features interleaved stdout/stderr, exit status indication, and Ractor-safe implementation using `tui.overlay` for opaque rendering.
|
|
175
|
+
|
|
176
|
+
### Changed
|
|
177
|
+
|
|
178
|
+
- **Command Module Rename (Breaking)**: The `Cmd` module is now `Command` with Rubyish naming:
|
|
179
|
+
- `Cmd::Quit` → `Command::Exit` (use `Command.exit` factory)
|
|
180
|
+
- `Cmd::Exec` → `Command::System` (use `Command.system(cmd, tag)` factory)
|
|
181
|
+
|
|
182
|
+
### Fixed
|
|
183
|
+
|
|
184
|
+
### Removed
|
|
185
|
+
|
|
186
|
+
## [0.2.0] - 2026-01-08
|
|
187
|
+
|
|
188
|
+
### Added
|
|
189
|
+
|
|
190
|
+
- **The Elm Architecture (TEA)**: Implemented the core Model-View-Update (MVU) runtime. Use `Rooibos.run(model, view: ..., update: ...)` to start an interactive application with predictable state management.
|
|
191
|
+
- **Async Command System**: Side effects (database, HTTP, shell) are executed asynchronously in a thread pool. Results are dispatched back to the main loop as messages, ensuring the UI never freezes.
|
|
192
|
+
- **Ractor Safety Enforcement**: The runtime strictly enforces that all `Model` and `Message` objects are Ractor-shareable (deeply frozen). This guarantees thread safety by design and prepares for future parallelism.
|
|
193
|
+
- **Flexible Update Returns**: The `update` function supports multiple return signatures for developer ergonomics:
|
|
194
|
+
- `[Model, Cmd]` — Standard tuple.
|
|
195
|
+
- `Model` — Implicitly `[Model, Cmd::None]`.
|
|
196
|
+
- `Cmd` — Implicitly `[CurrentModel, Cmd]`.
|
|
197
|
+
- **Startup Commands**: `Rooibos.run` accepts an `init:` parameter to dispatch an initial command immediately after startup, useful for loading initial data without blocking the first render.
|
|
198
|
+
- **View Validation**: The `view` function must return a valid widget. Returning `nil` raises `RatatuiRuby::Error::Invariant` to catch bugs early.
|
|
199
|
+
|
|
200
|
+
|
|
201
|
+
## [0.1.0] - 2026-01-07
|
|
202
|
+
|
|
203
|
+
### Added
|
|
204
|
+
|
|
205
|
+
- **First Release**: Empty release of `rooibos`, a Ruby implementation of The Elm Architecture (TEA) for `ratatui_ruby`. Scaffolding generated by `ratatui_ruby-devtools`.
|
|
206
|
+
|
|
207
|
+
[Unreleased]: https://git.sr.ht/~kerrick/rooibos/refs/HEAD
|
|
208
|
+
[0.5.0]: https://git.sr.ht/~kerrick/rooibos/refs/v0.5.0
|
|
209
|
+
[0.4.0]: https://git.sr.ht/~kerrick/rooibos/refs/v0.4.0
|
|
210
|
+
[0.3.1]: https://git.sr.ht/~kerrick/rooibos/refs/v0.3.1
|
|
211
|
+
[0.3.0]: https://git.sr.ht/~kerrick/rooibos/refs/v0.3.0
|
|
212
|
+
[0.2.0]: https://git.sr.ht/~kerrick/rooibos/refs/v0.2.0
|
|
213
|
+
[0.2.0]: https://git.sr.ht/~kerrick/rooibos/refs/v0.2.0
|
|
214
|
+
[0.1.0]: https://git.sr.ht/~kerrick/rooibos/refs/v0.1.0
|