Files
RedBear-OS/local
vasilito bade5b81f7 cub: TUI rewrite + AUR hardening + god-module split (v6.0 2026)
TUI rewrite (the visible half of the change):

- 8 views instead of 6: Home, Search, Info, Install, Build,
  Query, Remove, Updates — central VIEW_ORDER const in
  tui/views/mod.rs and cycle_view() / parent_view() helpers
  mean adding a 9th view is one line.
- Help overlay is now view-scoped: shows a Global section and
  an In this view section that only lists keybindings the
  current view actually honors.
- Esc goes back one view (parent_view map); q still quits.
- New ConfirmAction enum and full-screen confirm_banner
  widget: pressing i / b / r / U now sets pending_confirm
  and shows a banner; y confirms, n cancels.
- TUI build routed through the canonical fetch_aur_to_store
  + validate_git_target instead of an inline git clone. The
  6 swallowed errors are now surfaced in build_log and
  status_message.
- panic-catching wrapper around spawn_action so a panic in
  the worker thread becomes a visible ActionUpdate instead
  of a frozen spinner.
- TUI cancel architecture: Arc<Mutex<Option<Child>>> shared
  between parent and worker drainer, Arc<AtomicBool> cancel
  flag, c keypress in Install/Build views calls child.kill().
- Terminal too-small guard: < 14 rows or < 40 cols renders
  a Terminal too small overlay instead of broken layout.
- Sticky error coloring in the status bar: success uses
  theme.success, failure uses theme.error, neutral uses
  status_style.
- PgUp / PgDn global scroll bindings for Install/Build log
  views; scroll position tracked in install_log_scroll /
  build_log_scroll u16 fields; install_log_joined /
  build_log_joined pre-joined strings avoid repeated
  Vec<String>::join calls during render.
- CubApp::new() returns Result<Self, CubError>; HOME missing
  or store.init() failure is now a fatal error overlay
  instead of a silent /tmp/.cub fallback.

AUR hardening:

- AUR client (reqwest::blocking::Client) gets 5s connect +
  15s request timeouts.
- fetch_aur_to_store writes the recipe atomically: stage in
  store.tmp_dir()/recipe-staging-<name>-<nanos>, then
  fs::rename. TmpGuard drop cleans up the clone directory.
- validate_git_target rejects names with .., ://, leading -,
  empty, or NUL bytes (was previously only catching leading -).
- redox-pkg dependency pinned to rev
  52f7930f8e6dfbe85efd115b3848ea802e1a56f0 to match the
  resolved Cargo.lock.

God-module split (main.rs 2063 -> 1723 lines):

- constants.rs: 10 path / URL constants.
- bur_helpers.rs: search_cached_bur, ensure_bur_package_dir,
  sync_bur_repo, default_bur_repo_url, bur_repo_dir,
  aur_repo_url, BurMatch struct.
- fs_helpers.rs: find_stage_dir, directory_has_entries,
  copy_dir_recursive, remove_dir_if_exists,
  current_unix_timestamp, join_strings, join_package_names,
  empty_if_blank, yes_no.
- paths.rs: cub_temp_dir, validate_git_target.

Tests:

- 19 unit tests in main-side modules (was 5); 121 in the
  lib (unchanged). Total 140/140 pass.
- New CubError variant tests, validate_git_target
  happy-path + 4 attack vectors, cub_temp_dir unique-name
  under concurrent calls, bur_repo_dir / aur_repo_url
  composition, fs_helpers round-trips with tempfile
  scratch dirs.

Policy:

- local/AGENTS.md gains a TUI CONVENTION section: single
  binary, -i flag, no separate -tui crate, ratatui 0.30
  + termion 4.0.6, anti-pattern list. cub, redbear-info,
  and redbear-netctl-console are listed as already
  compliant.
- cubl (the cub lib-only consumer) recipe path updated
  from -p cub-cli to -p cub.

Verified: cargo build --workspace and --no-default-features
and --features full and --features tui all clean; cargo
test --workspace 140/140 pass; cub --version cub 0.2.3;
cub --help 21 subcommands.
2026-06-11 09:16:48 +03:00
..
2026-06-10 11:23:09 +03:00