mirror of
https://oauth2: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@github.com/m1ngsama/TNT.git
synced 2026-06-26 05:44:38 +08:00
3.4 KiB
3.4 KiB
User Lifecycle
TNT solves one narrow problem: create a keyboard-first chat room that anyone with an SSH client can join without installing a custom client.
The product path should stay short:
- Operator installs
tnt, chooses a state directory, and starts the server. - User connects with
ssh -p 2222 host. - User picks a display name or presses Enter for
anonymous. - User lands in INSERT mode at the live tail and can type immediately.
- User presses Esc to browse history with Vim-style movement.
- User uses
:helpfor the concise manual or?for the full key reference. - User searches from NORMAL with
/term, or uses commands when needed::users,:msg,:reply,:inbox,:last,:search,:nick,:mute-joins, and:q. - Scripts and operators use
tntctlor SSH exec commands forhealth,stats,users,tail,dump, andpost.
TUI Experience Notes
- The first screen should make the product legible without reading external docs: this is an SSH chat room, not a shell.
- INSERT mode is the default because most users arrive to send a message.
- NORMAL mode opens at the latest messages, not the oldest history. Users can
move upward for older context and use
Gor End to return to live chat. - NORMAL mode accepts
/as the fast path for history search, matching a common terminal-reader habit while reusing the existing:searchcommand. - INSERT mode keeps a small per-session sent-message history on Up/Down and
completes trailing
@mentionprefixes with Tab. :helpis a compact manual, while?is a full key reference. Do not add parallel support commands for the same task.- Command syntax stays ASCII even in localized UI text. Translations explain; they do not change the command language.
- Private messages are visible in each participant's in-memory
:inbox: recipients see incoming messages, senders see local sent-message copies, newest first. They are not written tomessages.logand do not survive a reconnect. :inboxis live enough for normal chat use: it can be refreshed withrand refreshes automatically when a new private message arrives while the inbox is open. Incoming unread messages are marked with*until the inbox renders them.:inbox clearremoves private messages and the reply target for the current session.:reply/:rkeeps the private-message path keyboard-short: it answers the latest private-message peer in the current session without retyping a username.- Long command output uses a small pager so
:lastand:searchare readable on small terminals.
Regression Coverage
make user-lifecycle-test runs a two-user SSH TUI journey:
- second user joins and is visible through
users --json - first user opens
?, checks:users, sends a public message, scrolls, uses:lastand:search - first user toggles
:mute-joins, sends two:msgmessages, receives a:reply, confirms private-message copies in:inbox, clears the inbox, changes nickname, sends/me, and exits - second user opens
:inboxbefore the private messages arrive, sees it auto-refresh after delivery, newest first, and replies without retyping the sender's username - exec
tailsees public messages messages.logcontains public history and excludes private-message content
This test is intentionally closer to a user story than a unit regression. Keep it focused on lifecycle guarantees, not every keybinding.