skills/textual/SKILL.md
Textual patterns for building and testing terminal UIs in Python. Covers app structure, widgets, layout, styling, bindings, focus, screens, and headless testing with `run_test()` and the Pilot API.
npx skillsauth add oornnery/.agents textualInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
Use when work is primarily Textual TUI, terminal workflow, or tests for Textual widgets and screens.
Use for:
.tcss stylingrun_test()Pair with:
python for general Python conventions, typing, project workflowrich when renderables, terminal formatting, or console UX matter outside TUIquality when interaction regressions or state bugs need stronger testsreferences/app-structure.md -- app shape, widgets, reactivity, messages, screens, state boundariesreferences/widgets.md -- common widgets, tables, forms, containers, custom widget guidancereferences/widget-development.md -- custom widget patterns: base class selection, composition, lifecycle, advanced compositionsreferences/layout-and-styling.md -- .tcss, containers, layout, spacing, ids, classes, visual structure, themes, colorsreferences/reactive-programming.md -- reactive attrs, watchers, computed props, valid, complex state, recomposereferences/interactivity.md -- bindings, actions, focus, mouse and keyboard handling, interaction patternsreferences/testing.md -- headless tests, full Pilot API, resize, animations, workers, assert patterns for complex widgetsassets/app.py -- small Textual app with bindings, dialog-like screen, stable selectors for testsassets/app.tcss -- matching .tcss file for example appassets/test_app.py -- headless functional tests using run_test()Keep this file focused on defaults and guardrails.
.tcss, not large inline CSS stringswatch_* methodsaction_* + BINDINGS for keyboard behaviorrun_test() over only checking impl detailssuper().__init__(name=name, id=id, classes=classes) in custom widget __init__.append() won't fire watch_*from textual.app import App, ComposeResult
from textual.widgets import Footer, Header, Label
class DemoApp(App):
CSS_PATH = "app.tcss"
def compose(self) -> ComposeResult:
yield Header()
yield Label("Hello, Textual!", id="status")
yield Footer()
if __name__ == "__main__":
DemoApp().run()
async with app.run_test() as pilot: for functional testsawait pilot.pause() after interactions that queue updatesawait pilot.wait_for_animation() when animation timing mattersawait pilot.wait_for_scheduled_animations() for all scheduled animationsawait pilot.app.workers.wait_for_complete() for worker-driven flowsasyncio_mode = "auto" -- avoids @pytest.mark.asyncio on every testpilot.app.query_one("#id", WidgetType) for typed queryingrun_test(size=(w, h))For deeper patterns, load references/testing.md.
attr: reactive[Type] = reactive(default)init=False when initializing in __init__; omit when reactive sets defaultrecompose=True when attribute change should rebuild child widget treelayout=True when attribute change affects size/positionwatch_attr(self, old: T, new: T) -> None@property for derived values; update via watcher when dependency changeswatch_*, revert or clamp value thereFor full patterns, load references/reactive-programming.md.
Static for display-only content; extend Container/Vertical/Horizontal for compositionDEFAULT_CSS on class for self-contained defaults*) for id, name, classesname, id, classes to super().__init__()_prefixed instance vars; never in class vars that aren't ClassVarpost_message() from child, handle in parentFor deep patterns, load references/widget-development.md.
App classdevelopment
--- name: verification description: Discover and run project validation gates: format, lint, typecheck, LSP diagnostics, tests, build, static security checks, dependency audits, and RTK output handling. Use before claiming work is complete, when fixing broken checks, or when setting up a validation plan. --- # Verification Use this skill to prove changes with the strongest practical checks the repo already supports. ## Discovery Order 1. Read task aliases: `package.json`, `pyproject.toml`, `
tools
Build, review, or validate standalone Python scripts run with uv inline metadata. Use for one-file automation, operational scripts, script dependencies, shebangs, idempotency, safety, representative runs, and promoting scripts to packages.
development
Build, review, or validate Python packages and libraries where public API stability, packaging metadata, imports, examples, changelogs, build output, and compatibility matter.
tools
Build, review, or validate Python command-line applications and terminal tools. Use for argparse, Typer, Rich, Textual-adjacent CLI UX, stdout/stderr contracts, exit codes, automation-friendly flags, help output, and CLI tests.