Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ Command-line tools and libraries for interacting with comma devices and the comm

- `comma-connect-api`: Async Rust client for `https://api.commadotai.com`
- `comma-cli`: CLI application that demonstrates configuration handling and basic API calls
- `comma-tui`: Lightweight terminal user interface (binary name: `comma`). Early design phase; see `crates/comma-tui/docs/`.
- `comma-test-utils`: Shared helpers for cucumber/BDD tests (not published)

## Quick start
Expand Down
33 changes: 33 additions & 0 deletions crates/comma-tui/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
[package]
name = "comma-tui"
version = "0.1.0"
edition.workspace = true
rust-version.workspace = true
authors.workspace = true
description = "Terminal user interface for comma devices"
repository.workspace = true
homepage.workspace = true
documentation.workspace = true
license.workspace = true
keywords.workspace = true
categories.workspace = true

[[bin]]
name = "comma"
path = "src/main.rs"

[dependencies]
comma-connect-api.workspace = true
anyhow.workspace = true
clap.workspace = true
serde.workspace = true
serde_json.workspace = true
tokio.workspace = true
tracing.workspace = true
tracing-subscriber.workspace = true

# TUI (to be added when implementation starts)
# ratatui = "0.29"
# crossterm = "0.28"

[dev-dependencies]
24 changes: 24 additions & 0 deletions crates/comma-tui/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
# comma-tui

Lightweight terminal user interface for interacting with comma devices and the comma connect API.

The binary is named `comma` for convenience.

## Status

Early design phase. No real UI yet. See `docs/` for TUI design notes and decisions.

## Design goals

- Text-only early versions (no video, no thumbnails, no graphics protocols).
- Tabbed main screen inspired by rustnet.
- Fully configurable keybindings (Vim-like defaults).
- Separate config from `comma-cli`, but respects the same environment variables.
- Dongle switcher + routes + upload queue as the first useful views.

## Building

```bash
cargo build -p comma-tui
./target/debug/comma
```
124 changes: 124 additions & 0 deletions crates/comma-tui/docs/DESIGN.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,124 @@
# TUI Design Notes

These are working notes on the intended look, feel, and behaviour of the `comma` TUI.
They are not formal architecture decision records (ADRs); they capture use-case and
interaction design thinking so we can implement deliberately.

Related: see the individual notes in this directory.

## Core principles

- **Lightweight first.** Early versions are pure text. No video playback, no
thumbnails, no half-block rendering, no graphics protocols.
- **Useful before pretty.** Prioritise routes list, upload queue, device overview,
and dongle switching. Visual flourishes (coloured route markers, etc.) come later.
- **Fixed, source-defined keybindings.** Keybindings are not user-configurable.
They live in one place in the source code (with associated display strings).
Defaults are Vim-like, with support for modifiers and multiple keys per action.
- **Separate but compatible config.** The TUI has its own config file (TOML via
confy, same strategy as `comma-cli`). Dongle ID and token can live there, but
environment variables (`COMMA_TOKEN`, `COMMA_DONGLE`) are preferred and shared
with `comma-cli`. CLI flags override both.

## Main screen layout (inspired by rustnet)

```
┌───────────────────────────────────────────────────────┐
│ Routes Queue Device Devices Help │ ← tab bar
├───────────────────────────────────────────────────────┤
│ │
│ (active tab content) │
│ │
│ │
├───────────────────────────────────────────────────────┤
│ j/k: move space: select q: quit ? : help │ ← status / key hints
└───────────────────────────────────────────────────────┘
```

- Top line: list of tabs, active tab highlighted.
- Bottom line: context-sensitive keyboard shortcuts currently available
(subset of bindings, ranked by importance, limited by terminal width).
- Rightmost tab is always **Help**, which lists all keybindings (including
alternatives and modifiers) generated from the source-defined binding table.

## Tabs (initial set)

1. **Routes** — list of routes for the active dongle (metadata only).
2. **Queue** — upload queue for the active dongle.
3. **Device** — overview of the active dongle.
4. **Devices** — switch the active dongle. Lists all devices the user can access
(owned + shared). Only one is active at a time; other tabs show data for it.
5. **Help** — full keybinding and command overview (generated from source).

## Dongle selection

- On startup, select the dongle from (in order): `--dongle` / `-d` CLI flag,
`COMMA_DONGLE` environment variable, last-selected dongle stored in the TUI
config, or prompt / first available.
- The Devices tab lets the user change the active dongle at runtime.
The choice is persisted to the TUI config.
- All other data tabs operate on the currently selected dongle.
- Users who want to ignore a persisted or environment dongle temporarily can
use `env -u COMMA_DONGLE comma` (or pass `--dongle`).

