Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Introduction

A fast, lightweight terminal client for streaming and downloading movies, TV shows, anime, and live TV — powered by your local media player.

moviebox-tui walkthrough.webm

MovieBox-TUI replaces ad-heavy streaming websites and clunky browser players with a clean, keyboard-driven terminal interface. It scrapes stream links directly from multiple sources and launches playback in your native media player with hardware acceleration, audio track switching, and automatic subtitle synchronization.

Features

  • Multi-Source Streaming: Search and stream titles across MovieBox, 4KHDHub, BDIX mirrors, custom IPTV playlists, and community Stremio HTTP addons. Press Ctrl+P on the Details screen to switch providers in-place.
  • Hardware-Accelerated Playback: Direct playback in mpv, IINA (macOS), or VLC with stream authentication headers forwarded automatically.
  • Automatic Subtitles: Automatically searches, downloads, and syncs subtitles in your preferred language directly into your player.
  • Season Batch Downloads: Download individual episodes or entire seasons with one keypress (d), with HTTP range resume support and clean folder structure (Movies/ and Series/).
  • Interactive Settings Hub: Configure your default media player, download folder, content modes, and themes inside an in-app visual modal via /settings (Ctrl+S).
  • Modes: Switch instantly between standard Streaming, Live TV (Ctrl+T), and Addon Mode (Ctrl+A).
  • Ergonomics & Themes: Full keyboard navigation (vim-style j/k, /, Tab) and mouse support (click, scroll, drag) with 6 built-in themes (Catppuccin, TokyoNight, Nord, Dracula, Gruvbox, Rosé Pine) and terminal theme autodetection.

Prerequisites

MovieBox-TUI delegates video decoding to an external media player. Install at least one of the following:

PlayerPlatformQuick Install
mpv (Recommended)Linux, macOS, Windowsbrew install mpv / sudo apt install mpv / winget install mpv
IINAmacOS (Native GUI)brew install --cask iina
VLCCross-platformbrew install --cask vlc / sudo apt install vlc / winget install VideoLAN.VLC
Android PlayerAndroid (Termux)pkg install -y termux-tools termux-am (launches external player)

Documentation Directory Map

Getting Started

GuideDescription
InstallationPlatform installation instructions, package managers, and binary verification
Keyboard & ControlsComplete keybindings, vim navigation, text editing, and slash commands
Configuration Guideconfig.json schema, settings hub options, and environment variables

Features & Modes

GuideDescription
Content ProvidersBuilt-in providers, scrapers, stream extractors, and authentication headers
Hardware PlayersMedia player detection, launch flags, stream headers, and watch tracking
Batch DownloadsMulti-segment download engine, range resume, and folder layout
Stremio AddonsAddon manifest installation, catalog browsing, and stream resolution
Live TV & IPTVM3U playlist manager, channel parsing, and live stream playback

Architecture & Internals

GuideDescription
System ArchitectureSubsystem diagrams, async event loop, and task cancellation
Module BreakdownCrate structure, module responsibilities, and call boundaries
Caching StrategyBinary disk caching, TTL policies, and LRU memory management
Logging SystemFile logging, log rotation, and tracing diagnostics
Cross-Platform OperationsPlatform compatibility matrix across macOS, Linux, Windows, and Termux

Reference & Maintenance

GuideDescription
Testing SuiteUnit tests, integration tests, and verification gates
Debugging GuideTroubleshooting common issues, terminal rendering, and player errors
Release ChecklistPre-release validation, binary packaging, and deployment workflow
Known IssuesTracked limitations, terminal quirks, and workarounds
Contributing GuideContribution guidelines, code standards, and PR process
ChangelogComplete release history and unreleased changes

Installation

MovieBox-TUI is available across macOS, Linux, Windows, and Android (Termux).


macOS & Linux

Install via the automated script:

curl -fsSL https://raw.githubusercontent.com/mesamirh/MovieBox-Tui/main/install.sh | bash

macOS via Homebrew

brew tap mesamirh/moviebox-tui https://github.com/mesamirh/MovieBox-Tui
brew trust mesamirh/moviebox-tui
brew install moviebox-tui

Windows

Install via PowerShell (run in Windows Terminal or PowerShell 5.1+):

irm https://raw.githubusercontent.com/mesamirh/MovieBox-Tui/main/install.ps1 | iex

Android (Termux)

Install Termux tools and the intent bridge, run the installer script to fetch the precompiled native Android ARM64 binary, and grant storage permissions:

pkg update && pkg install -y curl tar termux-tools termux-am
curl -fsSL https://raw.githubusercontent.com/mesamirh/MovieBox-Tui/main/install.sh -o install.sh && bash install.sh
termux-setup-storage

The installer automatically downloads the native Android ARM64 release package (MovieBox_Android_arm64.tar.gz) built against the Android NDK and Bionic libc, requiring zero on-device compilation.

Media Player Requirements: Android streams are rendered through external Android video players (such as VLC for Android, MX Player, Just Player, or MPV Android APK) triggered via termux-open or termux-am. Command-line mpv installed directly in Termux (pkg install mpv) runs without a video output surface unless an X11 desktop environment (like Termux:X11) is configured.

To compile from source on Termux:

pkg install -y rust clang
cargo install moviebox-tui --locked

Cargo (Crates.io)

Install directly using Cargo:

cargo install moviebox-tui --locked

Compile from Source

Clone the repository and build the release binary:

git clone https://github.com/mesamirh/MovieBox-Tui.git
cd MovieBox-Tui
cargo build --release --locked

The compiled binary will be located at target/release/moviebox-tui.


Verify Release Integrity

All release assets include cryptographically signed SHA-256 checksums and GitHub provenance attestations:

sha256sum -c SHA256SUMS --ignore-missing
gh attestation verify <archive-file> -R mesamirh/MovieBox-Tui

Controls & Shortcuts

MovieBox-TUI is designed for fast keyboard navigation with complete mouse support throughout the interface. You can press ? anywhere inside the application to open the mode-aware interactive help dialog.

Global Shortcuts

KeyAction
/ / k / jNavigate lists, search results, or move cursor up/down
/ / h / lMove text input cursor, step wide grid columns, or switch Details panes (Audio/Seasons/Episodes/Streams)
Home / End / g / GJump to start / end of list or search results (auto-fetches next page), or move cursor to beginning / end of input line
PageUp / PageDownScroll search results, lists, and modal pickers by visible page height (or scroll help overlay)
EnterOpen, play, or confirm the selected item
Space / PDirect resume playback for recorded season/episode on /history or Home Continue Watching items
EscFocus search input (when results present), dismiss popup dialog, or return to landing
Tab / Shift+TabAuto-complete suggestion / command; cycle landing deck tabs (Continue Watching / Favorites); switch details panes; toggle dialog buttons
BackspaceDelete character before cursor, or return focus to search bar from results
DeleteDelete character at cursor in text inputs, or remove entry in TV/Addon managers
Ctrl+UClear entire input line (Search, TV URL, Addon URL)
Ctrl+WDelete backward word in text inputs
cClear active search query and return to landing screen (Normal mode)
x / XCancel active download and preserve partial .part data
Ctrl+SSwitch to standard Streaming Mode
Ctrl+TToggle / switch to TV Mode
Ctrl+AToggle / switch to Addon Mode
?Open interactive in-app help menu
Ctrl+C / qQuit application and restore terminal

Text Input & Cursor Editing

Text editing across Search, TV Playlist Manager, and Addon Manager uses a unified grapheme-safe input engine:

KeyAction
Left / RightMove text cursor one grapheme cluster left or right
Home / EndJump cursor directly to the beginning or end of the input line
BackspaceDelete the grapheme cluster immediately before the cursor
DeleteDelete the grapheme cluster at the cursor position
Ctrl+WDelete the preceding word (up to space or punctuation delimiter)
Ctrl+UClear the entire input buffer
TabAuto-complete active search suggestion or slash command
EnterSubmit search query, save TV playlist URL/path, or verify and install Addon manifest
EscCancel input, dismiss input prompt, or clear search buffer

All popup dialogs (Theme picker, Browse categories, Provider menu, Settings Media Player picker, TV Manager, Addon Manager, Download Confirmation) support standard keyboard controls:

  • / / k / j: Move selection up / down by one item (vim keys k/j supported in pickers such as theme selector in Settings).
  • Home / End: Jump immediately to the first or last item in the list.
  • PageUp / PageDown: Step up or down by 5 items.
  • Enter: Confirm selection, activate entry, or submit dialog.
  • Esc: Dismiss popup dialog without applying changes.
  • Download Confirmation Dialog:
    • Tab / Shift+Tab / BackTab: Toggle active selection between [ Download ] and [ Cancel ].
    • Left / Right: Switch between [ Download ] and [ Cancel ].
    • Enter: Confirm the currently focused action.
    • Esc: Cancel and close the confirmation dialog.

Mode-Specific Controls

Streaming Mode

  • Ctrl+P: Cycle content providers (MovieBox4KHDHubBDIX). On the Details screen, re-searches and fetches alternate streams for the current movie in-place.
  • / / h / l / Tab / Shift+Tab: Switch Details screen selector panes (Audio Languages, Seasons, Episodes, Streams).
  • Enter: Play selected stream or open selected title.
  • d: Download current episode or full season batch.
  • r: Refresh search results / stream list.
  • f: Favorite / unfavorite the selected title (Home & Details screens).
  • /settings: Open interactive Settings & Preferences Hub.
  • /browse: Open curated browse categories (Trending, Popular, Top Rated, etc.).
  • /history: Open watch history (Space or P to instantly resume recorded episode/movie).
  • /favorites: Open your starred titles.
  • /clear: Clear active search query and return to landing.

Live TV Mode

  • Enter: Play selected TV channel immediately with default player.
  • r: Reload all active M3U playlist sources.
  • /list: Show all loaded channels.

Addon Mode (HTTP Addons)

  • /settings: Open Settings Hub to manage addons and configuration.
  • Enter: Select title or play resolved stream.
  • d: Download HTTP stream release.
  • r: Refresh addon catalog search results.
  • f: Favorite / unfavorite the selected title (Home & Details screens).
  • /history: Open watch history (Space or P to instantly resume recorded episode/movie).
  • /favorites: Open your starred titles.
  • /clear: Clear active search query and return to landing.

Mouse Controls

ActionResult
Click provider badgeOpen anchored provider selection menu; click provider to switch directly
Click search barEnter search input mode
Click search result rowSelect item and load preview; click again to open full details
Click landing deck tab headerSwitch between Continue Watching and Favorites tabs
Click [x] Cancel on download barCancel active download
Click Continue Watching row (landing)Select an in-progress title; click again to resume playback with auto-play
Click Favorites row (landing)Select a starred title; click again to open details
Click “+N more • /history” or “+N more • /favorites”Open the full watch history or favorites list
Click audio / season / episode / streamSwitch audio language, change season, or select episode; click a specific stream row to play; click empty stream pane space to focus without playing
Click footer buttonsSwitch provider / mode, open help ([?]), or quit ([q])
Click modal buttonsChoose a theme, subtitles, player, or confirm actions
Click outside a modalDismiss popup dialog

Slash Commands

Type these commands directly into the search bar:

CommandApplicable ModeAction
/settingsAllOpen interactive Settings & Preferences Hub (aliases /config, /pref, /preferences, /options)
/browseStreaming / AddonBrowse curated views (Trending, Popular) or Addon catalogs (Top Movies, Top Series)
/historyStreaming / AddonView watch history with latest progress
/favoritesStreaming / AddonView all starred titles
/clearAllClear search results and return to landing
/helpAllOpen interactive keybinding help menu (alias /?)
/listTVView live TV channels
/exitAllExit application and return to shell (aliases /quit, /q)

Help Menu Overlay

  • Open with ?; close with ?, Esc, or q.
  • /, PageUp/PageDown, and the mouse wheel scroll long content.
  • Other keys are ignored while help is open.

Update Notification & Self-Update Modals

When a new release is detected, a centered modal card displays the version comparison, environment instructions, release highlights, and quick actions:

  • u / U: Download and install update immediately (direct binary replacement platforms).
  • b / B: Copy Homebrew upgrade command (brew upgrade moviebox-tui) to clipboard with status toast on Homebrew-managed installations.
  • o / O: Open GitHub release notes in the system browser.
  • Esc: Dismiss modal and return to previous screen.
  • The notification modal formats release notes into clean, indented category sections ([Added], [Fixed]) with bold feature titles and bullet items, stripping decorative prefixes and duplicate paragraph text.
  • During self-update (u), a focused progress modal displays an active spinner with a unified action status (⠋ Downloading MovieBox-Tui v... / ⠋ Installing MovieBox-Tui v...) and a cross-platform warning notice (⚠ Please wait • do not close terminal on modern terminals, [!] Please wait - do not close terminal on basic terminals) with generous border clearances.
  • Modal presentation is deferred while actively typing in the search bar (InputMode::Editing) to prevent input hijacking. During update installation, keyboard and mouse inputs are locked while the progress modal is displayed.

Wide-Terminal Grid

On terminals at least 110 columns wide, search results render in two columns (three at 160+). / move one visual row, / move one item, and clicks map through column bounds. Narrower terminals keep the classic single-column list where / jump a full page.

Configuration

config.json

Written atomically under the config directory (dirs::config_dir()/moviebox-tui/; macOS ~/Library/Application Support/moviebox-tui, Linux ~/.config/moviebox-tui).

FieldTypeMeaning
auto_updateboolCheck for updates on startup (max once/hour).
last_update_checku64Epoch seconds of the last update check.
active_modestringLast active mode (streaming, tv, addon) restored on startup.
active_providerstringLast provider (moviebox, fourkhdhub, …).
active_themestringTheme name.
bdix_enabledboolShow BDIX providers (Bangladesh-only).
streaming_enabledboolEnable Streaming Mode navigation in bottom dock (/settings → Content Modes).
tv_enabledboolEnable TV Mode navigation in bottom dock (/settings → Content Modes).
addons_enabledboolEnable Addon Mode navigation in bottom dock (/settings → Content Modes).
default_playerstring or nullPreferred player: mpv, iina, vlc, android; absent/null until you choose one from the in-app picker.
download_dirstring or nullCustom directory for video and subtitle downloads (null uses OS default).

Interactive Settings Hub (/settings)

All settings in config.json can be configured interactively inside the application by typing /settings into the search bar.

  • General: Toggle automatic update checks, choose default media player (mpv, VLC, IINA, Android), and edit download folder path.
  • Content Modes: Enable or disable Streaming Mode, BDIX FTP sources, Live TV (IPTV), and HTTP Addons with safety guards (preventing 0 active modes).
  • Appearance: Cycle color themes live with real-time palette swatches and launch the visual theme swatch picker.
  • Maintenance: Purge disk cache, query GitHub for release updates, and view repository information.

Other persisted files

  • addons_config.json — list of installed HTTP addons in the config directory (see addons-mode.md).
  • tv_config.json — list of M3U playlist sources in the config directory (see tv-mode.md).
  • history.json — watch history in the system data directory (dirs::data_dir()/moviebox-tui/).
  • favorites.json: starred titles in the system data directory. Independent of history.json; clearing watch history or cache never touches it.
  • playback/ — temporary playback states in the system data directory for resilient progress tracking.
  • scripts/ — bundled player scripts (moviebox_tracker.lua) in the system data directory.
  • iptv_cache/ — legacy TV image cache directory that ClearCache still removes.

Environment variables

VariablePurpose
MOVIEBOX_LOGLog level: off, error, warn, info, debug, trace. See logging.md.
MOVIEBOX_PLAYERPreferred player (overrides default_player).
MOVIEBOX_MPV_PATHCustom mpv executable.
MOVIEBOX_VLC_PATHCustom VLC executable.
MOVIEBOX_IINA_PATHCustom IINA/iina-cli executable.
MOVIEBOX_FOURKHDHUB_URLOverride the 4KHDHub base URL.
MOVIEBOX_THEMEForce a theme (e.g. Mocha, Latte, Macchiato, Frappe, Nord, TokyoNight, Dracula, Gruvbox, RosePine). When unset and no saved theme exists, the app auto-detects: NO_COLOR wins, truecolor terminals get full palettes, 256-color terminals get quantized palettes, and the OSC 11 background query picks light/dark variants with WCAG AA contrast.
MOVIEBOX_NO_IMAGEDisable poster image queries (set to 1 or true).
MOVIEBOX_IMAGE_PROTOCOLOverride image protocol (kitty, sixel, iterm2, or none/off).
MOVIEBOX_CELL_SIZEOverride terminal cell size as WxH (e.g. 10x20) for poster scaling.

CLI

  • moviebox-tui --help and moviebox-tui -h print the help manual and exit.
  • moviebox-tui --version, moviebox-tui -v, and moviebox-tui -V print the version and exit.

Providers

MovieBox-Tui aggregates several movie/stream providers plus user M3U playlists. Each provider is an independent async client exposing a similar shape, normalized into the shared typed models in providers/models.rs and the moviebox JSON schema used by the UI.

Provider kinds

ProviderModuleDescription
MovieBoxproviders/movieboxPrimary provider. Requires request signing (crypto).
FourKHdHubproviders/fourkhdhub4K releases; hubcloud mirror resolver.
BdixCircleFtpproviders/bdix/circleftpBDIX FTP directory scrapes.
BdixDhakaFlixproviders/bdix/dhakaflixBDIX indexer.
Addonsproviders/addonsCommunity HTTP addons (Cinemeta, streams).

BDIX sources are only reachable from supported Bangladeshi ISPs and are hidden by default (bdix_enabled in config; /settings → Content Modes → BDIX Sources).

Active streaming providers can be cycled via Ctrl+P or visually selected by clicking the provider badge ([MovieBox · ^P]) on the landing search bar to open the anchored provider popup menu.

Shared Provider Contract

Search, details, and episode-streams are dispatched per provider. Pluggable provider seams in providers/mod.rs give every client a shared, strictly-typed async trait shape:

  • Provider::id(&self) -> ProviderKind: Returns the provider’s unique identifier.
  • Provider::capabilities(&self) -> ProviderCapabilities: Reports supported capabilities (supports_search, supports_pagination, supports_series, supports_subtitles, supports_homepage).
  • Provider::search(&self, query: &str, page: usize) -> Result<Vec<CatalogItem>, ProviderError>: Dispatches search queries, returning strongly-typed CatalogItems.
  • Provider::details(&self, id: &str) -> Result<MediaDetails, ProviderError>: Dispatches metadata queries, returning strongly-typed MediaDetails.
  • ReleaseProvider::episode_streams(&self, id: &str, season: usize, episode: usize) -> Result<Vec<Release>, ProviderError>: Returns the typed Release list for release-based providers.
  • ProviderError: Standardized error boundary (Network, RateLimited, NotFound, Parsing, Unavailable) with .user_message(provider) generating clean UI toast notifications.

Strongly Typed Architecture & Binary Disk Caching

All internal state (AppState), UI screens (details.rs, home.rs), and the action event bus transport native Rust structs directly:

  • CatalogItem / SearchResult for search results and discover catalogs.
  • MediaDetails (with Vec<Season> and Vec<AudioTrackOption>) for media metadata.
  • Release (with Vec<SourceMirror> and optional resource_id) for streams.
  • SubtitleOption for external subtitles.

Disk caching in src/cache.rs uses high-performance portable binary serialization via rmp-serde (MessagePack) with a 4-byte magic signature (MBC1) and versioned TTL envelope (CacheEnvelope<T>), eliminating all runtime JSON parsing and string allocation bottlenecks.

Playback resolves to a PlaybackSource { provider, url, headers, subtitle, source_label }, which app/playback.rs::launch_player feeds to the external player.

Adding a New Provider

