espressoTUI 1.0.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- espressotui-1.0.0/LICENSE +21 -0
- espressotui-1.0.0/PKG-INFO +315 -0
- espressotui-1.0.0/README.md +285 -0
- espressotui-1.0.0/pyproject.toml +59 -0
- espressotui-1.0.0/src/espresso/__init__.py +61 -0
- espressotui-1.0.0/src/espresso/beans/__init__.py +304 -0
- espressotui-1.0.0/src/espresso/beans/bar_chart.py +301 -0
- espressotui-1.0.0/src/espresso/beans/codeviewer.py +349 -0
- espressotui-1.0.0/src/espresso/beans/command_palette.py +398 -0
- espressotui-1.0.0/src/espresso/beans/confetti.py +272 -0
- espressotui-1.0.0/src/espresso/beans/datepicker.py +493 -0
- espressotui-1.0.0/src/espresso/beans/detail_selector.py +191 -0
- espressotui-1.0.0/src/espresso/beans/dialog.py +120 -0
- espressotui-1.0.0/src/espresso/beans/diff_viewer.py +468 -0
- espressotui-1.0.0/src/espresso/beans/filepicker.py +276 -0
- espressotui-1.0.0/src/espresso/beans/form.py +294 -0
- espressotui-1.0.0/src/espresso/beans/git_tree.py +366 -0
- espressotui-1.0.0/src/espresso/beans/help.py +200 -0
- espressotui-1.0.0/src/espresso/beans/image.py +329 -0
- espressotui-1.0.0/src/espresso/beans/list.py +506 -0
- espressotui-1.0.0/src/espresso/beans/markdown.py +259 -0
- espressotui-1.0.0/src/espresso/beans/marquee.py +161 -0
- espressotui-1.0.0/src/espresso/beans/metric.py +177 -0
- espressotui-1.0.0/src/espresso/beans/navstack.py +161 -0
- espressotui-1.0.0/src/espresso/beans/paginator.py +159 -0
- espressotui-1.0.0/src/espresso/beans/pipeline_progress.py +313 -0
- espressotui-1.0.0/src/espresso/beans/progress.py +59 -0
- espressotui-1.0.0/src/espresso/beans/prompt.py +269 -0
- espressotui-1.0.0/src/espresso/beans/quickfix.py +219 -0
- espressotui-1.0.0/src/espresso/beans/slider.py +417 -0
- espressotui-1.0.0/src/espresso/beans/sortable_list.py +305 -0
- espressotui-1.0.0/src/espresso/beans/sparkline.py +285 -0
- espressotui-1.0.0/src/espresso/beans/spinner.py +69 -0
- espressotui-1.0.0/src/espresso/beans/splitter.py +329 -0
- espressotui-1.0.0/src/espresso/beans/spring.py +284 -0
- espressotui-1.0.0/src/espresso/beans/statusbar.py +161 -0
- espressotui-1.0.0/src/espresso/beans/table.py +139 -0
- espressotui-1.0.0/src/espresso/beans/tabs.py +125 -0
- espressotui-1.0.0/src/espresso/beans/textarea.py +425 -0
- espressotui-1.0.0/src/espresso/beans/textinput.py +138 -0
- espressotui-1.0.0/src/espresso/beans/timer.py +277 -0
- espressotui-1.0.0/src/espresso/beans/toast.py +118 -0
- espressotui-1.0.0/src/espresso/beans/tree.py +160 -0
- espressotui-1.0.0/src/espresso/beans/viewport.py +104 -0
- espressotui-1.0.0/src/espresso/cli.py +219 -0
- espressotui-1.0.0/src/espresso/core/__init__.py +45 -0
- espressotui-1.0.0/src/espresso/core/keys.py +226 -0
- espressotui-1.0.0/src/espresso/core/mouse.py +189 -0
- espressotui-1.0.0/src/espresso/core/program.py +388 -0
- espressotui-1.0.0/src/espresso/core/tea.py +187 -0
- espressotui-1.0.0/src/espresso/core/terminal.py +178 -0
- espressotui-1.0.0/src/espresso/crema/__init__.py +74 -0
- espressotui-1.0.0/src/espresso/crema/border.py +87 -0
- espressotui-1.0.0/src/espresso/crema/color.py +131 -0
- espressotui-1.0.0/src/espresso/crema/flexbox.py +257 -0
- espressotui-1.0.0/src/espresso/crema/gradient.py +196 -0
- espressotui-1.0.0/src/espresso/crema/grid.py +174 -0
- espressotui-1.0.0/src/espresso/crema/layout.py +130 -0
- espressotui-1.0.0/src/espresso/crema/overlay.py +151 -0
- espressotui-1.0.0/src/espresso/crema/style.py +464 -0
- espressotui-1.0.0/src/espresso/crema/width.py +119 -0
- espressotui-1.0.0/src/espresso/crema/wrap.py +346 -0
- espressotui-1.0.0/src/espresso/py.typed +1 -0
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Kim Schulz
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
@@ -0,0 +1,315 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: espressoTUI
|
|
3
|
+
Version: 1.0.0
|
|
4
|
+
Summary: A lightweight, declarative Elm Architecture (TEA) TUI framework for Python inspired by Bubble Tea.
|
|
5
|
+
Author-email: Kim Schulz <kim@schulz.dk>
|
|
6
|
+
Requires-Python: >=3.10
|
|
7
|
+
Description-Content-Type: text/markdown
|
|
8
|
+
Classifier: Development Status :: 3 - Alpha
|
|
9
|
+
Classifier: Environment :: Console
|
|
10
|
+
Classifier: Intended Audience :: Developers
|
|
11
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
12
|
+
Classifier: Operating System :: POSIX
|
|
13
|
+
Classifier: Operating System :: Unix
|
|
14
|
+
Classifier: Operating System :: MacOS
|
|
15
|
+
Classifier: Programming Language :: Python :: 3
|
|
16
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
18
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
19
|
+
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
|
20
|
+
Classifier: Topic :: Software Development :: User Interfaces
|
|
21
|
+
Classifier: Typing :: Typed
|
|
22
|
+
License-File: LICENSE
|
|
23
|
+
Requires-Dist: pytest>=7.0 ; extra == "dev"
|
|
24
|
+
Requires-Dist: mypy>=1.0 ; extra == "dev"
|
|
25
|
+
Project-URL: Homepage, https://github.com/kimusan/espresso
|
|
26
|
+
Project-URL: Issues, https://github.com/kimusan/espresso/issues
|
|
27
|
+
Project-URL: Repository, https://github.com/kimusan/espresso.git
|
|
28
|
+
Provides-Extra: dev
|
|
29
|
+
|
|
30
|
+
# โ Espresso
|
|
31
|
+
|
|
32
|
+
> A lightweight, declarative Elm Architecture (TEA) terminal UI framework for Python.
|
|
33
|
+
> Inspired by Charm's **Bubble Tea**, **Lip Gloss**, and **Bubbles**.
|
|
34
|
+
|
|
35
|
+
[](https://www.python.org/downloads/)
|
|
36
|
+
[](https://opensource.org/licenses/MIT)
|
|
37
|
+
[](#features)
|
|
38
|
+
[](https://guide.elm-lang.org/architecture/)
|
|
39
|
+
|
|
40
|
+
```
|
|
41
|
+
( ) ( ) )
|
|
42
|
+
) ( ) ( (
|
|
43
|
+
( ) ( ) )
|
|
44
|
+
_____________
|
|
45
|
+
<_____________> ___
|
|
46
|
+
| |/ _ \
|
|
47
|
+
| ESPRESSO | | | |
|
|
48
|
+
| CREMA |_| |_|
|
|
49
|
+
|___BEANS_____|\___/
|
|
50
|
+
\_____________/
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
---
|
|
54
|
+
|
|
55
|
+
## ๐ Why Espresso?
|
|
56
|
+
|
|
57
|
+
Terminal applications in Python have historically required heavy object-oriented widget hierarchies, complex retained-state DOM trees, or callback-laden curses wrappers.
|
|
58
|
+
|
|
59
|
+
**Espresso brings The Elm Architecture (TEA) to Python:**
|
|
60
|
+
1. **Purity & Determinism**: Your application state is a simple `Model`. Changes only happen through an `update(msg)` function.
|
|
61
|
+
2. **View is Pure**: Rendering is a simple `view() -> str` function that turns state into a styled ANSI string.
|
|
62
|
+
3. **No Race Conditions**: Background operations (network, timers, disk I/O) are isolated in `Cmd` (commands) that emit messages back into the event loop.
|
|
63
|
+
4. **Zero Dependencies**: Runs out of the box using Python's standard library (`asyncio`, `termios`, `tty`, `unicodedata`).
|
|
64
|
+
5. **Modern Python 3.10+ Ergonomics**: Native support for structural pattern matching (`match / case`).
|
|
65
|
+
|
|
66
|
+
---
|
|
67
|
+
|
|
68
|
+
## โ The Espresso Ecosystem
|
|
69
|
+
|
|
70
|
+
| Layer | Charm Equivalent | Description |
|
|
71
|
+
| :--- | :--- | :--- |
|
|
72
|
+
| **`espresso`** | `bubbletea` | **The Strong Base**: Core TEA framework, runtime event loop, raw terminal driver, command primitives, line-diffing alt-screen renderer, SGR mouse tracking, and gesture engine. |
|
|
73
|
+
| **`espresso.crema`** | `lipgloss` | **The Smooth Crema**: Declarative styling, box model, TrueColor (24-bit RGB), ANSI 256, borders, border titles, TrueColor linear gradients, ANSI word-wrapping, 2D layout alignment, FlexBox, and responsive Grid. |
|
|
74
|
+
| **`espresso.beans`** | `bubbles` | **The Flavorful Beans**: 39 reusable UI components including TextArea, GitTree, CommandPalette, BarChart, Splitter, Sliders, Form, DiffViewer, SortableList, Confetti, CodeViewer, MarkdownViewer, Tables, Viewports, and more. |
|
|
75
|
+
|
|
76
|
+
---
|
|
77
|
+
|
|
78
|
+
## ๐ Quickstart
|
|
79
|
+
|
|
80
|
+
### Installation
|
|
81
|
+
|
|
82
|
+
**Via PyPI**:
|
|
83
|
+
```bash
|
|
84
|
+
pip install espressoTUI
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
**Universal Standalone Executable (Zero Installation)**:
|
|
88
|
+
Download the standalone `espresso.pyz` from [GitHub Releases](https://github.com/kimusan/espresso/releases):
|
|
89
|
+
```bash
|
|
90
|
+
curl -LO https://github.com/kimusan/espresso/releases/latest/download/espresso.pyz
|
|
91
|
+
chmod +x espresso.pyz
|
|
92
|
+
./espresso.pyz gallery
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
**Native Binaries (No Python Runtime Required)**:
|
|
96
|
+
Pre-compiled self-contained native binaries are available on every release for:
|
|
97
|
+
- **Linux x86_64**: `espresso-linux-x86_64`
|
|
98
|
+
- **macOS Apple Silicon**: `espresso-macos-arm64`
|
|
99
|
+
- **macOS Intel**: `espresso-macos-x86_64`
|
|
100
|
+
- **Windows x86_64**: `espresso-windows-x86_64.exe`
|
|
101
|
+
|
|
102
|
+
### 1. Minimal Interactive Counter
|
|
103
|
+
```python
|
|
104
|
+
from espresso import Model, Msg, Cmd, KeyMsg, Program, quit_app
|
|
105
|
+
|
|
106
|
+
class Counter(Model):
|
|
107
|
+
def __init__(self):
|
|
108
|
+
self.count = 0
|
|
109
|
+
|
|
110
|
+
def init(self) -> Cmd | None:
|
|
111
|
+
return None
|
|
112
|
+
|
|
113
|
+
def update(self, msg: Msg) -> tuple[Model, Cmd | None]:
|
|
114
|
+
match msg:
|
|
115
|
+
case KeyMsg(key="+" | "up"):
|
|
116
|
+
self.count += 1
|
|
117
|
+
case KeyMsg(key="-" | "down"):
|
|
118
|
+
self.count -= 1
|
|
119
|
+
case KeyMsg(key="q" | "esc"):
|
|
120
|
+
return self, quit_app
|
|
121
|
+
return self, None
|
|
122
|
+
|
|
123
|
+
def view(self) -> str:
|
|
124
|
+
return f"Count: {self.count}\n\n[+/-] Adjust [q] Quit"
|
|
125
|
+
|
|
126
|
+
if __name__ == "__main__":
|
|
127
|
+
Program(Counter()).run()
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
---
|
|
131
|
+
|
|
132
|
+
## ๐จ Crema: Declarative Terminal Styling
|
|
133
|
+
|
|
134
|
+
Crema brings CSS-like fluency and box-model precision to terminal strings:
|
|
135
|
+
|
|
136
|
+
```python
|
|
137
|
+
from espresso.crema import Style, ROUNDED_BORDER, Align
|
|
138
|
+
|
|
139
|
+
card = (
|
|
140
|
+
Style()
|
|
141
|
+
.bold(True)
|
|
142
|
+
.foreground("#FAFAFA")
|
|
143
|
+
.background("#7D56F4")
|
|
144
|
+
.border(ROUNDED_BORDER)
|
|
145
|
+
.border_foreground("#00E676")
|
|
146
|
+
.border_title(" [ Espresso Crema ] ", align=Align.LEFT)
|
|
147
|
+
.padding(1, 2)
|
|
148
|
+
.width(40)
|
|
149
|
+
.align(Align.CENTER)
|
|
150
|
+
.render("Hello from Espresso Crema!")
|
|
151
|
+
)
|
|
152
|
+
print(card)
|
|
153
|
+
```
|
|
154
|
+
|
|
155
|
+
### Word-Wrapping & Linear Gradients
|
|
156
|
+
Crema includes advanced ANSI-aware text processing:
|
|
157
|
+
```python
|
|
158
|
+
from espresso.crema import wrap_ansi, linear_gradient
|
|
159
|
+
|
|
160
|
+
# Wrap text with full style preservation across soft line breaks
|
|
161
|
+
wrapped = wrap_ansi(long_styled_text, width=60)
|
|
162
|
+
|
|
163
|
+
# Smooth TrueColor linear RGB gradients across string characters
|
|
164
|
+
banner = linear_gradient("Espresso TrueColor Gradient", "#FF5E3A", "#FF2A68")
|
|
165
|
+
```
|
|
166
|
+
|
|
167
|
+
### Layout Primitives, Responsive Grid & Overlays
|
|
168
|
+
Stack and stitch styled blocks side-by-side, vertically, in a proportional flex layout, or in a responsive multi-column grid:
|
|
169
|
+
```python
|
|
170
|
+
from espresso.crema import join_horizontal, join_vertical, place_overlay, Grid, FlexBox, Align
|
|
171
|
+
|
|
172
|
+
# 1. 2D Side-by-side join
|
|
173
|
+
split_view = join_horizontal(Align.TOP, left_sidebar, " ", right_content)
|
|
174
|
+
|
|
175
|
+
# 2. Multi-column grid & auto-fitting panels
|
|
176
|
+
grid_view = Grid.columns([card1, card2, card3], cols=3, gap=1, total_width=80)
|
|
177
|
+
card_panel = Grid.panel("System Metrics", metrics_text, width=32, height=12)
|
|
178
|
+
|
|
179
|
+
# 3. Responsive proportional layout (FlexBox)
|
|
180
|
+
flex = FlexBox(width=80, height=24)
|
|
181
|
+
row = flex.new_row(ratio_y=1)
|
|
182
|
+
row.new_cell("Sidebar", ratio_x=1, min_width=20)
|
|
183
|
+
row.new_cell("Main View", ratio_x=3)
|
|
184
|
+
|
|
185
|
+
# 4. Floating modal compositor with backdrop dimming
|
|
186
|
+
screen = place_overlay(background_view, dialog.view(), center=True, dim_backdrop=True)
|
|
187
|
+
```
|
|
188
|
+
|
|
189
|
+
---
|
|
190
|
+
|
|
191
|
+
## ๐ฑ๏ธ First-Class Mouse & Gesture Support
|
|
192
|
+
|
|
193
|
+
Espresso provides built-in mouse tracking (SGR 1006) with advanced gesture synthesis:
|
|
194
|
+
|
|
195
|
+
- **Program Toggle**: `Program(App(), mouse=True)` or `Program(App()).with_mouse(True)`
|
|
196
|
+
- **Dynamic TEA Commands**: Emit `enable_mouse` or `disable_mouse` commands directly from `update()`
|
|
197
|
+
- **Event Handling**: Pattern match `MouseMsg(action, button, x, y)` in `update()`
|
|
198
|
+
- **Gestures Supported**: `MouseAction.PRESS`, `RELEASE`, `MOTION`, `DOUBLE_CLICK`, and drag-and-drop tracking with `MouseGestureTracker`
|
|
199
|
+
|
|
200
|
+
---
|
|
201
|
+
|
|
202
|
+
## ๐งฉ Beans: Standard Component Library
|
|
203
|
+
|
|
204
|
+
Espresso includes **39 ready-to-use building blocks** that follow the exact same TEA model:
|
|
205
|
+
|
|
206
|
+
* **`TextArea`**: Multi-line interactive text editor with line numbers, cursor navigation, and viewport scrolling.
|
|
207
|
+
* **`Help`**: Adaptive hotkey documentation rendering compact single-line or multi-column full keybinding views.
|
|
208
|
+
* **`Timer`**: High-precision countdown timer driven by tea tick commands with formatted duration and percentage completion.
|
|
209
|
+
* **`Stopwatch`**: High-precision elapsed time tracker with split-second hundredths display and toggle/reset controls.
|
|
210
|
+
* **`Spinner`**: Animated loading indicators (`DOTS`, `LINE`, `PULSE`, `COFFEE`, `GLOBE`, `MOON`).
|
|
211
|
+
* **`TextInput`**: Single-line text input with blinking cursor, password masking, and navigation.
|
|
212
|
+
* **`Progress`**: Customizable gradient progress bars with percentage indicators.
|
|
213
|
+
* **`Table`**: Column-based tabular data viewer with navigable row selection and sticky headers.
|
|
214
|
+
* **`Viewport`**: Scrollable pane for viewing long-form text or logs.
|
|
215
|
+
* **`Paginator`**: Pagination manager with bullet dots, numeric counters, descriptive ranges, and zero-jitter bounds slicing.
|
|
216
|
+
* **`Dialog`**: Modal confirmation and decision box with custom action buttons and `place_overlay` backdrop dimming.
|
|
217
|
+
* **`List`**: Searchable, filterable list with real-time `/` search query input, pagination, and selection events.
|
|
218
|
+
* **`FilePicker`**: Interactive directory browser with file size formatting, extension filters, and hidden file toggle.
|
|
219
|
+
* **`Prompt`**: CLI prompts (`SelectPrompt`, `MultiSelectPrompt` checkboxes, and `ConfirmPrompt` `[y/N]`).
|
|
220
|
+
* **`ToastManager`**: Transient notification alerts (`INFO`, `SUCCESS`, `WARNING`, `ERROR`) with auto-dismiss timers.
|
|
221
|
+
* **`Tabs`**: Top tab bar navigation with customizable styles (`PILL`, `LINE`, `BRACKET`) and hotkeys 1-9.
|
|
222
|
+
* **`Tree`**: Hierarchical collapsible tree view with Unicode branch connectors (`โโโ`, `โโโ`).
|
|
223
|
+
* **`StatusBar`**: Multi-section responsive status bar with Left/Center/Right clusters and priority-based auto-truncation.
|
|
224
|
+
* **`Metric` & `MetricGroup`**: Dashboard KPI stat cards, tags, and summary lists with delta trend arrows and inverted metrics.
|
|
225
|
+
* **`NavStack`**: Hierarchical view router with push/pop management, breadcrumb trails, and automatic message forwarding.
|
|
226
|
+
* **`DatePicker`**: Interactive calendar date picker with month/year navigation, mouse selection, and date range clamping.
|
|
227
|
+
* **`PipelineProgress`**: Multi-stage CI/CD workflow pipeline visualizer with real-time spinners, checkmarks, and timestamps.
|
|
228
|
+
* **`MarkdownViewer`**: Streaming GitHub-flavored markdown viewer with code blocks, tables, lists, and mouse scrolling.
|
|
229
|
+
* **`CodeViewer`**: Syntax-highlighted source code editor viewer (Python, JS, Go, Rust, SQL, JSON) with line numbers and themes.
|
|
230
|
+
* **`QuickFix`**: Interactive diagnostics and code action list with severity badges (`ERROR`, `WARNING`, `INFO`).
|
|
231
|
+
* **`DetailSelector`**: Master-detail dual-pane list selector with real-time preview panels and category filtering.
|
|
232
|
+
* **`ImageViewer`**: Terminal ASCII and Unicode half-block TrueColor image renderer for BMP and PPM formats.
|
|
233
|
+
* **`Splitter`**: Interactive dual-pane container (`Horizontal` / `Vertical`) with draggable divider bar and keyboard resizing.
|
|
234
|
+
* **`Slider` & `RangeSlider`**: Tactile numeric sliders and dual-thumb range bars with mouse dragging.
|
|
235
|
+
* **`Sparkline`**: High-resolution 2D Unicode Braille curves and 1D block charts with trend indicators.
|
|
236
|
+
* **`Marquee`**: Animated horizontal scrolling text banner with loop and bounce physics.
|
|
237
|
+
* **`SortableList`**: Reorderable list with drag-and-drop mouse handling and visual drop targets.
|
|
238
|
+
* **`Spring`**: Physical damped harmonic oscillator simulation solving harmonic differential equations.
|
|
239
|
+
* **`Confetti`**: 2D celebratory particle physics emitter (radial bursts, cannons, rain) with drag & gravity.
|
|
240
|
+
* **`DiffViewer`**: Git diff visualizer with Unified and Split dual-pane views and intra-line word diffs.
|
|
241
|
+
* **`Form` & `FormBuilder`**: Composite multi-field container with field/form validation, error badges, and Tab cycling.
|
|
242
|
+
* **`CommandPalette`**: Fuzzy spotlight search runner (Ctrl+P / Cmd+P) with recents tracking and modal overlay.
|
|
243
|
+
* **`GitTree`**: Multi-column collapsible file tree with Git status badges (`[M]`, `[A]`, `[D]`, `[?]`) and branch headers.
|
|
244
|
+
* **`BarChart`**: Horizontal and vertical bar charts with sub-character precision, auto-scaling, and TrueColor gradients.
|
|
245
|
+
|
|
246
|
+
---
|
|
247
|
+
|
|
248
|
+
## ๐ ๏ธ Built-in CLI Tool
|
|
249
|
+
|
|
250
|
+
Espresso includes a powerful command-line interface for running and scaffolding applications:
|
|
251
|
+
|
|
252
|
+
```bash
|
|
253
|
+
# List all 14 built-in interactive examples
|
|
254
|
+
espresso list
|
|
255
|
+
|
|
256
|
+
# Run any example by ID or file path
|
|
257
|
+
espresso run 14
|
|
258
|
+
espresso run 10
|
|
259
|
+
|
|
260
|
+
# Launch interactive component gallery
|
|
261
|
+
espresso gallery
|
|
262
|
+
|
|
263
|
+
# Scaffold a production-ready Espresso TEA app
|
|
264
|
+
espresso new my_dashboard.py
|
|
265
|
+
```
|
|
266
|
+
|
|
267
|
+
---
|
|
268
|
+
|
|
269
|
+
## ๐ Examples Included
|
|
270
|
+
|
|
271
|
+
Explore the interactive demos in `examples/`:
|
|
272
|
+
|
|
273
|
+
| Example | Command | Highlights |
|
|
274
|
+
| :--- | :--- | :--- |
|
|
275
|
+
| **01 Counter** | `espresso run 01` | Basic Model-Update-View state transitions |
|
|
276
|
+
| **02 Shopping List** | `espresso run 02` | List cursor navigation & item selection toggle |
|
|
277
|
+
| **03 Styled Dashboard** | `espresso run 03` | Crema cards, TrueColor, tabs, side-by-side layout |
|
|
278
|
+
| **04 Fullscreen & Mouse** | `espresso run 04` | Alt-screen mode, SGR mouse clicks, wheel scrolling, resize |
|
|
279
|
+
| **05 Beans Wizard** | `espresso run 05` | Multi-component wizard (TextInput, Table, Spinner, Progress, Viewport) |
|
|
280
|
+
| **06 Commit Helper** | `espresso run 06` | Practical developer tool for Conventional Commits |
|
|
281
|
+
| **07 Editor** | `espresso run 07` | Multi-line text editor with TextArea, status bar, and Help |
|
|
282
|
+
| **08 RSS Reader** | `espresso run 08` | Fullscreen 3-panel RSS reader with live feed fetching from schulz.dk |
|
|
283
|
+
| **09 Colors & Gradients** | `espresso run 09` | TrueColor showcase, multi-stop gradients, box background fills, palette cycling |
|
|
284
|
+
| **10 Component Gallery** | `espresso run 10` | Full-window edge-to-edge gallery of 20+ beans, mouse support, tabs, modals, prompts |
|
|
285
|
+
| **11 Markdown Viewer** | `espresso run 11` | Streaming GitHub-flavored markdown viewer with code blocks and mouse scrolling |
|
|
286
|
+
| **12 Interactive & Animated** | `espresso run 12` | Splitter, Sliders, Marquee, and SortableList with mouse drag |
|
|
287
|
+
| **13 Physics & Tools** | `espresso run 13` | Confetti physics engine, forms with validation, and diff viewer |
|
|
288
|
+
| **14 Developer Workspace** | `espresso run 14` | Flagship IDE integrating GitTree, BarChart, CodeViewer, and CommandPalette |
|
|
289
|
+
|
|
290
|
+
---
|
|
291
|
+
|
|
292
|
+
## ๐ In-Depth Documentation
|
|
293
|
+
|
|
294
|
+
* [Architecture & The Elm Pattern](docs/architecture.md)
|
|
295
|
+
* [Crema Styling & Layout Guide](docs/crema_styling.md)
|
|
296
|
+
* [Beans Component Catalog](docs/beans_components.md)
|
|
297
|
+
* [Release & Packaging Guide](docs/releasing.md)
|
|
298
|
+
* [GitHub Project Wiki](https://github.com/kimusan/espresso/wiki)
|
|
299
|
+
|
|
300
|
+
---
|
|
301
|
+
|
|
302
|
+
## ๐งช Running Tests
|
|
303
|
+
|
|
304
|
+
Espresso includes a comprehensive automated test suite testing state transitions, ANSI parsing, and event loops deterministically:
|
|
305
|
+
|
|
306
|
+
```bash
|
|
307
|
+
PYTHONPATH=src python3 -m unittest discover tests
|
|
308
|
+
```
|
|
309
|
+
|
|
310
|
+
---
|
|
311
|
+
|
|
312
|
+
## ๐ License
|
|
313
|
+
|
|
314
|
+
MIT License. Copyright (c) 2026 Kim Schulz.
|
|
315
|
+
|
|
@@ -0,0 +1,285 @@
|
|
|
1
|
+
# โ Espresso
|
|
2
|
+
|
|
3
|
+
> A lightweight, declarative Elm Architecture (TEA) terminal UI framework for Python.
|
|
4
|
+
> Inspired by Charm's **Bubble Tea**, **Lip Gloss**, and **Bubbles**.
|
|
5
|
+
|
|
6
|
+
[](https://www.python.org/downloads/)
|
|
7
|
+
[](https://opensource.org/licenses/MIT)
|
|
8
|
+
[](#features)
|
|
9
|
+
[](https://guide.elm-lang.org/architecture/)
|
|
10
|
+
|
|
11
|
+
```
|
|
12
|
+
( ) ( ) )
|
|
13
|
+
) ( ) ( (
|
|
14
|
+
( ) ( ) )
|
|
15
|
+
_____________
|
|
16
|
+
<_____________> ___
|
|
17
|
+
| |/ _ \
|
|
18
|
+
| ESPRESSO | | | |
|
|
19
|
+
| CREMA |_| |_|
|
|
20
|
+
|___BEANS_____|\___/
|
|
21
|
+
\_____________/
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
---
|
|
25
|
+
|
|
26
|
+
## ๐ Why Espresso?
|
|
27
|
+
|
|
28
|
+
Terminal applications in Python have historically required heavy object-oriented widget hierarchies, complex retained-state DOM trees, or callback-laden curses wrappers.
|
|
29
|
+
|
|
30
|
+
**Espresso brings The Elm Architecture (TEA) to Python:**
|
|
31
|
+
1. **Purity & Determinism**: Your application state is a simple `Model`. Changes only happen through an `update(msg)` function.
|
|
32
|
+
2. **View is Pure**: Rendering is a simple `view() -> str` function that turns state into a styled ANSI string.
|
|
33
|
+
3. **No Race Conditions**: Background operations (network, timers, disk I/O) are isolated in `Cmd` (commands) that emit messages back into the event loop.
|
|
34
|
+
4. **Zero Dependencies**: Runs out of the box using Python's standard library (`asyncio`, `termios`, `tty`, `unicodedata`).
|
|
35
|
+
5. **Modern Python 3.10+ Ergonomics**: Native support for structural pattern matching (`match / case`).
|
|
36
|
+
|
|
37
|
+
---
|
|
38
|
+
|
|
39
|
+
## โ The Espresso Ecosystem
|
|
40
|
+
|
|
41
|
+
| Layer | Charm Equivalent | Description |
|
|
42
|
+
| :--- | :--- | :--- |
|
|
43
|
+
| **`espresso`** | `bubbletea` | **The Strong Base**: Core TEA framework, runtime event loop, raw terminal driver, command primitives, line-diffing alt-screen renderer, SGR mouse tracking, and gesture engine. |
|
|
44
|
+
| **`espresso.crema`** | `lipgloss` | **The Smooth Crema**: Declarative styling, box model, TrueColor (24-bit RGB), ANSI 256, borders, border titles, TrueColor linear gradients, ANSI word-wrapping, 2D layout alignment, FlexBox, and responsive Grid. |
|
|
45
|
+
| **`espresso.beans`** | `bubbles` | **The Flavorful Beans**: 39 reusable UI components including TextArea, GitTree, CommandPalette, BarChart, Splitter, Sliders, Form, DiffViewer, SortableList, Confetti, CodeViewer, MarkdownViewer, Tables, Viewports, and more. |
|
|
46
|
+
|
|
47
|
+
---
|
|
48
|
+
|
|
49
|
+
## ๐ Quickstart
|
|
50
|
+
|
|
51
|
+
### Installation
|
|
52
|
+
|
|
53
|
+
**Via PyPI**:
|
|
54
|
+
```bash
|
|
55
|
+
pip install espressoTUI
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
**Universal Standalone Executable (Zero Installation)**:
|
|
59
|
+
Download the standalone `espresso.pyz` from [GitHub Releases](https://github.com/kimusan/espresso/releases):
|
|
60
|
+
```bash
|
|
61
|
+
curl -LO https://github.com/kimusan/espresso/releases/latest/download/espresso.pyz
|
|
62
|
+
chmod +x espresso.pyz
|
|
63
|
+
./espresso.pyz gallery
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
**Native Binaries (No Python Runtime Required)**:
|
|
67
|
+
Pre-compiled self-contained native binaries are available on every release for:
|
|
68
|
+
- **Linux x86_64**: `espresso-linux-x86_64`
|
|
69
|
+
- **macOS Apple Silicon**: `espresso-macos-arm64`
|
|
70
|
+
- **macOS Intel**: `espresso-macos-x86_64`
|
|
71
|
+
- **Windows x86_64**: `espresso-windows-x86_64.exe`
|
|
72
|
+
|
|
73
|
+
### 1. Minimal Interactive Counter
|
|
74
|
+
```python
|
|
75
|
+
from espresso import Model, Msg, Cmd, KeyMsg, Program, quit_app
|
|
76
|
+
|
|
77
|
+
class Counter(Model):
|
|
78
|
+
def __init__(self):
|
|
79
|
+
self.count = 0
|
|
80
|
+
|
|
81
|
+
def init(self) -> Cmd | None:
|
|
82
|
+
return None
|
|
83
|
+
|
|
84
|
+
def update(self, msg: Msg) -> tuple[Model, Cmd | None]:
|
|
85
|
+
match msg:
|
|
86
|
+
case KeyMsg(key="+" | "up"):
|
|
87
|
+
self.count += 1
|
|
88
|
+
case KeyMsg(key="-" | "down"):
|
|
89
|
+
self.count -= 1
|
|
90
|
+
case KeyMsg(key="q" | "esc"):
|
|
91
|
+
return self, quit_app
|
|
92
|
+
return self, None
|
|
93
|
+
|
|
94
|
+
def view(self) -> str:
|
|
95
|
+
return f"Count: {self.count}\n\n[+/-] Adjust [q] Quit"
|
|
96
|
+
|
|
97
|
+
if __name__ == "__main__":
|
|
98
|
+
Program(Counter()).run()
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
---
|
|
102
|
+
|
|
103
|
+
## ๐จ Crema: Declarative Terminal Styling
|
|
104
|
+
|
|
105
|
+
Crema brings CSS-like fluency and box-model precision to terminal strings:
|
|
106
|
+
|
|
107
|
+
```python
|
|
108
|
+
from espresso.crema import Style, ROUNDED_BORDER, Align
|
|
109
|
+
|
|
110
|
+
card = (
|
|
111
|
+
Style()
|
|
112
|
+
.bold(True)
|
|
113
|
+
.foreground("#FAFAFA")
|
|
114
|
+
.background("#7D56F4")
|
|
115
|
+
.border(ROUNDED_BORDER)
|
|
116
|
+
.border_foreground("#00E676")
|
|
117
|
+
.border_title(" [ Espresso Crema ] ", align=Align.LEFT)
|
|
118
|
+
.padding(1, 2)
|
|
119
|
+
.width(40)
|
|
120
|
+
.align(Align.CENTER)
|
|
121
|
+
.render("Hello from Espresso Crema!")
|
|
122
|
+
)
|
|
123
|
+
print(card)
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
### Word-Wrapping & Linear Gradients
|
|
127
|
+
Crema includes advanced ANSI-aware text processing:
|
|
128
|
+
```python
|
|
129
|
+
from espresso.crema import wrap_ansi, linear_gradient
|
|
130
|
+
|
|
131
|
+
# Wrap text with full style preservation across soft line breaks
|
|
132
|
+
wrapped = wrap_ansi(long_styled_text, width=60)
|
|
133
|
+
|
|
134
|
+
# Smooth TrueColor linear RGB gradients across string characters
|
|
135
|
+
banner = linear_gradient("Espresso TrueColor Gradient", "#FF5E3A", "#FF2A68")
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
### Layout Primitives, Responsive Grid & Overlays
|
|
139
|
+
Stack and stitch styled blocks side-by-side, vertically, in a proportional flex layout, or in a responsive multi-column grid:
|
|
140
|
+
```python
|
|
141
|
+
from espresso.crema import join_horizontal, join_vertical, place_overlay, Grid, FlexBox, Align
|
|
142
|
+
|
|
143
|
+
# 1. 2D Side-by-side join
|
|
144
|
+
split_view = join_horizontal(Align.TOP, left_sidebar, " ", right_content)
|
|
145
|
+
|
|
146
|
+
# 2. Multi-column grid & auto-fitting panels
|
|
147
|
+
grid_view = Grid.columns([card1, card2, card3], cols=3, gap=1, total_width=80)
|
|
148
|
+
card_panel = Grid.panel("System Metrics", metrics_text, width=32, height=12)
|
|
149
|
+
|
|
150
|
+
# 3. Responsive proportional layout (FlexBox)
|
|
151
|
+
flex = FlexBox(width=80, height=24)
|
|
152
|
+
row = flex.new_row(ratio_y=1)
|
|
153
|
+
row.new_cell("Sidebar", ratio_x=1, min_width=20)
|
|
154
|
+
row.new_cell("Main View", ratio_x=3)
|
|
155
|
+
|
|
156
|
+
# 4. Floating modal compositor with backdrop dimming
|
|
157
|
+
screen = place_overlay(background_view, dialog.view(), center=True, dim_backdrop=True)
|
|
158
|
+
```
|
|
159
|
+
|
|
160
|
+
---
|
|
161
|
+
|
|
162
|
+
## ๐ฑ๏ธ First-Class Mouse & Gesture Support
|
|
163
|
+
|
|
164
|
+
Espresso provides built-in mouse tracking (SGR 1006) with advanced gesture synthesis:
|
|
165
|
+
|
|
166
|
+
- **Program Toggle**: `Program(App(), mouse=True)` or `Program(App()).with_mouse(True)`
|
|
167
|
+
- **Dynamic TEA Commands**: Emit `enable_mouse` or `disable_mouse` commands directly from `update()`
|
|
168
|
+
- **Event Handling**: Pattern match `MouseMsg(action, button, x, y)` in `update()`
|
|
169
|
+
- **Gestures Supported**: `MouseAction.PRESS`, `RELEASE`, `MOTION`, `DOUBLE_CLICK`, and drag-and-drop tracking with `MouseGestureTracker`
|
|
170
|
+
|
|
171
|
+
---
|
|
172
|
+
|
|
173
|
+
## ๐งฉ Beans: Standard Component Library
|
|
174
|
+
|
|
175
|
+
Espresso includes **39 ready-to-use building blocks** that follow the exact same TEA model:
|
|
176
|
+
|
|
177
|
+
* **`TextArea`**: Multi-line interactive text editor with line numbers, cursor navigation, and viewport scrolling.
|
|
178
|
+
* **`Help`**: Adaptive hotkey documentation rendering compact single-line or multi-column full keybinding views.
|
|
179
|
+
* **`Timer`**: High-precision countdown timer driven by tea tick commands with formatted duration and percentage completion.
|
|
180
|
+
* **`Stopwatch`**: High-precision elapsed time tracker with split-second hundredths display and toggle/reset controls.
|
|
181
|
+
* **`Spinner`**: Animated loading indicators (`DOTS`, `LINE`, `PULSE`, `COFFEE`, `GLOBE`, `MOON`).
|
|
182
|
+
* **`TextInput`**: Single-line text input with blinking cursor, password masking, and navigation.
|
|
183
|
+
* **`Progress`**: Customizable gradient progress bars with percentage indicators.
|
|
184
|
+
* **`Table`**: Column-based tabular data viewer with navigable row selection and sticky headers.
|
|
185
|
+
* **`Viewport`**: Scrollable pane for viewing long-form text or logs.
|
|
186
|
+
* **`Paginator`**: Pagination manager with bullet dots, numeric counters, descriptive ranges, and zero-jitter bounds slicing.
|
|
187
|
+
* **`Dialog`**: Modal confirmation and decision box with custom action buttons and `place_overlay` backdrop dimming.
|
|
188
|
+
* **`List`**: Searchable, filterable list with real-time `/` search query input, pagination, and selection events.
|
|
189
|
+
* **`FilePicker`**: Interactive directory browser with file size formatting, extension filters, and hidden file toggle.
|
|
190
|
+
* **`Prompt`**: CLI prompts (`SelectPrompt`, `MultiSelectPrompt` checkboxes, and `ConfirmPrompt` `[y/N]`).
|
|
191
|
+
* **`ToastManager`**: Transient notification alerts (`INFO`, `SUCCESS`, `WARNING`, `ERROR`) with auto-dismiss timers.
|
|
192
|
+
* **`Tabs`**: Top tab bar navigation with customizable styles (`PILL`, `LINE`, `BRACKET`) and hotkeys 1-9.
|
|
193
|
+
* **`Tree`**: Hierarchical collapsible tree view with Unicode branch connectors (`โโโ`, `โโโ`).
|
|
194
|
+
* **`StatusBar`**: Multi-section responsive status bar with Left/Center/Right clusters and priority-based auto-truncation.
|
|
195
|
+
* **`Metric` & `MetricGroup`**: Dashboard KPI stat cards, tags, and summary lists with delta trend arrows and inverted metrics.
|
|
196
|
+
* **`NavStack`**: Hierarchical view router with push/pop management, breadcrumb trails, and automatic message forwarding.
|
|
197
|
+
* **`DatePicker`**: Interactive calendar date picker with month/year navigation, mouse selection, and date range clamping.
|
|
198
|
+
* **`PipelineProgress`**: Multi-stage CI/CD workflow pipeline visualizer with real-time spinners, checkmarks, and timestamps.
|
|
199
|
+
* **`MarkdownViewer`**: Streaming GitHub-flavored markdown viewer with code blocks, tables, lists, and mouse scrolling.
|
|
200
|
+
* **`CodeViewer`**: Syntax-highlighted source code editor viewer (Python, JS, Go, Rust, SQL, JSON) with line numbers and themes.
|
|
201
|
+
* **`QuickFix`**: Interactive diagnostics and code action list with severity badges (`ERROR`, `WARNING`, `INFO`).
|
|
202
|
+
* **`DetailSelector`**: Master-detail dual-pane list selector with real-time preview panels and category filtering.
|
|
203
|
+
* **`ImageViewer`**: Terminal ASCII and Unicode half-block TrueColor image renderer for BMP and PPM formats.
|
|
204
|
+
* **`Splitter`**: Interactive dual-pane container (`Horizontal` / `Vertical`) with draggable divider bar and keyboard resizing.
|
|
205
|
+
* **`Slider` & `RangeSlider`**: Tactile numeric sliders and dual-thumb range bars with mouse dragging.
|
|
206
|
+
* **`Sparkline`**: High-resolution 2D Unicode Braille curves and 1D block charts with trend indicators.
|
|
207
|
+
* **`Marquee`**: Animated horizontal scrolling text banner with loop and bounce physics.
|
|
208
|
+
* **`SortableList`**: Reorderable list with drag-and-drop mouse handling and visual drop targets.
|
|
209
|
+
* **`Spring`**: Physical damped harmonic oscillator simulation solving harmonic differential equations.
|
|
210
|
+
* **`Confetti`**: 2D celebratory particle physics emitter (radial bursts, cannons, rain) with drag & gravity.
|
|
211
|
+
* **`DiffViewer`**: Git diff visualizer with Unified and Split dual-pane views and intra-line word diffs.
|
|
212
|
+
* **`Form` & `FormBuilder`**: Composite multi-field container with field/form validation, error badges, and Tab cycling.
|
|
213
|
+
* **`CommandPalette`**: Fuzzy spotlight search runner (Ctrl+P / Cmd+P) with recents tracking and modal overlay.
|
|
214
|
+
* **`GitTree`**: Multi-column collapsible file tree with Git status badges (`[M]`, `[A]`, `[D]`, `[?]`) and branch headers.
|
|
215
|
+
* **`BarChart`**: Horizontal and vertical bar charts with sub-character precision, auto-scaling, and TrueColor gradients.
|
|
216
|
+
|
|
217
|
+
---
|
|
218
|
+
|
|
219
|
+
## ๐ ๏ธ Built-in CLI Tool
|
|
220
|
+
|
|
221
|
+
Espresso includes a powerful command-line interface for running and scaffolding applications:
|
|
222
|
+
|
|
223
|
+
```bash
|
|
224
|
+
# List all 14 built-in interactive examples
|
|
225
|
+
espresso list
|
|
226
|
+
|
|
227
|
+
# Run any example by ID or file path
|
|
228
|
+
espresso run 14
|
|
229
|
+
espresso run 10
|
|
230
|
+
|
|
231
|
+
# Launch interactive component gallery
|
|
232
|
+
espresso gallery
|
|
233
|
+
|
|
234
|
+
# Scaffold a production-ready Espresso TEA app
|
|
235
|
+
espresso new my_dashboard.py
|
|
236
|
+
```
|
|
237
|
+
|
|
238
|
+
---
|
|
239
|
+
|
|
240
|
+
## ๐ Examples Included
|
|
241
|
+
|
|
242
|
+
Explore the interactive demos in `examples/`:
|
|
243
|
+
|
|
244
|
+
| Example | Command | Highlights |
|
|
245
|
+
| :--- | :--- | :--- |
|
|
246
|
+
| **01 Counter** | `espresso run 01` | Basic Model-Update-View state transitions |
|
|
247
|
+
| **02 Shopping List** | `espresso run 02` | List cursor navigation & item selection toggle |
|
|
248
|
+
| **03 Styled Dashboard** | `espresso run 03` | Crema cards, TrueColor, tabs, side-by-side layout |
|
|
249
|
+
| **04 Fullscreen & Mouse** | `espresso run 04` | Alt-screen mode, SGR mouse clicks, wheel scrolling, resize |
|
|
250
|
+
| **05 Beans Wizard** | `espresso run 05` | Multi-component wizard (TextInput, Table, Spinner, Progress, Viewport) |
|
|
251
|
+
| **06 Commit Helper** | `espresso run 06` | Practical developer tool for Conventional Commits |
|
|
252
|
+
| **07 Editor** | `espresso run 07` | Multi-line text editor with TextArea, status bar, and Help |
|
|
253
|
+
| **08 RSS Reader** | `espresso run 08` | Fullscreen 3-panel RSS reader with live feed fetching from schulz.dk |
|
|
254
|
+
| **09 Colors & Gradients** | `espresso run 09` | TrueColor showcase, multi-stop gradients, box background fills, palette cycling |
|
|
255
|
+
| **10 Component Gallery** | `espresso run 10` | Full-window edge-to-edge gallery of 20+ beans, mouse support, tabs, modals, prompts |
|
|
256
|
+
| **11 Markdown Viewer** | `espresso run 11` | Streaming GitHub-flavored markdown viewer with code blocks and mouse scrolling |
|
|
257
|
+
| **12 Interactive & Animated** | `espresso run 12` | Splitter, Sliders, Marquee, and SortableList with mouse drag |
|
|
258
|
+
| **13 Physics & Tools** | `espresso run 13` | Confetti physics engine, forms with validation, and diff viewer |
|
|
259
|
+
| **14 Developer Workspace** | `espresso run 14` | Flagship IDE integrating GitTree, BarChart, CodeViewer, and CommandPalette |
|
|
260
|
+
|
|
261
|
+
---
|
|
262
|
+
|
|
263
|
+
## ๐ In-Depth Documentation
|
|
264
|
+
|
|
265
|
+
* [Architecture & The Elm Pattern](docs/architecture.md)
|
|
266
|
+
* [Crema Styling & Layout Guide](docs/crema_styling.md)
|
|
267
|
+
* [Beans Component Catalog](docs/beans_components.md)
|
|
268
|
+
* [Release & Packaging Guide](docs/releasing.md)
|
|
269
|
+
* [GitHub Project Wiki](https://github.com/kimusan/espresso/wiki)
|
|
270
|
+
|
|
271
|
+
---
|
|
272
|
+
|
|
273
|
+
## ๐งช Running Tests
|
|
274
|
+
|
|
275
|
+
Espresso includes a comprehensive automated test suite testing state transitions, ANSI parsing, and event loops deterministically:
|
|
276
|
+
|
|
277
|
+
```bash
|
|
278
|
+
PYTHONPATH=src python3 -m unittest discover tests
|
|
279
|
+
```
|
|
280
|
+
|
|
281
|
+
---
|
|
282
|
+
|
|
283
|
+
## ๐ License
|
|
284
|
+
|
|
285
|
+
MIT License. Copyright (c) 2026 Kim Schulz.
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
[build-system]
|
|
2
|
+
requires = ["flit_core >=3.2,<4"]
|
|
3
|
+
build-backend = "flit_core.buildapi"
|
|
4
|
+
|
|
5
|
+
[project]
|
|
6
|
+
name = "espressoTUI"
|
|
7
|
+
dynamic = ["version"]
|
|
8
|
+
description = "A lightweight, declarative Elm Architecture (TEA) TUI framework for Python inspired by Bubble Tea."
|
|
9
|
+
readme = "README.md"
|
|
10
|
+
requires-python = ">=3.10"
|
|
11
|
+
license = { file = "LICENSE" }
|
|
12
|
+
authors = [
|
|
13
|
+
{ name = "Kim Schulz", email = "kim@schulz.dk" },
|
|
14
|
+
]
|
|
15
|
+
classifiers = [
|
|
16
|
+
"Development Status :: 3 - Alpha",
|
|
17
|
+
"Environment :: Console",
|
|
18
|
+
"Intended Audience :: Developers",
|
|
19
|
+
"License :: OSI Approved :: MIT License",
|
|
20
|
+
"Operating System :: POSIX",
|
|
21
|
+
"Operating System :: Unix",
|
|
22
|
+
"Operating System :: MacOS",
|
|
23
|
+
"Programming Language :: Python :: 3",
|
|
24
|
+
"Programming Language :: Python :: 3.10",
|
|
25
|
+
"Programming Language :: Python :: 3.11",
|
|
26
|
+
"Programming Language :: Python :: 3.12",
|
|
27
|
+
"Topic :: Software Development :: Libraries :: Python Modules",
|
|
28
|
+
"Topic :: Software Development :: User Interfaces",
|
|
29
|
+
"Typing :: Typed",
|
|
30
|
+
]
|
|
31
|
+
dependencies = []
|
|
32
|
+
|
|
33
|
+
[project.scripts]
|
|
34
|
+
espresso = "espresso.cli:main"
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
[project.optional-dependencies]
|
|
38
|
+
dev = [
|
|
39
|
+
"pytest>=7.0",
|
|
40
|
+
"mypy>=1.0",
|
|
41
|
+
]
|
|
42
|
+
|
|
43
|
+
[project.urls]
|
|
44
|
+
Homepage = "https://github.com/kimusan/espresso"
|
|
45
|
+
Repository = "https://github.com/kimusan/espresso.git"
|
|
46
|
+
Issues = "https://github.com/kimusan/espresso/issues"
|
|
47
|
+
|
|
48
|
+
[tool.flit.module]
|
|
49
|
+
name = "espresso"
|
|
50
|
+
|
|
51
|
+
[tool.mypy]
|
|
52
|
+
python_version = "3.10"
|
|
53
|
+
strict = true
|
|
54
|
+
warn_return_any = true
|
|
55
|
+
warn_unused_configs = true
|
|
56
|
+
|
|
57
|
+
[tool.pytest.ini_options]
|
|
58
|
+
testpaths = ["tests"]
|
|
59
|
+
python_files = ["test_*.py"]
|