Interactive TUI (Terminal User Interface) tools for:
- File Packaging - Create ZIP/TAR archives with custom directory structures
- Form Generation - Auto-generate forms from Pydantic models
# Clone and install
git clone <repository>
cd fstui
uv venv
uv pip install -e .Create custom archives with drag-and-drop style operations:
# Package files interactively
uv run fstui package /path/to/sourceFeatures:
- Dual-panel interface (source | destination)
- Add files/folders (
a) - Create folders (
n) - Rename items (
r) - Delete items (
d) - Export as ZIP or TAR.GZ
from fstui import create_model
from pydantic import BaseModel
class User(BaseModel):
name: str
email: str
age: int
# Interactive form
user = create_model(User)
if user:
print(f"Created: {user.name}")from fstui import update_model, show_changes
# Load existing data
user = User(name="Alice", email="alice@example.com", age=30)
# Edit interactively
updated = update_model(user)
if updated:
show_changes(user, updated)# Form examples
uv run fstui form --example task
uv run fstui form --example blog
# Edit examples
uv run fstui edit task
uv run fstui edit blogfstui/
βββ fstui/ # Core package
β βββ __init__.py # Public API
β βββ packager.py # File packaging widget
β βββ form_generator.py # Form generation widget
β βββ model_app.py # create_model/update_model functions
βββ examples/ # Example models and demos
β βββ example_models.py
β βββ form_app.py
β βββ edit_demo.py
βββ tests/ # Test files
β βββ test_list_parsing.py
β βββ test_list_widget.py
βββ docs/ # Documentation
β βββ MODEL_APP_API.md
β βββ QUICKSTART.md
β βββ ...
βββ main.py # CLI entry point
βββ README.md # This file
from fstui import FilePackager
from textual.app import App
class MyApp(App):
def compose(self):
yield FilePackager("/path/to/source")
app = MyApp()
app.run()from fstui import create_model, update_model, show_changes
# Create
new_instance = create_model(ModelClass)
# Update
updated_instance = update_model(existing_instance)
# Show changes
show_changes(original, updated)from fstui import PydanticFormGenerator, ModelFormApp
# Custom form widget
form = PydanticFormGenerator(ModelClass, initial_data={...})
# Custom app
app = ModelFormApp(ModelClass, model_instance=existing)
result = app.run()- Quick Start Guide - Get started quickly
- Model App API - Complete API reference
- Form Features - New features and testing
| Type | Widget | Notes |
|---|---|---|
str |
Input | TextArea for long text |
int, float |
Input | Numeric validation |
bool |
Switch | Toggle on/off |
Enum |
Select | Dropdown menu |
date |
Input | YYYY-MM-DD format |
list[T] |
Input | Comma-separated |
Optional[T] |
Any | Allow blank |
Markdown Support: Fields named description, content, notes or with json_schema_extra={"format": "markdown"} use a TextArea widget.
from enum import Enum
from pydantic import BaseModel
from fstui import create_model
class Priority(Enum):
LOW = "low"
HIGH = "high"
class Task(BaseModel):
title: str
priority: Priority
completed: bool = False
task = create_model(Task)from datetime import date
from pydantic import BaseModel, Field
from fstui import update_model
class BlogPost(BaseModel):
title: str
content: str = Field(..., json_schema_extra={"format": "markdown"})
published_date: date
post = BlogPost(title="Hello", content="# Welcome\n\nHello world!", published_date=date.today())
updated = update_model(post)All major bugs have been fixed:
- β Enum select values
- β PydanticUndefined handling
- β List field parsing
- β Optional[list[T]] support
See docs/FORM_FIXES.md for details.
Contributions welcome! Please check the project structure and follow existing patterns.
[Add license information]
Built with: