Metadata-Version: 2.4
Name: stui-terminal
Version: 1.0.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` v1.0.0 is the first stable release of 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.0.0 release treats 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.0.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` | Pre-v1 experimental while terminal grouping/help formatting gathers feedback |
| Display | `st.code`, `st.json`, `st.progress`, `st.table`, `st.dataframe` | Mixed: `st.code` is v1-stable; `st.json`, `st.progress`, `st.table`, and `st.dataframe` are pre-v1 experimental static terminal displays |
| Inputs | `st.button`, `st.slider`, `st.text_input`, `st.checkbox`, `st.number_input`, `st.selectbox`, `st.radio` | Mixed: core inputs are v1-stable; `st.number_input`, `st.selectbox`, and `st.radio` are pre-v1 experimental |
| Forms | `st.form`, `st.form_submit_button` | Pre-v1 experimental deferred commit to `session_state` until submit |
| Layout/grouping | `st.container`, `st.columns`, `st.expander` | Pre-v1 experimental terminal grouping primitives; columns stack on narrow terminals |
| Metrics and charts | `st.metric`, `st.bar_chart`, `st.line_chart` | Pre-v1 experimental terminal summaries, not plotting replacements |
| State and flow | `st.session_state`, `st.rerun`, `st.stop` | Mixed: `st.session_state` is v1-stable; `st.rerun` and `st.stop` are pre-v1 experimental flow control |
| 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.0.0 stable surface is intentionally small: text/status output, `st.code`,
core inputs, `st.session_state`, and the documented CLI/demo/example commands.
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. This includes forms, grouping/layout
helpers, selection/numeric widgets, status/help helpers, static data display
beyond `st.code`, metrics/charts, and flow control. 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.0.0 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.
- Public announcement copy is prepared for v1.0.0, but social posts should be
  published manually only after PyPI install, docs, examples, CI, and terminal
  compatibility are verified together.

## 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.0.0 Stable Status

v1.0.0 is the first stable release. The stable API contract, PyPI install path,
bundled demo/example commands, starter templates, docs, CI, and release notes
are verified together for this line.

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.
