Klix
CLI interfaces that just click.
Klix is a Python framework for building polished, interactive command-line applications. It combines command routing, typed session state, prompt-driven input, rich rendering, middleware, events, and lightweight layout primitives into one developer-facing toolkit.
Why Klix
Klix is built for developers who want more than print() and argparse, but do not want to hand-roll a terminal framework every time they start a new tool.
It is a framework, not a finished app. You define the commands, state, UI, and flow. Klix provides the runtime pieces that make those tools feel deliberate instead of improvised.
Key Features
- Command-first app model with decorators and first-class
Commandobjects - Typed session state for per-run data and persisted workflows
- Prompt-driven input powered by
prompt_toolkit - Rich terminal rendering with sensible fallback behavior
- Reusable UI helpers for tables, panels, spinners, selectors, forms, and streaming
- Middleware and lifecycle events for cross-cutting behavior
- Lightweight layout regions for headers, status lines, and structured screens
- Built-in scaffold CLI via
klix init mytool
Demo
Minimal command flow:
$ python examples/minimal.py
Minimal
Try /help, /deploy staging, /ask, /login, /markdown, or /exit.
> /deploy staging --force
Deploying to staging in forced mode
> /help
/deploy <environment> [--force] Deploy to an environment
/ask Prompt for free-form input
/login Collect credentials interactively
/markdown Render markdown output
> /exit
Chat-style UI example:
$ python examples/chat_ai.py
Klix Assistant
Talk to the demo like a ai chat app. Type normal text to send a message...
You > explain terminal UX
Assistant: terminal UX looks manageable. I would break it into a small core...
You > /theme
Assistant: Theme switched to light.
Installation
For local development:
python -m pip install -e .
This installs:
- the
klixPython package - the
klixscaffold command
After installation:
klix
Expected output:
Usage: klix init <name>
Quickstart
Create a small Klix app:
from dataclasses import dataclass
import klix
@dataclass
class DemoState(klix.SessionState):
runs: int = 0
app = klix.App(
name="demo",
version="0.1.0",
description="Small Klix example",
state_schema=DemoState,
)
@app.on("start")
def on_start(session: klix.Session) -> None:
session.ui.print("Demo is ready. Try /hello or /exit.", color="muted")
@app.command("/hello", help="Say hello")
def hello(session: klix.Session) -> None:
session.state.runs += 1
session.ui.print(f"Hello from Klix. Run #{session.state.runs}", color="success")
if __name__ == "__main__":
app.run()
Run it:
python main.py
Core Concepts
App: the composition root for commands, middleware, events, theme, and persistenceSession: per-run context holding state, metadata, UI, and input historyRouter: parses slash commands and validates typed argumentsInputEngine: prompt handling, input modes, and interactive terminal behaviorRenderer: rich-aware output with fallback modes for simpler terminalsUI: the main application-facing namespace for input, output, layout, and streamingLayout: lightweight persistent regions for header, main output, and status
If you want the deeper architectural walkthrough, start with docs/index.md and then docs/concepts/architecture.md.
Example Command Usage
Typed command with arguments:
from pydantic import BaseModel
class DeployArgs(BaseModel):
environment: str
force: bool = False
@app.command("/deploy", args_schema=DeployArgs, help="Deploy the service")
def deploy(args: DeployArgs, session: klix.Session) -> None:
session.ui.print(
f"Deploying to {args.environment} (force={args.force})",
color="warning",
)
Interactive command with reusable UI components:
@app.command("/release", help="Run a guided release flow")
async def release(session: klix.Session) -> None:
version = await session.ui.input.text("Version", placeholder="1.2.3")
target = await session.ui.input.select(
["staging", "production"],
label="Environment",
)
confirmed = await session.ui.input.confirm(
f"Release {version} to {target}?",
default=False,
)
if not confirmed:
session.ui.print("Release cancelled.", color="warning")
return
session.ui.output.panel(
f"Released {version} to {target}",
title="Release Complete",
border_color="success",
)
Examples In This Repository
examples/minimal.py: compact command-oriented starter appexamples/full_demo.py: broader framework walkthrough with persistence and middlewareexamples/chat_ai.py: Gemini-style conversational UI demoexamples/ui_showcase.py: reusable input and output component showcase
Documentation
The full docs live in docs/.
Recommended starting points:
Contributing
Contributions are welcome. Good issues, focused pull requests, example improvements, and documentation fixes all help.
Start with CONTRIBUTING.md for local setup, project structure, and contribution guidelines.
License
Klix is licensed under the Apache License 2.0.
Metadata
Release files for klix 0.1.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| klix-0.1.0.tar.gz | 37.6 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| klix-0.1.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 78.2 kB
Release files / klix-0.1.0.tar.gz
| Download URL | klix-0.1.0.tar.gz |
|---|---|
| Size | 37.6 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
834d16ad37fb8b91d3f26b00e1a24e56b918db219722f5a96c75b8baa0a960b1
|
|
BLAKE2b-256 checksum How to use checksums |
9d6e8b123e0f325edd5f6db55d6f7c0bbd1d0360fe073c1e0b4d2197f8946412
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.14.0
|
Release files / klix-0.1.0-py3-none-any.whl
| Download URL | klix-0.1.0-py3-none-any.whl |
|---|---|
| Size | 40.6 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
d8e5314c19d686a9ede13a00ebd314316898af0a3a9efa3aa98b274fefdfb71d
|
|
BLAKE2b-256 checksum How to use checksums |
c9e4c4be1d9ed7869ffdbb26b264d08230d207528e60cf5a8d172ae6c75afa69
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.14.0
|