Terminal UI (xopc tui)
The tui command opens a full-screen terminal chat interface powered by @earendil-works/pi-tui. It streams assistant output, tool calls, and thinking blocks similarly to the gateway Web UI, but entirely in the terminal.
For CLI flags and one-liners, see also CLI Reference — tui.
When to use which mode
| Mode | Flag | Needs gateway? | Best for |
|---|---|---|---|
| Gateway | (default) | Yes — a running xopc gateway | Shared sessions with the Web UI, remote host, listing sessions/models via REST |
| Embedded | --local | No | Quick local chat using the same config and workspace as the CLI agent; no HTTP |
Gateway mode (default)
- Start the gateway (see Gateway).
- Point the TUI at its base URL and token if your gateway requires auth:
xopc tui
xopc tui --url http://localhost:18790 --token <your-gateway-token>The CLI’s built-in default base URL is http://localhost:3120. If your gateway.port in config is different (the project default is often 18790), pass --url explicitly.
Obtain or rotate a token with:
xopc gateway tokenEmbedded mode (--local)
Runs AgentService in-process (same stack as the non-TUI agent): loads xopc.json, workspace, and default model. No gateway process is required.
xopc tui --localLimitations in embedded mode:
- Session list and model list APIs are not wired;
/sessionsand/model(without arguments) show empty or “not available” style results, and/model <id>does not change the model (patch is not supported). - Chat history is not loaded from disk in this iteration.
/resetand/newreset the session transcript (archive + newsessionId) while keeping the same session key and persisted overrides. Embedded mode uses the in-process reset path; gateway mode callsPOST /api/sessions/:key/reset.
For switching sessions and models from the TUI, prefer gateway mode.
CLI options
| Option | Description |
|---|---|
--url <url> | Gateway base URL (no trailing path). |
--token <token> | Authorization: Bearer token for the gateway. |
-s, --session <key> | Session key. Omitted: agent:{defaultAgentId}:{mainKey} (usually agent:main:main; see Session keys). Shorthand mytopic → agent:{currentAgent}:mytopic. |
-m, --message <text> | After connect, send this message once and keep the UI open. |
--local | Embedded mode (no gateway). |
--theme <name> | Theme: auto, dark, light, or a custom name from ~/.xopc/themes/. |
--thinking <level> | Thinking level override passed through to the agent (same semantics as gateway/agent). |
Examples:
xopc tui -s agent:main:telegram:default:direct:123456
xopc tui -s mytopic
xopc tui -m "Summarize my inbox"
xopc tui --url http://192.168.1.10:18790 --token "$TOKEN"Keyboard and input
| Input | Action |
|---|---|
| Enter | Submit the current line (normal message or slash command). |
| Escape | Abort the active assistant run (if any). |
| Ctrl+D | Exit the TUI. |
| Ctrl+C | If the input buffer is non-empty: clear it. If empty: first press warns; second press within ~1s exits. |
| Ctrl+O | Toggle tool blocks expanded / collapsed. |
| Ctrl+T | Toggle thinking content in the stream display. |
| Ctrl+Shift+P | Session picker (search, rename, delete). |
| Ctrl+L | Model picker. |
| Ctrl+P / Shift+Ctrl+P | Cycle models (respects /scoped-models filter). |
Settings and customization:
| Input | Action |
|---|---|
/settings | Overlay: theme, thinking display, tool expansion, double-escape action, terminal progress. |
/scoped-models | Limit which models Ctrl+P cycles through. |
/hotkeys | Show resolved shortcuts (reads ~/.xopc/keybindings.json overrides). |
/reload-keybindings | Reload keybindings without restarting. |
XOPC_THEME | Env override for theme id (auto, dark, light, or custom). |
~/.xopc/tui-settings.json | Persisted TUI preferences from /settings. |
~/.xopc/keybindings.json | Custom app.* keybindings (pi-compatible names). |
/compact | Compact session transcript (gateway API or embedded). Queues messages while running. |
@path / quoted paths | File autocomplete when fd is on PATH (pi-tui). |
Lines starting with / are treated as slash commands (not sent to the model). The editor offers autocomplete for command names.
Slash commands
| Command | Description |
|---|---|
/help | List commands. |
/model | With args: set session model (provider/model). Without args: list models (gateway mode). |
/models | Same as /model without args. |
/session <key> | Switch session; clears the on-screen log. |
/sessions | List sessions (gateway mode). |
/new, /reset | Abort if needed; reset transcript on the server (gateway: POST …/reset; embedded: AgentService.resetSession). Model/thinking overrides are preserved. |
/abort | Abort the current run. |
/thinking | Toggle thinking display (same effect as Ctrl+T). |
/tools | Toggle tools expanded (same as Ctrl+O). |
/settings | Open TUI settings overlay (theme, thinking, tools, terminal progress). |
/scoped-models | Choose models for Ctrl+P cycling. |
/resume | Open session picker (Ctrl+Shift+P). |
/hotkeys | Show resolved keyboard shortcuts. |
/reload-keybindings | Reload ~/.xopc/keybindings.json. |
/status | Show connection and activity text (gateway mode only). |
/exit, /quit | Leave the TUI. |
TUI extensions (Phase 4)
Extensions can contribute terminal UI when xopc tui --local starts. Register deferred callbacks from register():
import type { ExtensionApi } from 'xopc/extension-sdk';
export function register(api: ExtensionApi) {
api.registerTui((host) => {
host.setFooterWidget('status', ['My extension · ready']);
host.registerSlashCommand('my-tui', 'Local TUI command', async (args) => {
host.notify(`Args: ${args || '(none)'}`);
});
host.addAutocompleteProvider(async (query) => [
{ name: `tag-${query || 'all'}`, description: 'Example @ mention' },
]);
host.registerToolRenderer('my_tool', (ctx) => [
`Rendered by extension: ${ctx.toolName}`,
ctx.resultText,
]);
});
}| Host API | Purpose |
|---|---|
setHeaderWidget / setFooterWidget | Extra lines under the header or footer |
setStatus | Short status chips in the footer stats row |
addAutocompleteProvider | @-prefix suggestions in the editor |
registerToolRenderer | Custom expanded tool output |
registerSlashCommand | TUI-local /commands (not forwarded to the agent) |
notify | System message in the chat log |
showOverlay / hideOverlay | Full-screen pi-tui overlay |
Notes:
--localonly for full extension load (tools + hooks + TUI host share one registry withAgentService).- Gateway mode still gets built-in
@skillautocomplete; extensionregisterTuicallbacks run only when extensions are loaded in-process. - Types:
TuiExtensionHostContractand related types are exported fromxopc/extension-sdk.
Type @ in the editor to autocomplete skill names from workspace / ~/.xopc/skills / bundled skills.
Logs and the terminal
While the TUI owns the screen, JSON log lines written by the Node logger are filtered so they do not corrupt the layout. After exit, normal stdout/stderr behavior is restored.
Technical notes
- Gateway path: chat uses
POST /api/agentwithAccept: text/event-stream; the UI also keepsGET /api/eventsfor broadcast-style events. Session and model helpers use the same REST surface as the Web UI (/api/sessions,/api/models, etc.). - Embedded path: messages go through
AgentService.processDirectStreamingand events are derived from the agent stream types (token,thinking,tool_start,tool_end,error,result, …).