From 9d1160f281f838c57103b09fb5fa7477a0561557 Mon Sep 17 00:00:00 2001 From: thePR0M3TH3AN <53631862+PR0M3TH3AN@users.noreply.github.com> Date: Sun, 1 Mar 2026 18:23:22 -0500 Subject: [PATCH] Add explicit legacy CLI launcher command --- README.md | 6 ++++++ docs/README.md | 1 + memory-update.md | 6 ++++++ src/seedpass/cli/__init__.py | 28 ++++++++++++++++++---------- src/tests/test_typer_cli.py | 34 ++++++++++++++++++++++++++++++++++ 5 files changed, 65 insertions(+), 10 deletions(-) diff --git a/README.md b/README.md index 649f9cd4..2188b0e1 100644 --- a/README.md +++ b/README.md @@ -446,6 +446,12 @@ Once installed, launch the interactive TUI with: seedpass ``` +To launch the legacy interactive TUI explicitly: + +```bash +seedpass legacy +``` + You can also run directly from the repository with: ```bash diff --git a/docs/README.md b/docs/README.md index 46ba888a..0a9a2e99 100644 --- a/docs/README.md +++ b/docs/README.md @@ -45,6 +45,7 @@ This directory contains SeedPass project documentation. - `seedpass --help` - `seedpass --legacy-tui` +- `seedpass legacy` - `seedpass --help` - `seedpass tui2 --help` - `seedpass tui2 --check` diff --git a/memory-update.md b/memory-update.md index f5fc00ab..8af60e4f 100644 --- a/memory-update.md +++ b/memory-update.md @@ -284,3 +284,9 @@ - accent borders/focus: `#58f29d`, `#2abf75`, `#274533`, `#1a3024` - Styled Header/Footer/Input/ListView/ListItem focus/selection states to reduce default Textual blue and align with SeedPass mint-green terminal aesthetic. - Added website-style icon semantics into TUI copy and sensitive panel titles (key/mobile/network/lock/bolt/document/users/seed mappings) to improve visual continuity between landing and app. + +## 2026-03-01 Legacy launch ergonomics +- Added explicit CLI command `seedpass legacy` to launch the legacy interactive TUI directly, in addition to existing global flag `--legacy-tui`. +- Refactored legacy launch path through a shared helper in `seedpass.cli` so root fallback, `--legacy-tui`, `tui2` fallback, and `legacy` command all use consistent behavior and fingerprint forwarding. +- Added CLI regression tests for `seedpass legacy` with and without `--fingerprint`. +- Updated discoverability docs in `README.md` and `docs/README.md`. diff --git a/src/seedpass/cli/__init__.py b/src/seedpass/cli/__init__.py index d38072fa..24b5e35b 100644 --- a/src/seedpass/cli/__init__.py +++ b/src/seedpass/cli/__init__.py @@ -96,6 +96,12 @@ def _prime_tui2_service( return None, exc +def _launch_legacy_tui(*, fingerprint: Optional[str]) -> typer.Exit: + """Launch legacy interactive TUI and return Typer exit.""" + tui = importlib.import_module("main") + return typer.Exit(tui.main(fingerprint=fingerprint)) + + @app.callback(invoke_without_command=True) def main( ctx: typer.Context, @@ -118,8 +124,7 @@ def main( } if ctx.invoked_subcommand is None: if legacy_tui: - tui = importlib.import_module("main") - raise typer.Exit(tui.main(fingerprint=fingerprint)) + raise _launch_legacy_tui(fingerprint=fingerprint) service, preflight_error = _prime_tui2_service(ctx) if preflight_error is not None: @@ -127,8 +132,7 @@ def main( "TUI v2 preflight failed; falling back to legacy TUI. " f"Details: {preflight_error}" ) - tui = importlib.import_module("main") - raise typer.Exit(tui.main(fingerprint=fingerprint)) + raise _launch_legacy_tui(fingerprint=fingerprint) launched = launch_tui2( fingerprint=fingerprint, @@ -141,8 +145,7 @@ def main( "TUI v2 runtime unavailable; falling back to legacy TUI. " "Run `seedpass tui2 --check` for diagnostics." ) - tui = importlib.import_module("main") - raise typer.Exit(tui.main(fingerprint=fingerprint)) + raise _launch_legacy_tui(fingerprint=fingerprint) @app.command("lock") @@ -180,8 +183,7 @@ def tui2( "TUI v2 preflight failed; falling back to legacy TUI. " f"Details: {preflight_error}" ) - tui = importlib.import_module("main") - raise typer.Exit(tui.main(fingerprint=fingerprint)) + raise _launch_legacy_tui(fingerprint=fingerprint) typer.echo( f"TUI v2 preflight failed: {preflight_error}", err=True, @@ -200,8 +202,7 @@ def tui2( "TUI v2 runtime unavailable; falling back to legacy TUI. " "Run `seedpass tui2 --check` for diagnostics." ) - tui = importlib.import_module("main") - raise typer.Exit(tui.main(fingerprint=fingerprint)) + raise _launch_legacy_tui(fingerprint=fingerprint) typer.echo( "TUI v2 runtime unavailable. Install `textual` and retry.", @@ -210,6 +211,13 @@ def tui2( raise typer.Exit(1) +@app.command("legacy") +def legacy_tui(ctx: typer.Context) -> None: + """Launch the legacy interactive TUI explicitly.""" + fingerprint = (ctx.obj or {}).get("fingerprint") + raise _launch_legacy_tui(fingerprint=fingerprint) + + @app.command() def gui( install: bool = typer.Option( diff --git a/src/tests/test_typer_cli.py b/src/tests/test_typer_cli.py index 9c8cf764..74dbac60 100644 --- a/src/tests/test_typer_cli.py +++ b/src/tests/test_typer_cli.py @@ -1006,6 +1006,40 @@ def test_root_legacy_tui_flag_forwards_fingerprint(monkeypatch): assert called.get("fp") == "abc" +def test_legacy_command_forwards_fingerprint(monkeypatch): + called = {} + + def fake_main(*, fingerprint=None): + called["fp"] = fingerprint + return 0 + + monkeypatch.setattr( + cli, + "importlib", + SimpleNamespace(import_module=lambda _: SimpleNamespace(main=fake_main)), + ) + result = runner.invoke(app, ["--fingerprint", "abc", "legacy"]) + assert result.exit_code == 0 + assert called.get("fp") == "abc" + + +def test_legacy_command_default_profile(monkeypatch): + called = {} + + def fake_main(*, fingerprint=None): + called["fp"] = fingerprint + return 0 + + monkeypatch.setattr( + cli, + "importlib", + SimpleNamespace(import_module=lambda _: SimpleNamespace(main=fake_main)), + ) + result = runner.invoke(app, ["legacy"]) + assert result.exit_code == 0 + assert called.get("fp") is None + + def test_tui2_check(monkeypatch): monkeypatch.setattr( cli,