API Design
The public API is the stable surface downstream apps use to build lazygit-style TUIs without copying framework internals. Lazy-cuh should feel like a small layered framework: app authors can start with concise defaults, then drop down into focused packages when they need more control.
Before a stable release, the API may still change. Pre-alpha releases should
still keep the documented exports intentional: root and focused-package
__all__ surfaces are snapshot-tested so additions and removals are reviewed
instead of happening accidentally.
The public API is split into three surfaces:
lazy_cuhfor commonly used pure models, renderers, controllers, and specs- focused subpackages such as
lazy_cuh.inputs,lazy_cuh.view,lazy_cuh.keybar,lazy_cuh.modals,lazy_cuh.layout, andlazy_cuh.viewportwhen an app needs a narrower import lazy_cuh.widgetsfor Textual adapter widgets and widget messages
Those import surfaces are separate from the ergonomic layers described in API Layers. The root package is a convenience import surface, not the only recommended way to structure larger apps and examples.
The API should aim for SDK-like ergonomics without hiding the framework model: minimal runnable examples, typed declarations, validation near the declared value, clear errors, and presets for common lazygit-style screens.
The public API should expose:
- plain models for items, panels, tabs, actions, events, commands, and selection
- renderers for keybars, panel titles, line numbers, and item rows
- navigation state machines that accept plain keys and return typed intentions
- viewport helpers for visual-line mapping and scroll policy
- Textual adapters that are thin wrappers over the pure models
For example, external apps should be able to build shell state and action metadata without importing Textual:
import lazy_cuh as lc
actions = lc.inputs.ActionMap(...)panel = lc.view.PanelSpec(...)Textual should only enter at the adapter boundary:
from lazy_cuh.widgets import KeybarWidget, ListViewWidget, PanelWidgetSpec, ShellRuntime, ShellViewAdapterThe API should not expose:
- app-specific domain state
- app-specific profile, channel, or domain behavior
- Textual lifecycle details as the primary programming model
- raw widget subclasses as the only way to reuse behavior
Compatibility alias modules are intentionally avoided while the project is
pre-alpha. New docs and examples should prefer either the root package or
focused subpackages. New implementation code should live under focused packages
such as core, inputs, layout, viewport, view, keybar, modals, and
widgets.