## Configuration

Own config file managed by `confy` (TOML, platform-standard location, same
strategy as `comma-cli`; typically `~/.config/comma-tui/config.toml` on Linux).

Example sketch:

```toml
default_dongle = "0123456789abcdef"
# token = "..." # prefer env var
last_dongle = "0123456789abcdef" # written by the TUI on dongle switch
```

Keybindings are **not** in the config; they are defined in source code.

## Keybindings

- Defined in a single place in the source code.
- Each binding has an associated display string (e.g. `space`, `enter`,
`ctrl-f`) used by the bottom bar and Help tab. Changing a binding or its
display string requires no other edits.
- Support for modifier keys (e.g. `Ctrl-F` / `Ctrl-B` for page up/down).
- Multiple keys may be bound to the same action (e.g. both `j`/`k` and arrow
keys for movement).
- Help tab lists all bindings for each action.
- Bottom bar shows a ranked subset (by importance), truncated as needed for
terminal width. The set of hints is context-sensitive per tab (Routes has
upload actions, Queue has cancel, Device has alias editing, etc.).

## Feature parity with the CLI

The TUI should offer roughly the same interactive capabilities as the CLI
(routes listing, upload queue management, requesting uploads of cameras/logs/
routes/recent-routes, device alias changes, etc.).

- CLI remains the right tool for scripting, one-off commands, and raw JSON
output.
- TUI translates API responses into human-friendly interactive views.
- Reusable helper logic currently living in `comma-cli/src/main.rs` (the
various `cmd_*` functions) should be extracted into a shared module that
both the CLI and TUI can use.

## Non-goals for early versions

- Rendering any frames from route video footage.
- Thumbnails or coloured route icons (possible later, e.g. time-of-day colour).
- Graphics protocol support (Kitty, Sixel, iTerm2) or half-block video.
- Replacing the web UI’s media viewing experience.
- User-configurable keybindings.

## Resolved questions

- **Config format and location:** TOML via `confy`, same strategy as
`comma-cli`.
- **Bottom bar:** Fully dynamic and context-sensitive. Number of shown hints
depends on terminal width and an importance ranking of the bindings.
- **Upload-request workflow:** Offer more or less the same features in CLI
and TUI. Extract shared helpers from the CLI.
- **Persistence of last-selected dongle:** Written to the TUI config.
Overridden by environment variable or CLI flag. Temporary override via
`env -u COMMA_DONGLE comma`.
30 changes: 30 additions & 0 deletions crates/comma-tui/docs/TDR-001-lightweight-text-only.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
# TDR-001: Lightweight text-only early versions

## Context

The comma web UI shows route video. Terminal video playback is possible via
graphics protocols (Kitty, iTerm2, Sixel) or unicode half-blocks, but:

- Stock Alacritty supports none of the graphics protocols.
- Half-block video is blocky and bandwidth-heavy.
- The primary value of a TUI for many users is metadata, queue management,
and quick navigation, not media playback.

## Decision

Early versions of `comma` (the TUI) will contain **no** rendering of video
footage, not even still thumbnails or coloured route markers.

Routes are listed as plain text lines derived from metadata.

## Consequences

- Faster to implement and ship useful functionality.
- Works identically in Alacritty, over SSH, and in any truecolor terminal.
- Leaves the door open for optional visual enhancements later (time-of-day
colour blocks, half-blocks, or protocol-based images) without blocking
the core experience.

## Status

Accepted (2026-10-18)
31 changes: 31 additions & 0 deletions crates/comma-tui/docs/TDR-002-tabbed-layout.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
# TDR-002: Tabbed layout inspired by rustnet

## Context

We want a clear, keyboard-driven main screen. Two reference TUIs are rustnet
(ratatui, tabbed) and btop (more dashboard-like). The preference is closer to
rustnet.

## Decision

The main screen is tabbed:

- Top bar lists tabs and highlights the active one.
- Bottom bar shows currently relevant keybindings (ranked subset, limited by
terminal width; generated from the source-defined binding table).
- Rightmost tab is always Help and lists all bindings (including alternatives
and modifiers) generated from the same source table.

Initial tabs: Routes, Queue, Device, Devices, Help.

## Consequences

- Familiar mental model for users of rustnet-style tools.
- Help and bottom bar stay automatically consistent with the code-defined
bindings.
- Easy to add further tabs later without redesigning the shell.
- Bottom bar can be context-sensitive per tab without extra configuration.

