Switch default interactive CLI routing to TUI v2

This commit is contained in:
thePR0M3TH3AN committed 2026-03-01 16:46:08 -05:00
1 parent 5f0dbe82af
commit e3c117110a
6 files changed
+66 -8

No files matched your search

+1
View File
@@ -43,6 +43,7 @@ This directory contains SeedPass project documentation.
## Discoverability Commands
- `seedpass --help`
- `seedpass --legacy-tui`
- `seedpass <group> --help`
- `seedpass tui2 --help`
- `seedpass tui2 --check`
+2 -5
View File
@@ -6,12 +6,9 @@ Decision owner: SeedPass maintainers
## Decision
Do not switch the default interactive entrypoint (`seedpass`) to TUI v2 yet.
Addendum (March 1, 2026, `beta`): default interactive routing now launches TUI v2 first, with `--legacy-tui` retained as a one-release fallback path.
Recommended rollout:
- Keep legacy TUI as default for the next release.
- Keep `seedpass tui2` as the opt-in path.
- Schedule default switch only after cutover gates below are met.
Original recommendation in this memo was conservative (defer default switch until all gates were complete). The `beta` branch now reflects the cutover implementation requested during active hardening.
## Rationale
+2
View File
@@ -198,3 +198,5 @@
- Added docs `docs/tui_v2_large_vault_validation.md` with exact commands and budgets; parity checklist now marks large-vault CI-like validation complete.
- 2026-03-01: Added deterministic TUI v2 parity scenarios across entry kinds in `src/tests/test_tui_v2_parity_scenarios.py` (kind filters, archive/restore roundtrip, non-document edit guard).
- Completed help/docs alignment gate: updated `seedpass tui2` help text, capabilities hints for keybindings/palette (`Ctrl+P`, `p/n`, `x`), and docs discoverability commands (`seedpass tui2 --help/--check`).
- 2026-03-01: Switched default root CLI interactive routing to TUI v2 in `seedpass.cli.main` (when no subcommand), with automatic legacy fallback when Textual runtime is unavailable.
- Added explicit one-release override flag `--legacy-tui` and updated test coverage (`test_typer_cli.py`) for default TUI v2 launch, forced legacy path, and root fallback behavior.
+23
View File
@@ -44,6 +44,12 @@ deterministic_totp_option = typer.Option(
help="Derive TOTP secrets deterministically",
)
legacy_tui_option = typer.Option(
False,
"--legacy-tui",
help="Use legacy interactive TUI (temporary fallback during TUI v2 cutover)",
)
# Sub command groups
from . import entry, vault, nostr, config, fingerprint, util, api, agent
from .capabilities import register_capabilities_command
@@ -82,6 +88,7 @@ def main(
fingerprint: Optional[str] = fingerprint_option,
no_clipboard: bool = no_clipboard_option,
deterministic_totp: bool = deterministic_totp_option,
legacy_tui: bool = legacy_tui_option,
) -> None:
"""SeedPass CLI entry point.
@@ -93,8 +100,24 @@ def main(
"fingerprint": fingerprint,
"no_clipboard": no_clipboard,
"deterministic_totp": deterministic_totp,
"legacy_tui": legacy_tui,
}
if ctx.invoked_subcommand is None:
if legacy_tui:
tui = importlib.import_module("main")
raise typer.Exit(tui.main(fingerprint=fingerprint))
launched = launch_tui2(
fingerprint=fingerprint,
entry_service_factory=lambda: _get_entry_service(ctx),
)
if launched:
return
typer.echo(
"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))
+1
View File
@@ -241,6 +241,7 @@ def build_capabilities() -> dict[str, Any]:
"Run `seedpass <group> --help` for detailed options.",
"Use `seedpass capabilities --format json` for machine-readable discovery.",
"Run `seedpass tui2 --check` before adopting Textual-based TUI v2.",
"Use `seedpass --legacy-tui` to force the legacy interface during cutover.",
"In TUI v2, use `Ctrl+P` for the command palette, `p/n` for paging, and `x` to retry the last failed action.",
"For graph workflows, start with `seedpass entry link-add --help` and `seedpass entry links --help`.",
"For document workflows, run `seedpass entry import-document --help` and `seedpass agent document-import --help`.",
+37 -3
View File
@@ -972,8 +972,23 @@ def test_update_checksum_command(monkeypatch):
assert called.get("called") is True
def test_tui_forward_fingerprint(monkeypatch):
"""Ensure --fingerprint is forwarded when launching the TUI."""
def test_root_tui2_forward_fingerprint(monkeypatch):
"""Ensure --fingerprint is forwarded when launching default TUI v2."""
called = {}
def fake_launch(**kwargs):
called["fp"] = kwargs.get("fingerprint")
called["factory"] = kwargs.get("entry_service_factory")
return True
monkeypatch.setattr(cli, "launch_tui2", fake_launch)
result = runner.invoke(app, ["--fingerprint", "abc"])
assert result.exit_code == 0
assert called.get("fp") == "abc"
assert callable(called.get("factory"))
def test_root_legacy_tui_flag_forwards_fingerprint(monkeypatch):
called = {}
def fake_main(*, fingerprint=None):
@@ -985,7 +1000,7 @@ def test_tui_forward_fingerprint(monkeypatch):
cli, "importlib", SimpleNamespace(import_module=lambda n: fake_mod)
)
result = runner.invoke(app, ["--fingerprint", "abc"])
result = runner.invoke(app, ["--legacy-tui", "--fingerprint", "abc"])
assert result.exit_code == 0
assert called.get("fp") == "abc"
@@ -1029,6 +1044,25 @@ def test_tui2_fallback_legacy(monkeypatch):
assert "falling back to legacy TUI" in result.stdout
def test_root_fallback_legacy_when_tui2_unavailable(monkeypatch):
called = {}
monkeypatch.setattr(cli, "launch_tui2", lambda **_: False)
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"])
assert result.exit_code == 0
assert called.get("fp") == "abc"
assert "falling back to legacy TUI" in result.stdout
def test_gui_command(monkeypatch):
called = {}