TermUI.Widgets.SupervisionTreeViewer (TermUI v1.0.0)

View Source

SupervisionTreeViewer widget for OTP supervision hierarchy visualization.

SupervisionTreeViewer displays the supervision tree with live status indicators, restart counts, and provides controls for process management and inspection.

Usage

SupervisionTreeViewer.new(
  root: MyApp.Supervisor,
  update_interval: 2000,
  on_select: fn node -> handle_select(node) end
)

Features

  • Tree view of supervision hierarchy
  • Live status indicators (running, restarting, terminated)
  • Restart count and history display
  • Supervisor strategy display
  • Process state inspection
  • Restart/terminate controls with confirmation
  • Explicit refresh API for supervision tree changes

Keyboard Controls

  • Up/Down: Move selection
  • Left: Collapse node or move to parent
  • Right: Expand node or move to first child
  • Enter: Toggle expand/collapse
  • i: Show process info panel
  • r: Restart selected process (with confirmation)
  • k: Terminate selected process (with confirmation)
  • R: Refresh tree
  • /: Filter by name
  • Escape: Clear filter/close panel

Monochrome Compatibility

This widget is fully functional in monochrome terminals:

  • Process status indicated by both color AND text markers:
    • [R] for running processes
    • [Y] for restarting processes
    • [T] for terminated processes
    • [U] for undefined status
  • Selected items use reverse video for visibility
  • Error states (terminated) use underline for emphasis
  • All critical information remains accessible without color

The widget uses both theme component styles and explicit text indicators for complete monochrome compatibility.

The :update_interval option is stored as refresh metadata but does not start a timer. In an Elm root, schedule Command.interval/2 yourself and call refresh/1 for each message. TermUI.Runtime does not invoke this widget's handle_info/2 callback automatically.

Summary

Functions

Collapses all nodes.

Expands all supervisor nodes.

Gets the process state for the selected node.

Gets the currently selected node.

Initializes the SupervisionTreeViewer state.

Creates new SupervisionTreeViewer widget props.

Forces a refresh of the supervision tree.

Sets the root supervisor.

Types

node_status()

@type node_status() :: :running | :restarting | :terminated | :undefined

node_type()

@type node_type() :: :supervisor | :worker

sup_node()

@type sup_node() :: %{
  id: term(),
  pid: pid() | :restarting | :undefined,
  name: atom() | nil,
  type: node_type(),
  status: node_status(),
  child_spec: map() | nil,
  strategy: atom() | nil,
  restart_count: non_neg_integer(),
  max_restarts: non_neg_integer() | nil,
  max_seconds: non_neg_integer() | nil,
  children: [sup_node()] | nil,
  memory: non_neg_integer(),
  reductions: non_neg_integer(),
  message_queue_len: non_neg_integer(),
  depth: non_neg_integer(),
  parent_pid: pid() | nil
}

Functions

collapse_all(state)

@spec collapse_all(map()) :: {:ok, map()}

Collapses all nodes.

expand_all(state)

@spec expand_all(map()) :: {:ok, map()}

Expands all supervisor nodes.

get_process_state(state)

@spec get_process_state(map()) :: {:ok, term()} | {:error, term()}

Gets the process state for the selected node.

get_selected(state)

@spec get_selected(map()) :: sup_node() | nil

Gets the currently selected node.

init(props)

Initializes the SupervisionTreeViewer state.

new(opts)

@spec new(keyword()) :: map()

Creates new SupervisionTreeViewer widget props.

Options

  • :root - Root supervisor (pid, registered name, or module) - required
  • :update_interval - Refresh interval metadata in ms (default: 2000); no timer is started by the widget
  • :on_select - Callback when node is selected: fn node -> ... end
  • :on_action - Callback when action is performed: fn {:restarted | :terminated, pid} -> ... end

  • :show_workers - Show worker processes (default: true)
  • :auto_expand - Expand all nodes initially (default: true)

refresh(state)

@spec refresh(map()) :: {:ok, map()}

Forces a refresh of the supervision tree.

set_root(state, root)

@spec set_root(map(), term()) :: {:ok, map()}

Sets the root supervisor.