Metadata-Version: 2.4
Name: cliss
Version: 0.3.5
Summary: A lightweight framework for building CLI applications on top of argparse
Project-URL: Homepage, https://github.com/Fkernel653/cliss
Project-URL: Repository, https://github.com/Fkernel653/cliss.git
Project-URL: Documentation, https://github.com/Fkernel653/cliss#readme
Author: Fkernel653
License-Expression: MIT
License-File: LICENSE
Keywords: argparse,cli,command-line,framework,lightweight
Classifier: Intended Audience :: Developers
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Programming Language :: Python :: 3.14
Classifier: Topic :: Software Development :: Libraries :: Python Modules
Classifier: Topic :: Software Development :: User Interfaces
Classifier: Topic :: Terminals
Classifier: Topic :: Utilities
Requires-Python: >=3.10
Provides-Extra: dev
Requires-Dist: ruff; extra == 'dev'
Description-Content-Type: text/markdown

# cliss — A lightweight framework for building CLI applications on top of argparse

[![Python](https://img.shields.io/badge/python-3.10+-blue.svg)](https://python.org)
[![PyPI](https://img.shields.io/pypi/v/cliss.svg)](https://pypi.org/project/cliss/)
[![License](https://img.shields.io/badge/license-MIT-green.svg)](LICENSE)
[![Platform](https://img.shields.io/badge/platform-linux%20%7C%20macOS%20%7C%20windows-lightgrey)]()
[![Ruff](https://img.shields.io/badge/code%20style-ruff-261230?logo=ruff&logoColor=white)](https://docs.astral.sh/ruff/)

Write type-annotated Python functions, get a full CLI — automatic `--help`, validation, and async support with zero dependencies.

## ✨ Features

- **Zero Dependencies** — Pure stdlib: `argparse`, `asyncio`, `inspect`
- **Type-Driven** — Automatic arguments from function signatures and type hints
- **Flexible** — Declarative `Argument` objects, type inference, or both
- **Async-Native** — `async def` handlers with automatic event loop management
- **Global Args** — Define flags shared across all commands
- **Customizable Help** — Choose between standard `argparse` help or an advanced `cliss` help system with themes and examples
- **Coloured Help** — Automatic coloured output on Python 3.14+, ANSI fallback for older versions
- **Bool Flags** — Automatic `--name`/`--no-name` mutually exclusive group
- **argparse Access** — Full access to underlying parsers for advanced use

## 🚀 Quick Start

### Installation
```bash
pip install cliss        # pip
uv pip install cliss     # uv
pipx install cliss       # pipx
```

### Usage
```python
from cliss import CLI

cli = CLI(name="todo", description="Task manager", version="1.0.0")

@cli.command()
def add(task: str, priority: int = 1, done: bool = False):
    """Add a task."""
    status = "✓" if done else "○"
    return f"[{status}] {task} (priority: {priority})"

cli.run()
```

```bash
$ python todo.py add "Buy milk" --priority 2
[○] Buy milk (priority: 2)

$ python todo.py add "Call mom" --done
[✓] Call mom (priority: 1)

$ python todo.py add "Test" --no-done
[○] Test (priority: 1)
```

## 📋 API Reference

### `CLI` class
```python
CLI(name="myapp", description="...", version="1.0.0", auto_help=True, colour=True, helper="cliss")
```
| Parameter | Type | Default | Description |
|-----------|------|---------|-------------|
| `name` | `Optional[str]` | `None` | Program name in help |
| `description` | `Optional[str]` | `None` | Description in help |
| `version` | `Optional[str]` | `None` | Adds `--version` flag |
| `auto_help` | `bool` | `True` | Adds `--help` flag |
| `colour` | `bool` | `True` | Coloured help (3.14+ native, else ANSI) |
| `helper` | `Literal["argparse", "cliss"]` | `"cliss"` | Help system to use |

### `Help` System
When `helper="cliss"`, you get an extended help system accessible via `cli.help_system`.

#### `HelpTheme`
Configure colors and styles for your help output. Available styles: `\033[1m` (bold), `\033[2m` (dim), `\033[32m` (green), `\033[33m` (yellow), and more.
```python
from cliss import HelpTheme
theme = HelpTheme(usage="\033[1m", header="\033[1m", option_string="\033[32m", metavar="\033[33m")
cli = CLI(helper="cliss", theme=theme)
```

#### Registering Additional Command Help
Add long descriptions and usage examples for your commands.
```python
cli.help_system.register_command_help(
    "add",
    help_text="Add a new task to the list with optional priority.",
    usage="todo add <task> [--priority <int>]",
    examples=["todo add 'Buy milk' --priority 2", "todo add 'Call mom' --done"]
)
```

### `Argument` class
```python
from cliss import Argument

Argument("--output", "-o", type=str, default=None, help="...", choices=["json","csv"], action="store_true")
```
| Parameter | Type | Default | Description |
|-----------|------|---------|-------------|
| `*flags` | `str` | — | Argument flags |
| `type` | `type` | `str` | Value type |
| `default` | `Any` | `None` | Default value |
| `help` | `str` | `""` | Help text |
| `required` | `bool` | `False` | Make required |
| `choices` | `list` | `None` | Allowed values |
| `action` | `str` | `None` | argparse action |

### Type → CLI Mapping
| Function Signature | CLI Argument |
|--------------------|--------------|
| `name: str` | Positional `name` |
| `count: int = 1` | `--count` (default: 1) |
| `verbose: bool = False` | `--verbose`/`--no-verbose` |
| `mode: Optional[str] = None` | `--mode` (default: None) |

## 📖 Examples

### CRUD Application
```python
from cliss import CLI

cli = CLI(name="db")
db = {}

@cli.command()
def set(key: str, value: str):
    db[key] = value
    return f"OK: {key} = {value}"

@cli.command()
def get(key: str):
    return db.get(key, "Not found")

@cli.command()
def delete(key: str, force: bool = False):
    if force or key in db:
        db.pop(key, None)
        return f"Deleted: {key}"
    return f"Not found (use --force)"

cli.run()
```

### Command Groups
```python
cli = CLI(name="git")

remote = cli.group("remote", "Manage remotes")
stash = cli.group("stash", "Stash changes")

@remote.command()
def add(name: str, url: str):
    return f"Added remote {name}"

@stash.command()
def push(message: str = ""):
    return f"Stashed: {message or 'WIP'}"

cli.run()
```

### Async Commands
```python
@cli.command()
async def fetch(url: str, retries: int = 3):
    return f"Fetched {url} (retries: {retries})"
```

## ❓ FAQ

### Why cliss over argparse/Click/Typer/Fire?
| Tool | Deps | Style |
|------|------|-------|
| **cliss** | 0 | Decorators + type hints |
| Click | Click | Decorators |
| Typer | Click + typing-extensions | Type hints |
| Fire | 0 | Introspection |

cliss = Fire's zero-deps + Typer's type-driven design. ~200 lines, pure stdlib.

### Bool flags?
Automatic `--name`/`--no-name` mutually exclusive group. `store_true` by default, `store_false` if default is `True`.

### Async?
`async def` handlers auto-run with `asyncio.run()`. Sync functions returning coroutines also work.

### Custom Help Themes?
Yes! When using `helper="cliss"`, you can pass a `HelpTheme` instance to style the help output. You can also register long descriptions and usage examples for each command.

### argparse access?
`cli.parser` and `cli.subparsers` are standard argparse objects. Mutually exclusive groups, custom actions, parent parsers — all available.

## 📄 License

MIT — see [LICENSE](LICENSE) file.

---

**Author:** [Fkernel653](https://github.com/Fkernel653)
**Repository:** [github.com/Fkernel653/cliss](https://github.com/Fkernel653/cliss)
**PyPI:** [pypi.org/project/cliss](https://pypi.org/project/cliss/)
