feat(tui): add interactive Terminal UI for mmore commands#298
feat(tui): add interactive Terminal UI for mmore commands#298perrin-arthur wants to merge 17 commits into
Conversation
Adds a `mmore tui` command that launches an interactive terminal interface built with `questionary` and `rich`. Lets users pick a pipeline command (process / postprocess / index / rag), reuse or build a config interactively, and run the full pipeline with progress feedback — without having to write YAML configs by hand. - New `src/mmore/tui/` module (app, commands registry, config builder, pipeline runner, theme). - Wires up `tui` as a top-level Click command in `cli.py`. - Adds `questionary>=2.0` and `rich>=13` to core dependencies.
There was a problem hiding this comment.
Pull request overview
Adds an interactive mmore tui command (questionary + rich) to help users pick and run mmore pipeline stages with guided config selection/generation and richer terminal feedback.
Changes:
- Introduces a new
src/mmore/tui/package implementing menus, config prompting/validation, and a “full pipeline” runner. - Wires a new top-level Click command
mmore tuiintosrc/mmore/cli.py. - Adds
questionaryandrichas core dependencies (with corresponding lockfile updates).
Reviewed changes
Copilot reviewed 8 out of 9 changed files in this pull request and generated 5 comments.
Show a summary per file
| File | Description |
|---|---|
| uv.lock | Locks new runtime deps needed for the TUI (questionary, rich, transitive deps). |
| pyproject.toml | Adds questionary>=2.0 and rich>=13 to core dependencies. |
| src/mmore/cli.py | Adds the tui Click command entrypoint. |
| src/mmore/tui/init.py | Exposes run() for the CLI entrypoint. |
| src/mmore/tui/app.py | Main TUI loop: menu selection and command execution UX. |
| src/mmore/tui/commands.py | Registry mapping TUI options to existing run_* functions and config validation dataclasses. |
| src/mmore/tui/config_builder.py | Guided config generation + config picking + YAML validation loop. |
| src/mmore/tui/pipeline.py | Orchestrates process → postprocess → index (+ optional chat) with progress UI and summary. |
| src/mmore/tui/theme.py | Shared Rich styling helpers (banner/panels/colors). |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
- Centralise QSTYLE/QMARK in theme.py (was duplicated in app.py and config_builder.py) - Derive pipeline output paths via load_config + jsonl_path so env-var expansion ($ROOT_OUT_DIR, ...) and the directory-vs-jsonl logic match what the underlying commands actually use - Add paths.py: repo_root() walks up from CWD to find examples/, so the TUI works from any working directory; cwd_default() gives ./data-style defaults instead of repo-relative paths - Replace examples/... defaults in guided prompts with cwd_default() fallbacks so the TUI is sensible from outside the repo - ruff format pass on the tui/ package
Gsharpp
left a comment
There was a problem hiding this comment.
1. The TUI doesn't detect missing extras
Repro: uv sync (no extras) → mmore tui → pick process → run → ModuleNotFoundError: No module named 'torch'. The TUI opens happily because questionary and rich are in core deps, but the pipelines it offers depend on the process / index / rag / cpu|cu126 extras, which aren't guaranteed to be installed.
We need to check that the required modules are importable before launching a stage, and surface the matching uv sync --extra <stage> --extra cpu command. Ideally: gray out (in the menu) stages whose extra isn't installed.
2. questionary + rich declared as dependencies instead of an extra
This joins the previous paragraph. We may prefer the TUI functionality to be optional in the dependencies
3. KeyboardInterrupt used to signal "sub-prompt cancellation"
Pressing ctrl + C exit the full tui application. There is no current signal to cancel a command while staying in the app.
4. Better YAML creator function
There is currently no wizard to create yml config files. This might be great to create several templates of configuration files that the wizard could use to help the user
5. No documentation about this integration
No mention of the TUI functionality in the README
- Add a guided wizard ("Build a full pipeline config") that generates
coherent process + postprocess + index YAMLs in one flow, exposing
only processors / post-processors / indexer types that actually exist
in the repo (pulled from ProcessorRegistry, TAGGER_TYPES, FILTER_TYPES).
- Detect missing extras per stage via importlib.util.find_spec canaries;
disable menu entries and surface the exact `uv sync --extra ...` hint
instead of crashing mid-run with ModuleNotFoundError.
- Move questionary + rich out of core dependencies into a new `tui`
extra (included in `all`); friendly error from `mmore tui` if missing.
- Introduce CancelledByUser so Ctrl-C / Esc inside a sub-flow returns
to the main menu instead of exiting the whole TUI. Ctrl-C at the main
menu still quits.
- Add a spinner during YAML validation (dataclass imports take ~5s and
made the TUI look frozen).
- Document the TUI in the README with install commands and behavior.
…OR edit - Add post-validation menu (preview / edit / run) when picking a config: syntax-highlighted YAML preview via rich.Syntax, and $EDITOR launch with automatic re-validation on save. - New inspector module (src/mmore/tui/inspector.py) that streams JSONL output files and prints a summary table (doc count, processor types, file types, avg text length, modalities) plus a sample of the first 3 documents. Called automatically after process and postprocess steps. - Wizard builders now detect existing output files and propose resuming via previous_results instead of always writing null, leveraging the existing incremental.py module for skipping unchanged files. - Add "Edit an existing YAML in $EDITOR" choice to pick_or_build_config.
| """Locate bundled example configs regardless of CWD or install layout. | ||
|
|
||
| Strategy: | ||
| - If `examples/` exists relative to CWD (source checkout), use it. | ||
| - Else, walk up from CWD looking for a repo root that contains `examples/`. | ||
| - Else, fall back to `importlib.resources` to read examples shipped with the | ||
| package (only available if the wheel actually bundles them). | ||
| - If nothing is found, return the original repo-relative path so error | ||
| messages stay readable; callers handle "missing" gracefully. | ||
| """ |
| """Open a config file in $EDITOR (falls back to vi).""" | ||
| editor = os.environ.get("EDITOR", "vi") | ||
| subprocess.call([editor, path]) | ||
|
|
| try: | ||
| from .tui import run | ||
| except ImportError as e: | ||
| click.echo( | ||
| f"TUI dependencies missing ({e.name or e}). " | ||
| "Install with: uv sync --extra tui" | ||
| ) | ||
| raise SystemExit(1) |
| tui = [ | ||
| # Interactive terminal launcher (`mmore tui`) | ||
| "questionary>=2.0", | ||
| "rich>=13", | ||
| ] |
- Use time.time_ns() for config filenames to avoid collisions
- Support $EDITOR with flags (e.g. "code -w") via shlex.split
- Use _validate_with_spinner in pick_or_build_config to show feedback
during slow dataclass imports
- Expand ~ and env vars on manual path input (expanduser/expandvars)
- Replace cwd_default("examples/...") with resolve_example() so
defaults resolve correctly from any CWD
- Narrow ImportError catch in cli.py to ModuleNotFoundError for
expected TUI deps only, re-raise other import errors
- Fix paths.py docstring to match actual implementation (no
importlib.resources fallback)
Add a guided setup flow accessible from the main menu that walks the user through picking pipeline stages, selecting a compute backend (cpu / cu126), running `uv sync` with the right extras, and generating a .env file with the API keys / paths each stage needs. Existing .env entries are preserved on merge, and secret values are masked in the preview table.
Outline characters in white, filled blocks in pure black, second M in yellow — matches the m(m)ore logo. Uses hex colors to avoid terminal themes remapping ANSI black to dark grey.
Summary
Adds a
mmore tuicommand that launches an interactive terminal interface built onquestionary+rich. Users can:Lowers the barrier for non-CLI-savvy users who currently have to hand-write YAML configs.
Changes
src/mmore/tui/module:app.py— entry point, command picker, full-pipeline orchestrationcommands.py— registry of available commandsconfig_builder.py— interactive config builderpipeline.py— runs a sequence of stages with rich-style progresstheme.py— color tokens, banner, console helperssrc/mmore/cli.py— wirestuias a top-level Click command (mmore tui)pyproject.toml— addsquestionary>=2.0andrich>=13to core depsuv.lock— lockfile update for the new depsTest plan
mmore tuilaunches the menu without errorspyteststill green (no test changes in this PR)Execution
If not already done, install the dependencies:
uv pip install -eThen launch the CLI:
mmore tui