# IronStorage terminal UI

The Ratatui frontend uses a Mutt-inspired, keyboard-first interaction model.
The left pane is the password tree; the right pane is the current viewer,
editor, search result, Git dashboard, or form. Actions are mode-specific, so a
key never silently changes meaning inside an active editor or confirmation.
Press `?` for the current mode's generated help and `:` for the typed command
prompt. `Esc` closes the current overlay or entry. `Tab` and `Shift-Tab` move
between panes, fields, and form controls.

The `:` prompt calls `ironstorage::command::parse_from`, so flags, aliases, and
validation are shared with the pass-compatible CLI. Quoting and completion are
in-process; no shell, CLI, `pass`, `git`, or `gpg` executable is started.
Secret-bearing commands are masked and omitted from history.

## Default key reference

| Context | Keys | Action |
| --- | --- | --- |
| Global | `?`, `:`, `C-l`/`C-z`, `q` | help, command prompt, secure lock, quit |
| Tree | `j`/`k`, arrows, `h`/`l`, `Enter`, `/`, `n`/`N` | move, collapse/expand, open, filter, cycle matches |
| Entry | `j`/`k`, arrows, `Tab`/`Shift-Tab`, `v`/`V`, `y`, `e`, `Esc` | focus, reveal/hide, timed copy, edit, close |
| Editor | `i`, `a`, `d`, `K`/`J`, `g`, `C-s` | edit/add/remove/reorder/generate/save fields |
| Store | `I`, `i`, `p`, `\\`, `K`, `d d`, `m`, `c` | init, insert, generate, grep, KDBX import, remove, move, copy |
| Git | `g p`, `g P` | pull, push; all other Git operations use `:git …` |
| OTP | `o c`, `o y`, `o u`, `o x`, `o q` | code, copy code, URI, copy URI, QR |
| OTP write | `o i`, `o a`, `o v` | insert, append, validate URI forms |
| Dialog | `y`, `n`, `Esc` | confirm, decline, cancel |
| Locked | `Enter`, `:unlock` | begin authentication |

Bracketed paste is accepted only as inert text in an active command, filter,
editor, or form. A paste containing control characters is rejected and never
submits a command or creates extra entry lines. Losing terminal ownership
(including terminal suspension/focus loss) immediately revokes the lease,
cancels Git and clipboard work, removes plaintext presentation state, and
returns to the locked screen. A native authentication prompt may temporarily
own focus; its result stays hidden until terminal focus returns. `NO_COLOR` or
`TERM=dumb` selects the monochrome fallback while preserving focused selections
through reverse-video attributes.
Selected rows override nested field colors so labels, masked values, metadata,
and OTP codes keep one high-contrast foreground across the complete selection.

## Pass and pass-otp coverage matrix

An em dash in the hotkey column means the command prompt is the intentional
keyboard UI for that less-frequent operation. The executable counterpart of
this table is `TUI_COVERAGE` in `src/command.rs`; tests require every base
command-contract operation to have an element, command, and registered hotkey
where one is listed.

| Upstream operation | TUI element | Default hotkey | `:` command |
| --- | --- | --- | --- |
| init | recipient form | `I` | `:init GPG-ID…` |
| list | password tree | `Enter` | `:list [PATH]` |
| show | structured viewer | `Enter` | `:show [ENTRY]` |
| show clipboard | clipboard feedback | `y` | `:show --clip [LINE] ENTRY` |
| show QR | resizable QR popup | — | `:show --qrcode [LINE] ENTRY` |
| find | incremental tree filter | `/` | `:find TERM…` |
| grep | decrypted result pane | `\\` | `:grep [OPTIONS] PATTERN` |
| insert | masked insert form | `i` | `:insert [OPTIONS] ENTRY` |
| edit | structured editor | `e` | `:edit ENTRY` |
| generate | generation form | `p` | `:generate [OPTIONS] ENTRY [LENGTH]` |
| generate clipboard/QR | presentation selector | `p` | `:generate --clip/--qrcode ENTRY` |
| remove | confirmed removal form | `d d` | `:remove [OPTIONS] ENTRY` |
| move | move form | `m` | `:move [OPTIONS] SOURCE DESTINATION` |
| copy | copy form | `c` | `:copy [OPTIONS] SOURCE DESTINATION` |
| KeePass KDBX import | masked additive-import form | `K` | `:import-kdbx [--key-file PATH] [--quick-add] SOURCE` |
| git init/status/log/diff/add/commit | Git dashboard/detail pane | — | `:git SUBCOMMAND …` |
| git remote/config | Git dashboard | — | `:git remote …`, `:git config …` |
| git fetch/sync | cancellable progress view | — | `:git fetch …`, `:git sync …` |
| git pull/push | cancellable progress view | `g p` / `g P` | `:git pull …`, `:git push …` |
| git conflict resolution | conflict view | — | `:git resolve-local`, `:git resolve-remote` |
| otp code | responsive entry OTP panel/compact field | `o c` | `:otp code ENTRY` |
| otp code clipboard | clipboard feedback | `o y` | `:otp code --clip ENTRY` |
| otp insert/append | masked OTP forms | `o i` / `o a` | `:otp insert …`, `:otp append …` |
| otp URI terminal/clipboard/QR | secret popup/clipboard/QR | `o u` / `o x` / `o q` | `:otp uri [--clip\|--qrcode] ENTRY` |
| otp validate | masked validation form | `o v` | `:otp validate URI` |
| otp version | status line | — | `:otp version` |
| help/version | help overlay/status line | `?` / — | `:help [TOPIC]`, `:version` |
| lock/unlock | locked screen | `C-l`/`C-z`, `Enter` | `:lock`, `:unlock` |

Remove and HOTP operations always require explicit confirmation. TOTP repaint
ticks, storage completion, Git progress, and clipboard timers do not extend the
authentication lease. Clipboard and QR payloads are storage-produced,
zeroizing values and disappear immediately on relock.

Opening an entry with a TOTP field requests its read-only code without requiring
field focus. If the viewer pane can retain both the code and field list, the TUI
renders five-row digit-only glyphs and a storage-period-driven countdown bar.
Shorter panes fall back to a leading inline code and remaining-seconds label.
The displayed TOTP survives field navigation, refreshes at its exact storage
boundary, and is removed when the entry closes or the application relocks.
The details viewport remains fixed while the focused field is visible. It moves
by the minimum number of rows only when field navigation crosses an edge, and
recalculates that visibility after terminal and OTP layout changes.

`:quit` is a TUI convenience. Shell-completion script generation is a CLI
build-time/integration surface; interactive Tab completion replaces it here.

## Milestone audit evidence

The TUI tests exercise narrow, normal, wide, and rejected terminal sizes;
Unicode-width content; masked paste; resize; focus-loss relock; panic
restoration; stale async results; and storage work blocked behind a deterministic
channel while UI state continues to update. The workspace
`authentication_leases` tests use a manual monotonic clock for both the default
120-second lease and configured timeouts; TUI state tests verify that the
resulting expiry event removes viewers, editor drafts, OTP/QR data, clipboard
feedback, and pending results. Source audit tests scan every production TUI
module for process construction, direct repository reads/writes, OTP/QR parser
duplication, filesystem access, and unsafe blocks.