## Status

Accepted (2026-10-19)
38 changes: 38 additions & 0 deletions crates/comma-tui/docs/TDR-003-config-and-env.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
# TDR-003: Separate config with shared environment variables

## Context

`comma-cli` already stores a default dongle ID and token via confy
(`~/.config/comma-cli/config.toml`) and prefers `COMMA_TOKEN` /
`COMMA_DONGLE` environment variables.

The TUI has different needs (persistence of last-selected dongle, possibly
other UI state) and different usage patterns. Keybindings are deliberately
not part of the config.

## Decision

- The TUI has its **own** config file, managed by `confy` (TOML, same
strategy and platform-standard locations as `comma-cli`).
- It may store a default dongle ID, token, and the last-selected dongle.
- It **must** honour the same environment variables (`COMMA_TOKEN`,
`COMMA_DONGLE`) that the CLI uses.
- CLI flags (`--dongle`, `--token`) override both config and environment.
- Keybindings are **not** stored in the config; they are defined in source
code (see TDR-004).

Duplication of dongle/token is acceptable; environment variables remain the
preferred shared mechanism.

## Consequences

- Users can keep secrets out of config files via environment variables.
- TUI-specific state (last dongle) does not pollute the CLI config.
- Startup selection order is well-defined: CLI flag > env > config (including
last-selected) > fallback.
- Temporary override of a persisted or environment dongle is possible with
`env -u COMMA_DONGLE comma` or an explicit `--dongle` flag.

## Status

Accepted (2026-10-19)
40 changes: 40 additions & 0 deletions crates/comma-tui/docs/TDR-004-keybindings.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
# TDR-004: Fixed source-defined keybindings (not user-configurable)

## Context

Earlier design considered fully user-configurable keybindings (to accommodate
layouts such as Colemak-DH). After further thought, the complexity of a
configurable binding system (config parsing, validation, dynamic Help and
status-bar generation from user input, conflict handling) is not worth the
benefit for a focused TUI. A single source-of-truth in code is simpler,
easier to test, and still allows the display strings to stay in sync with
the actual keys.

## Decision

- Keybindings are **not** user-configurable.
- All bindings live in one place in the source code.
- Each binding carries its own display string (e.g. `space`, `enter`,
`ctrl-f`, `up`). The bottom bar and Help tab are generated from this table,
so changing a key or its label requires no other edits.
- Modifier keys are supported (examples: `Ctrl-F` / `Ctrl-B` for page
up/down).
- Multiple keys may be bound to the same action (e.g. both `j`/`k` and the
arrow keys for vertical movement).
- The Help tab lists every binding for each action.
- The bottom bar shows a ranked subset of the currently relevant bindings
(importance rank + available terminal width). The set of hints is
context-sensitive per tab.

## Consequences

- Much less implementation and testing complexity.
- Help and status bar stay automatically consistent with the code.
- Users who strongly prefer a different layout must either live with the
defaults or fork/patch the binding table (acceptable trade-off).
- Easy to add alternative keys (arrows, etc.) without user configuration.

## Status

Accepted (2026-10-19) — supersedes the previous “fully configurable”
decision.
32 changes: 32 additions & 0 deletions crates/comma-tui/docs/TDR-005-dongle-switcher.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
# TDR-005: Dongle switcher tab (Devices)

## Context

A user may own multiple devices or have been granted read access to devices
owned by others (via useradmin.comma.ai). The TUI needs a clear way to choose
which dongle’s data is shown in the other tabs.

## Decision

- There is a dedicated **Devices** tab that lists all accessible devices.
- Exactly one dongle is active at a time.
- Other tabs (Routes, Queue, Device, …) always operate on the active dongle.
- On startup the active dongle is chosen by: CLI `--dongle`/`-d` >
`COMMA_DONGLE` env > last-selected dongle stored in the TUI config >
first available (or prompt).
- Changing the selection in the Devices tab updates the active dongle for the
rest of the session **and** persists the choice to the TUI config.
- Users can temporarily ignore the persisted or environment value with
`env -u COMMA_DONGLE comma` or by passing `--dongle`.

## Consequences

- Clear model for multi-device users.
- CLI and environment overrides are honoured, matching `comma-cli` behaviour.
- Avoids the need to restart the TUI when switching devices.
- Last-selected dongle survives across runs without requiring the user to
edit the config by hand.

## Status

Accepted (2026-10-19)
Loading
Loading