Chabeau
OpenAI-API compatible terminal chatbot and MCP client in Rust
Ask AI about Chabeau
Powered by Claude Β· Grounded in docs
I know everything about Chabeau. Ask me about installation, configuration, usage, or troubleshooting.
0/500
Reviews
Documentation
Chabeau - Terminal Chat Interface

Chabeau is a full-screen terminal chat interface that connects to various AI APIs for real-time conversations. Chabeau brings the convenience of modern chat UIs to the terminal with a focus on speed, ergonomics, and sensible defaults. It is not a coding agent, but preliminary support for the Model Context Protocol is in development. This makes it possible to connect Chabeau with various local and remote services as well.

Table of Contents
- Features
- Getting Started
- Working with Providers and Models
- Configuration
- MCP Servers
- Character Cards
- Personas
- Presets
- Appearance and Rendering
- Keyboard and Workflow Tips
- Architecture Overview
- Development
- License
Features
See it in action
- Message retry
- Presets
- Themes
- User message editing
- Assistant response editing
- Character cards
- In-place refinement
- Syntax highlighting
- Code block selection
- Complex tables
- MCP tool calls
- Inspecting MCP requests
The MCP server shown in the videos above is "MCP Research Friend", a Permacommons project.
Full feature list
- Full-screen terminal UI with real-time streaming responses
- Markdown rendering in the chat area (headings, lists, quotes, tables, callouts, horizontal rules, superscript/subscript, inline/fenced code) with clickable OSC 8 hyperlinks
- Modal pickers and inspectors temporarily suspend hyperlink rendering to keep the screen clean
- Built-in support for many common providers (OpenAI, OpenRouter, Poe, Anthropic, Venice AI, Groq, Mistral, Cerebras)
- Support for quick custom configuration of new OpenAI-compatible providers
- Interactive dialogs for selecting models and providers
- Character card support (v2 format) with in-app picker and defaults per provider/model
- Persona system for defining reusable user identities with variable substitution support
- Reusable preset instructions with picker and CLI toggles for quick context switching
- Extensible theming system that degrades gracefully to terminals with limited color support
- Secure API key storage in system keyring with config-based provider management
- Multi-line input (IME-friendly) with compose mode that can expand to half the terminal for longer responses
- Message retry and message editing
- On-demand refinements of the last assistant response with
/refine <prompt> - Slash command registry with inline help for faster command discovery
- Conversation logging with pause/resume; quick
/dumpof contents to a file - Syntax highlighting for fenced code blocks (Python, Bash, JavaScript, and more)
- Inline block selection (Ctrl+B) to copy or save fenced code blocks
- User message selection (Ctrl+P) to revisit and copy prior prompts
- Assistant message editing (Ctrl+X) to revise or truncate assistant responses without resending, with compose-mode shortcuts available while refining replies
- Prettified API error output with Markdown summaries for easier troubleshooting
For features under consideration, see WISHLIST.md.
Getting Started
Install
cargo install chabeau
Versioned release binaries (tagged semver releases) are published on the
GitHub Releases page
after the release tag becomes reachable from main (for example, when a
release/* branch carrying the tag is merged).
Nightly pre-release binaries are also published under the Nightly
pre-release tag.
Each nightly artifact includes per-file SHA-256 checksums plus a combined
SHA256SUMS file. Nightly releases also include SHA256SUMS.sig and
SHA256SUMS.pem, produced by keyless Sigstore signing in GitHub Actions.
On macOS, unsigned nightly binaries may be quarantined by Gatekeeper. If you trust the downloaded artifact, you can remove the quarantine attribute:
xattr -d com.apple.quarantine ./chabeau
Run unsigned binaries at your own risk.
Stable release artifacts are signed by .github/workflows/publish.yml.
Nightly checksum manifests are signed by .github/workflows/nightly.yml.
You can verify them with:
# Stable release checksums
cosign verify-blob \
--signature SHA256SUMS.sig \
--certificate SHA256SUMS.pem \
--certificate-identity-regexp 'https://github.com/permacommons/chabeau/\.github/workflows/publish\.yml@refs/heads/main' \
--certificate-oidc-issuer https://token.actions.githubusercontent.com \
SHA256SUMS
# Nightly checksums
cosign verify-blob \
--signature SHA256SUMS.sig \
--certificate SHA256SUMS.pem \
--certificate-identity-regexp 'https://github.com/permacommons/chabeau/\.github/workflows/nightly\.yml@refs/heads/main' \
--certificate-oidc-issuer https://token.actions.githubusercontent.com \
SHA256SUMS
sha256sum -c SHA256SUMS
Configure Providers
chabeau provider list
chabeau provider add
Launch
chabeau # Uses defaults; opens pickers when needed
Inside the TUI, use /provider and /model to switch, and /help to see a full breakdown of commands and keyboard shortcuts.
Working with Providers and Models
chabeau # Start chat with defaults (pickers on demand)
chabeau --provider openai # Use specific provider
chabeau --model gpt-5 # Use specific model
chabeau --log conversation.log # Enable logging immediately on startup
Discover available options:
chabeau -p # List providers and auth status
chabeau -m # List available models
chabeau -p openrouter -m # List models for specific provider
Manage providers from the CLI:
chabeau provider list
chabeau provider add # Built-in token or custom provider
chabeau provider add poe # Shortcut for built-in provider token
chabeau provider add my-provider # Shortcut for custom provider id
chabeau provider edit <provider-id>
chabeau provider remove <provider-id> # Remove custom provider, or built-in token
Most users only need provider add; it can either attach a token to a
built-in provider or create a custom provider and prompt for a token.
Use chabeau provider token ... commands later when rotating or removing
credentials.
Environment variables are used only if no providers are configured, or when you pass --env.
export OPENAI_API_KEY="your-api-key-here"
export OPENAI_BASE_URL="https://api.openai.com/v1" # Optional
chabeau --env # Force using env vars even if providers are configured
Quick, Single-Turn Chats
For quick, one-off questions without launching the full TUI, use the say command:
chabeau say "What is the capital of France?"
This command sends a single-turn message to the configured model, streams the response directly to your terminal, and exits. It respects your markdown settings, emits OSC8 hyperlinks when your terminal supports them, and uses a monochrome theme for clean, readable output.
MCP is disabled in chabeau say mode.
When you omit the prompt argument, chabeau say will read from piped or redirected stdin (trimming trailing whitespace) before showing the usage message, so cat prompt.txt | chabeau say works as expected.
When stdout is redirected to a file or piped into another program, Chabeau automatically falls back to a plain-text streaming mode. This mode skips OSC8 hyperlinks and cursor control so captured output stays free of escape codes.
If you have multiple providers configured but no default set, Chabeau will prompt you to specify a provider with the -p flag. The -p and other global flags can be placed before or after the prompt.
Environment variable values can make their way into shell histories or other places they shouldn't, so using the keyring is generally advisable.
Configuration
Chabeau stores its configuration in config.toml.
- Linux:
~/.config/chabeau/config.toml - macOS:
~/Library/Application Support/org.permacommons.chabeau/config.toml
Generally, you can rely on the UI: when you use interactive commands like /model, /provider, /theme, or /character, press Alt+Enter (or Ctrl+J) to persist the selection.
chabeau set / chabeau unset
chabeau set handles scalar values and selection defaults β anything that's a single value or a provider/model mapping. Run chabeau set with no arguments to print the current configuration and see which values are explicitly set versus inherited defaults.
chabeau set # Show all settings
chabeau set default-provider openai # Provider selection
chabeau set theme dracula # Theme selection
chabeau set default-model openai gpt-4o # Default model per provider
chabeau set default-character openai gpt-4 hypatia # Default character per provider/model
chabeau set default-persona anthropic claude-3 developer # Default persona per provider/model
chabeau set default-preset openai gpt-4o short # Default preset per provider/model
chabeau set markdown off # Toggle markdown rendering
chabeau set syntax off # Toggle syntax highlighting
chabeau set builtin-presets off # Toggle built-in presets
chabeau set refine-prefix "REVISE:" # Custom refine trigger
chabeau set refine-instructions "Custom instructions" # Custom refine system prompt
chabeau set mcp agpedia off # Enable/disable an MCP server
chabeau set mcp agpedia yolo on # Toggle auto-approve for a server
Every set key has a matching unset to clear the value:
chabeau unset default-provider
chabeau unset default-model openai # Provider-keyed: pass the provider
chabeau unset default-character "openai gpt-4" # Provider/model-keyed: quote both
chabeau unset markdown # Reverts to default (on)
chabeau unset mcp agpedia # Reverts to default (on)
chabeau unset mcp "agpedia yolo" # Reverts to default (off)
Editing config.toml by hand
The following structured definitions need to be edited in config.toml
directly:
- Custom themes β multi-field color/style definitions under
[[custom_themes]] - Personas β id, display name, and bio under
[[personas]] - Presets β id, pre, and post instructions under
[[presets]]
You can also edit the following in config.toml, but you don't strictly need to:
- Custom providers β can be configured via
chabeau providersubcommands - MCP servers β can be configured via
chabeau mcpsubcommands
Copy examples/config.toml.sample to your config directory for a starting point.
Both the CLI and TUI run mutations through the same configuration orchestrator. Chabeau caches the parsed file based on its last-modified timestamp, skipping redundant reloads when nothing has changed, and persists updates atomically so a failed write never clobbers your existing config.toml.
MCP Servers
Chabeau lets you connect MCP servers (HTTP or stdio) and use their tools/resources from the TUI.
- Manage servers from the CLI:
chabeau mcp list,chabeau mcp add,chabeau mcp add -a,chabeau mcp edit <server-id>,chabeau mcp edit <server-id> -a, andchabeau mcp remove <server-id>. chabeau mcp addandchabeau mcp editrun in basic mode by default and prompt only for required settings; use-a/--advancedto configure optional fields.- HTTP servers can use bearer tokens with
chabeau mcp token list [server-id],chabeau mcp token add <server-id>, andchabeau mcp token remove <server-id>. - Advanced MCP HTTP configs support custom request headers via
headers = { KEY = "VALUE" }in[[mcp_servers]]. - Streamable HTTP transport reuses pooled HTTP connections across MCP initialize/list/tool calls for lower request overhead.
chabeau mcp addprobes OAuth discovery for HTTP/HTTPS servers and starts browser auth when available. You can also runchabeau mcp oauth list [server-id],chabeau mcp oauth add <server-id>, andchabeau mcp oauth remove <server-id>directly. Usechabeau mcp oauth add <server-id> -ato provide an OAuth client id manually.- For OAuth-backed MCP HTTP servers, Chabeau automatically refreshes expiring access tokens when a refresh token is available; if refresh fails, re-run
chabeau mcp oauth add <server-id>. - Stdio servers run a local command with optional
argsandenv. - In the TUI,
/mcplists servers and/mcp <server-id>shows server info, including whether cached MCP tool schemas have client-side validation available. Toggle with/mcp <server-id> on|off(orchabeau set mcp <server-id> on|off). To also clear session runtime MCP state, use/mcp <server-id> forgetinstead. - If a tool requires approval, Chabeau prompts you; use
/yolo <server-id> on|off(orchabeau set mcp <server-id> yolo on|off) for per-server auto-approve. --disable-mcpturns MCP off for a session.--debug-mcpwrites verbose MCP logs tomcp.log.
Character Cards
Chabeau supports character cards in the v2 format, letting you chat with AI personas that define tone, background, and greeting. Cards can be JSON or PNG files (with embedded metadata).
Import and Manage Cards
chabeau import path/to/character.json # Import JSON card
chabeau import path/to/character.png # Import PNG with embedded metadata
chabeau import character.json --force # Overwrite existing card
Cards are stored in the Chabeau configuration directory. Use chabeau -c to print the directory name and any cards Chabeau discovers.
Use Characters in Chat
chabeau -c hypatia # Start with character by name
chabeau -c hypatia.json # Start with character by filename
In the TUI, /character opens the character picker (ββ to navigate, Ctrl+O to inspect full definitions, Enter to select, Alt+Enter to set as default). You can also run /character <name> for quick switches.
Defaults and Directories
Set defaults for provider/model combinations via Alt+Enter (or Ctrl+J) in the picker, or on the CLI:
chabeau set default-character openai gpt-4 hypatia
chabeau unset default-character openai gpt-4
To use a separate configuration directory (including cards), set the CHABEAU_CONFIG_DIR environment variable before launching Chabeau.
Example cards live in examples/hypatia.json and examples/darwin.json.
Troubleshooting
- "Character not found": ensure the card is in
~/.config/chabeau/cards/(or its equivalent on macOS or Windows) or provide the full path. - "Invalid card format": verify the JSON structure matches the v2 spec with required fields (name, description, personality, scenario, first_mes, mes_example).
- "PNG missing metadata": PNG files must contain a
charatEXt chunk with base64-encoded JSON. - Cards not appearing in picker: check file permissions and ensure files have
.jsonor.pngextensions.
Format Reference
Character cards follow the v2 specification.
Personas
Personas allow you to define different user identities for conversations, each with their own name and optional biographical context. Unlike character cards (which define AI personas), personas define who you are in the conversation.
Configure Personas
Add personas to your config.toml:
[[personas]]
id = "developer"
name = "Alex"
bio = "You are talking to Alex, a senior software developer with expertise in Rust and distributed systems."
[[personas]]
id = "student"
name = "Sam"
bio = "Sam is a computer science student learning about AI and machine learning."
[[personas]]
id = "casual"
name = "Jordan"
# bio is optional - persona will just change the display name
Assign defaults per provider/model from the CLI or in config.toml:
chabeau set default-persona openai gpt-4o developer
[default-personas.openai]
"gpt-4o" = "developer"
Use Personas in Chat
chabeau --persona developer # Start with a specific persona
In the TUI, /persona opens the persona picker (ββ to navigate, Ctrl+O to read the persona text, Enter to select, Alt+Enter to set as default). You can also run /persona <id> for quick switches, or select "[Turn off persona]" to return to anonymous mode.
When a persona is active:
- Your messages are labeled with the persona's name instead of "You"
- The persona's bio (if provided) is prepended to the system prompt
Variable Substitutions
Both personas and character cards support {{user}} and {{char}} variable substitutions:
{{user}}is replaced with the active persona's display name (or "Anon" if no persona is active){{char}}is replaced with the character's name (or "Assistant" if no character is active)
Persona vs Character Integration
Personas and character cards work together seamlessly:
- Character cards define the AI's personality, background, and behavior
- Personas define your identity and context in the conversation
- Both support
{{user}}and{{char}}variable substitutions - The persona's bio is added to the system prompt before the character's instructions
Presets
Presets let you inject reusable system instructions into the first and last system messages that Chabeau sends to the model. They are ideal for lightweight tone or formatting tweaks that you want to toggle quickly.
Chabeau ships with three built-in presets (short, roleplay, and casual) so you can experiment without editing your config. Set builtin_presets = false in config.toml to hide them from /preset, /preset <id>, and the --preset flag. If you define a preset with the same ID, your version overrides the built-in automatically.
Configure Presets
Add presets to your config.toml:
[[presets]]
id = "focus"
pre = """
You are collaborating with {{user}}. Keep responses focused and direct.
"""
post = """
Before finishing, list any follow-up actions.
"""
[[presets]]
id = "roleplay"
pre = """
- Engage in roleplay with the user.
- Two paragraphs per turn max.
- Don't be shy to perform actions. Format these in italics, like this: *{{char}} frowns at {{user}}.*
- Be creative! Feel free to take the roleplay into new directions.
"""
pretext is wrapped in blank lines and prepended to the very first system message.posttext is wrapped in blank lines and appended to the final system message. If no system message exists at either position, Chabeau creates one automatically.- Presets support the same
{{user}}and{{char}}substitutions as personas and character cards.
Assign defaults per provider/model from the CLI or in config.toml:
chabeau set default-preset openai gpt-4o focus
[default-presets.openai]
"gpt-4o" = "focus"
Use Presets in Chat
Launch with an ID like --preset focus, or pick interactively with /preset. Use Ctrl+O in the picker to review the preset instructions. The picker includes a "Turn off preset" option to clear the active preset.
The status bar shows the current preset when one is active so you can confirm the context you're using at a glance.
Appearance and Rendering
Themes
Chabeau ships with built-in themes and supports custom ones. Use /theme in the TUI to preview and Alt+Enter (or Ctrl+J) to persist the choice. On the CLI, run:
chabeau set theme dark # Set a theme
chabeau themes # List themes (built-in and custom)
chabeau unset theme # Revert to default detection
When no explicit theme is set, Chabeau tries to infer a sensible default from your OS preference (e.g., macOS, Windows, GNOME). If no hint is available, it defaults to the dark theme.
Custom themes belong in config.toml under [[custom_themes]]. See src/builtins/themes.toml for color references and examples/config.toml.sample for structure.
Themes can also set a cursor_color to change the terminal cursor via OSC 12 when the theme is applied.
Input uses a steady bar cursor inside the chat box so the insertion point stays easy to see while typing.
App messagesβChabeauβs own informational banners, warnings, and errorsβuse dedicated theme knobs so theyβre easy to distinguish from assistant replies. Customize them with the app_info_*, app_warning_*, and app_error_* keys in your theme to control the prefix text, prefix styling, and message styling independently.
Markdown and Syntax Highlighting
Toggle these features at runtime:
/markdown on|off|toggle/syntax on|off|toggle
Chabeau persists these preferences to the config file automatically. Syntax colors adapt to the active theme and use the themeβs code block background for consistent contrast.
When markdown is enabled, image ALT text is rendered as an OSC hyperlink pointing to the underlying image URL so you can open assets directly from the transcript.
Color Support
Chabeau detects terminal color depth and adapts themes accordingly:
- Truecolor: if
COLORTERMcontainstruecoloror24bit, Chabeau uses 24-bit RGB. - 256 colors: if
TERMcontains256color, RGB colors are quantized to the xterm-256 palette. - ANSI 16: otherwise, colors map to the nearest 16 ANSI colors.
Force a mode when needed with CHABEAU_COLOR=truecolor|256|16.
Keyboard and Workflow Tips
Interface Controls
See the built-in help for a full list of keyboard controls. A few highlights:
- Alt+Enter (or Ctrl+J) to start a new line; Enter sends. Arrow keys always act on the focused area.
- Compose mode (F4) flips the newline/send defaults; focus behavior stays the same.
- Home/End and Ctrl+A/Ctrl+E jump to the start or end of the visible line in the focused pane, even when text is soft-wrapped.
- PgUp/PgDn scroll the focused area β the transcript or the multi-line input β by a page at a time.
- Ctrl+N repeats your most recent
/refineprompt on the latest assistant reply. - Tab switches focus between the transcript and input unless the current input starts with
/. When it does, Tab autocompletes slash commands. The active region shows aβΊ; the inactive one shows aΒ·. - Ctrl+O opens the inspect view for picker itemsβproviders include their ID, base URL, and auth mode; themes show their ID and every color override; character cards expand to the full v2 definition.
- Ctrl+D on an empty input prints the transcript and exits; Ctrl+C exits immediately.
Mousewheel
Chabeau avoids capturing the mouse so selection operations (copy/paste) work as expected. Some terminals treat mousewheel events as cursor key input, so scrolling moves the conversation. Others reveal terminal history; in that case, use the cursor keys or PgUp/PgDn instead.
External Editor
Set the EDITOR environment variable to compose longer responses in your favorite editor:
export EDITOR=nano # or vim, code, etc.
export EDITOR="code --wait" # VS Code with wait
Once set, press Ctrl+T in the TUI to launch the external editor.
Architecture Overview
See ARCHITECTURE.md for a high-level walkthrough aligned with the current repository state.
Chabeau uses a modular design with focused components:
main.rsβ Entry pointapi/β API data structures and model-related helpersmod.rsβ API data structuresmodels.rsβ Model fetching and sorting functionality
auth/β Authentication and provider managementmod.rsβ Authentication manager implementationui.rsβ Interactive prompts and input helpers for auth flows
builtins/β Build-time assets embedded into the binaryhelp.mdβ In-app keyboard shortcut and command referencemcp-preamble.mdβ System prompt preamble explaining MCP tool usage to the modelmodels.tomlβ Supported provider definitionsoauth-callback.htmlβ OAuth callback landing page templatepresets.tomlβ Built-in system instruction presetsthemes.tomlβ Built-in UI themes
character/β Character card support (v2 format)cache.rsβ In-memory caching with invalidationcard.rsβ Character card data structures and v2 spec parsingimport.rsβ Import command and validation logicloader.rsβ Card file loading (JSON and PNG with metadata extraction)mod.rsβ Module exports and public APIpng_text.rsβ PNG tEXt chunk reader/writerservice.rsβ Shared character cache and resolution helpers for the TUI and CLI
cli/β Command-line interface parsing and handlingcharacter_list.rsβ Character card listing functionalitymod.rsβ CLI argument parsing and command dispatchingmodel_list.rsβ Model listing functionalityprovider_list.rsβ Provider listing functionalitysay.rsβ TUI-lesssaycommand for streaming single-turn chat outputsettings/β Trait-basedset/unsethandler registrytheme_list.rsβ Theme listing functionality
commands/β Chat command processing and registry-driven dispatchhandlers/β Domain-specific command handlers (core,config,io,mcp)mcp_prompt_parser.rsβ/server-id:prompt-idparser and helpersmod.rsβ Command dispatcher and command result plumbingrefine.rsβ Message refinement logicregistry.rsβ Static command metadata registry
core/β Core application componentsapp/β Application state and controllersactions/β Internal action definitions grouped by domain plus dispatcher routinginput/β Input subdomains for compose, command, inspect, and status actionsfile_prompt.rsβ File prompt handlers for conversation dump and code block save-to-file flowsmcp_gate.rsβ MCP initialization gating and deferred-send handlingmcp_prompt.rsβ MCP prompt handler for collecting and validating sequential prompt argumentspicker.rsβ Picker action handlers (navigation, selection, escape)sampling.rsβ MCP sampling request queueing and permission flowstream_errors.rsβ Stream error handling and MCP unsupported fallback flowstream_lifecycle.rsβ Stream creation, chunk/app-message appends, and finalizationstreaming.rsβ Streaming action dispatchertool_calls.rsβ Tool permission and tool-result completion handling
app.rsβ MainAppstruct and event loop integrationconversation.rsβ Conversation controller for chat flow, retries, and streaming helpersinspect.rsβ Inspect panel state (title, content, scroll, mode, decode flag)mod.rsβ App struct and module exportspicker/β Generic picker that powers all TUI selection dialogspickers.rsβ Picker constructors and helpers for each picker typesession.rsβ Session bootstrap and provider/model statesettings.rsβ Theme and provider controllersstreaming.rsβ Stream request construction, tool-flow orchestration, and MCP integration helpersui_helpers.rsβ UI state transition helpersui_state.rsβ UI state management and text input helpers
builtin_mcp.rsβ Built-in MCP prompt/tool context injection helpersbuiltin_oauth.rsβ Built-in OAuth callback assets and helpersbuiltin_presets.rsβ Built-in preset loaderbuiltin_providers.rsβ Built-in provider configuration (loads frombuiltins/models.toml)chat_stream.rsβ Shared streaming service that feeds responses to the app, UI, and loggersconfig/β Configuration data, defaults, caching, and persistencedata.rsβ Configuration data types and pure helpersdefaults.rsβ Default selection helpers andConfigimplementationsio.rsβ Config path resolution and persistence routinesmod.rsβ Public exports for configuration helpersorchestrator.rsβ Cached config loader, mutation orchestrator, and test isolationtests.rsβ Configuration module tests
keyring.rsβ Secure storage for API keysmcp_auth.rsβ Keyring-backed MCP token storagemcp_sampling.rsβ MCP sampling request conversion and summarization helpersmessage.rsβ Message data structuresoauth.rsβ Shared MCP OAuth discovery, browser flow, callback handling, and token refresh helperspersona.rsβ Persona management and variable substitutionpreset.rsβ System instruction preset managementproviders.rsβ Provider selection and shared provider utilitiesshared_selection.rsβ Shared current-selection helperstext_wrapping.rsβ Text wrapping utilities
mcp/β Model Context Protocol client integrationclient/β MCP client orchestration, transport plumbing, protocol parsing, and operationsmod.rsβ Public MCP client manager API, state, and shared context typesoperations.rsβ MCPexecute_*entry points and shared request flow helpersprotocol.rsβ MCP response parsing and protocol-version helperstransport_http.rsβ Streamable HTTP session lifecycle, request exchange interface, and event listener helperstransport_stdio.rsβ Stdio transport client lifecycle, request dispatch, and server I/O readers
events.rsβ MCP server request envelopestransport/β MCP transport implementations and shared interfacesmod.rsβ Shared transport traits, enums, and list-fetch helpersstdio.rsβ Stdio transport request/list adaptersstreamable_http.rsβ Streamable HTTP list adapters plus shared SSE buffering/parsing utilities
mod.rsβ MCP module exports and tool name constantspermissions.rsβ Per-tool permission decision storeregistry.rsβ Enabled MCP server registry
ui/β Terminal interface renderingappearance.rsβ Theme and style definitionsbuiltin_themes.rsβ Built-in theme spec definitions and deserializationchat_loop/β Mode-aware chat loop orchestrating UI flows, keybindings, and command routingevent_loop.rsβ Async terminal loop orchestration, event polling, and stream dispatchexecutors/β Background task executors for model loading and MCP operationsmcp_init.rsβ Async MCP server initialization spawnermcp_tools.rsβ Async MCP tool call executor with sampling support and timeout handlingmodel_loader.rsβ Async model list fetcher that dispatches picker loaded/failed actions
keybindings/β Mode-aware keybinding registry and handlershandlers.rsβ Keybinding handler implementations organized by mode and categoryregistry.rsβ Keybinding registry system with handler trait and result types
lifecycle.rsβ Terminal setup/teardown helpers and resource guardsmodes.rsβ Mode-aware key handlers and text interaction utilitiessetup.rsβ App state bootstrapping, provider/model setup, and startup picker flows
help.rsβ Help text renderinglayout.rsβ Shared width-aware layout engine for Markdown and plain textmarkdown/β Modular markdown pipeline (parser, renderer, lists, code, metadata, table) plus wrapping helperscode.rsβ Fenced code block parsing and syntax-highlighted renderinglists.rsβ List parsing and renderingmetadata.rsβ Span metadata for inline styles and linksparser.rsβ Markdown token parserrender.rsβ Markdown-to-terminal renderer with theme and syntax supporttable.rsβ Table parsing and renderingtests/β Markdown rendering test suites (wrapping, lists, tables, syntax spans)
markdown_wrap.rsβ Unicode-aware span wrapping shared between markdown rendering and range computationmod.rsβ UI module declarationsosc.rs/osc_backend.rs/osc_state.rsβ OSC hyperlink and cursor-color supportpicker.rsβ Picker controls and renderingrenderer.rsβ Terminal interface rendering (chat area, input, pickers)span.rsβ Span metadata for clickable linkstheme.rsβ Theme loading and managementtitle.rsβ Header bar rendering
utils/β Utility functions and helpersauth.rsβ Auth and provider utility helpersclipboard.rsβ Cross-platform clipboard helpercolor.rsβ Terminal color detection and palette quantizationeditor.rsβ External editor integrationinput.rsβ Keyboard/input utility helpersline_editor.rsβ Shared single-line terminal editor for interactive CLI/auth promptslogging.rsβ Chat logging functionalitymod.rsβ Utility module declarationsscroll.rsβ Text wrapping and scroll calculationssyntax.rsβ Syntax highlighting support helpersurl.rsβ URL parsing and normalization helpers
Development
Running Tests
cargo test # All tests
cargo test scroll:: # Scroll functionality tests
cargo test --release # Faster execution
Local Quality Checks
cargo check
cargo fmt
cargo test
cargo clippy --all-targets --all-features
CI and Release Workflows
.github/workflows/ci.ymlruns build, test, and reproducibility checks on pushes and pull requests..github/workflows/publish.ymlselects the newest semver tag reachable frommain, then publishes the matching crates.io release and GitHub Release binaries with SHA-256 checksums, a keyless Sigstore-signed checksum manifest, and a GitHub Release description extracted from the matchingCHANGELOG.mdversion section..github/workflows/nightly.ymlbuilds Linux/macOS/Windows release binaries on a schedule and updates the movingNightlypre-release with checksummed artifacts and a keyless Sigstore-signed checksum manifest.
Performance
Chabeau includes lightweight performance checks in the unit test suite and supports optional Criterion benches.
- Built-in perf checks (unit tests):
- Short history prewrap (50 iters, ~60 lines): warns at β₯ 90ms; fails at β₯ 200ms.
- Large history prewrap (20 iters, ~400 lines): warns at β₯ 400ms; fails at β₯ 1000ms.
- Run with:
cargo test(warnings print to stderr; tests only fail past the fail thresholds).
- Optional benches (release mode) using Criterion 0.7:
- A
render_cachebench validates the cached prewrapped rendering path. - Run:
cargo bench - Reports live in
target/criterion/(HTML underreport/index.html). - To add new benches, create files under
benches/(e.g.,benches/my_bench.rs) and use Criterionβscriterion_group!/criterion_main!. - Benches import internal modules via
src/lib.rs(e.g.,use chabeau::...).
- A
License
CC0 1.0 Universal (Public Domain)
