All notable changes to this project will be documented in this file.

The format is based on Keep a Changelog, and this project adheres to Semantic Versioning.

Unreleased

0.3.1 - 2026-07-31

Added

  • usage-rules.md, shipped in the package. Matches the convention bb and bb_liveview already follow, so an agent working in a Beam Bots workspace picks up rules for the TUI layer alongside the framework's own (mix usage_rules.sync <file> bb_tui). Covers the entry points and how to pick between them, the full option table, BB.TUI.Renderer for consumer-owned payloads, command cancellation, and the anti-patterns that actually bite — declaring the dashboard in topology, calling the blocking run/2 from a supervision tree, or setting :node without connecting first. Added {:usage_rules, "~> 1.2", only: [:dev]} for the sync tooling.

Fixed

  • Continuous commands are no longer reported as timed out while they are still running. Commands dispatched from the UI were awaited with a UI-side deadline (:bb_tui, :command_timeout, default 30s), so a continuous command — one that only returns when it stops or is cancelled — surfaced {:error, :timeout} in the result panel after 30 seconds even though it was running normally, with no way to stop it. BB.Command.await/2 is now called with :infinity; runaways stay bounded by the command's own DSL timeout. Matches BB.LiveView.Components.Command, which bb_tui mirrors.

Added

  • Cancel a running command with c in the commands panel. Command execution is now two-phase — one async starts the command and reports {:command_started, _}, a second awaits it and reports {:command_result, _} — so the running command's pid reaches state (BB.TUI.State.Commands.executing_pid) and can be cancelled. BB.TUI.Robot.cancel_command/2 routes locally or over :rpc like every other runtime call. Cancelling resolves the pending await, so the result panel shows the cancellation instead of hanging on the throbber.

Removed

  • The :bb_tui, :command_timeout config key. It no longer has anything to bound now that the await is :infinity — the DSL timeout and the new cancel key cover both cases. Setting it is now a no-op and can be deleted from consumer config.

0.3.0 - 2026-06-23

Added

  • Configurable subscription paths. BB.TUI.run/2 (and start/2 / start_ssh/2) now accept a :subscribe_paths option that overrides the default control-plane set the dashboard subscribes to — e.g. [[:state_machine], [:command]] to narrow it, or a downsampled observability topic instead of the high-rate sensor firehose. Threaded through both the local and SSH transports; default behaviour is unchanged when the option is omitted. Thanks to @lostbean.
  • Consumer-supplied renderers. BB.TUI.run/2 (and start/2 / start_ssh/2) now accept a :renderers option — a %{path_prefix => module} map that lets a consumer teach the dashboard how to render a payload on a PubSub path it owns, without bb_tui knowing the payload's struct. A module implements the new BB.TUI.Renderer behaviour: summarize/2 returns the event-log line (or nil to fall back to the generic inspect/2), and the optional observed/2 feeds an at-a-glance status-bar slot. Messages route to a renderer by longest-matching prefix, like a routing table. Fully additive — with no :renderers, dispatch is unchanged. Threaded through both the local and SSH transports. Thanks to @lostbean.

0.2.0 - 2026-06-19

