mirror of
https://github.com/PR0M3TH3AN/SeedPass.git
synced 2026-11-02 10:52:05 +00:00
Switch default interactive CLI routing to TUI v2
This commit is contained in:
1 parent
5f0dbe82af
commit
e3c117110a
6 files changed
+66
-8
No files matched your search
@@ -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`
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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.
|
||||
@@ -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))
|
||||
|
||||
|
||||
@@ -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`.",
|
||||
|
||||
@@ -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 = {}
|
||||
|
||||
|
||||
Reference in new issue
Block a user