Skip to content

The terminal client ​

matterwave-tui is a chat client for the terminal: conversation list, transcript, composer, model picker and a status line, over the same /api routes as the web app. Conversations are shared: one started in the terminal is in the web app, and the other way round. It is a client, not an agent: it runs no tools and edits no files.

The package lives at clients/tui (Python 3.11+, Textual, on the Python SDK).

Install ​

bash
uvx matterwave-tui                 # run without installing
pipx install matterwave-tui        # or install it

From this repo: cd clients/tui && uv sync && uv run matterwave-tui.

Point it at a deployment with --base-url https://<host> or MATTERWAVE_BASE_URL (default http://localhost:8000).

Sign in ​

A stored credential lives in the OS keyring (Keychain, Credential Manager, Secret Service), one entry per base URL, never in a dotfile; with no usable keyring, sign-in fails rather than writing a file.

  • An API key. Run matterwave-tui login --key and paste it once, or set MATTERWAVE_API_KEY=mw_... for one shell (read, not stored). Create one in Settings → API keys; it needs chat:read and chat:write.
  • As yourself, by device code. matterwave-tui login, or just matterwave-tui with no stored credential, prints a URL and a short code. Open the URL in any browser, sign in, approve the code; the terminal picks the session up. The flow is in device-login.md; the key it issues appears in Settings → API keys and revoking it there signs the terminal out.

Keys ​

KeyWhereDoes
Ctrl+Enteranywheresend (also Ctrl+J / Ctrl+S, for terminals that do not report Ctrl+Enter)
Esccomposerto the transcript; cancels an edit; stops a streaming answer
↑ ↓ / k jtranscriptselect a message
[ / ]transcriptprevious / next sibling branch
etranscriptedit the selected user turn
rtranscriptregenerate the selected answer
xtranscriptshow / hide the messages a summary replaced
ctranscriptcompact the conversation now
mtranscriptmodel picker
ntranscriptnew conversation
/transcriptsearch conversations
Ctrl+Qanywherequit

Letter keys apply when focus is not in the composer or the search box; Esc gets you there.

The composer is multiline and keeps a draft per conversation while the app runs. matterwave-tui logout forgets the stored credential.

Branches ​

Editing a user turn or regenerating an answer writes a sibling; the original stays. [ and ] step through the siblings at the selected turn and move the conversation's active branch (PUT /api/conversations/{id}/active-leaf), so the web app opens on the same branch.

The status line ​

Model, the context meter (used / window, from the last context frame), the request id of the last error, the wait left on a rate limit, and online / offline. A dropped stream resumes once with Last-Event-ID (the SDK's resume); Esc stops a streaming answer, and what the server had sent is read back as a truncated turn.

When the server compacts a long thread, a divider marks where the summary begins; x expands the covered messages from the tree already loaded. See compaction.md.

Models ​

The picker shows /api/models, read again when it opens, grouped as on the web (GRT, partner, research preview). A model your plan does not include shows its upgrade path and cannot be selected. The choice is kept on the conversation (PATCH /api/conversations/{id}, its default_model), so the web app opens it on the same model.

Errors ​

Budget, moderation, upstream and truncated answers get the same wording as the web app, always with the request id, which is what to quote in a support thread. Two states the web app never shows: a key's per-minute limit (429, with the server's Retry-After counted down in the status line) and a model the plan does not include (402), which is not the budget's 402.