diff --git a/README.md b/README.md index 9b0ce21..448832e 100644 --- a/README.md +++ b/README.md @@ -241,6 +241,11 @@ python -m seedpass_gui seedpass-gui ``` +Install a platform-specific BeeWare backend before running these commands. Only +the headless `toga-dummy` backend is bundled for tests. Linux users should +install `toga-gtk`, Windows users need `toga-winforms`, and macOS users require +`toga-cocoa`. + The GUI works with the same vault and configuration files as the CLI. ```mermaid @@ -555,6 +560,10 @@ If the checksum file is missing, generate it manually: python scripts/update_checksum.py ``` +If SeedPass prints a "script checksum mismatch" warning on startup, regenerate +the checksum with `seedpass util update-checksum` or select "Generate Script +Checksum" from the Settings menu. + To run mutation tests locally, generate coverage data first and then execute `mutmut`: ```bash diff --git a/docs/docs/content/01-getting-started/01-advanced_cli.md b/docs/docs/content/01-getting-started/01-advanced_cli.md index 1c0bed6..3c86dcc 100644 --- a/docs/docs/content/01-getting-started/01-advanced_cli.md +++ b/docs/docs/content/01-getting-started/01-advanced_cli.md @@ -116,6 +116,10 @@ Miscellaneous helper commands. | Verify script checksum | `util verify-checksum` | `seedpass util verify-checksum` | | Update script checksum | `util update-checksum` | `seedpass util update-checksum` | +If you see a startup warning about a script checksum mismatch, +run `seedpass util update-checksum` or choose "Generate Script Checksum" +from the Settings menu to update the stored value. + ### API Commands Run or stop the local HTTP API. diff --git a/docs/docs/content/01-getting-started/06-gui_adapter.md b/docs/docs/content/01-getting-started/06-gui_adapter.md index 779fec4..e2c4917 100644 --- a/docs/docs/content/01-getting-started/06-gui_adapter.md +++ b/docs/docs/content/01-getting-started/06-gui_adapter.md @@ -14,6 +14,11 @@ python -m seedpass_gui seedpass-gui ``` +Install a platform-specific BeeWare backend before launching the GUI. The +distribution only bundles the headless `toga-dummy` backend for automated +tests. Linux users should install `toga-gtk`, Windows users need +`toga-winforms`, and macOS users require `toga-cocoa`. + The GUI shares the same encrypted vault and configuration as the command line tool. To generate a packaged binary, run `briefcase build` (after the initial `briefcase create`). diff --git a/docs/docs/content/index.md b/docs/docs/content/index.md index 35b069d..d272206 100644 --- a/docs/docs/content/index.md +++ b/docs/docs/content/index.md @@ -497,6 +497,10 @@ If the checksum file is missing, generate it manually: python scripts/update_checksum.py ``` +If SeedPass reports a "script checksum mismatch" warning on startup, +regenerate the checksum with `seedpass util update-checksum` or select +"Generate Script Checksum" from the Settings menu. + To run mutation tests locally, generate coverage data first and then execute `mutmut`: ```bash diff --git a/src/seedpass/cli.py b/src/seedpass/cli.py index df7f56c..bddc7ee 100644 --- a/src/seedpass/cli.py +++ b/src/seedpass/cli.py @@ -24,6 +24,7 @@ import uvicorn from . import api as api_module import importlib +import importlib.util app = typer.Typer( help="SeedPass command line interface", @@ -95,6 +96,14 @@ def _get_nostr_service(ctx: typer.Context) -> NostrService: return NostrService(pm) +def _gui_backend_available() -> bool: + """Return True if a platform-specific BeeWare backend is installed.""" + for pkg in ("toga_gtk", "toga_winforms", "toga_cocoa"): + if importlib.util.find_spec(pkg) is not None: + return True + return False + + @app.callback(invoke_without_command=True) def main(ctx: typer.Context, fingerprint: Optional[str] = fingerprint_option) -> None: """SeedPass CLI entry point. @@ -740,6 +749,14 @@ def api_stop(ctx: typer.Context, host: str = "127.0.0.1", port: int = 8000) -> N @app.command() def gui() -> None: """Launch the BeeWare GUI.""" + if not _gui_backend_available(): + typer.echo( + "No BeeWare GUI backend found. Install 'toga-gtk' (Linux), " + "'toga-winforms' (Windows) or 'toga-cocoa' (macOS) to run the GUI.", + err=True, + ) + raise typer.Exit(1) + from seedpass_gui.app import main main() diff --git a/src/tests/test_typer_cli.py b/src/tests/test_typer_cli.py index c2db4da..fc48c82 100644 --- a/src/tests/test_typer_cli.py +++ b/src/tests/test_typer_cli.py @@ -557,6 +557,14 @@ def test_gui_command(monkeypatch): "seedpass_gui.app", SimpleNamespace(main=fake_main), ) + monkeypatch.setattr(cli.importlib.util, "find_spec", lambda n: True) result = runner.invoke(app, ["gui"]) assert result.exit_code == 0 assert called.get("called") is True + + +def test_gui_command_no_backend(monkeypatch): + monkeypatch.setattr(cli.importlib.util, "find_spec", lambda n: None) + result = runner.invoke(app, ["gui"]) + assert result.exit_code == 1 + assert "BeeWare GUI backend" in result.stderr