# Scarab Navigation System Specification
## Objective
Enable keyboard-driven, Vimium/Vimium-C style navigation for TUI applications (like `tolaria-lens`) running within the `scarab` terminal environment.
## 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:**
```protobuf
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 `Rect`s 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()`:
```rust
let nav_recorder = NavRecorder::new();
let area = chunks[1];
nav_recorder.register(area, ElementType::Button, "Click Me");
frame.render_widget(my_widget, area);
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).
## Next Steps
1. Define the `UpdateLayout` protobuf in `hibana/proto` (or a new shared `scarab-protocol` crate).
2. Implement the `scarab-nav-client` crate.
3. Integrate into `tolaria-lens` as a proof of concept.