Get the FREE Ultimate OpenClaw Setup Guide →

textual-scaffolder

npx machina-cli add skill a5c-ai/babysitter/textual-scaffolder --openclaw
Files (1)
SKILL.md
4.0 KB

Textual Scaffolder

Generate Textual TUI applications with Python and modern async patterns.

Capabilities

  • Generate Textual project structure
  • Create custom widgets and screens
  • Set up CSS-based styling
  • Implement reactive attributes
  • Create component composition
  • Set up testing with textual.testing

Usage

Invoke this skill when you need to:

  • Build terminal UIs in Python
  • Create interactive CLI with CSS styling
  • Implement multi-screen TUI applications
  • Set up Textual project structure

Inputs

ParameterTypeRequiredDescription
projectNamestringYesProject name
screensarrayNoScreen definitions
widgetsarrayNoCustom widget definitions

Generated Patterns

Main Application

from textual.app import App, ComposeResult
from textual.widgets import Header, Footer, Static, Button, Input
from textual.containers import Container, Horizontal, Vertical
from textual.screen import Screen

class MainScreen(Screen):
    """Main application screen."""

    CSS = """
    MainScreen {
        layout: grid;
        grid-size: 2;
        grid-gutter: 1;
    }

    #sidebar {
        width: 30;
        background: $surface;
        border: solid $primary;
    }

    #content {
        background: $surface;
        border: solid $secondary;
    }
    """

    def compose(self) -> ComposeResult:
        yield Header()
        yield Container(
            Static("Sidebar", id="sidebar"),
            Static("Content", id="content"),
        )
        yield Footer()


class MyApp(App):
    """Main TUI application."""

    BINDINGS = [
        ("q", "quit", "Quit"),
        ("d", "toggle_dark", "Toggle dark mode"),
    ]

    CSS_PATH = "styles.tcss"

    def on_mount(self) -> None:
        self.push_screen(MainScreen())

    def action_toggle_dark(self) -> None:
        self.dark = not self.dark


if __name__ == "__main__":
    app = MyApp()
    app.run()

Custom Widget

from textual.widget import Widget
from textual.reactive import reactive
from textual.message import Message

class Counter(Widget):
    """A counter widget with increment/decrement."""

    value = reactive(0)

    class Changed(Message):
        """Counter value changed."""
        def __init__(self, value: int) -> None:
            self.value = value
            super().__init__()

    def render(self) -> str:
        return f"Count: {self.value}"

    def increment(self) -> None:
        self.value += 1
        self.post_message(self.Changed(self.value))

    def decrement(self) -> None:
        self.value -= 1
        self.post_message(self.Changed(self.value))

CSS Styles (styles.tcss)

Screen {
    background: $surface;
}

Header {
    dock: top;
    background: $primary;
}

Footer {
    dock: bottom;
    background: $primary;
}

Button {
    margin: 1;
}

Button:hover {
    background: $primary-lighten-1;
}

Input {
    margin: 1;
    border: tall $secondary;
}

Input:focus {
    border: tall $primary;
}

.error {
    color: $error;
}

.success {
    color: $success;
}

Data Table Widget

from textual.widgets import DataTable
from textual.app import ComposeResult

class DataScreen(Screen):
    def compose(self) -> ComposeResult:
        yield DataTable()

    def on_mount(self) -> None:
        table = self.query_one(DataTable)
        table.add_columns("Name", "Email", "Role")
        table.add_rows([
            ("Alice", "alice@example.com", "Admin"),
            ("Bob", "bob@example.com", "User"),
            ("Charlie", "charlie@example.com", "User"),
        ])

Dependencies

[project]
dependencies = [
    "textual>=0.40.0",
]

[project.optional-dependencies]
dev = [
    "textual-dev>=1.0.0",
]

Target Processes

  • tui-application-framework
  • interactive-form-implementation
  • dashboard-monitoring-tui

Source

git clone https://github.com/a5c-ai/babysitter/blob/main/plugins/babysitter/skills/babysit/process/specializations/cli-mcp-development/skills/textual-scaffolder/SKILL.mdView on GitHub

Overview

This skill scaffolds a complete Textual (Python) TUI project, generating a reusable structure with widgets, screens, and CSS-based styling. It includes patterns for reactive attributes, component composition, and testing hooks via textual.testing.

How This Skill Works

Provide inputs like projectName and optional screens and widgets. The scaffolder emits a ready-to-run skeleton: a main App with screens, a Custom Widget example, a CSS file (styles.tcss), and a DataTable widget scaffold; it wires in optional testing scaffolding for textual.testing.

When to Use It

  • You are building a multi-screen terminal UI in Python using Textual.
  • You want a CSS-styled TUI with a consistent theme across widgets.
  • You’re starting a new Textual project and need a ready-made app skeleton.
  • You need a sample DataTable and interactive widgets to prototype data views.
  • You want to incorporate testing with textual.testing early in development.

Quick Start

  1. Step 1: Provide inputs (projectName, screens, widgets) to the textual-scaffolder.
  2. Step 2: Run the scaffolder to generate the Main app, Custom Widget, and styles.tcss along with DataTable scaffolding.
  3. Step 3: Run and iterate on the app (e.g., python -m your_app) and customize widgets and CSS.

Best Practices

  • Map the UI flow by defining screens and widgets before generating code.
  • Use styles.tcss to apply a consistent theme across the app.
  • Prefer reactive attributes for dynamic UI updates and user interactions.
  • Keep main app, widgets, and data views in separate modules for maintainability.
  • Enable textual.testing from the start to validate behavior.

Example Use Cases

  • Dashboard with Header, Sidebar, and Content area powered by MainScreen.
  • CSV/DataTable viewer showing Name, Email, and Role in a DataTable widget.
  • Interactive form with Input fields and live validation.
  • Multi-screen help viewer with navigation and back/forward between screens.
  • Counter widget demonstrating increment/decrement with event messaging.

Frequently Asked Questions

Add this skill to your agents
Sponsor this space

Reach thousands of developers