Metadata-Version: 2.4
Name: stui-terminal
Version: 1.1.0
Summary: A tiny Streamlit-inspired terminal UI experiment.
Author: MarMar Labs
License-Expression: MIT
Project-URL: Homepage, https://github.com/marmar9615-cloud/stui-terminal
Project-URL: Repository, https://github.com/marmar9615-cloud/stui-terminal
Project-URL: Issues, https://github.com/marmar9615-cloud/stui-terminal/issues
Keywords: terminal,tui,textual,streamlit-inspired
Classifier: Development Status :: 5 - Production/Stable
Classifier: Environment :: Console
Classifier: Intended Audience :: Developers
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3 :: Only
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Topic :: Software Development :: Libraries :: Python Modules
Classifier: Topic :: Software Development :: User Interfaces
Classifier: Topic :: Terminals
Requires-Python: >=3.11
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: rich>=13.7
Requires-Dist: textual>=0.89
Requires-Dist: typer>=0.12
Provides-Extra: dev
Requires-Dist: build>=1.2; extra == "dev"
Requires-Dist: pytest>=8.0; extra == "dev"
Requires-Dist: ruff>=0.8; extra == "dev"
Requires-Dist: twine>=5.1; extra == "dev"
Dynamic: license-file

# stui

[![CI](https://github.com/marmar9615-cloud/stui-terminal/actions/workflows/ci.yml/badge.svg)](https://github.com/marmar9615-cloud/stui-terminal/actions/workflows/ci.yml)

`stui` is a small Streamlit-inspired framework for building terminal-native
Python apps. Write a short script, run it in your terminal, and get a Textual UI
with stateful controls, reruns, and a compact public API.

It is built for local tools, demos, data scripts, model debug panels, SSH
sessions, and headless environments where opening a browser, binding a port, or
running a dashboard server is unnecessary ceremony. The public API is
deliberately small and readable.

`stui` is serious about being smaller than the thing that inspired it. It is
not official Streamlit, is not affiliated with Streamlit, and is not a
Streamlit compatibility layer. Existing Streamlit apps usually need edits; new
`stui` apps should be written against the documented terminal-first API below.

## Preview

![stui model demo terminal screenshot](https://raw.githubusercontent.com/marmar9615-cloud/stui-terminal/main/assets/stui-model-demo.png)

```text
┌─ stui ───────────────────────────────────────────┐
│ stui demo basic                                  │
│                                                  │
│ x                                                │
│ [██░░░░░░░░░░░░] 10                              │
│                                                  │
│ [ Increment ]                                    │
│                                                  │
│ x = 10                                           │
│ count = 0                                        │
│                                                  │
│ q Quit   r Rerun   tab Focus next                │
└──────────────────────────────────────────────────┘
```

## Install

Use Python 3.11 or newer.

Install the PyPI distribution named `stui-terminal`. The import package and
command are both still named `stui`, which is the name used throughout the
examples and API reference:

```bash
python -m pip install stui-terminal
```

```python
import stui as st
```

Check the installed version, diagnostics, and terminal environment before
filing terminal or keyboard issues:

```bash
python -m stui --version
python -m stui doctor
python -m stui doctor --json
```

For local development from a checkout, use an editable install with the dev
extra:

```bash
python3.11 -m venv .venv
. .venv/bin/activate
python -m pip install -e ".[dev]"
```

For runtime-only local use, install without the dev extra:

```bash
python -m pip install -e .
```

The distribution/import split is intentional:

- PyPI package: `stui-terminal`
- Python import: `import stui as st`
- CLI command: `stui`
- Module CLI fallback: `python -m stui`

That split is also what users see on PyPI: install `stui-terminal`, then import
and run `stui`.

## 60-Second Quickstart

Create a file named `app.py`:

```python
import stui as st

st.title("Hello from the terminal")

name = st.text_input("Name", "MarMar")
level = st.slider("Level", 1, 10, 5)

if st.button("Greet"):
    st.success(f"Hi {name}. Level {level} selected.")
```

Install, launch a bundled demo, then run the app you just wrote:

```bash
python -m pip install stui-terminal
stui demo dashboard
stui run app.py
```

Or generate a starter file instead of writing `app.py` by hand:

```bash
stui init starter_app.py
stui run starter_app.py
```

If the `stui` command is not on your `PATH`, use the module entry point:

```bash
python -m stui run app.py
```

Check your install and terminal details:

```bash
stui --version
stui doctor
stui doctor --json
```

## Build Your First App

`stui` scripts rerun when users interact with widgets. Use
`st.session_state` for values that should survive reruns:

```python
import stui as st

st.title("Counter")

if "count" not in st.session_state:
    st.session_state.count = 0

step = st.slider("Step", 1, 10, 1)

if st.button("Add"):
    st.session_state.count += step

if st.button("Reset"):
    st.session_state.count = 0

st.write("count =", st.session_state.count)
```

Run it with:

```bash
stui run app.py
```

Start from the repository examples when you want a larger reference:

```bash
stui run examples/counter.py
stui run examples/inputs.py
stui run examples/data_display.py
stui run examples/dashboard.py
stui run examples/forms.py
stui run examples/layouts.py
stui run examples/charts.py
stui run examples/kitchen_sink.py
```

Those `examples/...` paths are repository files. Installed packages also expose
bundled examples that can be listed or copied into any working directory:

```bash
stui demo list
stui demo basic
stui demo dashboard
stui demo forms
stui demo charts
stui demo kitchen_sink
stui examples
stui example list
stui example copy basic ./basic.py
stui run ./basic.py
stui example copy counter ./counter.py
stui run ./counter.py
stui init ./new_app.py
stui init ./dashboard.py --template dashboard
stui init ./forms_app.py --template forms
```

Automated tests cover demo CLI behavior and bundled-resource resolution without
starting a full TUI. For an interactive smoke check, run `stui demo dashboard`
from any directory and press `q` to quit.

`stui init` currently supports the `basic`, `dashboard`, and `forms` templates.
Use `python -m stui ...` for the same commands when the `stui` script directory
is not on `PATH`.

Copied examples and generated starter files are plain Python scripts. They do
not require a checkout after they are copied:

```bash
stui example copy forms ./forms_app.py
python -m stui run ./forms_app.py

stui init ./signup.py --template forms
python -m stui run ./signup.py

stui init ./ops_dashboard.py --template dashboard
python -m stui run ./ops_dashboard.py
```

The v1.x releases treat these demo/example/init/copy commands as part of the
stable documentation contract. If an installed-package flow does not work
without a repository checkout, that is patch-release-worthy docs or packaging
debt.

The demo screenshot above is generated from a real terminal app in this
repository, not a browser mockup. If the image on PyPI or GitHub ever drifts
from the current package behavior, treat that as release polish debt.

For more detail, see the [API reference](docs/api-reference.md),
[API stability labels](docs/api-stability.md), [terminal compatibility
matrix](docs/terminal-compatibility.md), and
[v1 readiness checklist](docs/v1-readiness.md).

## Copy-Paste Examples

### Slider and Button

```python
import stui as st

st.title("Slider and Button")

if "runs" not in st.session_state:
    st.session_state.runs = 0

threshold = st.slider("Threshold", 0.0, 1.0, 0.5, step=0.1)

if st.button("Run"):
    st.session_state.runs += 1
    st.success(f"Run {st.session_state.runs} at threshold {threshold}")
```

### Inputs

```python
import stui as st

st.title("Inputs")

name = st.text_input("Name", "MarMar")
batch = st.number_input("Batch size", min_value=1, max_value=128, value=16)
model = st.selectbox("Model", ["tiny", "base", "large"], index=1)
mode = st.radio("Mode", ["fast", "balanced", "careful"], index=1)
dry_run = st.checkbox("Dry run", value=True)

st.write("name =", name)
st.write("batch =", batch)
st.write("model =", model)
st.write("mode =", mode)
st.write("dry run =", dry_run)
```

### Table and Dataframe

```python
import stui as st

st.title("Runs")

rows = [
    {"name": "baseline", "accuracy": 0.81, "latency_ms": 42},
    {"name": "quantized", "accuracy": 0.79, "latency_ms": 24},
    {"name": "distilled", "accuracy": 0.77, "latency_ms": 18},
]

st.table(rows)
st.dataframe({"setting": ["device", "batch"], "value": ["cpu", 16]})
```

### Progress and Status

```python
import stui as st

st.title("Job Status")

complete = st.slider("Complete", 0, 100, 35)
st.progress(complete, text="current job")

if complete == 100:
    st.success("Done")
elif complete >= 75:
    st.warning("Almost there")
else:
    st.info("Running")
```

## Why terminal-native?

Some useful Python apps do not need a browser runtime. `stui` keeps the
interface inside the terminal so it can fit naturally into:

- SSH sessions, remote machines, and headless boxes.
- Internal tools where opening ports or managing local server URLs is friction.
- Offline or locked-down environments where browser access is limited.
- Model, data, and DevOps workflows that already start from a shell.

That also keeps the boundary simple: `stui` does not start a web server, use
websockets, require port-forwarding, or depend on Streamlit at runtime.

## Commands

```bash
# Install the package from PyPI.
python -m pip install stui-terminal

# Run a bundled first-run demo, then create and run an app.
stui demo dashboard
stui init app.py
stui run app.py
python -m stui run app.py

# List, copy, or create starter examples.
stui demo list
stui examples
stui example list
stui example copy counter ./counter.py
stui init ./new_app.py
stui init ./dashboard.py --template dashboard
stui init ./forms_app.py --template forms

# Print version and install/terminal diagnostics.
stui --version
stui doctor
stui doctor --json

# Install the project for local development from a checkout.
python3.11 -m venv .venv
. .venv/bin/activate
python -m pip install -e ".[dev]"

# Run the smoke-size example app.
stui run examples/basic.py

# Run the stateful counter example.
stui run examples/counter.py

# Run the deterministic model-parameter demo.
stui run examples/model_demo.py

# Run the test suite.
python3.11 -m pytest
```

## Keyboard Shortcuts

- `q`: quit the app
- `r`: rerun the script
- `tab`: focus the next widget
- `shift+tab`: focus the previous widget
- `enter` or `space`: press the focused button
- `space`: toggle the focused checkbox
- `enter` in text and number inputs: submit the edited value
- `enter`, `right`, or `down`: move a selectbox to the next choice
- `left` or `up`: move a selectbox to the previous choice
- arrow keys in radio groups: choose another option
- `enter` or `space`: toggle a focused expander
- `left` or `h`: decrease the focused slider
- `right` or `l`: increase the focused slider
- `home`: set the focused slider to its minimum value
- `end`: set the focused slider to its maximum value

Some lower-level editing and focus behavior comes from Textual and can vary by
terminal. See [Terminal Compatibility](docs/terminal-compatibility.md) and the
[v1 compatibility gate](docs/v1-readiness.md#terminal-compatibility) for the
current checklist.

## API

Import the API as:

```python
import stui as st
```

The public API is intentionally compact and Streamlit-inspired, not
Streamlit-compatible.

For the working API reference, see
[docs/api-reference.md](docs/api-reference.md). The current API contract and v1
stability checklist are tracked in
[docs/v1-readiness.md#api-contract-status](docs/v1-readiness.md#api-contract-status)
and [docs/v1-readiness.md#stable-api](docs/v1-readiness.md#stable-api).
The terminal support checklist lives in
[docs/terminal-compatibility.md](docs/terminal-compatibility.md).

| Area | APIs | Status in v1.1.0 |
| --- | --- | --- |
| Text | `st.title`, `st.header`, `st.subheader`, `st.caption`, `st.text`, `st.markdown`, `st.write`, `st.divider` | v1-stable |
| Status | `st.info`, `st.success`, `st.warning`, `st.error`, `st.exception` | v1-stable |
| Status/help primitives | `st.status`, `st.spinner`, `st.help` | Post-v1 experimental while terminal grouping/help formatting gathers feedback |
| Display | `st.code`, `st.json`, `st.progress`, `st.table`, `st.dataframe` | v1-stable static terminal displays |
| Inputs | `st.button`, `st.slider`, `st.text_input`, `st.checkbox`, `st.number_input`, `st.selectbox`, `st.radio` | v1-stable input widgets |
| Forms | `st.form`, `st.form_submit_button` | v1-stable deferred commit to `session_state` until submit |
| Layout/grouping | `st.container`, `st.expander`, `st.columns` | Mixed: `st.container` and `st.expander` are v1-stable; `st.columns` remains post-v1 experimental and stacks on narrow terminals |
| Metrics and charts | `st.metric`, `st.bar_chart`, `st.line_chart` | Mixed: `st.metric` is v1-stable; charts remain post-v1 experimental terminal summaries, not plotting replacements |
| State and flow | `st.session_state`, `st.rerun`, `st.stop` | v1-stable state and flow-control helpers |
| Package metadata | `st.__version__` | v1-stable package version string |
| CLI and examples | `stui run`, `stui demo list`, `stui demo NAME`, `stui examples`, `stui example list`, `stui example copy`, `stui init`, `stui doctor`, `stui --version` | v1-stable command surface |

Inputs support stable `key` values and optional callbacks where the function
signature documents them. Tables and charts are simple static displays and do
not require pandas or plotting dependencies.

### Stable API

The v1.1.0 stable surface keeps the v1 core compact while graduating the safest
post-v1 APIs: static JSON/progress/table/dataframe display, numeric and choice
inputs, forms, containers, expanders, metrics, and explicit `st.rerun` /
`st.stop` flow control. These names should keep their call shape, return type,
and basic behavior through v1 unless a correctness, terminal, or security issue
forces a change.

### Experimental API

The documented experimental APIs are public enough to try, but they are not
promised as frozen v1 behavior yet. In v1.1.0 this includes `st.columns`,
`st.bar_chart`, `st.line_chart`, `st.status`, `st.spinner`, and `st.help`.
Release notes should call out any change with a migration note when practical.

APIs not shown in this table should be treated as private implementation
details. Experimental display/layout helpers may still tighten in v1.x unless they
are promoted in the API stability docs and covered by release notes.
Deferred APIs for v1 include `st.sidebar`, `st.tabs`, `st.file_uploader`,
`st.cache_data`, `st.cache_resource`, `st.components`, editable dataframes,
custom column ratios/gaps, plotting-library parity, and browser/server runtime
features.

## Compatibility

`stui` is Streamlit-inspired, not Streamlit-compatible. Existing Streamlit apps
usually need small edits before they run in `stui`; unsupported calls should be
removed or replaced with the compact API above.

Runtime expectations:

- Python 3.11 or newer.
- Terminal UI powered by Textual and Rich.
- No Streamlit runtime dependency.
- No browser tab, local web server, websocket, or port-forwarding flow.
- Static table/dataframe display without dataframe editing or sorting.
- Common modern terminals should work best with UTF-8, color support, and a
  normal interactive `TERM` such as `xterm-256color`.

See [Terminal Compatibility](docs/terminal-compatibility.md) for the current
evidence matrix and report format. v1.x stays evidence-driven: common modern
terminals are expected targets, but environments without project-owned evidence
remain labeled test-needed instead of claimed as fully supported.

## Common Mistakes

- Installing `stui` instead of `stui-terminal`. The PyPI package is
  `stui-terminal`; the import and CLI are `stui`.
- Running `stui run` from a different Python environment than the one where the
  package was installed. Try `python -m stui run app.py`.
- Expecting a browser dashboard. `stui` renders inside your terminal.
- Reusing Streamlit-only APIs such as sidebars, file upload, caching decorators,
  or arbitrary components. They are not part of this small API.
- Assuming newer APIs are present in an older install. Check
  `python -c "import stui; print(stui.__version__)"` before using forms,
  grouping primitives, metrics, charts, or packaged examples.
- Doing slow network or model work at top level. Scripts rerun after
  interactions, so keep top-level work light and cache expensive work yourself.
- Forgetting stable `key` values when creating similar widgets in loops.

## Troubleshooting

### `stui: command not found`

Make sure you installed into the same Python environment that your shell is
using:

```bash
python -m pip install stui-terminal
python -m stui --version
```

If `python -m stui --version` works but `stui --version` does not, your
environment's script directory is not on `PATH`. Running through
`python -m stui ...` is a reliable workaround.

### Python Version

`stui` requires Python 3.11 or newer:

```bash
python --version
```

If that prints an older version, create a 3.11+ environment first:

```bash
python3.11 -m venv .venv
. .venv/bin/activate
python -m pip install stui-terminal
```

### Terminal Rendering

`stui` renders a Textual app inside your terminal. For the best results, use a
modern terminal with UTF-8 and color support. If borders, focus rings, or block
characters look wrong, try another terminal app, make the window wider, and
check that `TERM` is set to a normal interactive terminal value such as
`xterm-256color`.

### macOS Editable Install Quirk

If a local editable install appears to succeed but `import stui` or
`stui --version` cannot find the package on macOS, check whether the virtual
environment or editable-install `.pth` file was marked hidden:

```bash
chflags -R nohidden .venv
python -m pip install -e ".[dev]"
python -m stui --version
```

## Examples

The commands below use repository paths from a checkout. If you installed
`stui-terminal` from PyPI and do not have this repository, copy a bundled
example first:

```bash
stui example copy counter ./counter.py
stui run ./counter.py
```

### Counter

`examples/counter.py` shows a minimal stateful app with increment, decrement, and
reset controls.

```bash
stui run examples/counter.py
```

### Model Demo

`examples/model_demo.py` shows a small model-parameter playground using text
input, checkbox, sliders, status messages, session state, and deterministic
scoring. It is intentionally local and fake: there are no network calls or model
dependencies.

```bash
stui run examples/model_demo.py
```

### Inputs

`examples/inputs.py` shows text, numeric, selectbox, radio, checkbox, and button
controls together.

```bash
stui run examples/inputs.py
```

### Data Display

`examples/data_display.py` shows tables, JSON, and code output.

```bash
stui run examples/data_display.py
```

### Dashboard

`examples/dashboard.py` combines controls, progress, status messages, and a
small table into a compact terminal control panel.

```bash
stui run examples/dashboard.py
```

### Forms

`examples/forms.py` shows the experimental form flow: form widget display
values can change during reruns, but keyed values commit to `session_state` on
submit.

```bash
stui run examples/forms.py
```

### Layouts

`examples/layouts.py` shows responsive columns, container, and
keyboard-toggleable expander patterns. The design notes are in
[`docs/layouts.md`](docs/layouts.md).

```bash
stui run examples/layouts.py
```

### Charts

`examples/charts.py` shows `metric`, `bar_chart`, and `line_chart` helpers with
source data shown in a table.

```bash
stui run examples/charts.py
```

### Kitchen Sink

`examples/kitchen_sink.py` exercises the stable API surface plus the
experimental terminal-app primitives that remain useful feedback targets before
v1.

```bash
stui run examples/kitchen_sink.py
```

## Limitations

- No browser, web server, websocket, or port-forwarding runtime.
- No Streamlit dependency and no promise of Streamlit compatibility.
- Forms still rerun the Textual app when a form widget changes, but pending
  form values stay out of `session_state` until submit.
- Expanders are keyboard-toggleable with Enter/Space and persist their state;
  this is still a modest terminal grouping primitive, not a full layout system.
- Columns accept only an integer count, stack when the terminal is narrow, and
  do not support custom ratios, sidebars, tabs, browser grids, or horizontal
  scrolling.
- Charts are compact terminal summaries, not plotting-library replacements.
  `st.bar_chart` supports signed values and zero-only data; `st.line_chart` is
  a simple static sparkline for numeric lists or dictionaries of numeric series.
- `st.status`, `st.spinner`, and `st.help` are display helpers, not live
  animation, background task, or pager systems.
- `st.rerun` and `st.stop` are small flow-control helpers, not a full job
  scheduler or async runtime.
- No sidebars, file upload, browser components, or caching decorators yet.
- Tables are static display only; there is no full dataframe editing or sorting.
- Slider input supports numeric values only.
- Layout remains terminal-first and intentionally modest.
- The app reruns the script as interactions change state, so examples should
  keep top-level work lightweight.
- Error handling is still early and meant for development feedback.
- Experimental APIs remain public, but may still tighten in v1.x releases with
  release-note coverage and migration notes when practical.

## Non-Goals

`stui` is deliberately not trying to become:

- A Streamlit compatibility layer or migration tool.
- A browser dashboard framework.
- A hosted/cloud product with auth, sync, collaboration, or deployment
  management.
- A plotting library or dataframe editor.
- A large component marketplace before the terminal API is stable.
- A wrapper around GPL slider/widget code or `textual-slider`.

## v1.1.0 Stable Status

v1.1.0 is the first post-v1 improvement release. It keeps the package/import/CLI
contract from v1.0.0 and graduates the safest experimental APIs after adding
regression coverage and documentation updates.

The remaining experimental APIs and terminal compatibility unknowns are visible
instead of hidden. Post-v1 work should be feedback-driven and kept out of the
core stable API unless it has enough real terminal evidence.

See [ROADMAP.md](ROADMAP.md) and
[docs/v1-readiness.md](docs/v1-readiness.md) for the full path to v1.

## Contributing

See [CONTRIBUTING.md](CONTRIBUTING.md) for the local development workflow and
project boundaries.
