Scarab Navigation System

Overview

Enable keyboard-driven, Vimium/Vimium-C style navigation for TUI applications running within the Scarab terminal environment.

Documentation

Getting Started

Reference

For Plugin Developers


Problem

Current navigation plugins in scarab rely on screen-scraping (regex on character buffers). This fails to identify semantic UI elements like buttons, lists, or tabs that don’t look like URLs.

Proposed Architecture: “Semantic Navigation Overlay”

The solution involves a side-channel communication protocol where the TUI application reports its interactive layout to the host (scarab).

1. The Protocol (Scarab Navigation Protocol - SNP)

We define a lightweight IPC protocol (JSON or Protobuf over Unix Domain Socket) for apps to report their UI state.

Message Structure:

message UpdateLayout {
  // Unique ID for the window/pane
  string window_id = 1;
  
  // List of interactive zones
  repeated InteractiveElement elements = 2;
}
 
message InteractiveElement {
  // Unique stable ID for the element (optional, for debugging)
  string id = 1;
  
  // Screen coordinates (relative to the terminal window)
  uint32 x = 2;
  uint32 y = 3;
  uint32 width = 4;
  uint32 height = 5;
  
  // Type of element (helps with styling the hint)
  ElementType type = 6;
  
  // Optional: Description for screen readers / accessibility
  string description = 7;
}
 
enum ElementType {
  BUTTON = 0;
  INPUT = 1;
  LINK = 2;
  LIST_ITEM = 3;
  TAB = 4;
}

2. The Host (Scarab)

  • Role: Server / Display Manager.
  • Action:
    • Exposes a Unix Socket (e.g., /tmp/scarab-nav-<pid>.sock).
    • Sets environment variable SCARAB_NAV_SOCKET for child processes.
    • Listens for UpdateLayout messages.
    • Maintains a Map<WindowID, List<InteractiveElement>>.
    • On Nav Key (e.g., f):
      1. Pauses input to child.
      2. Generates hints (e.g., “AA”, “AB”) for each stored element.
      3. Overlays these hints on the terminal grid.
      4. Waits for user input.
    • On Hint Selection:
      1. Lookups coordinates (x, y) of the selected element.
      2. Synthesizes a Mouse Click Event at (center_x, center_y) of the element.
      3. Sends this mouse event to the child process’s PTY.

3. The Client (Tolaria / Hibana Apps)

  • Role: The TUI Application.
  • Action:
    • During its render loop (e.g., in ratatui), it “records” the areas of interactive widgets.
    • Hook: A simple wrapper around frame.render_widget can capture the Rect and push it to a thread-local list.
    • Post-Render: Serialize the list of Rects and send it to SCARAB_NAV_SOCKET.
    • Input Handling: Must support Mouse Events (standard in ratatui and most modern TUI libs).

Integration Strategy

A. Shared Library (scarab-nav-client)

Create a small Rust crate scarab-nav-client that handles:

  1. Socket connection/reconnection (async/non-blocking).
  2. Buffering layout updates (debounce to avoid flooding).
  3. Helper traits for ratatui widgets.

B. Tolaria Implementation

In tolaria-lens/src/app.rs:

  1. Initialize NavClient on startup.
  2. In render():
    // Example pseudo-code
    let nav_recorder = NavRecorder::new();
     
    // When rendering a widget
    let area = chunks[1];
    nav_recorder.register(area, ElementType::Button, "Click Me");
    frame.render_widget(my_widget, area);
     
    // End of frame
    nav_recorder.flush(&app.nav_client);

C. Hibana Implementation

Since Hibana has a “pluggable kernel”, we can add a NavigationService to the kernel that apps can optionally talk to, which then bridges to Scarab. However, direct socket communication from the UI process is simpler and lower latency.

Advantages

  1. Decoupled: Scarab doesn’t need to know what the app is doing, just where the buttons are.
  2. Clean: Uses standard Mouse Events for interaction. No complex RPC callbacks needed.
  3. Retroactive: Can be added to existing TUI apps with minimal changes (just instrument the render loop).

For Maintainers

Next Steps

  1. Define the UpdateLayout protobuf in hibana/proto (or a new shared scarab-protocol crate). ✅ Done
  2. Implement the scarab-nav-client crate. ✅ Done
  3. Integrate into tolaria-lens as a proof of concept.