Adding a new streaming or BDIX provider to MovieBox TUI takes 3 simple steps:

  1. Define the Provider Variant (src/providers/models.rs): Add the new variant to ProviderKind with its label, cache key, and serialization aliases.

  2. Implement the Provider Trait (src/providers/<new_provider>/): Implement Provider::id, Provider::capabilities, Provider::search, and Provider::details for your client struct, returning typed domain models (CatalogItem, MediaDetails). If your provider resolves release streams, also implement ReleaseProvider.

  3. Register the Client in MovieBoxService (src/service.rs): Add your client struct to MovieBoxService, instantiate it in MovieBoxService::new(), and map it in capabilities, search_typed, and details_typed. All search, details, and stream dispatches operate natively with zero JSON shims.

MovieBox

  • Base host pool + per-request HMAC-MD5 signature, client token, and a spoofed Android device identity (crypto.rs) spoofing APK v4.0.01.0813.03 (version_codes: 50020117..50020121) to satisfy the backend gateway and prevent notice video substitution.
  • Hosts are retried; a shared runtime token is re-initialized when all hosts fail.
  • Mobile User-Agent generated by the crypto module is forwarded through playback and download pipelines to satisfy CDN anti-bot checks.
  • Multi-resolution discovery (fetch_collection_resolutions) dynamically discovers available stream resolutions with descending quality sorting.
  • Multi-resolution DASH manifests (index.mpd) and adaptive streams are labeled with a distinct [Multi] badge, stripping confusing raw CDN resolution tags from release titles.
  • Title normalization lives in moviebox/title.rs (clean_moviebox_title).
  • DASH Manifest Playback & Downloads: Media streams are hosted on CloudFront as segmented MPEG-DASH manifests (index.mpd) protected by signed policy cookies. Stream playback forwards Cookie, Referer, and User-Agent headers to external players (mpv, IINA). Local downloads utilize yt-dlp with forwarded authentication headers to demux and assemble audio/video streams into .mp4.

4KHDHub

  • client.rs::resolve_release resolves release mirrors concurrently using bounded-concurrency probing (select_ok in batches of 3) with a 3.5s per-probe timeout.
  • Direct links undergo automatic path percent-encoding normalization (validate_playback_url) to handle filenames containing unencoded spaces, brackets, and special characters.
  • Preflight probes issue a bounded range probe (Range: bytes=0-8191) and inspect response bodies for expired mirror errors ("Failed to extract link", "Token Expired", "404") to fail fast on expired torrents.
  • hubcloud.rs scores and prioritizes candidate streams (Cloudflare R2 / S3 / Seekable Streams → Storage → PixelDrain API → Google UserContent / Direct Attachments), automatically decoding base64 Watch Online mirrors (vdplay.pages.dev/?u=...).
  • Multilingual audio detection: parser.rs::detect_language parses release titles and metadata for 30+ regional and international languages (Hindi, Tamil, Telugu, Kannada, Malayalam, Bengali, Marathi, Punjabi, Gujarati, Urdu, Japanese, Korean, Chinese, Spanish, French, German, Italian, etc.) and formats all available audio tracks for stream display.
  • Errors are mapped into ProviderError::Unavailable with user-actionable instructions guiding selection of alternate releases.

BDIX

  • circleftp and dhakaflix scrape FTP-style indexes; both are used behind the Bangladesh-only gate.

Community HTTP Addons

  • providers/addons communicates with HTTP addon manifests (/manifest.json).
  • Cinemeta provides catalog searches and metadata details (/catalog, /meta).
  • Stream addons (e.g. HdHub, direct CDN manifests) resolve playable HTTP/HTTPS streams concurrently. See addons-mode.md.

M3U playlists (TV mode)

providers/tv parses an M3U playlist from an https:// URL or a local file path. Each channel yields { id, name, logo, group, stream_url }; TV mode groups channels by group-title and dedupes by stream_url. See tv-mode.md.

Error handling

Each provider defines its own thiserror enum (ScraperError, FourKHdHubError, CircleFtpError, DhakaFlixError). Errors bubble to app/requests.rs handlers, which surface them in the UI status bar and log the full detail (see logging.md).

Players

Playback is handed to an external player. player.rs detects available players and builds the exact command; tui/app/playback.rs spawns it.

Detection

