feat(tui-v3): implement modular TUI architecture and CLI selector

Scaffolded TUI v3 from scratch with modular directory structure. Created
RibbonHeader, ProfileTree, EntryDataTable, and BoardContainer widgets.
Implemented full-screen SettingsScreen and MaximizedInspectorScreen.
Updated CLI with unified '--tui [legacy|v2|v3]' option and 'tui3' command.
Reused existing service hooks for zero-logic migration.
This commit is contained in:
thePR0M3TH3AN committed 2026-03-02 23:01:00 -05:00
1 parent ac4b3b468b
commit 18a637d3a2
9 files changed
+864 -3

No files matched your search

+48 -3
View File
@@ -13,6 +13,7 @@ from .common import _get_entry_service, _get_services
from seedpass.core.errors import SeedPassError
from constants import GUI_BACKEND_CONFIG
from seedpass.tui_v2.app import check_tui2_runtime, launch_tui2
from seedpass.tui_v3 import launch_tui3
app = typer.Typer(
help=(
@@ -50,6 +51,12 @@ legacy_tui_option = typer.Option(
help="Use legacy interactive TUI (temporary fallback during TUI v2 cutover)",
)
tui_version_option = typer.Option(
"v2",
"--tui",
help="Select TUI version: legacy, v2, v3",
)
# Sub command groups
from . import entry, vault, nostr, config, fingerprint, util, api, agent, semantic
from .capabilities import register_capabilities_command
@@ -131,6 +138,7 @@ def main(
no_clipboard: bool = no_clipboard_option,
deterministic_totp: bool = deterministic_totp_option,
legacy_tui: bool = legacy_tui_option,
tui_version: str = tui_version_option,
) -> None:
"""SeedPass CLI entry point.
@@ -143,19 +151,34 @@ def main(
"no_clipboard": no_clipboard,
"deterministic_totp": deterministic_totp,
"legacy_tui": legacy_tui,
"tui_version": tui_version,
}
if ctx.invoked_subcommand is None:
if legacy_tui:
if legacy_tui or tui_version == "legacy":
raise _launch_legacy_tui(fingerprint=fingerprint)
services, preflight_error = _prime_tui2_service(ctx)
if preflight_error is not None:
typer.echo(
"TUI v2 preflight failed; falling back to legacy TUI. "
f"TUI {tui_version} preflight failed; falling back to legacy TUI. "
f"Details: {preflight_error}"
)
raise _launch_legacy_tui(fingerprint=fingerprint)
if tui_version == "v3":
launch_tui3(
fingerprint=fingerprint,
entry_service_factory=lambda: services["entry"],
profile_service_factory=lambda: services["profile"],
config_service_factory=lambda: services["config"],
nostr_service_factory=lambda: services["nostr"],
sync_service_factory=lambda: services["sync"],
utility_service_factory=lambda: services["utility"],
vault_service_factory=lambda: services["vault"],
semantic_service_factory=lambda: services["semantic"],
)
return
launched = launch_tui2(
fingerprint=fingerprint,
entry_service_factory=lambda: services["entry"],
@@ -171,7 +194,7 @@ def main(
return
typer.echo(
"TUI v2 runtime unavailable; falling back to legacy TUI. "
f"TUI {tui_version} runtime unavailable; falling back to legacy TUI. "
"Run `seedpass tui2 --check` for diagnostics."
)
raise _launch_legacy_tui(fingerprint=fingerprint)
@@ -247,6 +270,28 @@ def tui2(
raise typer.Exit(1)
@app.command("tui3")
def tui3(ctx: typer.Context) -> None:
"""Launch the experimental TUI v3 scratch architecture."""
fingerprint = (ctx.obj or {}).get("fingerprint")
services, preflight_error = _prime_tui2_service(ctx)
if preflight_error is not None:
typer.echo(f"TUI v3 preflight failed: {preflight_error}", err=True)
raise typer.Exit(1)
launch_tui3(
fingerprint=fingerprint,
entry_service_factory=lambda: services["entry"],
profile_service_factory=lambda: services["profile"],
config_service_factory=lambda: services["config"],
nostr_service_factory=lambda: services["nostr"],
sync_service_factory=lambda: services["sync"],
utility_service_factory=lambda: services["utility"],
vault_service_factory=lambda: services["vault"],
semantic_service_factory=lambda: services["semantic"],
)
@app.command("legacy")
def legacy_tui(ctx: typer.Context) -> None:
"""Launch the legacy interactive TUI explicitly."""