Added

  • 3D visualization tab. A new top-level tab ([ / ] to switch) renders the live robot in the terminal in 3D, built from its URDF topology and joint positions via forward kinematics. The camera orbits, tilts, zooms, and resets (//h/l, //k/j, +/-, r), and the arm reposes in real time as sensor data arrives. Built on ExRatatui's Viewport3D and ThreeD.Node scene-graph.
  • Battery / power readout in the status bar. When the robot publishes BB.Message.Sensor.BatteryState or BB.Message.Sensor.PowerState, the status bar shows an at-a-glance segment — charge percentage (colored green / yellow / red by remaining charge, with a bolt while charging), falling back to bus voltage when percentage is unmeasured. Latest-reading-wins; the event log keeps the history. Especially useful when driving a headless robot over SSH.
  • Hardware-error and estimator events. The dashboard now also subscribes to [:safety] and [:estimator], so BB.Safety.HardwareError detail (the component and reason behind an error badge) and estimator output (Odometry / Pose) surface in the event log. Safety state transitions already arrived via [:state_machine], so the badge was already accurate — this adds the missing diagnostic detail.
  • Dev demo commands. Dev.TestRobot gains power (drains a simulated battery so the status-bar readout shifts green → yellow → red) and diagnostics (publishes a hardware-error report and an estimator pose so both surface in the event log).

0.1.0 - 2026-06-04

Initial release — a terminal dashboard for Beam Bots robots, built on ExRatatui.

Added

  • Dashboard layout. A multi-panel terminal UI — title bar, Safety, Joint Control, Commands, Events, Parameters, and a status bar — composed through ExRatatui's reducer runtime. Pure state transitions live in BB.TUI.State; BB.TUI.App wires input and async results to those transitions.
  • Safety panel. Arm / disarm / force-disarm controls with a confirmation popup for force-disarm, plus an animated throbber while disarming. Reflects the robot's live safety state (:armed / :disarmed / :disarming / :error).
  • Joint control panel. Position table showing joint type (revolute / prismatic / continuous), units (degrees / mm), visual range bars, last-commanded target markers, and simulated-joint tags. Direct keyboard position adjustment in 1%-of-range and 10%-of-range steps.
  • Commands panel. Lists available robot commands with Ready / Blocked indicators based on runtime state. Argument-less commands execute on Enter; commands with declared arguments open an inline edit mode (Tab / Shift+Tab to cycle fields, type-to-edit, Enter to run, Esc to cancel). Argument types — boolean, integer, float, atom, enum ({:in, [...]}), and string — are parsed before dispatch. Entered values are preserved per command across executions.
  • Parameters panel. Live parameter table grouped by path with real-time updates and schema-aware editing (min / max bounds drive 1%-of-range stepping). Bridge tabs surface remote-parameter lists fetched per bridge, editable through the same keys; press t to cycle tabs.
  • Event stream. Scrollable, color-coded event log with summaries and timestamps taken from BB.Message.wall_time (publish time, not arrival time). Pause / resume, clear, and Enter to open a detail popup showing the full payload.
  • High-rate sensor handling. The event log debounces repeats of the same {path, payload-type} within a one-second window so a fast sensor can't flood it, and sensor-driven re-renders are coalesced to ~30fps — keeping the UI responsive under high-rate telemetry while key presses, command results, and safety / parameter / state changes still render immediately. Both windows are tunable.
  • Status bar, help overlay, and theme system. Status bar shows robot name, safety indicator, runtime state, and contextual key hints; a scrollable help overlay lists the full keybinding reference; a consistent color palette provides semantic styles (safety colors, focus borders, panel headers).
  • Keyboard-driven navigation. Tab / Shift+Tab to cycle panels, number keys to jump directly to a panel, and vim-style j/k/h/l within panels.
  • SSH transport. Serve the dashboard over SSH; multiple operators can connect simultaneously, each with an isolated session (built on ExRatatui's :ssh transport).
  • Distribution attach. Run the TUI on the robot node and attach a thin renderer from any connected BEAM node (built on ExRatatui's :distributed transport).
  • Nerves support. Register the dashboard as a nerves_ssh subsystem so operators can attach over SSH on-device.
  • Runtime inspection. Snapshot, trace, and inject events into a running TUI via ExRatatui.Runtime — useful for debugging SSH sessions that aren't otherwise observable.
  • mix bb.tui task. Standalone launch — mix bb.tui --robot MyApp.Robot, with --ssh and distribution options.
  • mix bb_tui.install Igniter task. Adds bb_tui to a project, imports formatter rules, optionally scaffolds a BB robot, and wires up launch for the default, --ssh, or --nerves install shapes.
  • Headless test suite. Full coverage using Mimic and ExRatatui's test backend, including end-to-end tests that drive a real server via ExRatatui.Runtime.inject_event/2.