player::detect() (powered by a centralized probe_player_executable engine) returns players in priority order, resolving paths dynamically with non-negative caching:

  • macOS: IINA (if present), then mpv, then VLC (probing /Applications, ~/Applications, Homebrew /opt/homebrew/bin, MacPorts /opt/local/bin, Nix profiles ~/.nix-profile/bin and /run/current-system/sw/bin, and standard /bin).
  • Linux: mpv, then VLC (probing native $PATH, user .local/bin, Flathub/Flatpak user & system exports org.videolan.VLC / io.mpv.Mpv, Snap /snap/bin/*, Nix profiles, standard /bin, and flatpak run).
  • Windows: mpv, then VLC (probing executable-adjacent binaries, WinGet Links & Packages directory %LOCALAPPDATA%\Microsoft\WinGet\Packages, %USERPROFILE%\Downloads and %USERPROFILE%\Desktop extractions, Program Files including mpv, mpv-player, mpv.net, and VideoLAN\VLC, LOCALAPPDATA\Programs, portable drive roots C:\mpv, C:\vlc, C:\tools, Scoop shims & apps, Chocolatey, and Windows Registry App Paths and Environment\Path).
  • Android/Termux: Android intent chooser (termux-open, termux-open-url, or termux-am). Streams play via external Android video players (VLC for Android, Just Player, MX Player, MPV Android APK).

Resolution caches detected paths across runs while allowing newly installed players to be discovered dynamically when opening or navigating the Settings Hub (/settings), without requiring an application restart. A preferred player can be forced via MOVIEBOX_PLAYER env or default_player in config (e.g. mpv, iina, vlc, android), which reorders the list. The media player picker in the Settings Hub lists every detected player on your system and saves your selection to config.json. Playback launches directly using the preferred compatible player without intermediate modal dialogs.

Command construction

PlayerInvocationNotes
mpvmpv --autofit=WxH --geometry=50%:50% --idle=no --keep-open=no [--start=..] [--script=..] [--script-opts=..] [--http-header-fields=..] [--sub-file=..] <url>Window sized to the terminal. Injects moviebox_tracker.lua for position tracking and resume. Flatpak mpv is launched via flatpak run.
VLCvlc --width=W --height=H --play-and-exit [--start-time=..] [--http-referrer=..] [--http-user-agent=..] [--sub-file=..] <url>Supports start time resume via --start-time.
IINAiina-cli --keep-running --no-stdin --mpv-autofit=.. [--mpv-start=..] --mpv-http-header-fields=.. --mpv-sub-files=.. <url>Uses the installed IINA iina-cli; falls back to open -a IINA <url> only if the CLI is absent.
Android / Termuxtermux-open --chooser --content-type video/* <url> (or termux-open-url / termux-am)Opens an app chooser on the device, delegating playback to external apps (VLC, MX Player, Just Player, MPV Android). Requires pkg install -y termux-tools termux-am. Forwards User-Agent, Referer, and subtitles when using termux-am.

Window size is derived from the live terminal size times the font cell size reported by the image picker, then clamped to a fixed range.

Headers

Playback sources (for example 4KHD and MovieBox) may carry Referer/User-Agent headers. MovieBox DASH streams additionally carry signed Cookie headers for CloudFront authentication. mpv/IINA send them via http-header-fields (--http-header-fields=... or --mpv-http-header-fields=...), while VLC maps them to --http-referrer / --http-user-agent. Android intent playback forwards Referer/User-Agent extras when using am/termux-am, and supports unauthenticated streams (CircleFTP, DhakaFlix, IPTV) and CDN streams natively. The supports_headers gate in app/playback.rs validates whether a player can satisfy required stream headers. MovieBox-TUI strictly respects the user’s configured default player: if the chosen player cannot satisfy a stream’s headers (such as VLC or Android Player attempting to play signed MovieBox DASH manifests with CloudFront cookie requirements), playback will not silently fall back to an alternative player. Instead, an explicit warning notification informs the user of the exact incompatibility and lists available compatible alternatives (e.g. mpv) or the option to switch providers with Ctrl+P.

Subtitles

  • mpv receives the remote subtitle URL directly (--sub-file=<url>); mpv fetches it with the stream headers applied.
  • VLC and IINA download the subtitle to a temp file first, preserving the URL’s extension (srt/vtt/ass/…), and pass the local path. The download applies the source headers. On failure a status is shown and playback continues without subtitles.
  • Android intent playback passes subtitle paths to am/termux-am via subtitles_location and subs intent extras.
  • Temp files are cleaned up after the player exits and purged at startup if stale.

Playback Tracking & Resume

When launching media with in-progress watch history, the player command automatically includes the starting position (--start / --mpv-start / --start-time).

  • Immediate Start Registration: Media sessions are pre-registered into watch history (record_start) upon launch, ensuring that fast-exiting intent dispatchers (Android termux-open / am start, macOS open -a IINA) and unexpected terminal terminations retain history immediately.
  • Pre-Seeded State Files: Before launching mpv or IINA, MovieBox-TUI creates a pending state file populated with metadata (title, cover_url, stype, release_year). If the application exits abruptly during playback, reconcile_from_dir self-heals and inserts new items into watch history without data loss.
  • Latched Lua Tracker (moviebox_tracker.lua): Observes time-pos and duration every 5 seconds. State file writes are atomic (.tmp file flushed and renamed with destination removal for Windows compatibility). Video completion at ≥ 90% or EOF is permanently latched, preventing player shutdown events from resetting completion status. Missing or live stream durations write JSON null to prevent invalid duration calculations.
  • Isolated Tracker vs Fallback Reconciliation: Players with active Lua trackers (mpv, iina-cli) rely strictly on state file reconciliation, eliminating wall-clock progress overwrite races during pauses or seeks. Process elapsed time is used strictly as a guarded fallback for players without tracker scripts (e.g. VLC).

Spawning

launch_player spawns the player with null stdin/stdout, piped stderr, and its own process group (Unix) or no-console flag (Windows). A blocking task reads stderr and reports every non-zero process exit as a player error, including failures with no diagnostic output. Watch progress is reconciled only after a successful exit.

Android / Termux Playback Architecture

On Android (Termux), terminal sessions do not have access to an X11 or Wayland display server by default:

  • Command-Line mpv (pkg install mpv): Operates in headless/audio-only mode. Video output cannot be rendered to the terminal screen and will fail or produce audio without video.
  • External Player Intent Dispatch: Video playback is designed to open in dedicated Android video player applications (VLC for Android, Just Player, MX Player, or MPV Android APK).
  • Prerequisites: Termux requires pkg install -y termux-tools termux-am.
    • termux-open (from termux-tools) broadcasts an android.intent.action.VIEW intent to TermuxOpenReceiver, presenting Android’s native app chooser.
    • termux-am (from termux-am) connects directly to termux-app’s local Unix domain socket (am.sock), allowing intent parameter passing (including User-Agent, Referer, and subtitles).
    • SELinux & Exit Code 126 Protection: On Android 10+, executing /system/bin/am directly from an unrooted Termux environment causes Android’s system shell to call cmd activity, which is blocked by SELinux when executing Termux app data binaries (Permission denied, exit code 126). MovieBox-TUI detects Termux environments, prevents illegal system am invocations, preserves LD_PRELOAD for Termux applet compatibility, and surfaces actionable remediation notifications.

Downloads

The download engine in download.rs streams a video URL to disk with resume, ranges, and optional segmentation. Orchestration lives in app/download.rs.

How it works

  • Single-episode downloads write to <dest>.part plus a <dest>.part.json metadata sidecar (etag, last-modified, total size, segment count).
  • Resume: on a retry, the engine checks what is already in the .part file and continues from there using Range requests.
  • Segmentation: files above a size threshold can be downloaded in parallel segments (up to a capped count), then stitched.
  • I/O Aggregation: Download segment writers are buffered with a 256KB tokio::io::BufWriter, aggregating incoming 8KB–16KB HTTP response chunks into sequential disk writes and reducing filesystem syscalls by up to 96.8%.
  • Retries: a failed attempt is retried a limited number of times; 30s idle
  • Cancel: an AtomicBool cancel flag pauses/resumes cleanly, preserving the partial file for a later resume.
  • User-Agent: the download HTTP client inherits the active provider’s mobile User-Agent to prevent CDN stream rejections when downloading media segments.
  • Stream Engines:
    • Progressive Streams (CircleFTP, DhakaFlix, 4KHDHub, Addons): Handled directly by the native Rust multi-segment range downloader, splitting files into parallel chunks with .part state tracking.
    • MPEG-DASH Streams (MovieBox): Multi-track segmented audio/video streams (index.mpd) requiring CloudFront cookie authentication. Downloaded via yt-dlp with automatic authentication header forwarding (Cookie, Referer, User-Agent), real-time progress parsing, and track multiplexing into .mp4.

External Tool Prerequisites

Downloading from MovieBox requires yt-dlp and ffmpeg on the host system to demux and merge MPEG-DASH audio and video streams:

  • macOS: Install via Homebrew: brew install yt-dlp ffmpeg
  • Linux: Install via your system package manager (e.g. sudo apt install yt-dlp ffmpeg, sudo pacman -S yt-dlp ffmpeg)
  • Windows: Install via WinGet or Scoop: winget install yt-dlp.yt-dlp Gyan.FFmpeg
  • Android / Termux: Install via Termux package manager: pkg install yt-dlp ffmpeg

If a MovieBox download is initiated without yt-dlp installed, MovieBox-TUI prevents execution and displays an OS-tailored notification with installation guidance. Progressive streams from other providers (CircleFTP, DhakaFlix, 4KHDHub, Addons) do not require yt-dlp or ffmpeg.

File names and directories

safe_file_stem sanitizes titles for all platforms: control/whitespace/illegal characters are replaced, Windows reserved names (CON, COM1-COM9, …) are avoided, and length is capped.

  • Series downloads: Saved under <base_dir>/Series/<Title>/Season <N>/<Title> - S<N:02>E<E:02>.<ext> (and subtitle <Title> - S<N:02>E<E:02>.<lang>.<sub_ext>).
  • Movie downloads: Saved under <base_dir>/Movies/<Title>/<Title>.<ext> (and subtitle <Title>.<lang>.<sub_ext>).
  • Default path: Files go to the user’s OS download directory (~/Downloads/MovieBox-TUI). On Android-family environments the code prefers shared storage/downloads when present.
  • Custom path: Users can set a custom download directory in /settings → General → Download Folder or reset to default. Target directories are validated with a write probe before saving, and the code creates the MovieBox-TUI subfolder hierarchy (Movies/ and Series/). If custom storage becomes unavailable at runtime, the engine falls back to the default download location.

Contextual triggers & Seasons

  • Contextual trigger: Pressing d (or clicking [Download]) while focused on the Seasons pane prompts to download all episodes of the selected season. Triggering download while on the Episodes or Streams pane prompts to download only that single episode.
  • Duplication prevention: When starting a download or processing a season batch queue, the engine checks if the target media file is already completed on disk. Existing completed episodes are skipped.
  • A season download enqueues every episode (download_queue) and processes them one at a time, each resolving its stream and subtitle. Progress is reported through Action::UpdateDownload and the status bar; failures pause and preserve partial data.
  • Season downloads ask for the subtitle policy once per batch. The selected language, including an explicit None choice, is reused for every queued episode.

Selected subtitle sidecars are saved next to the video using ISO 639-1 language codes (e.g. .en.srt, .hi.srt) and supported subtitle extensions (.srt, .vtt, .ass, .ssa, .sub).

Download Bar & Progress Architecture

  • High-Contrast Responsive Bar: Renders a proportional progress track ([━━━━━────] on modern terminals and [=====>----] on basic terminals) with prominent media title display (⬇ Downloading: <Title>), percentage badge, and separated transfer metrics (<Size> | <Speed> | ETA <Time>).
  • Monotonic DASH Normalization: Multi-stream MPEG-DASH downloads via yt-dlp automatically normalize segmented tracks (video 0–90%, audio 90–98%, and track merger 99–100%) so that progress strictly increases and never resets backwards to 0% mid-download.
  • Throttled Updates: Progress events are throttled to 250ms intervals, eliminating terminal flicker and event-channel flooding from high-frequency chunk streams.
  • Background Download Continuity: Downloads continue running uninterrupted in the background when switching content providers (Ctrl+P) or toggling modes (Ctrl+T, Ctrl+A), keeping all active transfer workers and queues alive.
  • Isolated Cancellation Hitbox: Cancellation is bound strictly to the x / X keyboard shortcut and the [x] Cancel button in the top-right corner of the download bar. Clicking anywhere else on the bar safely consumes the mouse event without interrupting active downloads.

Outcomes

DownloadCompleted / DownloadPaused / DownloadFailed drive the UI status and notifications. ClearCache and stale-file cleanup do not touch in-progress downloads.

Addon Mode (HTTP Addons)

Addon Mode enables support for community HTTP addon manifests. You can install any standard addon manifest URL to fetch metadata catalogs and aggregate direct HTTP/HTTPS media streams.

Features

  • Standard Protocol Support: Compatibility with standard addon manifests (/manifest.json, /catalog, /meta, /stream).
  • Core Metadata Protection & Fast Resolution: Cinemeta is pre-installed out-of-the-box as the core metadata provider ([Core]) and locked to prevent accidental removal. Metadata requests prioritize media type resolution with full support for alternate crew fields (directors, writers, stars).
  • Direct HTTP Stream Engine: Automatically extracts and filters direct Cloudflare R2, PixelDrain, direct video CDN, and HubCloud/HubDrive HTTP streams.
  • Multi-Addon Concurrency: Simultaneously queries all enabled stream addons and aggregates releases.
  • Quality, Resolution & Codec Parsing: Ranks streams with high-contrast color-coded resolution badges (4K UHD, 1080p FHD, 720p HD, SD) and granular audio/video codec tags (HDR, DV, ATMOS, 5.1, HEVC, AV1, BluRay, WEB-DL, REMUX), file size in GB/MB, and audio language tracks (e.g. [Dual], [Multi], Hindi + English).
  • Series & Episode Hierarchy: Series are automatically organized into explicit Seasons and Episodes selector panes with smooth horizontal navigation (//h/l/Tab). Selecting any episode drives episode-specific stream requests (/stream/series/:id:season:episode.json).
  • Episode Stream Isolation: Built-in token parsing (parse_season_episode) guarantees that only streams matching the selected season and episode are displayed, eliminating cross-episode stream mixing.
  • Direct Playback & Custom Headers: Video stream headers (behaviorHints.headers) such as Referer and User-Agent are preserved and forwarded directly to external media players (mpv, IINA, VLC) and the multi-segment downloader.
  • Watch History & Progress Parity: Full /history support in Addon Mode with real-time mpv position tracking, scrub lines, and auto-resume.
  • High-Performance Caching: Curated /browse catalogs are cached for 1 hour, manifests for 24 hours, and stream aggregations for 2 hours.

Entering Addon Mode

  • Ctrl+A: Toggle / Enter Addon Mode.
  • Ctrl+S: Return to standard Streaming Mode.
  • Ctrl+T: Toggle TV Mode.
  • /browse: Browse curated addon catalogs (Top Movies, Top Series, Top Rated Movies, Top Rated Series).
  • /settings → Content Modes: Enable or disable Addon Mode navigation.

Addon Manager

  • Interactive modal listing installed addons with capability badges ([Core], [Meta], [Streams], [Catalog]).
  • [x] / [ ]: Toggle addon enabled/disabled state (Enter or Space). Core provider remains locked.
  • [ Add Manifest URL ]: Install any public HTTP addon manifest by URL.
  • [d] or [Delete]: Remove the selected addon (protected for core addons).

Persistence

Installed addons are atomically saved to addons_config.json inside the application config directory (~/Library/Application Support/moviebox-tui/ on macOS, ~/.config/moviebox-tui/ on Linux, %APPDATA%\moviebox-tui\ on Windows). If addons_config.json encounters corrupt data on disk, it is preserved and rotated to addons_config.json.corrupt.{timestamp} before initializing fallback defaults, preventing silent data loss.

TV Mode

TV mode streams live channels from M3U playlists. You add playlists by URL or local file path, and the app parses, groups, dedupes, and lets you search and play them.

Entering TV mode

  • Ctrl+T toggles Streaming / TV mode.
  • On first entry with no playlists, the playlist manager opens.
  • While in TV mode, type to filter channels by name or group, Enter to play, /list for all channels, /config to manage playlists, [r] to reload.

Adding playlists

  1. /config opens the playlist manager, split into URL playlists and File playlists.
  2. Select [ Add URL ] or [ Add file ], type the source, Enter to add.
    • URL example: https://example.com/playlist.m3u
    • File example: ~/playlists/mine.m3u
  3. Sources persist in tv_config.json (under the config dir). Local file playlists are reread directly on every TV-mode entry; remote URL playlists may reuse a recent cached snapshot for up to 24 hours. If tv_config.json encounters corrupt data on disk, it is safely rotated to tv_config.json.corrupt.{timestamp} rather than deleted.
  4. Highlight a source and press d (or Enter) to remove it; the list reloads.

src/providers/tv/ parses each source (http(s) or local file), extracting channel id, name, logo, group-title, and stream URL. Playlist lines are pre-counted to preallocate vector capacity, eliminating dynamic heap reallocations during large 50,000+ channel imports. Channels are deduped by stream URL across all playlists. The search box filters by name or group; the status bar reports how many channels were imported and which playlists failed.

Playback

Enter on a channel launches the default player with the channel URL (via the same launch_player path as movies). Channel logos are cached under the iptv image namespace.

Commands in TV mode

  • /list — display all loaded TV channels.
  • [r] key — reload all active M3U playlist sources.
  • Global commands (/settings, /clear, /help, /exit) are active across all modes.
  • Streaming/Addon-only commands (e.g. /browse, /history, /favorites) display friendly guidance notifications prompting you to switch modes (Ctrl+S or Ctrl+A).

Architecture

MovieBox-Tui is a terminal client (ratatui + crossterm + tokio) for streaming movies, series and TV channels from multiple providers. This document describes the shape of the code and how data flows through it.

Module map

src/
  main.rs                       entry point: logging init, panic hook, raw mode,
                                alternate screen, App::new + App::run
  lib.rs                        crate root, module declarations
  cache.rs                      disk cache: provider-namespaced, TTL'd, atomic writes
  config.rs                     Config load/save (config.json)
  download.rs                   download engine (resume, ranges, segments, retry)
  favorites.rs                  starred-titles persistence (favorites.json)
  history.rs                    watch history persistence
  logging.rs                    file logging (rotation, sanitization)
  models.rs                     shared domain models (SearchResult, BrowseMetrics, StreamPool,
                                Notification, SubjectIdentity)
  net.rs                        fallback DNS resolution, HTTP client builder, URL validation
  player.rs                     player detection (OnceLock) and command construction (mpv/VLC/IINA/Android)
  providers/
    mod.rs                      provider module tree
    models.rs                   shared typed models (ProviderKind, CatalogItem,
                                MediaDetails, Release, PlaybackSource, …)
    moviebox/                   primary provider (client + request signing)
    fourkhdhub/                 4KHDHub provider (client, hubcloud resolver, parser)
    bdix/circleftp/             BDIX CircleFTP provider
    bdix/dhakaflix/             BDIX DhakaFlix provider
    addons/                     Community HTTP addons provider
    tv/                         Live TV / IPTV provider (M3U parser and models)
  service.rs                    MovieBoxService headless engine (search, details, streams, captions)
  updater/                      GitHub release update check (mod, check, download, verify,
                                extract, apply, artifact)
  tui/
    app/                        the application object and all behavior
      mod.rs                    App struct, App::new, helpers
      run.rs                    terminal event loop (run), rendering (draw),
                                and handle_action dispatcher (thin routing table)
      network.rs                poster fetch + provider dispatch helpers
      search.rs                 search command routing, search request setup,
                                provider search dispatch, poster prefetch
      playback.rs               player launching + playback actions
      download.rs               download orchestration actions
      favorites.rs              favorite toggle/open actions, /favorites virtual list
      requests.rs               suggest/history/homepage/details/preview/
                                episode-stream actions
      navigation.rs             list navigation, submit actions, provider helpers
      tv.rs                     TV mode: playlist manager + playback
      addons.rs                 Addon mode: addon manager + HTTP addon actions
      keyboard.rs               raw key-event handling
      mouse.rs                  mouse click handling and hitbox routing
      system.rs                 help, refresh, cache, theme, updates, focus, resize
    state.rs                    AppState: all UI state + in-memory LRU caches
    action.rs                   the Action enum (event/message model)
    commands.rs                 Slash command registry, parsing, and suggestions
    event.rs                    EventHandler: input events + tick → Action channel
    overlay.rs                  popups, pickers, notifications
    screens/                    render-only modules (home, details, help)
    terminal.rs                 terminal capability probes
    theme.rs                    color themes
    widgets/                    reusable widgets (badge, input, modal, poster, scrollbar, settings)
    text.rs                     grapheme-safe text helpers and zero-allocation cursor slicing

The event loop

App::run (in app/run.rs) owns the only loop:

  1. If clear_terminal_before_draw is set, the terminal buffer is cleared.
  2. If state.dirty, the screen is drawn (App::draw).
  3. tokio::select! waits for either:
    • an Action from the EventHandler (keyboard/mouse/focus/resize/tick), or
    • an Action pushed by a background task (network results, downloads, posters).

EventHandler (event.rs) spawns one task that reads crossterm events and a Tick interval, forwarding them into the action channel (capacity 128).

Async model

  • The tokio runtime is multi-threaded (rt-multi-thread).
  • State is single-threaded: all mutations to AppState happen inside handle_action, which is driven by the single event-loop task. Actions are serialized through the channel, so there are no data races on UI state.
  • Network uses async reqwest clients (one per provider) plus per-provider signing.
  • Blocking work (disk cache reads/writes, image decoding, M3U parsing, watch-history save, log cleanup) runs on tokio::task::spawn_blocking so the event loop is never blocked.
  • Background tasks send Action messages back (e.g. SearchSuccess, EpisodeStreamsReady, DownloadCompleted), which handle_action consumes.
  1. User types a query; the Key handler updates search_query and sends Action::Search.
  2. handle_action resolves the active provider, dispatches to the provider client (async), and spawns the request in a background task.
  3. On success the task sends Action::SearchSuccess; handle_action stores search_results, marks dirty, and writes the provider search cache.
  4. Posters for result rows are fetched by background tasks and delivered via SearchPosterLoaded/PosterSuccess; image protocols are cached per terminal.
  5. App::draw renders the results; dirty is cleared.

Playback flow

  1. User selects a result → Action::PlayStream (moviebox) or 4KHDHub/BDIX resolve.
  2. The provider resolves a PlaybackSource (url + optional headers/subtitle).
  3. launch_player builds the player command (player.rs), optionally downloads the subtitle to a temp file, and spawns the player with null stdin/stdout and piped stderr; a blocking task waits and reports crashes.
  4. Playback is handed to mpv / VLC / IINA / Android intent per the active player.

Configuration and persistence

  • config.json — settings (mode persistence, mode toggles, theme, provider, auto-update, default_player, download directory, BDIX) in the config dir.
  • addons_config.json — installed HTTP community addons in the config dir.
  • tv_config.json — user M3U playlist sources (URLs or file paths) in the config dir.
  • history.json — watch history in the system data dir.
  • favorites.json: starred titles in the system data dir, independent of history.json.
  • playback/ — temporary playback states for session crash/kill reconciliation in the system data dir.
  • scripts/ — bundled player scripts (moviebox_tracker.lua) in the system data dir.
  • Cache lives under the system cache dir, keyed per provider.
  • Logs live under the system data dir with rotation.

See config.md and logging.md for exact locations and formats.

Modules

The crate (moviebox_tui) is split into top-level modules and, inside tui, an app directory that holds the application object. Below is the full tree with each module’s responsibility.

src/
  main.rs            Entry point. Logging init, panic hook, raw mode, alternate
                     screen, TerminalGuard, App::new + App::run.
  lib.rs             Crate root: declares pub mod cache/config/download/favorites/
                     history/logging/models/net/player/providers/service/tui/updater.

  cache.rs           Disk cache: provider-namespaced directories, TTL expiry,
                     atomic temp-file writes, payload validation, background purge.

  config.rs          Config struct: load/save config.json (mode persistence,
                     mode toggles, provider, theme, auto-update, default player,
                     download directory, bdix flag).

  download.rs        Download engine (pure, async): resume via .part files,
                     HTTP ranges, optional multi-segment download, retries, cancel
                     via an AtomicBool, Windows-safe file stems.

  favorites.rs       Starred titles: read/write favorites.json, whole-title identity
                     dedupe via SubjectIdentity, no cap.

  history.rs         Watch history: read/write history.json, dedupe exact
                     provider/subject/episode entries, cap 100.

  logging.rs         File logging: flexi_logger, rotation (5MB, keep 3),
                     MOVIEBOX_LOG level, URL/path sanitization for sharing.

  models.rs          Pure domain data models: SearchResult, BrowseMetric,
                     BrowsePreset, BrowseMetrics, SubjectStreamPool, Notification,
                     SubjectIdentity (cross-provider identity rules shared by
                     history and favorites).

  net.rs             Shared HTTP plumbing: FallbackResolver (hickory DNS reading the
                     OS configuration, falling back to Cloudflare/Google/Quad9 when
                     absent) wired into every reqwest client via
                     net::http_client_builder().

  player.rs          Player detection (OnceLock) and command construction for
                     mpv / VLC / IINA / Android intent, subtitle args, headers,
                     terminal-sized window.
  player/
    tracker.rs       Injected Lua tracker script (`moviebox_tracker.lua`) and
                     periodic 5-second playback state auto-saving.

  providers/
    mod.rs           Module declarations.
    models.rs        Shared typed models (ProviderKind, CatalogItem, MediaDetails,
                     Release, PlaybackSource, RequestContext, SourceMirror) and
                     canonical JSON domain adapters.
    moviebox/        Primary provider.
      client.rs      Async reqwest client with signed requests (anti-bot).
      crypto.rs      Request signing: HMAC-MD5 signature, client token,
                     spoofed device identity (by design of the scraper).
      title.rs       clean_moviebox_title: strip quality/site suffix noise.
    fourkhdhub/      Secondary provider.
      client.rs      Search/details/stream resolution + preflight validation.
      hubcloud.rs    Mirror resolver: fetch drive pages, extract playable links.
      parser.rs      HTML parsing into typed CatalogItem/MediaDetails/Release.
    bdix/
      circleftp/     BDIX CircleFTP provider (client + parser).
      dhakaflix/     BDIX DhakaFlix provider (client + parser).
    addons/          Community HTTP addons provider (client, aggregator, adapter, models).
    tv/              Live TV / IPTV provider (models + M3U parser).

  service.rs         MovieBoxService: unified multi-provider headless client &
                     engine (suggest, search, details, homepage, resolutions,
                     captions, subtitle download, path resolution).

  updater/           GitHub release update check.
    mod.rs           Module declarations, re-exports, perform_self_update orchestration.
    check.rs         GitHub release API query (with redirect fallback) and version compare.
    download.rs      Release asset download (https-only) with retry.
    verify.rs        SHA-256 hashing and sha256sums parsing for artifact verification.
    extract.rs       tar.gz / archive extraction for the staged binary.
    apply.rs         Swap in the new binary, install-environment detection, restart.
    artifact.rs      Release/ReleaseAsset types, target-platform matching.

  tui/
    action.rs        The Action enum: every UI event/message (input, network
                     results, downloads, playback, tv, system).
    commands.rs      Slash command registry (SlashCommand enum, argument parsing,
                     availability filters, dynamic suggestions, descriptions).
    state.rs         AppState: all UI state, LRU image/preview caches, and the
                     PlayerKind enum + label()/parse(), tv manager row model.
    event.rs         EventHandler: crossterm event stream + tick interval,
                     forwards to the action channel.
    overlay.rs       Popups: notifications, pickers, confirmation, modal centering.
    screens/
      home.rs        Home/startup + search list rendering (streaming and TV).
      details.rs     Details screen rendering.
      help.rs        Keybinding help (mode-aware).
    terminal.rs      Terminal capability probes (basic UI, image querying).
    theme.rs         Color themes + terminal color detection.
    text.rs          Grapheme-safe text input buffer (TextInputBuffer) and width/truncation helpers.
    widgets/         Centralized UI widgets subsystem.
      badge.rs       Resolution pill badges and audio/video media tag extraction.
      input.rs       Single-line text input field rendering with grapheme cursor and truncation.
      modal.rs       Modal dialog frame builder (ModalFrame) and centered footer key action bars.
      scrollbar.rs   Viewport-accurate vertical scrollbars.
      poster.rs      Standardized poster placeholder container with in-flight loading animation.
      settings.rs    Interactive 4-tab Settings Hub modal widget.

  tui/app/           The application object (App) and all behavior.
    mod.rs           App struct, App::new, and small helpers.
    run.rs           App::run (event loop), App::draw (rendering), and
                     handle_action dispatcher (thin routing table over action groups).
    network.rs       fetch_poster_bytes, decode_poster, provider_search,
                     provider_details.
    search.rs        Search-mode command routing, search state setup, provider
                     search dispatch, poster prefetch helpers.
    requests.rs      handle_requests: suggest/history/homepage/details/preview/
                     episode-streams/poster actions.
    playback.rs      handle_playback: play/subtitle/picker/launch/crash actions
                     + launch_player.
    download.rs      handle_download: download orchestration + start_resilient_download.
    favorites.rs     handle_favorites: toggle/open favorite actions, /favorites virtual
                     list builder.
    navigation.rs    handle_navigation + provider/nav helpers.
    keyboard.rs      handle_key: raw key-event handling.
    mouse.rs         handle_mouse: mouse click routing and hitboxes across screens,
                     popups, tabs, buttons, and dialogs.
    system.rs        handle_system: tick/quit/focus/resize/help/refresh/cache/
                     theme/status/updates.
    tv.rs            handle_tv: playlist manager + TV actions.
    addons.rs        handle_addons: addon manager + HTTP addon actions.

See architecture.md for the event loop, async model and data flow, and the per-topic docs for details.

Cache

Disk caching lives in cache.rs; in-memory caches live in AppState.

Disk layout

<cache dir>/moviebox-tui/
  <provider>/            moviebox, fourkhdhub, bdix_circleftp, bdix_dhakaflix, addons
    search/<hash>_<page>.cache
    details/details_<schema><hash>.cache
    streams/<schema><hash>_<season>_<episode>.cache
    images/<hash>.img
  moviebox/
    homepage/home_<tab>_<page>.cache
    captions/captions_<hash>.cache
  addons/
    catalogs/catalog_<hash>.cache
    manifests/manifest_<hash>.cache
    streams/<hash>_<season>_<episode>.cache
  tv_playlists/<md5>.m3u       cached remote playlist snapshots

The cache directory is dirs::cache_dir()/moviebox-tui (macOS ~/Library/Caches, Windows %LOCALAPPDATA%, Linux $XDG_CACHE_HOME).

Properties

  • Binary MessagePack Envelopes: Cache entries are serialized with rmp-serde wrapped in a binary envelope starting with the 4-byte magic signature MBC1 and an 8-byte TTL timestamp (CacheEnvelope<T>). Legacy JSON files are read and migrated on the fly.
  • Fast Table-Lookup Hex Hashing: Cache file naming and key hashing in md5_hex uses static 16-byte lookup table encoding, eliminating dynamic core::fmt::write formatting allocations and speeding up digest encoding by 2.51x.
  • Provider namespacing: Keys include provider.cache_key(), preventing collisions across sources.
  • Atomic writes: Entries are written to a unique temp file (path.with_extension("tmp-PID-STAMP")) and atomically replaced (durable_replace), preventing truncated or corrupt files on unexpected exits.
  • Validation: Empty search or stream results are never written or served from cache.
  • Purge: Background cleanup runs at startup to delete entries older than 7 days. /settings → Maintenance → Clear Disk Cache recursively empties all cached provider responses, images, TV playlists, temporary subtitles across Android/Windows/Unix, resets in-memory LRU caches, and cancels in-flight background request tasks.

In-memory caches (AppState)

  • image_cache (30), search_posters (300), failed_posters (300), search_poster_protocols (300), preview_cache (30): lru::LruCache for poster images, negative lookup cache, and terminal image protocols; stream_pool: resolved streams per subject.

All disk access in async code is wrapped in tokio::task::spawn_blocking so the event loop never blocks. Failures are logged (see logging.md) and treated as cache misses.

Logging

The app writes a file log so issues invisible in the TUI (full error text, URLs, statuses, content-types) are recorded and can be shared.

Location

  • macOS: ~/Library/Application Support/moviebox-tui/logs/
  • Windows: %LOCALAPPDATA%\moviebox-tui\logs\
  • Linux: $XDG_DATA_HOME/moviebox-tui/logs/ (else ~/.local/share/moviebox-tui/logs/)

The active file is moviebox-tui_rCURRENT.log; rotated files are moviebox-tui_r00000.log, .

Behavior

  • Level is controlled by MOVIEBOX_LOG (off|error|warn|info|debug|trace). Default is warn in release builds, info in debug builds.
  • Rotation: rotates at 5MB and keeps 3 files.
  • Terminal output: normal log lines go only to the file without writing to stdout or stderr, preventing screen bleed before entering alternate screen mode. Setup errors (if any) are reported on stderr.
  • Session header: version, OS, and the log path are written on startup.
  • Panics: the panic hook logs the payload to the file, then restores the terminal.
  • --version and --help never create a log file.

What is logged

  • error: hard failures (all-hosts exhausted, resolve failures, player spawn/crash, download failures, panics) and every Error: status the UI shows.
  • warn: recoverable issues (mirror rejected, subtitle unavailable, cache write failed, GitHub rate limit).
  • info: session start, playable mirror found, playback launch.
  • debug: full request context (enable with MOVIEBOX_LOG=debug).

Privacy / sharing

Logs are sanitized so they can be pasted into a GitHub issue:

  • URLs are reduced to scheme://host — file tokens, filenames, and query params are removed.
  • Absolute paths are rewritten to ~ so your username does not appear.
  • Headers, Authorization, search queries, and watch history are never logged.

Reproduce the problem, then attach the current log file. See debugging.md.

Cross-platform

Build targets: macOS, Linux, Windows, and Android (Termux via the Linux ARM64 binary). The codebase uses crossterm (all platforms), ratatui, and a couple of small per-OS branches.

“Build target” does not mean every runtime integration is verified on every device. Desktop builds are covered by CI; external players and Termux require the release checks in release-checklist.md.

OS notes

PlatformNotes
macOSIINA preferred player (via the installed IINA iina-cli); VLC/mpv .app paths detected. process_group(0) on spawn.
Windowsmpv/VLC detected via Program Files + %LOCALAPPDATA%; path-safe file stems; static MSVC CRT linking (+crt-static) for zero-dependency standalone binaries; handle-safe atomic download replacement (dropping file handles before renames); background process spawning (registry queries, yt-dlp downloader, and update helper) hardened with canonical CREATE_NO_WINDOW (0x08000000).
LinuxFlatpak mpv/VLC supported (flatpak run …); xdg data/cache dirs.
Android (Termux)Targets aarch64-linux-android linked against the Android NDK (Clang API 24+) and system Bionic libc.so, producing a native ELF executable with a valid PT_PHDR program header table and /system/bin/linker64 dynamic loader. This eliminates Could not find a PHDR: broken executable? crashes and executes natively without on-device compilation. Includes a pure-Rust DNS resolver that reads system configuration and falls back to public resolvers (Cloudflare, Google, Quad9) for zero-config name resolution. Android playback delegates to external video players (VLC for Android, Just Player, MX Player, MPV Android) via Termux intent dispatchers (termux-open, termux-open-url, termux-am), requiring pkg install -y termux-tools termux-am. To protect against Android 10+ SELinux execute restrictions (exit code 126), system /system/bin/am fallbacks are strictly avoided in Termux; LD_PRELOAD is preserved for Termux applets while PATH is sanitized for system calls. Android intent playback supports unauthenticated streams (CircleFTP, DhakaFlix, IPTV) and standard CDN streams (4KHDHub). Real-device chooser behavior is a release prerequisite.

Terminal capabilities

The app probes the terminal at startup via ratatui_image (400ms cap, off the UI thread). Non-graphics terminals (e.g. macOS Apple_Terminal, legacy Windows conhost, and TERM=dumb/linux/cygwin) are skipped to prevent escape sequence probe leakage (Gi=31...):

  • Poster rendering: Sixel, Kitty, and iTerm2 protocols where the probe detects them. Terminals that report kitty/sixel capability but no cell size (Windows Terminal sixel, iTerm2 over SSH) are salvaged with default cell metrics. On terminals lacking graphics support (e.g. standard Windows PowerShell, legacy console host, macOS Terminal.app), search result cards and details screens display standardized bordered containers with centered No Art indicators, ensuring consistent layout geometry without confusing broken blocks. automatically gated behind has_active_modal() to prevent graphic bleed through modal popups and overlays. MOVIEBOX_NO_IMAGE=1 disables queries; MOVIEBOX_IMAGE_PROTOCOL forces a protocol (kitty, sixel, iterm2); MOVIEBOX_CELL_SIZE=WxH overrides metrics.
  • Colors & Themes: With no explicit theme, NO_COLOR wins, then truecolor RGB (auto-detected across Ghostty, Kitty, WezTerm, iTerm2, Alacritty, Foot, Windows Terminal, Hyper, Tabby, Warp, and VSCode; enabled by default on Windows 10/11 console host and Windows Terminal), quantized 256-color palettes for strict terminals, and a tuned high-contrast 16-color ANSI fallback palette (Theme::fallback) using crisp cyan accents; an OSC 11 background query picks light/dark variants. Light mode themes (including Catppuccin Latte) are tuned for WCAG AA compliance, ensuring high-contrast readability across light terminal backgrounds. Modal pickers feature clean transparent border backdrops, minimum 7-row breathing room, and background selection suppression to isolate dialog focus. An explicit MOVIEBOX_THEME or saved theme always wins over autodetection.
  • Keyboard & Cursor: The kitty keyboard protocol (disambiguated escapes, event types) is requested at start and popped on exit; unsupported terminals ignore it. Real input cursor styling (SetCursorStyle::SteadyBar) activates during text editing modes on supported terminals.
  • Loading & Progress Indicators: Unicode Braille loading spinners (⠋ ⠙ ⠹ ...) render during search, metadata discovery, and stream fetching, falling back to clean text indicators (..) on basic/dumb terminals.
  • Window Titles: Contextual terminal emulator window titles are emitted dynamically reflecting active navigation mode and title (MovieBox-Tui — Streaming, MovieBox-Tui — Live TV, MovieBox-Tui — Addons, MovieBox-Tui — {Title}).
  • Terminal classification: TERM=dumb/linux fall back to a basic UI.
  • Focus events re-render in place without clearing; results render in two columns from 110 columns wide (three from 160).
  • Responsive Installers: Both Unix (install.sh) and Windows (install.ps1) installation scripts query terminal width dynamically (tput cols / stty size / $Host.UI.RawUI.WindowSize.Width), adapting the header across wide (72-column block art), compact (31-column 2-line half-block art for mobile/Termux portrait mode), and minimal (text-only) tiers with dynamic horizontal centering to prevent line wrapping.

Network & TLS portability

  • TLS Engine: Uses rustls with embedded Mozilla roots (webpki-roots) across all targets (macOS, Linux, Windows, Android/Termux). The release binary has no OpenSSL runtime dependency; the ring cryptography backend is compiled into the binary by the platform build toolchain.
  • DNS Resolution: Pure-Rust resolver (hickory) on all platforms: it reads the OS configuration first (/etc/resolv.conf, registry on Windows) and falls back to embedded public resolvers (Cloudflare 1.1.1.1, Google 8.8.8.8, Quad9 9.9.9.9) when no system configuration exists — as on Android/Termux or minimal containers. No JNI or ndk-context required.

In-App Self-Update Engine

MovieBox-TUI embeds an in-app binary upgrade engine (src/updater/) with cross-platform environment detection and deterministic fallback:

  • Direct Replacement: Supported on Linux (x86_64, aarch64), macOS (Universal binary), and Windows (x64, arm64). Downloaded release archives are validated against SHA-256 checksums, unpacked to temporary staging files, and swapped atomically with rollback on failure.
  • Windows Helper Script: On Windows, because running executables are locked by the OS, an external transient batch helper (moviebox_update_helper.bat) waits for the parent process PID to terminate, attempts atomic binary replacement with a 5-iteration retry loop (to tolerate antivirus/SmartScreen file locks), restarts the application, and self-deletes.
  • Homebrew Managed Environments: Automatically detected via path markers (/Cellar/, /opt/homebrew/, /usr/local/Cellar/, /home/linuxbrew/). In-app binary overwrites are disabled to protect package manager integrity; the update modal displays Homebrew instructions (brew upgrade moviebox-tui) with a dedicated [b] shortcut.
  • Android / Termux: Protects Termux environments from overwriting bionic libc binaries with incompatible Linux glibc binaries. Instructs users to re-run the universal installer script (curl -fsSL ... | bash).
  • Deterministic GitHub Asset Fallback: When GitHub API requests are unauthenticated or rate-limited (status 403), tag resolution falls back to HTTP redirects, and asset download URLs are computed deterministically from release tags rather than failing update operations.
  • Input Isolation & Event Locking: Update notifications defer blocking modal presentation while typing in search mode (InputMode::Editing) to prevent keystroke hijacking. During in-flight update execution (is_updating), all keyboard and mouse events are locked while displaying an active Braille progress spinner.

Things to verify per release

  • Player launch on each OS (mpv/VLC/IINA/Android intent) — window sizing, subtitles, headers.
  • Poster rendering across Sixel (Windows Terminal, foot), Kitty, iTerm2, and basic non-graphics terminals.
  • TV mode with a sample M3U playlist (URL and local file).
  • Addon Mode with sample HTTP addon manifests (Cinemeta, torrent/stream addons).
  • Termux: on-device check that Play opens the Android chooser and the stream plays.

Testing & QA Architecture

This document describes the testing architecture, quality assurance procedures, and validation guidelines for MovieBox-TUI.

1. Test Architecture

The test suite comprises 320+ automated tests across 10 test suites (213 unit tests in src/lib.rs and 110 integration tests across 9 focused suites in tests/), running fully offline by default without mocking or live network dependencies. The MovieBox-TUI test architecture follows a strict separation of concerns:

MovieBox-TUI/
├── src/
│   └── **/*.rs              # Pure algorithms & inline unit tests (#[cfg(test)])
└── tests/
    ├── common/
    │   └── mod.rs           # Shared test utilities & temporary directory helpers
    ├── fixtures/
    │   └── addons/
    │       └── manifest.json
    ├── settings_hub.rs        # Interactive Settings Hub modal tab navigation, choices, & option rows
    ├── tui_acceptance.rs      # Headless TUI rendering, theme rendering, and resize matrix
    ├── update_lifecycle.rs    # Update single-flight checks, modal hitboxes, & platform assets
    ├── content_pipeline.rs    # Content/metadata pipeline, stale request isolation, & cache keys
    ├── addons_manifest.rs     # Addon manifest deserialization & catalog checks
    ├── error_handling.rs      # Failure state cleanup, error toasts, and recovery
    ├── history_audit.rs       # Cross-mode watch progress, series advancement, & boundary audit
    ├── favorites_lifecycle.rs # Favorites persistence, identity, and navigation lifecycle
    ├── performance_audit.rs   # Empirical benchmark measurements (truncation, hashing, M3U, draw latency)
    └── live_stream_verification.rs # Live MovieBox CDN signed stream & resolution verification (opt-in)

A. Inline Unit Tests (src/**/*.rs)

Inline unit tests live inside #[cfg(test)] mod tests blocks within their respective modules. They verify:

  • Title normalization (clean_moviebox_title)
  • HMAC-MD5 cryptographic signing and token generation (generate_x_client_token, generate_x_tr_signature)
  • Segment partitioning math and byte range calculations
  • Internal helper logic, parsing functions, and release asset matching
  • Update modal layout geometry calculations and semver comparisons

B. Subsystem Integration Tests (tests/*.rs)

Integration tests live in the tests/ directory and test externally observable behaviors without mocking internal types:

  • settings_hub.rs: Validates the interactive Settings Hub modal tabs, choices, dynamic player detection refresh, mode toggles, and appearance settings.
  • tui_acceptance.rs: Validates headless TUI rendering, all theme palettes, end-to-end user journeys (search, details, navigation, mode switching), mouse click and scroll interactions, modal dismissals, and terminal resize matrices across 8 standard and boundary dimensions without panics.
  • update_lifecycle.rs: Validates update single-flight concurrency barriers, error recovery on network failure, modal actions, checksum integrity verification (valid, mismatch, missing, multi-format), archive extraction with strict path traversal rejection (..), active work protection (playback and download guards), environment detection (Homebrew, ReadOnly, DirectReplace), and safe atomic binary replacement/rollback.
  • content_pipeline.rs: Validates stale metadata response protection (request_id validation), cache key dimensional isolation, search failure vs empty result status distinction, mode-switch stale response isolation, poster image identity mapping, and search preview fallback metadata isolation.
  • addons_manifest.rs: Validates deserialization of Cinemeta/Stremio addon manifests, multi-season episode decomposition, episode stream isolation (parse_season_episode), token and codec parsing, core Cinemeta protection, and addon enabling/disabling lifecycle.
  • error_handling.rs: Validates active player session lifecycle, playback debounce guards, search failure cleanup, stream and download resolution failure notifications, URL scheme rejection, and authoritative player bypass protections.
  • history_audit.rs: Validates cross-mode watch progress, series advancement and completion tracking, threshold boundaries for in-progress states, history disk persistence roundtrips, Lua tracker reconciliation, update precision preservation, repeated play deduplication, and /history search list integration.
  • favorites_lifecycle.rs: Validates Favorites persistence boundaries, identity deduplication, /favorites loading, landing-row navigation, and independence from watch-history clearing.
  • performance_audit.rs: Validates empirical performance benchmarks and regression thresholds across algorithmic hot paths (SIMD text truncation, MD5 hex table lookup, M3U capacity preallocation, and headless frame draw latencies).
  • live_stream_verification.rs: Validates real-world stream link resolution across MovieBox signed CDN endpoints and 4KHDHub multi-mirror releases. The tests are #[ignore]-gated for offline execution; opt in with cargo test --test live_stream_verification -- --ignored.

2. Running Automated Tests

Run the full test suite (all unit and integration tests):

cargo test --all-features --locked

Run only unit tests:

cargo test --lib --all-features --locked

Run a specific integration test:

cargo test --test settings_hub --all-features --locked
cargo test --test tui_acceptance --all-features --locked
cargo test --test history_audit --all-features --locked

Run the opt-in live-network acceptance test:

MOVIEBOX_LIVE_TESTS=1 cargo test --test real_acceptance --all-features --locked -- --ignored

3. Code Hygiene and Static Analysis

Every commit and pull request must pass all hygiene checks:

# Check formatting
cargo fmt -- --check

# Compiler check
cargo check --all-targets --all-features --locked

# Clippy linter with warnings treated as errors
cargo clippy --all-targets --all-features --locked -- -D warnings

# Security vulnerability scan
cargo audit

4. Manual QA Matrix

Because TUI and media player interactions depend on terminal capabilities and external processes, manual QA testing covers:

Terminal Emulators

  • Ghostty (Primary testing terminal)
  • macOS Terminal.app
  • iTerm2
  • Windows Terminal
  • Linux VTE / Alacritty / Kitty
  • tmux session & pane switching

Supported Media Players

  • mpv (Full IPC tracking, script options, state reconciliation)
  • VLC (Local playback and stream forwarding)
  • IINA (macOS native player integration)
  • termux-open / Android Intents (Android Termux)

Key Flows to Verify

  1. Search & Browse: Type queries, switch between MovieBox, 4KHDHub, BDIX, Addons, and Live TV.
  2. Playback Launch & Return: Launch stream in player, exit player, verify terminal state is cleanly restored without residual escape sequences.
  3. History & State: Verify playback progress and watched checkmarks update accurately.
  4. Downloads: Test single episode and batch season download queuing.

5. Performance Verification & Benchmarking Guidelines

All performance optimizations in MovieBox-TUI must be backed by empirical before-and-after measurements. Changes without quantitative verification must be classified as refactors or code cleanups, not performance improvements.

A. Required Benchmark Measurements

When submitting or claiming a performance improvement, measure and report exact deltas:

  1. CPU & Algorithmic Hot Paths:

    • Measure wall-clock duration using std::time::Instant across ≥ 1,000 iterations.
    • Run benchmarks on release builds (cargo test --release or isolated binary harness) to reflect production compiler optimizations.
    • Report: Baseline vs. Optimized duration in microseconds (µs) or milliseconds (ms), plus relative speedup (N×).
  2. Memory & Allocations:

    • Count heap allocations and memory footprint deltas on hot paths (e.g., zero-copy slices vs. cloned String or Vec).
    • Report: Total allocations eliminated or reduction percentage.
  3. TUI Render Latency:

    • Measure full frame draw cycles using headless TestBackend:
      #![allow(unused)]
      fn main() {
      let backend = TestBackend::new(120, 30);
      let mut terminal = Terminal::new(backend).unwrap();
      let start = std::time::Instant::now();
      for _ in 0..1_000 {
          terminal.draw(|f| app.draw(f)).unwrap();
      }
      let avg_us = start.elapsed().as_micros() as f64 / 1_000.0;
      }
    • Report: Average draw duration per frame across standard terminal dimensions (80x24, 120x30).
  4. I/O & Syscalls:

    • Quantify eliminated filesystem operations (e.g. cache lookups, redundant directory reads) or network roundtrips.
    • Report: Number of disk reads/writes or HTTP requests saved per action.
  5. Release Binary Footprint:

    • Measure stripped release binary size (target/release/moviebox-tui).
    • Report: Baseline size, optimized size, and exact byte/kilobyte delta.

B. Standard Performance Reporting Format

Document benchmark results in PR descriptions, commit messages, or changelog entries using this structured format:

Benchmark: [Subsystem / Hot Path Name]
- Baseline:   [value] [unit] (e.g. 142.3 µs / op, 84 allocs)
- Optimized:  [value] [unit] (e.g. 12.1 µs / op, 2 allocs)
- Delta:      [multiplier]x faster (-[percentage]% allocations)
- Target:     [Architecture / OS, e.g. Apple M3 / arm64-darwin, release profile]

Debugging

The app writes a sanitized file log so full errors are available even though the TUI only shows a short status line. See logging.md for location and settings.

Reproducing an issue

  1. Run with debug logging: MOVIEBOX_LOG=debug moviebox-tui
  2. Reproduce the problem (search, open details, play, download, TV).
  3. Grab the current log file (path printed at startup, and in the log’s session header):
    • macOS: ~/Library/Application Support/moviebox-tui/logs/moviebox-tui_rCURRENT.log
    • Windows: %LOCALAPPDATA%\moviebox-tui\logs\moviebox-tui_rCURRENT.log
    • Linux: $XDG_DATA_HOME/moviebox-tui/logs/moviebox-tui_rCURRENT.log (else ~/.local/share/moviebox-tui/logs/moviebox-tui_rCURRENT.log)
  4. Include it when opening an issue.

What to include in a GitHub issue

  • The version (moviebox-tui --version).
  • Operating system and terminal (e.g. macOS + iTerm2, Windows + Windows Terminal, Termux).
  • The player used, if the issue is playback.
  • The log file (sanitized — safe to share; URLs and paths are redacted).

Reading the log

Each line is [timestamp] LEVEL [module:line] message. Focus on ERROR lines first; WARN lines explain recoverable fallbacks (e.g. a 4KHD mirror rejected, subtitles unavailable). With MOVIEBOX_LOG=debug you also get request context.

Known quick checks

  • “Player unavailable” → no mpv/VLC/IINA detected; set MOVIEBOX_PLAYER or install one.
  • “no playable mirrors” on 4KHD → all mirrors were rejected by the preflight; the log lists each mirror and the reason.
  • TV mode “no channels” → playlists failed to load; the log names the failing source.

Release Checklist

Use this before calling a new build production-ready. Static gates are necessary but not sufficient for this project because player launch, terminal rendering, and Termux chooser behavior depend on the real runtime environment.

1. Static gates

Run the repository checks first:

cargo fmt --check
cargo clippy --all-targets --all-features --locked -- -D warnings
cargo check --all-targets --all-features --locked
cargo test --all-features --locked
cargo audit
cargo package --locked

Confirm the entire unit and integration test suite passes on the CI host matrix (docs/testing.md). Release targets that are cross-compiled must at least build cleanly and pass the release workflow’s target-binary --version smoke test; they still require native player/runtime checks before release certification. A local host without the target C/linker toolchain cannot substitute for that runner result. Known gap: the Windows ARM64 binary is built and published but never executed by the release workflow (x64 runners cannot run it); smoke-test it manually, e.g. under Windows on ARM emulation or a native ARM64 device, before certifying a release.

Confirm the main GitHub Actions workflows are green:

  • CI
  • Release
  • Publish to Crates.io when applicable
  • Update Homebrew Formula when applicable

If you manually dispatch Publish to Crates.io or Update Homebrew Formula, run them against the explicit release tag, not a branch head.

2. Desktop playback checks

Verify at least one real playback launch on each supported desktop OS:

  • macOS: IINA and/or mpv/VLC
  • Linux: mpv and/or VLC
  • Windows: mpv and/or VLC

For each checked platform, confirm:

  • the player launches from MovieBox-Tui
  • the window size is reasonable
  • playback works for a source with no extra headers
  • playback works for a source carrying Referer / User-Agent
  • subtitles still attach for mpv / VLC / IINA

3. Terminal rendering checks

Verify poster rendering on the terminal families the docs claim to support:

  • Kitty protocol terminal
  • Sixel-capable terminal
  • iTerm2 protocol terminal
  • Non-graphics basic terminal (clean text placeholder)

Confirm:

  • posters appear on search/details screens
  • resize redraw still works
  • focus loss/gain redraw does not corrupt the screen after returning from playback

4. TV mode checks

Verify TV mode with both supported playlist source types:

  • remote http(s) M3U
  • local file M3U

Confirm:

  • playlist import succeeds
  • broken playlists report an error without breaking the app
  • dedupe by stream URL still behaves correctly
  • /config and /list work in TV mode
  • channel playback launches the player

5. Termux / Android checks

Verify on a real Termux device before calling the desktop release production-ready:

  • app starts normally
  • app does not reproduce the historical rustls-platform-verifier initialization panic
  • Play opens the Android chooser through termux-open or /system/bin/am
  • chosen player starts playback
  • downloads still go where the docs describe

This remains mandatory because chooser behavior is device/environment dependent.

6. Release artifact checks

Verify the published release contains:

  • expected archives for macOS, Linux x64, Linux arm64, Windows x64, and Windows arm64
  • SHA256SUMS
  • working install scripts / formula references

Spot-check:

  • install.sh
  • install.ps1
  • Homebrew formula install path

Exit criteria

Only call the release production-ready when:

  • all static gates pass
  • the relevant GitHub Actions workflows pass
  • the runtime checks above were performed on real target environments
  • no open blocker remains in docs/known-issues.md for the release target

Known issues and limitations

Tracked here so future work and issue reports reference the same facts.

Latent / by-design

  • supports_headers is compatibility policy, not just a parser guard. Sources that carry authentication headers (e.g. MovieBox CloudFront signed cookies) exercise it for Android intent and VLC playback. Android intent and VLC players support unauthenticated streams (CircleFTP, DhakaFlix, IPTV, direct streams) as well as streams with standard referer/user-agent headers (4KHDHub). Streams requiring custom cookies or auth tokens trip the compatibility gate and guide the user to mpv. Keep player.rs::supports_headers in sync with VLC and Android opener capabilities.
  • BDIX clients use nested if let Ok pyramids in search handling; they work and are logged, but are harder to read. Flattening is deferred (behavior-neutral refactor with moderate churn).
  • MovieBox request signing hardcodes an API secret and spoofs a device identity in crypto.rs. This is inherent to the scraper; treat the module as one unit.
  • Android intent playback forwards User-Agent, Referer, and subtitles (subtitles_location/subs) when using am or termux-am. Chooser-based launches via termux-open open the raw video URL directly.

Environment-dependent

  • 4KHDHub mirrors rotate and can be expired on upstream hosts. Direct streams are resolved concurrently across all available release mirrors using prioritized scoring (Cloudflare R2 / S3 / Seekable Streams → Storage → PixelDrain API → Google UserContent / Direct Attachments) and bounded concurrency (select_ok in chunks of 3). When all upstream mirrors for an older release are dead/expired (e.g. 404 or expired tokens), the resolver fails fast (<4.5s) and guides the user to select another release.
  • Termux playback needs the device confirmed on each release: termux-open / am availability and the Android chooser behavior. The historical rustls-platform-verifier initialization panic reported for v0.1.12 is not in the v0.1.13 dependency graph, but the upstream report remains open until a real Termux launch is observed.

Verification

  • Automated testing is enforced via cargo test --all-features --locked covering 346+ unit and integration tests across 21 test suites (see docs/testing.md). The count is updated when tests change; it does not replace real-player and real-device verification.
  • Static correctness is enforced by strict compiler type checking, the lint gate (cargo clippy --all-targets --all-features --locked -- -D warnings), formatting (cargo fmt --check), dependency vulnerability scanning (cargo audit), and packaging verification (cargo package --locked).
  • Runtime and platform-specific behavior (terminal resize, focus handling, external player launch, and Termux chooser) are verified through the release checklist in release-checklist.md.

Contributing to MovieBox-Tui

Thanks for taking the time to contribute. Bug reports, ideas, docs improvements, and pull requests are all welcome.

If you’re planning a large or breaking change, please open an issue first so we can talk it through before you invest significant time.

Getting set up

You’ll need Rust 1.90 or newer (edition 2024). Install it via rustup.rs.

# Fork on GitHub, then clone your fork
git clone https://github.com/<your-username>/MovieBox-Tui.git
cd MovieBox-Tui

# Add the upstream remote to keep in sync
git remote add upstream https://github.com/mesamirh/MovieBox-Tui.git

# IMPORTANT: Enable our pre-commit hooks to ensure your code formatting and lints pass
git config core.hooksPath .githooks

# Build and run
cargo run --release

To test playback and download features locally, install mpv (see Media Players).

Project layout

The app is message-driven and organized into focused modules. Full maps live in docs/architecture.md and docs/modules.md.

Short version:

  • src/tui/app/: The application object (App). run.rs holds the thin handle_action dispatcher that routes every Action to a handle_* method in its module (run.rs, requests.rs, search.rs, playback.rs, download.rs, navigation.rs, tv.rs, addons.rs, keyboard.rs, mouse.rs, system.rs, network.rs).
  • src/tui/: UI state, event loop plumbing, slash commands (commands.rs), screens, themes.
  • src/providers/: HTTP clients for streaming sources (moviebox, fourkhdhub, bdix), community HTTP addons (addons/), and Live TV playlists (tv/).
  • src/service.rs: Unified headless multi-provider client & engine.
  • src/download.rs: Background media downloading.
  • src/cache.rs: Local disk caching to minimize API calls.

The app is message-driven. User input and background tasks produce Action values, handled by the dispatcher in src/tui/app/run.rs. When adding behavior, prefer adding a new Action variant over blocking the UI thread.

Workflow

  1. Create a branch off main:
    git checkout main
    git pull upstream main
    git checkout -b feat/short-description
    
  2. Make your change in small, logical commits.
  3. Push and open a pull request against main.

Local Checks & Pre-Commit Hook

Formatting and linting are enforced automatically: the pre-commit hook (enabled during setup with git config core.hooksPath .githooks) runs cargo fmt --check and cargo clippy --all-targets --locked -- -D warnings on every commit, and the commit is rejected if either fails. You do not need to run them manually before every commit, but you should still run the full local/CI parity checks before opening a PR or cutting a release.

If the hook rejects a commit, run cargo fmt to auto-fix the formatting, then stage and commit again.

For release readiness, static checks are not enough on their own. Before declaring a release production-ready, work through docs/release-checklist.md.

Guidelines:

  • Follow idiomatic Rust and standard rustfmt defaults. Don’t hand-format.
  • Keep the async, message-passing architecture intact.
  • Avoid panics on paths that handle network or user input.
  • Don’t add new dependencies without a good reason. Mention it in the PR if you do.

Commit messages

Follow Conventional Commits. Keep the subject concise and in the imperative mood.

Examples:

  • feat: add support for custom mpv arguments
  • fix: prevent panic when clipboard is unavailable
  • docs: document /browse categories
  • refactor: extract stream resolution into helper

Common types: feat, fix, refactor, docs, style, perf, chore.

Pull requests

  • Keep PRs focused on a single concern. Large PRs mixing unrelated changes may be asked to be split.
  • In your PR description, explain what changed and why. Link related issues (Closes #12) and include screenshots or recordings for anything visible in the UI.
  • Never commit target/, editor settings, or debug dump files.

License

By contributing, you agree that your contributions will be dual-licensed under the MIT and Apache-2.0 licenses, consistent with the rest of the project.

Changelog

[0.1.18] - 2026-09-06

Added

  • Minimal Update Available Modal & Indented Release Notes:
    • Formatted release notes into a clean, scannable indented hierarchy under Release Notes: with category badges ([Added], [Fixed]) and bullet points, displaying concise feature titles without decorative tree glyphs, block prefixes (), or multi-line duplicate text walls.
    • Stripped decorative star icons and redundant prompt sentences, keeping the header focused on a clean, high-contrast version diff (Installed: vX.Y.Z → Latest: vX.Y.Z).
    • Separated dialog sections with subtle horizontal card divider lines () and dedicated action button pills ([u] Update Now, [o] Open Release Page, [Esc] Dismiss).
  • Calm, Minimal Self-Updating Progress Dialog:
    • Redesigned draw_updating_modal into a calm, focused card with top and bottom border clearances, eliminating visual crowding against the title and frame.
    • Streamlined the in-flight display into a unified active status line with spinner (⠋ Downloading MovieBox-Tui v... / ⠋ Installing MovieBox-Tui v...) and a cross-platform safety warning (⚠ Please wait • do not close terminal / [!] Please wait - do not close terminal).

Fixed

  • Landing Screen ASCII Banner Bleed-Through:
  • Modal Frame Corner Backdrops & Transparent Halos:
    • Removed block-level background color overrides from ModalFrame, eliminating dark rectangular halos and square pixel spillage around rounded corner glyphs (, , , ) across transparent and custom terminal themes.
  • Update Modal Geometry & Border Clearances:
    • Widened the modal from 72 to 76 columns to align with standard dialog geometry and provide a generous 3-column safety margin, preventing text lines and bullet points from crowding the outer borders.
  • Search Bar Synthetic Cursor Artifacts:
    • Removed artificial block glyphs ( / ) drawn directly into search input paragraphs, relying on native terminal cursor positioning without visual cursor duplication or blinking redraw churn.
  • README Walkthrough Media Attachment:
    • Formatted the WebM walkthrough attachment link in README.md and docs/README.md for native inline playback.
  • CI Performance Benchmark Runner Tolerance:
    • Bound wall-clock timing assertion tolerances during unoptimized debug test execution in tests/performance_audit.rs, eliminating flaky runner noise failures across virtualized CI runners while maintaining release regression bounds.

Performance

  • Zero-Allocation Text Truncation Pipeline (src/tui/text.rs):
    • Implemented SIMD is_ascii() fast path in width and migrated truncate_width to Cow<'a, str>, eliminating 100% of heap allocations on fitting titles and text spans.
    • Reduced 10,000-operation truncation latency from 5,243.5µs to 246.2µs (21.3x faster, 524.3ns -> 24.6ns/op) under release compiler profile on Apple Silicon.
    • Streamlined truncate_middle_width to construct output into a single preallocated buffer, eliminating intermediate Vec<&str>, reversal, and concatenation allocations.
  • Table-Lookup Hex Encoding (src/cache.rs):
    • Replaced 16 dynamic core::fmt::write dispatches per MD5 digest with direct 16-byte static lookup table indexing in md5_hex.
    • Reduced 10,000-digest hashing latency from 4,597.9µs to 1,829.8µs (2.51x faster, 459.8ns -> 183.0ns/op).
  • Preallocated IPTV M3U Playlist Parser (src/providers/tv/parser.rs):
    • Added newline-count capacity preallocation to M3UParser::parse_m3u, eliminating repeated dynamic vector reallocations during large playlist loads and achieving 352.0µs parse duration for 500-channel playlists.
  • Buffered Downloader Chunk Write Aggregation (src/download.rs):
    • Wrapped segment file descriptors in tokio::io::BufWriter::with_capacity(256 * 1024), aggregating incoming 8KB–16KB HTTP response chunks into sequential 256KB disk blocks and eliminating up to 96.8% of unbuffered filesystem write syscalls.
  • TUI Draw Loop Allocation Pruning (src/tui/screens/home.rs, src/tui/screens/details.rs):
    • Eliminated redundant display_title.clone() and duplicate Unicode width calculations in search result and landing deck render loops, delivering headless draw latencies of 32.3µs/frame (80×24), 43.4µs/frame (120×30), and 67.3µs/frame (160×40).

[0.1.17] - 2026-09-06

Added

  • Anchored Provider Selection Menu:
    • Replaced immediate mouse cycling on the landing search bar provider badge ([MovieBox · ^P]) with a styled popup menu anchored directly beneath the provider badge.
    • Added dedicated keyboard navigation (//k/j, Home/End, Enter/Space, Esc) for the provider menu while preserving direct Ctrl+P sequential provider cycling across all screens.
    • Implemented shared geometry (search_bar_provider_pill_rect and provider_popup_bounds) between renderers and mouse hitboxes, ensuring exact alignment and zero geometry divergence.
  • Redesigned High-Contrast Download Bar & Responsive Layout:
    • Replaced the solid rectangular download gauge with a sleek proportional track ([━━━━━────] on modern terminals and [=====>----] on basic terminals) with filled accent contrast and dimmed surface rail.
    • Added prominent media title indicators on the top border (⬇ Downloading: <Title> or ⬇ S<N>E<N> (<current>/<total>): <Title>) with bold styling and automatic terminal width truncation.
    • Replaced ambiguous whole-area click cancellation with an isolated [x] Cancel button hitbox on the top-right border, preventing accidental download interruptions while keeping the bar mouse-safe.
    • Formatted transfer statistics into clean badges (<Size> | <Speed> | ETA <Time>) with zero unclosed parenthesis artifacts and zero floating dots.
  • Details Screen UX & UI Deduplication:
    • Replaced repetitive audio language strings in the metadata header with a concise summary badge (N Audio Tracks), reserving line space for genre tags and IMDb ratings.
    • Eliminated the redundant workflow breadcrumb bar on wide/desktop layouts where selector columns are already visible side-by-side, reclaiming a vertical display row to show more episodes without scrolling.
    • Standardized selector list typography and cursor alignment, eliminating irregular bullet padding and double-space indentation across Audio, Season, and Episode items.
    • Deduplicated stream table columns by showing clean CDN/provider origins under SOURCE and stripping redundant resolution/codec suffixes from the RELEASE column.
    • Added count context to pane titles (Audio (N), Seasons (N), Episodes (N)), providing immediate visibility into available content quantities.
  • Native Android ARM64 Release Target & Pipeline:
    • Added native aarch64-linux-android build target to the release workflow (.github/workflows/release.yml) using Android NDK r26d and Clang (API 24+).
    • Configured automated packaging of MovieBox_Android_arm64.tar.gz with native Bionic dynamic linking (libc.so), valid ELF PT_PHDR program header table, and /system/bin/linker64 dynamic loader.
    • Added Android ELF header validation in CI to verify PT_PHDR and /system/bin/linker64 presence, preventing Could not find a PHDR: broken executable? aborts on Android devices.
    • Updated universal installer script (install.sh) to detect Android Termux on 64-bit ARM and automatically fetch MovieBox_Android_arm64.tar.gz with verified SHA256 checksums, enabling 1-second native installation without on-device compilation.
  • Native mdBook & GitHub Pages Documentation Architecture:
    • Integrated mdBook documentation engine reading directly from canonical docs/*.md guides with zero duplicated markdown files and zero third-party web frameworks.
    • Added docs/SUMMARY.md defining table-of-contents chapter navigation across all guides, architecture diagrams, and operational workflows.
    • Added docs/installation.md detailing complete installation instructions for macOS (curl script and Homebrew tap), Linux, Windows (PowerShell), Android (Termux), Cargo, and source builds.
    • Formatted docs/README.md as the book’s introductory landing page featuring core capabilities, prerequisites player matrix, and the live terminal demonstration video streamed from the GitHub CDN.
    • Added minimal root book.toml with navy dark theme, collapsible sidebar navigation, and client-side full-text search.
    • Added automated GitHub Actions deployment workflow (.github/workflows/pages.yml) publishing the documentation site to GitHub Pages on every push to main.
    • Added documentation build integrity validation step in CI hygiene pipeline (.github/workflows/ci.yml).

Changed

  • Codebase Cleanups, Dead Code Removal & Shared Logic Centralization:
    • Removed obsolete compatibility forwarders and dead code (render_favorites_landing, remove_last_grapheme, pad_to_width, ctrl_key, and unused shortcut constants).
    • Centralized theme_color in src/tui/theme.rs, eliminating duplicate definitions across widgets and screens.
    • Centralized favorite status lookups for active details into AppState::is_selected_details_favorited, unifying 30-line duplicate calculations in details screen rendering and mouse hitbox detection.
    • Unified subtitle picker label formatting ("None" -> "No subtitles", language sanitization) into format_subtitle_label.
    • Consolidated details pane border, title, and selection styling through pane_styles, eliminating over 50 lines of duplicate style branching.
    • Streamlined details footer action definitions into declarative primary/secondary group builders, cutting redundant code blocks while preserving exact keybindings and layout.
    • Hardened cross-platform process spawning by unifying the Windows CREATE_NO_WINDOW (0x08000000) flag into a canonical constant in player.rs.
    • Decoupled network URL validation by moving is_http_url to crate::net, eliminating backend network provider dependencies on the TUI text formatting module.

Fixed

  • Global Modal Background Unfocus & Dimming:
    • Automatically unfocused and dimmed all background components across Details, Home, and Runner views whenever any modal or popup dialog is active, replacing bright active borders, focus bullets, and selection highlight rectangles with dimmed styling (theme.muted).
    • Dimmed background resolution badges (Multi, 4K, 1080p, etc.) and provider origin tags to muted styling (theme.muted on surface backgrounds) during active modal popups, preventing neon badge colors from competing with foreground dialogs.
    • Dimmed unselected list items across Audio dubs, Seasons, Episodes, and Search Results to theme.muted, eliminating bright white text bleeds in the background.
    • Dimmed background footer shortcuts and download bar elements during open dialogs, ensuring visual focus remains strictly on the active foreground popup.
    • Suppressed terminal graphics protocol rendering for background posters when a modal dialog is open, preventing image pixels from bleeding over foreground confirmation dialogs.
  • Stream Table Source Column Resolution:
    • Prioritized specific mirror and uploader labels (file.source_label()) in the stream table SOURCE column before falling back to generic provider names, displaying actual source tags (Pahe.in, PSA, NF, GalaxyRG, etc.) when present while retaining provider fallbacks for direct CDN streams.
  • MovieBox DASH Progress Normalization, Throttling & Background Continuity:
    • Normalized multi-stream MPEG-DASH download percentages across video (0–90%), audio (90–98%), and merger (99–100%) stages, eliminating progress resets back to 0% when the video stream finishes and the audio stream begins.
    • Enforced monotonic progress tracking and throttled progress event emissions to 250ms intervals, eliminating terminal text jitter and channel saturation.
    • Preserved active downloads and queue processing across content provider switching (Ctrl+P) and mode toggling (Ctrl+T, Ctrl+A), eliminating premature download pauses and false cancellation warnings when navigating the TUI.
    • Added explicit cancellation feedback notifications when dismissing the subtitle selection popup via Esc or outside mouse click, preventing silent stream launch cancellations.
  • Empty Search Clear Guarding on Landing Screen:
    • Guarded search-cleared status notifications in Action::GoBack, c/C, and Ctrl+U to only fire when an active search query or loaded results actually existed, eliminating spurious “Search cleared.” status messages when navigating on an already-empty landing page.
    • Allowed pressing Enter on an empty search input in editing mode to cleanly switch back to normal mode without triggering unneeded state resets.
  • MovieBox DASH Stream Download Engine & Header Authentication:
    • Forwarded mirror authentication headers (Cookie containing CloudFront signed policy and Referer) through Action::StartDownload and start_resilient_download, eliminating HTTP 403 Forbidden errors on MovieBox CDN downloads.
    • Added dedicated MPEG-DASH stream engine utilizing yt-dlp to assemble multi-track audio/video manifests (index.mpd) into .mp4, maintaining full feature parity with progressive single-file downloads.
    • Integrated real-time child process progress parsing (parse_ytdlp_progress), reporting live percentage, speed, and ETA metrics to the TUI status bar.
    • Implemented dynamic, OS-tailored installation guidance for yt-dlp and ffmpeg when missing from the host system (Homebrew on macOS, package managers on Linux, WinGet on Windows, and Termux pkg install yt-dlp ffmpeg on Android).
    • Hardened Windows background process spawning with CREATE_NO_WINDOW and added cross-platform path resolution fallbacks for macOS Homebrew, Nix, and Termux environments.
    • Preserved external subtitle sidecar retrieval alongside DASH video downloads, maintaining clean <base_dir>/Movies/<Title>/ and <base_dir>/Series/<Title>/Season <N>/ directory hierarchy.
  • Series Season Default & Episode List Rendering Normalization:
    • Initialized unselected series search results with season: 0, preventing catalog season counts from masquerading as watch history progress and erroneously defaulting multi-season shows (e.g. Breaking Bad) to their final season on initial selection.
    • Guarded history pre-seeding in search submission strictly to /history queries and active continue-watching items, ensuring search results always open at Season 1 Episode 1 for new series while resuming at the user’s progress for previously watched shows.
    • Authoritatively resolved target season and episode in DetailsSuccess, preserving in-view season and episode positions across audio dub switches while defaulting fresh series navigation to Season 1 Episode 1.
    • Replaced "· " unwatched episode status prefix with clean whitespace padding, eliminating double middots (· · EP 01) and stray dots before unselected episodes in the details pane.
    • Guarded duration formatting against empty strings in MediaDetails, eliminating duplicate bullet dividers (· ·) in the metadata header for series without runtime durations.
  • Accurate Playback & Download Preparation Notifications:
    • Replaced misleading “Fetching subtitles” toast notifications during stream and episode download preparation with accurate stream preparation notices (Preparing <filename>... and Resolving episode stream...), eliminating false subtitle retrieval messages when streams rely on embedded subtitles or contain no external captions.
    • Clarified external subtitle download failure status to External subtitle unavailable; playing stream directly. to prevent ambiguity when video containers carry built-in subtitles.
    • Standardized download mirror error notice to No downloadable mirrors were found for this release. and normalized notification title casing.
  • MovieBox Subtitle Resolution & High-Speed Multi-Tier Aggregation:
    • Implemented multi-tier subtitle resolution in MovieBoxService::get_ext_captions with immediate early-exit (< 250ms) when the active stream provides rich subtitles (≥ 5 tracks), eliminating 15–20 superfluous sibling network round-trips that previously triggered 15-second playback resolution timeouts.
    • Replaced sequential nested loops for sibling dub crawls with concurrent parallel dispatch via futures::future::join_all, bounding multi-dub subtitle aggregation (e.g. Ek Deewane Ki Deewaniyat) to < 1.2s.
    • Added asynchronous background subtitle cache pre-warming in Action::EpisodeStreamsReady, fetching and caching subtitle options as soon as streams are received so that pressing Enter on a stream yields an instant < 1ms cache hit.
    • Resolved full multi-language subtitle availability (English, Bengali, Arabic, Chinese, Filipino, French, Hindi, Indonesian, Malay, Portuguese, Punjabi, Russian, Urdu) on MovieBox by linking genuine upload resourceId identifiers to releases instead of internal CDN transcoding stream IDs.
    • Filtered out 34-byte dummy placeholder caption files returned by transcoding endpoints and deduplicated subtitle tracks by language and download URL.
    • Added automatic fallback to subject resources in MovieBoxService::get_ext_captions when a stream ID does not directly attach captions.
    • Added in_id language code mapping to sanitize_language_label for localized Indonesian subtitle display.
    • Registered draw_subtitle_picker in App::draw, restoring the visual “Subtitles” modal picker overlay during stream playback and download preparation when external captions exist.
    • Tightened modal picker vertical height calculation in picker_layout, eliminating blank gap lines between the last list item and the bottom divider for short lists.
    • Hardened Action::PlayStream error handling with structured diagnostic warnings on subtitle timeout or resolution failure before dispatching direct playback.
  • Termux Android Player Exit Code 126 & Intent Bridge Resolution:
    • Eliminated Player Error: Crash code: 126 (/system/bin/am[11]: /data/data/com.termux/files/usr/bin/cmd: Permission denied) crash in Termux on Android 10+ by prioritizing native Termux openers (termux-open, termux-open-url, termux-am) and strictly avoiding unprivileged /system/bin/am shell script calls.
    • Preserved LD_PRELOAD for Termux applet compatibility while prepending system paths (/system/bin:/system/xbin) for system command invocations.
    • Added actionable diagnostic notifications when player execution fails or when no player is detected in Termux, directing users to install termux-tools termux-am and verify an external Android player (VLC, Just Player, MX Player).
    • Updated universal installer (install.sh), README, and documentation guides with termux-am prerequisites and architecture details explaining external Android video player integration versus headless CLI mpv.
  • Android Intent Player Stream Compatibility:
    • Eliminated blanket player incompatibility errors on Android: unauthenticated streams (CircleFTP, DhakaFlix, IPTV, direct streams) and streams carrying standard Referer/User-Agent headers (4KHDHub) now dispatch directly to Android video players via termux-open or am start.
    • Added empty-header guard to supports_headers, ensuring streams without authentication requirements are never falsely rejected as incompatible.
    • Forwarded User-Agent, Referer, and subtitles (subtitles_location and subs) as intent extras when dispatching playback via am or termux-am.
    • Prevented circular provider switch prompts when playing 4KHDHub streams by tailoring notification hints based on the active provider.
  • Documentation Mobile Layout & Typesetting Normalization:
    • Replaced unparsed LaTeX syntax ($\to$, $\ge$, $\mu\text{s}$, $N\times$) across all documentation guides with standard Unicode characters (, , µs, ), eliminating raw unrendered markup in mdBook output.
    • Added responsive documentation stylesheet (docs/custom.css) integrated via book.toml, enabling smooth touch horizontal scrolling, compact cell padding, visible scrollbars, and dynamic code text wrapping across mobile and small screen viewports.
    • Formatted provider matrix table in docs/providers.md with explicit column alignments and bold provider labels to optimize scannability on narrow screens.

Changed

  • Documentation Readability & Typography Polish:
    • Expanded reading container width (--content-max-width: 860px) and relaxed line-height (1.62em) with vertical list spacing (0.45em) in docs/custom.css.
    • Added theme-adaptive inline code badge containers (:not(pre) > code) with bordered backgrounds, and framed <pre> code blocks with rounded corners and drop shadows.
    • Added table row hover transitions and container borders across configuration, platform, and player documentation tables.
    • Implemented responsive mobile header title scaling (.menu-title) and smooth anchor navigation scrolling (scroll-behavior: smooth).

[0.1.16] - 2026-09-05

Added

  • Home Landing Deck Continue Watching & Multi-Tab Navigation:
    • Implemented interactive multi-tab landing deck on the Home screen supporting both Continue Watching and Favorites.
    • Added seamless Tab and Shift+Tab keyboard cycling between Continue Watching and Favorites tabs with instant row focus retention.
    • Added one-click/key direct resume (Enter, Space, or P) on Continue Watching items, automatically configuring episode advancement, season positioning, and auto-play in Details view.
    • Formatted Continue Watching rows with title truncation, series episode badge (S01E03), progress percentage, and remaining duration (45% · 24m left).
    • Added mouse support for clicking the landing deck header bar to switch tabs, and double-clicking items to play/open.
  • Windows TrueColor & High-Contrast Terminal Theming:
    • Enabled 24-bit TrueColor auto-detection by default on Windows 10/11 (conhost.exe, Windows Terminal, PowerShell, CMD), ensuring Windows users receive rich Catppuccin themes out of the box.
    • Overhauled 16-color ANSI dark fallback palette (Theme::fallback), replacing low-contrast dark blue and magenta with high-contrast cyan accents for borders, titles, headers, and highlights.
    • Added background row selection suppression in Settings Hub when modal popups (media player picker, theme picker, download directory input) are active, directing 100% of user focus to floating dialogs.
    • Clamped popup picker minimum height to 7 rows, eliminating visual crowding on single-item selections.
    • Elevated active selection surface styling to theme.surface1 with accent-highlighted cursor indicators ( / ) across lists and settings rows.
  • In-App Self-Update Engine Hardening:
    • Added deterministic fallback download URL generation for GitHub release assets and SHA256SUMS when unauthenticated API requests encounter HTTP 403 rate limits.
    • Added active in-flight self-update progress modal (draw_updating_modal) featuring animated Braille spinners, version upgrade indicators (v{old} → v{new}), and real-time status steps.
    • Added environment-aware update modal actions: displays Homebrew upgrade instructions (brew upgrade moviebox-tui) with [b] shortcut on Homebrew installations, Termux installer guidance on Android, and package manager notifications on read-only installations.
    • Added 5-iteration retry loop with bounded 1-second backoff in the Windows update helper script (moviebox_update_helper.bat) to tolerate transient file locks from antivirus or Windows search indexers during binary replacement.
    • Cached full Release metadata in AppState and action pipeline, eliminating duplicate network queries between release checking and self-update invocation.
  • Empirical Performance Standards & Benchmark Testing Guidelines:
    • Added strict performance verification standards requiring empirical before-and-after measurements (runtime latency, allocations, frame render latency, I/O syscalls, binary footprint) across hot paths.
    • Documented standardized performance benchmark reporting format in docs/testing.md for reproducible optimization audits.
  • Centralized Poster Placeholder & UI Animation Widgets:
    • Extracted reusable render_poster_placeholder widget to src/tui/widgets/poster.rs, standardizing placeholder containers, loading dots, and geometry clamping across Home and Details screens.
    • Centralized loading_spinner in src/tui/widgets, providing uniform ASCII fallback (.., ...) on basic terminals and animated Braille frames on modern terminals.
    • Added zero-allocation cursor helpers (cursor_prefix_str, cursor_column_offset, cursor_split_parts) to TextInputBuffer, replacing dynamic vector and string allocations with zero-copy slices during typing and cursor blinking.
    • Added step_list_selection to src/tui/state.rs, centralizing bounds-safe list stepping for PageUp and PageDown navigation across browse, theme, and favorites lists.
    • Added clear_poster_cache and clear_poster_protocols to AppState, guaranteeing consistent flushing of in-flight requests, LRU image handles, and terminal protocols across provider switches and search resets.

Removed

  • Poster Graphics Configuration & Halfblocks Engine:
    • Removed Unicode Halfblocks poster engine (/), eliminating low-resolution cell distortion, font scanlines, and terminal redraw lag during list scrolling.
    • Removed redundant Poster Graphics toggle from Settings Hub (/settings $\to$ Appearance) and config.json, delegating terminal graphics strictly to automatic native GPU protocol detection (Kitty, Sixel, iTerm2).

Fixed

  • Cross-Platform Handle Safety & Silent Failure Elimination:
    • Fixed Windows file sharing violation (ERROR_SHARING_VIOLATION) in multi-segment download assembly by explicitly flushing, syncing, and dropping the file write handle before executing destination renames.
    • Added overwrite handling on destination collisions during download finalization on Windows, preventing failed renames on re-downloaded media.
    • Guarded FavoritesManager::load_from_path against premature corrupt file rotation on transient read errors, matching history and configuration persistence invariants.
    • Hardened Lua tracker script and state file directory initialization to return None on directory creation or write failures rather than passing non-existent paths to media players.
    • Handled web browser launch failures in Settings Hub (open::that), logging warnings and displaying the repository URL on headless or restricted environments.
    • Added CREATE_NO_WINDOW flag (0x08000000) to the Windows update helper process spawn to eliminate console window flashes during in-app updates.
  • Resilient Cross-Platform Cache Clearing & In-Flight Task Isolation:
    • Hardened clear_all_cache with recursive directory contents deletion, leaving the root directory node intact to prevent ERROR_ACCESS_DENIED and ERROR_SHARING_VIOLATION failures when Windows processes or shells hold folder handles.
    • Added Windows read-only attribute clearing before unlinking locked files.
    • Included external Android subtitle cache directory (~/storage/downloads/moviebox_subs) and temporary system subtitle caches in the cache purge sequence.
    • Connected Action::ClearCache directly to self.request_tasks.cancel_all() and added cancellation guards in spawn_search_posters, preventing in-flight background requests from writing stale responses or posters immediately after cache clearance.
    • Propagated concrete filesystem Result<(), String> to Action::CacheCleared, replacing hardcoded success notifications with real error reporting.
  • Unified Search Result Selection Background:
    • Unified search result card selection highlight across the entire item slot (item_area), eliminating fragmented background rendering between cursor indicators, posters, and text columns.
    • Removed redundant poster sub-area buffer clearing before image rendering, preventing selection background clipping and black gutter artifacts on the right edge of posters.
  • High-Precision Playback Tracking & Race Elimination:
    • Eliminated wall-clock race condition where process elapsed time overwrote exact seek/pause positions from mpv and iina-cli Lua trackers.
    • Hardened moviebox_tracker.lua with latched completion: reaching $\ge 90%$ playback or EOF permanently latches completion, preventing shutdown events from reverting completed status.
    • Implemented atomic state file persistence in Lua using temporary files (.tmp) and clean destination replacement for Windows and Unix platforms.
    • Handled unknown stream durations by writing JSON null, preventing zero-duration calculations.
    • Pre-registered media playback on launch (record_start), ensuring immediate watch history persistence for Android intent dispatchers (termux-open, am start) and app fallbacks.
    • Added self-healing recovery in reconcile_from_dir: pre-seeded pending state files carry metadata (title, cover_url, stype, release_year), restoring new items into watch history even after sudden terminal exits or reboots.
    • Implemented smart series episode advancement: completing an episode automatically cues the next episode (episode + 1 or next season) on resume (Space/P) and in the Details view.
  • Details View Empty Stream Source Label Geometry:
    • Replaced verbose empty stream message with a compact string (No stream sources found on {provider} (Ctrl+P to switch provider, r to retry)), preventing awkward multi-line text wrapping on standard 80-column terminals.
  • Standardized ‘No Art’ Poster Containers Across Terminals:
    • Replaced robot eyes and broken infinite loading spinners with clean, static, centered No Art bordered blocks across search results and details screens on terminals without graphics support.
    • Preserved full-fidelity native GPU graphics rendering on supported terminals while standardizing card geometry and poster container boundaries across all platforms.
    • Gated background poster network requests and CPU image decoding strictly behind image_supported, eliminating redundant network bandwidth and CPU cycles on standard terminals.

Changed

  • Provider Switching Shortcut:

    • Scoped Ctrl+P strictly to Streaming Mode for provider cycling, eliminating redundant Ctrl+P handling in TV and Addon modes.
    • Streamlined /config as a direct alias for /settings.
  • Pruned Redundant Theme Slash Command:

    • Removed standalone /theme slash command, parser routing, and auto-suggestions; theme selection and visual palette swatches are managed directly within the interactive Settings Hub (/settings $\to$ Appearance $\to$ Theme).
  • Discover Categories Landing Card UX:

  • Clean Segmented Landing Deck Header Styling:

    • Replaced crowded decorative star () and bracket ([ ]) glyphs with a clean, segmented tab bar header (Continue Watching │ Favorites (Tab)).
    • Streamlined overflow row formatting to centered minimalist pill indicators (+N more · /history and +N more · /favorites).
    • Streamlined Discover & Quick Categories card: elevated /browse command to a right-aligned header badge ([ /browse ]), eliminated redundant /browse · row prefixes, and adapted category rows dynamically between Streaming and Addon modes.
    • Added direct mouse click navigation to discover categories, routing clicks to preset browse queries or the addon catalog menu.
  • Command Dispatch & Cache Lookup Optimization:

    • Unified ParsedCommand and SlashCommand into a single canonical enum, eliminating duplicate type definitions across command dispatch and testing.
    • Streamlined image disk cache lookups (get_namespaced_image_cache), eliminating 6-iteration fallback namespace scans across unrelated provider directories on cache misses.
    • Replaced duplicate is_termux_env in player module with crate::updater::artifact::is_termux_environment.
  • Automation Workflows & Installer Hardening:

    • Added bounded execution timeouts (timeout-minutes) across all CI and release pipeline jobs to prevent runner hangs.
    • Accelerated release preflight by eliminating redundant cross-compilation target toolchain downloads during source packaging.
    • Streamlined Homebrew formula updater (homebrew.yml) by parsing the release’s attested SHA256SUMS manifest directly with strict 64-char hex validation, eliminating redundant ~50MB archive downloads.
    • Added on-device binary execution smoke tests to install.ps1 and enhanced install.sh error diagnostics with API version resolution fallbacks.
  • Documentation & User Guide Streamlining:

    • Overhauled root README.md into a developer-focused technical guide, pruning marketing copy, redundant comparison tables, and promotional buzzwords.
    • Added structured media player setup guide with package manager commands (brew, apt, winget).
    • Updated macOS Homebrew installation with explicit brew trust step required by Homebrew 6.0+ for third-party taps.
    • Streamlined quickstart section to reference in-app interactive help (?) and docs/controls.md, preventing documentation drift.
  • Streamlined Test Architecture & High-Signal Test Suite:

    • Consolidated unit assertions for file stem sanitization, MD5 hashing, atomic writing, and badge rendering directly into their respective modules (src/download.rs, src/cache.rs, src/tui/widgets/badge.rs).
    • Pruned 10 redundant, weightless, and duplicate test suites (player_integration.rs, url_security.rs, download_integration.rs, m3u_integration.rs, cache_lifecycle.rs, real_acceptance.rs, grand_user_journey.rs, history_reconciliation.rs, version_upgrade_e2e.rs), reducing integration test files from 20 to 9 focused suites while preserving complete regression coverage.
    • Hardened .omp/AGENTS.md and docs/testing.md with strict engineering rules rejecting weightless tests, duplicate test layers, and monolithic multi-phase journey tests.
    • Aligned update modal keyboard tests with modal input isolation, verifying keystrokes do not fall through to background search results while the dialog is active.

Fixed

  • Responsive Text Sizing & Layout Truncation:

    • Raised Details footer split threshold (DETAILS_FOOTER_SPLIT_THRESHOLD) to 106 columns, ensuring shortcuts use a clean 2-row layout on terminals between 80 and 105 columns without clipping.
    • Omitted [Ctrl+P] Provider hint from the Details footer when in Addon mode or viewing addon streams, recovering 18 columns of footer space.
    • Added line-width budgeting to Details metadata: audios and extra metadata (Genre, Director, Cast) now dynamically truncate to available row width without wrapping beyond their allocated lines.
    • Synchronized Settings tab hit-testing (category_tab_rects) with compact rendering (popup_area.width < 58), resolving mouse click target divergence on compact terminals.
    • Added dynamic subtext and label truncation in Settings rows, preventing 2-row Paragraph wrapping and off-screen line displacement.
    • Replaced hardcoded path truncation in Settings download directory with dynamic middle truncation (truncate_middle_width), maximizing displayed path length while fitting compact rows.
    • Added dynamic description truncation to Home discover categories card, preventing overflow on narrow (50–54 col) screens.
    • Added responsive compact labels ([Try Provider (P)] and [Clear (c)]) and narrowed separation to No-Results buttons when terminal width is under 56 columns.
    • Removed obsolete Ctrl+P hint from search bar mode pill in Addon mode, replacing it with [Addon Mode].
    • Added available width clamping to non-landing search bar placeholders and status messages to prevent 1-row Paragraph wrapping.
    • Omitted redundant media type separator in search results metadata when terminal width is under 36 columns and release year is present, keeping provider badges intact.
    • Budgeted list entry lengths in TV Playlists and Addon Manager popups to fit within inner popup bounds regardless of installed badge counts.
    • Raised Help menu two-column threshold to 102 columns to prevent keybinding description truncation.
    • Added compact title formatting to download gauge when width is under 60 columns.
    • Added compact button formatting ([u] Update [o] Web [Esc] Back) to Update Modal on terminals under 60 columns.
    • Added compact header formatting to Updating progress modal when inner width is under 42 columns.
    • Added title boundary protection to ModalFrame, truncating overly long titles to preserve border integrity.
    • Eliminated dark rectangular halo artifact around modal popups by removing block-level background color overrides from ModalFrame, allowing rounded borders to cleanly render against transparent and custom terminal backgrounds without pixel spillage.
  • Resilient Configuration & Accurate Metadata:

    • Safeguarded user TV playlists (tv_config.json) and HTTP addons (addons_config.json): replaced destructive error-swallowing deletion with timestamped .corrupt.{timestamp} file rotation and sanitized logging on JSON parse failures.
    • Eliminated fabricated S01E01 fallback in addon metadata adapter, accurately reporting empty series episodes when an upstream catalog entry lacks episode records instead of injecting unplayable dummy data.
  • Discover Card Layout & Truncation:

    • Fixed horizontal text clipping on discover card category descriptions by adjusting margins_len to account for visual pointer and margin cell budgets.
    • Suppressed discover card rendering while search suggestions dropdown is open, preventing visual overlap.
  • Update Modal Input Isolation & Event Guards:

    • Prevented keystroke hijacking: deferred blocking update modal presentation while the user is actively typing in the search bar (InputMode::Editing), ensuring keys (u, o, Esc) never trigger unintended update actions.
    • Added input lock during in-flight updates (is_updating), consuming all keyboard and mouse events to prevent mid-upgrade process termination or disk corruption.
  • Comprehensive Multi-Platform Player Detection & Dynamic Settings Refresh:

    • Expanded Windows MPV and VLC candidate discovery across executable-adjacent directories (.\mpv.exe, .\vlc.exe), WinGet Packages (%LOCALAPPDATA%\Microsoft\WinGet\Packages), user Downloads and Desktop extractions, mpv.net (mpvnet.exe, mpv.net), mpv.com, Scoop apps and shims, Chocolatey, portable drive roots (C:\mpv, C:\vlc, C:\tools), and Windows Registry App Paths and Environment\Path.
    • Expanded macOS and Linux discovery across Nix profiles (~/.nix-profile/bin, /run/current-system/sw/bin), Homebrew, MacPorts, user .local/bin, and user/system Flatpak exports.
    • Replaced permanent negative caching (OnceLock<Option<String>>) with non-negative path caching across MPV, VLC, IINA, and Android Intent openers, ensuring players installed after cold start are discovered immediately.
    • Added non-destructive dynamic player detection merging to Settings Hub (ToggleSettingsPopup, ShowSettingsPopup), player selection activation, and value cycling, refreshing available_players in real time without requiring an app restart.
  • Direct Playback & Header Compatibility:

    • Eliminated vestigial in-stream “Open with” popup that blocked playback when only VLC was installed, routing playback directly to the preferred compatible player.
    • Prevented silent player overrides: when a user explicitly selects a default player (e.g. VLC) that cannot satisfy stream authentication headers (e.g. MovieBox signed DASH manifests), the app now halts playback and warns the user with actionable detected alternatives instead of silently launching an unselected player.
    • Added structured PlaybackResolution engine with dynamic context-aware notifications across playback resolution and download operations.
  • Terminal Graphics Probe Leak:

    • Prevented raw Kitty APC escape sequence leak (Gi=31...) on macOS Terminal.app and legacy non-graphics consoles by skipping graphics stdio probes.
    • Removed unsafe mid-session stdio graphics re-probing on FocusChange events.
  • High-Performance Player Detection Engine (src/player.rs):

    • Centralized OS executable probing (mpv, vlc, IINA) into a single probe_player_executable engine, stripping ~150 lines of duplicate path traversal.
    • Added static caching (OnceLock) to IINA resolution and Android Termux Intent detection, eliminating repeated expensive filesystem IO and PATH lookups during playback launches.
    • Expanded candidate resolution: added macOS MacPorts (/opt/local/bin/*) and standard /bin/* locations.
    • Aligned installer (install.sh, install.ps1) player detection with the app engine, explicitly probing standard /Applications/*.app and C:\Program Files deployments so GUI installations are correctly discovered immediately post-install.
  • Responsive Mobile Installer Headers (install.sh & install.ps1):

    • Implemented dynamic terminal column detection (tput cols, stty size, and $COLUMNS in install.sh; $Host.UI.RawUI.WindowSize.Width in install.ps1) with automatic multi-tier banner sizing.
    • Eliminated ASCII art banner wrapping and visual corruption on narrow mobile viewports (e.g. Android Termux portrait mode at 40–55 columns) by rendering an adaptive 31-column compact half-block banner (█▀▄▀█...) and dynamic horizontal centering.
  • Android Termux Static-PIE & TLS Alignment:

    • Linked aarch64-unknown-linux-musl target as static-PIE (-C relocation-model=pic -C link-arg=-pie) to produce ET_DYN (ELF e_type: 0x0003) binaries accepted by Android Bionic’s /system/bin/linker64, resolving runtime failure (unexpected e_type: 2).
    • Added 64-byte PT_TLS alignment anchor in src/main.rs and post-build ELF program header alignment in .github/workflows/release.yml to satisfy Android Bionic’s ARM64 TLS segment minimum alignment validation.
    • Added automated ELF e_type and PT_TLS validation checks to .github/workflows/release.yml and a post-installation execution smoke test to install.sh.

Removed

  • Pruned unused legacy type aliases (SeasonInfo, EpisodeInfo, StreamResource, StreamMirror) in src/models.rs.
  • Removed dead util_row struct field from LandingRows in src/tui/screens/home.rs.
  • Removed vestigial ShowPlaybackPicker and ShowPlayerPicker action variants and playback picker state fields in favor of direct compatible player dispatch.
  • Removed unreferenced static screenshot assets (assets/), reducing repository clone size by ~1.3MB.
  • Redundant Slash Commands:
    • Pruned 10+ legacy slash commands (/download-dir, /clear-cache, /update, /github, /probe, /toggle-update, /toggle-bdix, /toggle-streaming, /toggle-tv, /toggle-addons, /enable-*, /disable-*) superseded by the interactive Settings Hub.
    • Removed 300+ lines of redundant command execution and file write probing in src/tui/app/search.rs.
    • Removed duplicate unreachable Ctrl+U key handling in src/tui/app/keyboard.rs.

[0.1.15] - 2026-09-03

Added

  • MovieBox MPEG-DASH Stream Playback:
    • Implemented visitor login authentication with JWT session tracking and atomic disk persistence (~/.cache/moviebox-tui/moviebox_session.bin).
    • Added CloudFront DASH manifest resolution (index.mpd) labeled with [Multi] badge in stream listings for multi-resolution playback (1080p, 720p, 480p).
    • Forwarded authentication headers and mobile User-Agent to mpv, IINA, and VLC for authenticated CloudFront DASH demuxing.
  • Seekable 4KHDHub Stream Resolution:
    • Prioritized seekable Cloudflare R2, S3, and FSL stream mirrors (HTTP 206 Partial Content) over attachment downloads.
    • Added automatic unwrapping of base64 watch-online redirect URLs and expanded HubCloud button selectors.
    • Concurrently probe resolver mirror candidates in chunks of 3 with a 4-second timeout, filtering expired or broken links.
  • Interactive Settings Hub (/settings):
    • Added a unified 4-tab modal (General, Content Modes, Appearance, Maintenance) for media player selection, download directory configuration, live theme palette preview, and provider toggles.
  • TUI Layout & Ergonomics:
    • Added /exit slash command (with /quit and /q aliases) to exit and restore the terminal directly from the search prompt.
    • Added direct watch history resume on Space / P for the recorded season and episode.
    • In-place provider switching (Ctrl+P) on the Details screen to re-query titles without returning to the landing screen.
    • Multi-Esc navigation: first Esc returns focus to the search bar; second Esc clears the query and returns to the home landing.
    • Added fluid 10-frame Unicode Braille loading spinners (⠋⠙⠹...) with ASCII fallbacks.
    • Grapheme-cluster-safe text input (TextInputBuffer) across search, TV playlist, and addon inputs with Ctrl+W, Ctrl+U, Delete, and Home/End support.
    • Added 4-tier responsive stream table layout and dynamic single-column fallback for narrow terminals (<85 cols).
    • Added Kitty keyboard protocol support (DISAMBIGUATE_ESCAPE_CODES, REPORT_EVENT_TYPES) for lower latency input on supported terminals.
    • Added terminal theme autodetection using OSC 11 background luminance queries, with NO_COLOR override support.

Changed

  • Unified Favorite Keybinding: Standardized favorite toggling across all screens exclusively on f / F.
  • Search & Landing UX:
    • Anchored search bar at row 0 across empty, loading, and zero-results states to eliminate layout shifting.
    • Structured zero-results and query error screens with actionable guidance shortcuts ([Ctrl+P] Switch Provider, [r] Retry, [Esc] Back).
    • Enclosed landing favorites list in an aligned bordered card.
  • Streams Table Display:
    • Replaced non-existent stream duration column with source and uploader columns, expanding room for codec and media tags.
    • Grouped secondary stream audio/video codec tags (DV, ATMOS, HEVC) with subtle separator points.
    • Isolated stream row selection highlight so background styling applies exclusively to the active stream row rather than table headers.
  • MovieBox Client Spoofing: Updated client identity headers to APK v4.0.01 to ensure backend compatibility and avoid upgrade notice videos.
  • Search Prefetching: Bounded initial search prefetching to visible viewport bounds to reduce initial network requests.

Fixed

  • Stream Playback & Resolver State:
    • Fixed an issue where timed-out or failed stream resolutions left the playback state locked, preventing subsequent playback attempts.
    • Fixed empty stream panel click focusing the pane without inadvertently triggering playback of index 0.
    • Prevented transient “No stream sources found” flash while metadata or streams are loading.
  • Metadata & UI Isolation:
    • Guarded search preview metadata and details merging with strict provider and item ID checks, preventing stale metadata leakage when navigating quickly.
    • Suppressed Sixel, Kitty, and iTerm2 poster graphics while modal dialogs or search dropdowns are open to prevent graphic bleed-through.
    • Fixed poster placeholder widget incorrectly drawing over loaded images on the results screen.
    • Fixed text wrapping panic on multibyte / CJK characters during title year extraction.
  • Cross-Platform & Installation:
    • Windows: Fixed self-update batch script losing staged binary on process exit, preserved leading backslashes on UNC paths, and sanitized NTFS forbidden characters in tracker state filenames.
    • Android (Termux): Added fallback directory resolution for config, cache, and data paths, and added architecture guard preventing incompatible glibc Linux ARM64 binaries from overwriting Termux installations.
    • DNS: Replaced hardcoded /etc/resolv.conf requirement with custom resolver querying OS DNS first and falling back to public DNS (Cloudflare, Google, Quad9) on zero-config platforms.
    • Installers: Hardened path quoting, signal handling, and TLS 1.2 negotiation in install.sh and install.ps1.

Performance

  • MessagePack Binary Disk Cache (src/cache.rs): Replaced raw JSON disk caching with binary MessagePack serialization (rmp-serde) with magic signature MBC1, versioned envelopes, and automatic migration from legacy JSON caches.
  • Zero-Copy IPTV M3U Parser (src/providers/tv/parser.rs): Converted playlist attribute parsing to single-pass slice scanning, eliminating bulk heap allocations on large playlists.
  • Scraper Efficiency (src/providers/fourkhdhub/): Precompiled static CSS selectors using LazyLock<Selector> across scraping paths.
  • Connection Pooling & DNS (src/net.rs): Shared static DNS resolver cache and tuned HTTP connection pool settings (tcp_nodelay, keepalive, idle timeouts).

Removed

  • Removed deprecated JSON conversion adapters and untyped serde_json::Value service endpoints in favor of strongly typed domain structs.
  • Removed redundant [o] Open With and [s] Subtitles Details shortcuts in favor of /settings media player selection and automatic subtitle loading.
  • Removed obsolete * favorite shortcut in favor of f / F.

[0.1.14] - 2026-08-26

Added

  • Favorites:
    • Added a Favorites feature for starring whole movies and series (src/favorites.rs, favorites.json), independent of watch history and unaffected by /clear-cache.
    • Added * on the Home screen and f / F on the Details screen to toggle a title’s favorite status, with a indicator on favorited rows and a [f] Favorite / [f] Unfavorite hint on the Details screen.
    • Added an arrow-navigable Favorites row on the landing screen (Streaming and Addon modes) showing up to 5 recently-starred titles, with a +N more • /favorites overflow link; Down from the search bar focuses the row, Enter opens the selected title, Esc releases focus.
    • Added the /favorites slash command, mirroring /history, to load the full starred list into the results view; * unstars the selected row there.
    • Added mouse support for the landing Favorites row (select/open rows, open the full list via the overflow line).
    • Extracted cross-provider title-identity matching into SubjectIdentity (src/models.rs), now shared by watch history and Favorites so remakes, cross-provider duplicates, and movie/series title collisions are deduplicated identically.

Fixed

  • External player failure reporting: Treat every non-zero player exit, including exits after several seconds or without stderr output, as a playback error instead of reconciling false watch progress.
  • Search focus: Restore Backspace on the Home screen as a reliable way to focus the search input from results or Favorites.
  • Season subtitles: Remember an explicit subtitle or no-subtitle choice for every episode in a season download.
  • Playback state safety: Sanitize provider and subject identifiers before using them in tracker state filenames.
  • Cross-platform release validation: Run all-feature locked builds/tests, binary startup smoke tests, Unix and Windows installer syntax checks, and release-target builds in CI.
  • Release artifact smoke tests: Execute each native release target’s produced binary on its CI runner before archiving.
  • Documentation accuracy: Document Android intent limitations, the actual Termux binary model, macOS-only IINA support, native runtime verification requirements, and the current automated test count.
  • Windows VLC & player spawn fix: Removed erroneous CREATE_NO_WINDOW flag that suppressed GUI window creation and caused VLC to crash on Windows; normalized Windows backslash subtitle paths in --sub-file and gracefully handle subtitle download failures without breaking stream playback.
  • Termux player opener resolution: Resolve termux-open, termux-open-url, and termux-am directly in $PREFIX/bin and static Termux paths; remove broken /system/bin/am fallback in unrooted Termux that crashed with Permission Denied (exit code 126).
  • Termux dependency path: Remove the Android platform-verifier dependency path that caused the v0.1.12 startup panic; real-device confirmation remains required.

[0.1.13] - 2026-08-21

Added

  • Production-Grade In-App Self-Update Engine:
    • Implemented modular self-update architecture (src/updater/ with check.rs, artifact.rs, download.rs, verify.rs, extract.rs, and apply.rs).
    • Added streaming SHA-256 integrity verification validating exact hash matching against release SHA256SUMS.
    • Added hardened archive extraction for .tar.gz and .zip with strict path traversal protection against .. components and absolute root paths.
    • Added multi-platform installation strategies: atomic binary replacement with .old backup and automatic rollback on Unix/Linux/macOS/Termux, detached helper process on Windows, and Homebrew prefix detection guiding users to brew upgrade moviebox-tui.
    • Added active work protection deferring self-update when active video playback or background downloads are running.
    • Connected [u] shortcut and [u] Update Now button in the existing Update Available modal, preserving visual styling, animations, and dismissal model.
    • Added safe terminal state restoration (disable_raw_mode, LeaveAlternateScreen, DisableMouseCapture, ShowCursor) before process exec/restart.
  • Update System Concurrency & Platform Compatibility Architecture:
    • Added single-flight guard (is_checking_updates) ensuring manual (/update) and automatic startup checks never spawn duplicate concurrent network requests.
    • Added shared geometry calculation (UpdateModalLayout, update_modal_layout) guaranteeing 1:1 synchronization between popup rendering and mouse hit testing.
    • Added release asset data modeling (Release, ReleaseAsset, TargetPlatform) with deterministic platform compatibility detection across macOS Universal, Linux x64/arm64, Windows x64/arm64, and Android Termux ARM64.
    • Added dedicated integration test suite tests/update_lifecycle.rs testing update single-flighting, error recovery, mouse hit testing, and asset filtering.
  • Comprehensive QA & Regression Test Architecture:
    • Introduced the initial 132-test automated suite covering critical algorithmic boundaries, end-to-end user journeys, watch history reconciliation & precision progress tracking, cross-mode history audit, in-app self-update lifecycle, real-world release artifact downloads, live SHA-256 verification, genuine version upgrade execution, content & metadata loading pipelines, stale request isolation, active player session lifecycle & duplicate launch protection, dynamic slash command autocomplete (/download-dir reset), search/command draft cancellation via Esc, error handling, addon manifest validation, mouse interactions, modal dismissals, TUI rendering across terminal size matrices, state reconciliation, crypto HMAC signing, download chunk arithmetic, and URL/stem security.
    • Added structured integration tests in tests/ (including content, error, TUI, history, Favorites, update, release, cache, player, TV playlist, addon, download, and URL-security suites) and test fixtures (tests/fixtures/).
    • Added docs/testing.md detailing test architecture, command references, and manual QA procedures.
  • Playback Tracking & Watch History Progress:
    • Added real-time playback position tracking for mpv with injected tracker script (moviebox_tracker.lua) and 5-second periodic state auto-save to disk.
    • Added automatic startup state reconciliation (reconcile_pending_playback_states) ensuring watched progress is preserved even when closing the terminal or killing tmux mid-playback.
    • Added two-tone smooth scrub line progress bars (━─────── 1% (2h 18m left) • Watched 11h ago) and completion status badges ([✓ Completed], [✓ Watched]) in /history and Details screens.
    • Added cross-provider title-based history deduplication and auto-resume from the last watched position.
  • Addon Mode Watch History Parity:
    • Added full watch history support (/history) in Addon Mode matching Streaming Mode, enabling seamless watch progress tracking, scrub bars, and completion badges for community HTTP addon content.
  • Pluggable Provider Trait & Capability Architecture:
    • Formalized the public Provider and ReleaseProvider traits across all built-in scrapers (MovieBox, 4KHDHub, CircleFTP, DhakaFlix, and Addons).
    • Added ProviderCapabilities (supports_search, supports_pagination, supports_series, supports_subtitles, supports_homepage) and MovieBoxService::capabilities() for dynamic capability reporting.
    • Added structured ProviderError boundaries (Network, RateLimited, NotFound, Parsing, Unavailable) with .user_message() for consistent error notifications.
  • Theme System Expansion & Official Color Calibration:
    • Added official Dracula, Gruvbox, and Rosé Pine themes to the /theme picker alongside Catppuccin and Nord.
    • Added alias parsing support for "dracula", "gruvbox", "rose-pine", and "catppuccin".
    • Guaranteed 100% transparent terminal compatibility across all themes with zero background opacity overrides.
    • Fixed modal backdrop rendering by removing fullscreen screen clearing when opening /theme.
    • Optimized live preview navigation to eliminate unnecessary disk I/O on arrow key navigation.
  • Universal Multi-OS Player Detection & Flathub/Snap Compatibility:
    • Added sub-millisecond, filesystem-backed player probing across Linux (Flathub, Flatpak exports, Snap, and Native), macOS (Homebrew, MacPorts, App Bundles), Windows (Program Files, WinApps, Scoop, Chocolatey, WinGet), and Android (Termux).
    • Fixed Flathub/Flatpak VLC detection failure by adding direct probes for ~/.local/share/flatpak/exports/bin/org.videolan.VLC and /var/lib/flatpak/exports/bin/org.videolan.VLC.
    • Added full Flathub/Flatpak and Snap compatibility for MPV (io.mpv.Mpv, /snap/bin/mpv).
    • Centralized player process construction (build_player_process_command) and standardized subtitle flag arguments (--sub-file=<path>) across all platforms.
  • Codebase Optimization & Comprehensive Caching Architecture:
    • Centralized application paths (config_dir, data_dir, cache_dir, logs_dir, scripts_dir, playback_state_dir) in src/config.rs.
    • Added dedicated disk caching for Addon Mode stream aggregation (2h TTL), catalog /browse presets (1h TTL), and verified manifests (24h TTL).
    • Added search pagination caching (search_{hash}_{page}.json) preventing redundant API calls when navigating multi-page search results.
    • Eliminated redundant reqwest::Client allocations in background poster pipelines in favor of the shared service.http_client().
    • Streamlined MovieBoxService usage across background tasks and removed redundant addon_client field from AppState.
    • Centralized formatting utilities (format_file_size, format_duration) in src/tui/text.rs.
    • Modernized Config loading and persistence with safe, standard Serde derives.
  • Addon Mode (Community HTTP Addons):
    • Added full support for community HTTP addon manifests (/manifest.json, /catalog, /meta, /stream) with dedicated Ctrl+A mode switching.
    • Pre-installed and locked Cinemeta out-of-the-box as the default core metadata provider with zero API keys required.
    • Added interactive Addon Manager dialog (/addons, Ctrl+P in Addon Mode) with one-click enabling, removal, and manifest URL adding.
    • Added concurrent multi-addon stream resolution aggregating playable releases from all enabled stream addons.
    • Added a smart runtime torrent detector that automatically detects if an addon’s streams are 100% blocked raw torrents (e.g., Torrentio without Debrid) and flashes a UI warning toast that only HTTP streams are supported.
  • Addon Mode /browse & Curated Catalog Exploration:
    • Added /browse support in Addon Mode with a minimal, organized 4-preset catalog picker (Top Movies, Top Series, Top Rated Movies, Top Rated Series).
    • Added direct catalog fetching (/catalog/{type}/{id}.json) with poster hydration, details navigation, stream resolution, and /reload support.
  • Strict Slash Command Guarding & Guidance:
    • Intercepted all / slash commands to guarantee zero remote catalog network requests.
    • Added warning toast notifications for unrecognized slash commands ("Command '/xyz' is not recognized. Type '/' to view available commands.").
    • Added platform-aware mode-guidance toasts (^T / ^S / ^A on macOS, Ctrl+T / Ctrl+S / Ctrl+A on Linux/Windows) for mode-restricted commands.
  • Active Mode & Provider State Persistence:
    • Added active_mode configuration field in config.json automatically persisting and restoring the last active mode (streaming, tv, addon) and active provider across app restarts.
  • Configurable Mode Navigation:
    • Added /enable-streaming, /disable-streaming, /enable-tv, and /disable-tv slash commands alongside /enable-addons and /disable-addons.
    • Enforced safety validation ensuring at least one mode remains active and gracefully migrating focus when disabling the current mode.
  • Dynamic Multi-Source Host & Resolver Resolution:
    • Added 100% dynamic domain-based host extractor (extract_domain_label) and stream tag parser (detect_stream_host) identifying and formatting direct hosts (Pixeldrain, Hubcloud, Fast Download, Google Drive, Mega, etc.) and debrid resolvers without hardcoded tables.
  • Full Emoji & Symbol Sanitization:
    • Added strip_emojis and clean_stream_text sanitizing all raw stream titles, release names, source labels, and languages from community addons for clean terminal alignment without broken characters.
    • Standardized checkbox representations to clean ASCII [x] / [ ].
  • Complete Mouse Navigation:
    • Added dynamic footer hitboxes for [Ctrl+S] Streaming, [Ctrl+T] TV, [Ctrl+A] Addons, [Ctrl+P] {Provider}, [?] Help, [q] Quit.
    • Added complete mouse click support for Addon Manager modal and browse popups.

Fixed

  • Windows MSVC Static CRT Linking (+crt-static):
    • Configured target-feature=+crt-static in .cargo/config.toml for x86_64-pc-windows-msvc and aarch64-pc-windows-msvc, statically embedding the C runtime to eliminate external VCRUNTIME140.dll dependency and resolve 0xC0000135 (STATUS_DLL_NOT_FOUND) on clean Windows installations.
  • Cross-Platform Installer Polish & Windows In-Memory Execution:
    • Replaced file-based execution commands in Windows documentation with the in-memory stream pipeline (irm ... | iex) to eliminate PSSecurityException execution policy blocks.
    • Added immediate active process $env:PATH update in install.ps1 so the command is recognized in the current shell session without terminal restart.
    • Replaced rigid fixed-width boxed summary tables with responsive, borderless hero layouts across both install.ps1 and install.sh, preventing broken box-drawing characters and layout overflow on narrow screens.
  • Pending History Reconciliation Order:
    • Sorted pending Lua tracker state files chronologically during startup reconciliation to guarantee correct playback state replay order.
  • MovieBox Title Sanitization (DEF-02):
    • Fixed destructive title truncation where leading bracket tags ([Dub], [1080p], [RAW]) and titles starting with parentheses (e.g. (500) Days of Summer) were stripped down to empty strings.
    • Preserved release years in parentheses (Inception (2010)) and added a fallback safeguard returning the trimmed original title if sanitization ever results in an empty string.
  • Watch History Identity & Deduplication Collisions (DEF-03):
    • Enforced stype separation in HistoryManager::is_same_show so Movies and TV Series sharing identical titles (e.g. Home) never overwrite one another.
    • Enforced strict canonical identity (provider + subject_id), preventing cross-provider conflicts and ensuring remakes with differing release years remain distinct entries.
  • Background Episode Playback State Reconciliation (MISS-01):
    • Fixed a state loss bug in reconcile_pending_playback_states where a completed episode’s watched status was discarded if the user had already advanced to a subsequent episode before the state file was processed.
  • Windows MPV Script Options Path Escaping (DEF-04):
    • Fixed path corruption in MPV’s --script-opts on Windows by normalizing backslashes (\) to forward slashes (/), preventing MPV escape sequence parsing from corrupting state_file paths in moviebox_tracker.lua.
  • M3U Single-Quoted Attribute Support (DEF-07):
    • Extended M3UParser attribute extraction to support both single-quoted (tvg-id='...') and double-quoted attributes, preserving channel IDs, logos, and groups across varied IPTV playlists.
  • Continuous OS-Level SIGINT Handling (DEF-05):
    • Wrapped tokio::signal::ctrl_c() in a continuous background loop to ensure repeated non-interactive OS signals are reliably handled.
  • Subtitle Prefetch Fallback (DEF-08):
    • Reduced subtitle download timeout from 30s to 8s to prevent unnecessary startup delays when launching external players if a subtitle mirror hangs.
  • Addon Stream Sorting & Rendering:
    • Fixed addon streams randomly scrambling on UI hover when sizes are tied by adding a secondary stable sort based on the mirror label.
    • Fixed misleading 0MB stream sizes for community addons that omit video sizes by cleanly rendering -- instead.
  • Terminal Race Condition & Blank Screen on /clear-cache:
    • Replaced physical terminal clear with a soft image refresh when executing /clear-cache, resolving a race condition with terminal emulators that swallowed the full Home screen render and caused the screen to go completely blank after a few seconds.
    • Added comprehensive state isolation preventing search queries, results, and details states from lingering after cache clears.
    • Sanitized slash command input handling to prevent visual query glitches.
    • Replaced standard status messages with elevated toast notifications for cache actions.
  • Atomic Mode Highlight & Single Active Selection:
    • Added canonical AppMode enum (Streaming, Tv, Addon) and atomic state transitions guaranteeing that only one active mode is highlighted in the bottom dock at any time.
    • Hardened state isolation with automatic cleanup across mode switches.
  • Notification Readability & Word-Boundary Wrapping:
    • Replaced horizontal middle-truncation with unicode display-width aware word wrapping (wrap_text).
    • Added adaptive width (up to 72 chars) and dynamic height scaling with guaranteed unbroken rounded borders.
  • Resilient Addon Metadata & Fallbacks:
    • Added flexible visitors and serde aliases for genres, cast, director, imdbRating, releaseInfo, and runtime preventing deserialization failures across varied community addon JSON schemas.
    • Added multi-tier fallback resolution in the Details screen to guarantee titles, release years, synopsis, and posters are always preserved from search results and previews.
  • Android / Termux TLS Certificate Compatibility:
    • Switched reqwest to use pure-Rust embedded webpki-roots certificate verification, resolving rustls-platform-verifier crashes and panics in non-JVM Android CLI environments like Termux.
  • Transparent Stream & Search Diagnostics:
    • Replaced misleading generic "No matches" and "Rate Limit" errors with truthful, contextual diagnostics: "No stream sources available on {provider}", "Network connection failed to {provider}", "Rate limited by {provider}", and "Episode S{season}E{episode} is not listed on {provider}".
    • Added helpful actionable hints (Press Ctrl+P to try another provider, or r to refresh).
  • Rate-Limiting & Concurrency Hardening:
    • Added HTTP 429 Retry-After header parsing with bounded exponential backoff in MovieBoxClient.
    • Added semaphore concurrency limiting (Semaphore::new(2)) during parallel episode page resolution to prevent burst requests from tripping provider rate limiters.
  • Addon Mode Series Hierarchy & Episode Stream Isolation:
    • Fixed series misclassification as movies in Addon Mode when metadata omitted the videos array by ensuring canonical season structures and series-first metadata endpoint prioritization.
    • Added regex and token-based episode stream isolation (parse_season_episode) in stream_item_to_release, preventing cross-episode stream pollution (e.g. S01E06 streams appearing when viewing S01E08).
    • Added preservation of episodeNumbers arrays from addon metadata in the season list state.
  • Direct Addon & BDIX Playback & Download Dispatch:
    • Fixed Addon and BDIX playback and download routing in handle_playback and handle_download to dispatch directly to external media players and the chunk downloader, preserving custom HTTP headers (behaviorHints.headers) and source labels without unnecessary Moviebox API subtitle timeouts.
  • Selector Tab Preservation in Standard Displays:
    • Maintained visibility of Audio Languages, Seasons, and Episodes selector tabs side-by-side in standard ~80-column terminals when focusing Streams, preventing tabs from disappearing when 0 streams are available.

Changed

  • Modular TV Provider Architecture:
    • Reorganized Live TV / IPTV provider into a dedicated module directory (src/providers/tv/) with separated models.rs and parser.rs.
  • Core Infrastructure Consolidation:
    • Centralized atomic file operations (atomic_write_file, atomic_write_file_async), MD5 digest formatting (md5_hex), and text extraction helpers in cache.rs and service.rs.
    • Centralized application paths, border type resolution, and mode status announcements across TUI modules.
  • Addon Manager UI Optimization:
    • Implemented full cursor navigation (Left/Right keys) and inline editing (Backspace/Delete) for the Addon Manager input field.
    • Implemented a scrolling viewport renderer for the Addon Manager input, allowing editing of very long manifest URLs without wrapping or truncation.
    • Compacted the Addon Manager dialog with an aligned two-tier layout placing [ Add Manifest URL ] and [ Done ] action buttons side-by-side.
  • Multi-System Core Module Decoupling:
    • Promoted player.rs (process management & detection), config.rs (shared configuration), and updater.rs (release checks) to core modules in src/, preparing the architecture for upcoming CLI and GUI frontends with full backward compatibility.

Documentation

  • Streamlined README & Controls Guide:
    • Transformed README.md into a focused landing page with measured ~5 MB RAM benchmark data, defensible value propositions, and direct links to deep guides in docs/.
    • Created standalone docs/controls.md covering all keyboard shortcuts, mouse controls, and slash commands.
    • Added a 3-phase project roadmap: Terminal UI (TUI) -> Command-Line Interface (CLI) -> Desktop GUI Client.
    • Added a community-first feedback and support section with optional crypto donation options.

[0.1.12] - 2026-08-15

Added

  • CLI Help Flag: Added -h / --help CLI flags printing formatted usage, available options, and environment variables.
  • Full Mouse Support: Complete mouse navigation throughout the application:
    • Click search bar to edit; click suggestion items to search immediately.
    • Click search results to select/preview; click again or double click to enter Details.
    • Click Details panes (Audio Languages, Seasons, Episodes, and Streams) to select and launch playback.
    • Click centered footer toolbar buttons ([Ctrl+P] Provider, [Ctrl+T] TV, [?] Help, [q] Quit).
    • Full click support across all modal popups (Theme, Browse, Subtitles, Players, TV playlists & actions, and Download confirmation).
  • Contextual Downloads:
    • Pressing d or clicking [Download] while on the Seasons pane prompts to download the whole season (all episodes).
    • Triggering download while on Episodes or Streams downloads that single episode.
  • Organized Downloads & Custom Directory:
    • Structured Series downloads under <base_dir>/Series/<Title>/Season <N>/<Title> - S<N:02>E<E:02>.<ext> and Movies under <base_dir>/Movies/<Title>/<Title>.<ext>.
    • Added ISO 639-1 language code tagging to subtitle sidecars (e.g. <BaseName>.en.srt) for automatic track identification in media players and servers.
    • Added smart duplication prevention: completed episodes on disk are automatically skipped during season batch downloads.
    • Added /download-dir <path> slash command with directory creation and active write-probe validation.
    • Added /download-dir reset (contextually suggested only when custom path is configured) to revert to OS default.
    • Safe automatic fallback to default OS Downloads folder if custom path becomes inaccessible.
    • Configuration persistence across sessions in config.json.
  • Tree Branch Suggestions:
    • Redesigned search and slash command autocomplete into a minimal, transparent tree-branch layout (├─ / └─ ) anchored directly under the search prompt.
    • Added aligned slash command descriptions (browse, history, theme, config, update, etc.) without duplicate leading slashes.
    • Clean typography-driven active selection with bold vibrant accent styling.
  • Multilingual Audio Track Detection:
    • Expanded 4kHDHub release parser to detect 30+ regional and international languages (Hindi, Tamil, Telugu, Kannada, Malayalam, Bengali, Marathi, Punjabi, Gujarati, Urdu, Japanese, Korean, Chinese, Spanish, French, German, Italian, etc.) and abbreviations (Tam, Tel, Kan, etc.).
    • Responsive stream list formatting showing all available languages without crowding mirror counts.
  • Floating Pill HUD & Smooth Resize:
    • Added floating terminal dimension HUD and event coalescing for smooth window resizing without blank screens.
  • Elevated Notification Badges:
    • Redesigned notification popups into elevated, rounded bottom-right badge cards with clean typography.
  • Persistent Long-Term Poster Caching:
    • Increased image cache retention to 30 days (IMAGE_CACHE_EXPIRY_SECS), serving previously fetched posters instantly from disk across sessions with zero redundant network requests.
    • Unified image caching under a shared namespace with automatic cross-namespace lookup across MovieBox, 4KHDHub, IPTV, CircleFTP, and DhakaFlix.
  • Streamlined Browse Views:
    • Curated /browse views into 4 categorized shelves (Popular, Top Rated, Trending, Most Watched) with proper filtering.
  • Native Graphics & Single Standardized ‘No Poster’ Placeholder:
    • Replaced redundant dual labels (Poster unavailable / No Art) and noisy halfblock mosaic fallback with a single clean, centered No Poster label across search results, details, and history on non-graphics terminals.
    • Eliminated ANSI block characters, yellow/white selection redraw bars, and unnecessary background image downloads on basic terminals.
    • Preserved full native high-resolution graphical rendering on Sixel, Kitty, and iTerm2 supported terminals.
    • Added MOVIEBOX_NO_IMAGE=1 environment override to disable image probing on slow or headless sessions.
  • Next-Gen Multi-Tiered Animated Installers (install.sh & install.ps1):
    • Multi-tier progressive rendering with official MovieBox branding and Catppuccin Mocha aesthetic.
    • Live smooth Braille spinners (⠋ ⠙ ⠹ ...), SHA256 cryptographic verification against SHA256SUMS, and media player ecosystem detection.
    • 100% sudo-less user-level installation into ~/.local/bin (or %LOCALAPPDATA%\Programs\MovieBox-Tui\bin on Windows) with automatic non-destructive shell PATH integration and zero password prompts.
    • Added full CLI flags: --version <tag>, --dir <path>, --force, --dry-run, and --uninstall.
  • Explicit Download Directory Autocomplete Hints:
    • Added /download-dir <path> slash command suggestion with clear action descriptions (Set custom folder (e.g. ~/Movies) vs. View current download folder).
    • Added friendly guidance notification if a user inputs literal <path> placeholders.

Fixed

  • Custom Download Directory Container Hierarchy:
    • Ensured custom download directories always maintain the standardized MovieBox-TUI root container (MovieBox-TUI/Movies/... and MovieBox-TUI/Series/...) without duplicating if already named MovieBox-TUI.
  • Multiline Notification Toast Rendering:
    • Upgraded notification toast layout to compute dynamic height and wrap multiline messages per line cleanly without horizontal middle-truncation across newlines.
    • Sanitized notification folder paths by substituting home directory with ~.
  • Default Audio Track Prioritization (Original / English):
    • Fixed movie and series details defaulting to regional Hindi dubs on MovieBox by prioritizing Original and English audio tracks over localized search result subject IDs.
    • Preserved explicit user language selections when intentionally switching between dubs.
  • Home Landing Header & Footer Persistence:
    • Fixed ASCII logo header and shortcut footer disappearing into a blank screen when clearing history or viewing empty search states by removing fragile tick-based animation gates.
    • Ensured the landing screen renders the logo, version, centered search bar, and footer shortcuts immediately on every frame.
  • Watch History Consolidation & Latest Progress Representation:
    • Consolidated watched episodes of the same series into a single entry per show in /history displaying the latest watched season and episode.
    • Automatically deduplicated and migrated legacy history rows on startup while maintaining complete per-episode checkmark indexes in self.watched.
  • History Poster Auto-Hydration & In-Memory Cache Retention:
    • Fixed “No Poster” placeholders in /history by automatically resolving missing cover URLs and decoding posters in the background.
    • Preserved in-memory decoded image caches when opening /history to eliminate unnecessary UI redraw latency.
    • Added multi-source fallback extraction for cover URLs across playback, preview, and search results.
  • Stream Pool Initialization on Audio Selection: Fixed stream fetching hanging on “Loading streams…” when selecting non-default audio dubs by ensuring stream pool entries are initialized before episode fetch.
  • Title Sanitization & Preservation: Enhanced clean_moviebox_title to sanitize international audio dubs, video quality tags, and format markers across downloads, folder organization, and watch history while preserving 4-digit release years.
  • Terminal Restoration & Signal Handling: Added Ctrl+C keyboard handling and asynchronous SIGINT signal listener to guarantee raw mode and alternate screen are always cleanly restored.
  • Download Hierarchy & Numbering: Fixed series media type detection and removed season/episode off-by-one addition.
  • Parser UTF-8 Safety: Hardened language detection boundary checks for multibyte titles against panics.
  • Startup Screen Artifacts: Removed early startup eprintln! to eliminate terminal screen artifacts before entering alternate screen mode.
  • Android / Termux Stability: Removed hickory-dns from network dependencies to resolve NDK context panics and crashes on Android.
  • Screen Flickering & Blanking:
    • Eliminated full terminal clear on list navigation and infinite scroll pagination.
    • Fixed screen blanking when pressing Esc or resizing windows.
    • Replaced terminal clear with direct backend clear to eliminate cursor read timeouts.
  • Search & Navigation:
    • Fixed search bar auto-closing when switching providers.
    • Fixed provider switching delays and event stream drops.
    • Kept chosen audio dub selected and prevented unwanted pane jumping on details refresh.
    • Handled empty query loading states and preset failures gracefully.
  • Downloads & Playback:
    • Resolved MovieBox movie stream key mismatches and hardened resilient download flows.
    • Protected active downloads from accidental cancellation when typing x in the search bar.
    • Fixed playback lock edge cases and subtitle picker clipping.
  • Theme & Configuration:
    • Fixed theme cancellation reverting correctly without persisting unapplied themes.
    • Unified /theme command and removed obsolete /discover, /tab, and /themes aliases.

Changed

  • Removed startup screen delay for instant app launch.
  • Modernized in-place update notifications and dialogs.
  • Rendered details footer on a single clean line to balance bottom margins.
  • Removed search bar underline clutter in favor of clean header spacing.

[0.1.11] - 2026-08-11

Added

  • User-Owned M3U Playlists: Full custom playlist management in TV mode with remote URL and local file support.
  • Android Runtime Support: Termux playback and shared-storage handling continue to be exercised on real devices, but release artifacts remain desktop-focused.

Refactored

  • Domain Modularization: Split the application monolith into cohesive domain modules (network, playback, download, requests, navigation, tv, system, keyboard).
  • State Decomposition: Split the monolithic application state into specialized domain state structs.
  • Strict Verification Gates: Enforced workspace lint checks, static analysis, and testing.