Terminal UI for the prismal
ecosystem — an interactive Textual
application you run locally to talk to a running
prismal-server,
exclusively through prismal-sdk
(AsyncPrismalClient).
There is no browser and no chat platform here: keystrokes go straight into
a ConversationSession that resolves or creates one engine thread_id per
locally-named conversation, persists that mapping in a local SQLite
ConversationStore (so restarting the app never forks an ongoing
conversation), streams the reply through prismal-sdk, and renders it as
Markdown in a scrollable transcript — with a single key press (Esc by
default) to cancel mid-turn.
Status: bootstrap (SDD seed). The design is complete in
specs/tui-bootstrap/(PLAN.md·ARCHITECTURE.md·SPEC.md·TASKS.md); implementation phases TUI-00…04 are tracked inTASKS.md.
developer's terminal ── keyboard/ANSI ──▶ prismal-tui (this repo)
│ prismal_sdk (HTTP + SSE)
▼
prismal-server ──▶ prismal (engine)
| Repo | Role | Status |
|---|---|---|
prismal |
Engine (LangGraph supervisor, 29 routes, RAG, security) | v3.10.1 — 21/21 specs |
prismal-server |
FastAPI host (REST + SSE + A2A) | v0.1 complete |
prismal-sdk |
Typed Python client (sync + async) | bootstrap complete |
prismal-webchat |
Embeddable browser chat widget | SDD seed |
prismal-chatbot |
External bots — Slack, Discord | SDD seed |
prismal-tui |
Terminal UI (this repo) | SDD seed |
A single-process Textual app: a scrollable, Markdown-rendered transcript
that streams tokens as the engine produces them, visible tool-call
activity, a sidebar to create/switch/rename/delete named local
conversations (each backed by its own durable engine thread), a small
slash-command set (/new, /switch, /rename, /delete, /cancel,
/quit, /help), immediate keyboard cancellation of an in-flight turn,
and friendly error messages on failure. See specs/tui-bootstrap/PLAN.md
§5 for the full in/out-of-scope list.
Requires Python 3.13 (dev target), uv, and
a running prismal-server (defaults to http://localhost:8000).
uv pip install -e ".[dev]"
export PRISMAL_TUI_SERVER_URL="http://localhost:8000"
export PRISMAL_TUI_TOKEN="…" # service credential, optional locally
prismal-tui
# or: python -m prismal_tuiInside the app: type a message and press Enter to send, Esc to cancel a
streaming reply, /new <name> to start a new conversation, /help for the
full key-binding and command list.
| Env var | Default | Meaning |
|---|---|---|
PRISMAL_TUI_SERVER_URL |
http://localhost:8000 |
Target prismal-server |
PRISMAL_TUI_TOKEN |
— | Bearer credential (never rendered or persisted) |
PRISMAL_TUI_ORG_ID |
— | Tenant for all TUI traffic (X-Org-Id) |
PRISMAL_TUI_STORE_PATH |
platformdirs user-data dir |
Local ConversationStore SQLite file |
PRISMAL_TUI_CANCEL_KEY |
escape |
Key binding that cancels an in-flight turn |
PRISMAL_TUI_LOG_LEVEL |
INFO |
Local log file verbosity |
Full reference: specs/tui-bootstrap/SPEC.md §8.
uv run pytest # unit + ui suite — offline, fake SDK client + Textual Pilot
uv run pytest -m contract # opt-in — against a running prismal-server
uv run ruff check . && uv run mypy prismal_tuiBoundary rules (no prismal/prismal_server imports, no direct HTTP to
the host, no secret ever rendered, logged, or persisted) are enforced by
tests — see CLAUDE.md for the review checklist.