diff --git a/src/basic_memory/cli/app.py b/src/basic_memory/cli/app.py index 2e88c810..4eb9d3c8 100644 --- a/src/basic_memory/cli/app.py +++ b/src/basic_memory/cli/app.py @@ -86,6 +86,7 @@ def app_callback( "reindex", "update", "watch", + "workspace", } if ( not version diff --git a/src/basic_memory/cli/commands/__init__.py b/src/basic_memory/cli/commands/__init__.py index 5f80a149..c61f4ca9 100644 --- a/src/basic_memory/cli/commands/__init__.py +++ b/src/basic_memory/cli/commands/__init__.py @@ -9,6 +9,7 @@ from . import ( format, schema, update, + workspace, ) __all__ = [ @@ -26,4 +27,5 @@ __all__ = [ "format", "schema", "update", + "workspace", ] diff --git a/src/basic_memory/cli/commands/workspace.py b/src/basic_memory/cli/commands/workspace.py new file mode 100644 index 00000000..62d050b0 --- /dev/null +++ b/src/basic_memory/cli/commands/workspace.py @@ -0,0 +1,17 @@ +"""Top-level workspace stub — redirects users to 'bm cloud workspace'.""" + +import typer + +from basic_memory.cli.app import app + + +@app.command( + "workspace", + context_settings={"allow_extra_args": True, "ignore_unknown_options": True}, +) +def workspace_redirect() -> None: + """'bm workspace' is not a command — see 'bm cloud workspace'.""" + typer.echo("'bm workspace' is not a command. Workspace verbs live under 'bm cloud workspace':") + typer.echo(" bm cloud workspace list") + typer.echo(" bm cloud workspace set-default ") + raise typer.Exit(1) diff --git a/src/basic_memory/cli/main.py b/src/basic_memory/cli/main.py index bd0d1cf9..63c8e88c 100644 --- a/src/basic_memory/cli/main.py +++ b/src/basic_memory/cli/main.py @@ -30,6 +30,7 @@ if not _version_only_invocation(sys.argv[1:]): status, tool, update, + workspace, ) warnings.filterwarnings("ignore") # pragma: no cover diff --git a/tests/cli/test_workspace_commands.py b/tests/cli/test_workspace_commands.py index 809bd27a..a5edf16d 100644 --- a/tests/cli/test_workspace_commands.py +++ b/tests/cli/test_workspace_commands.py @@ -15,6 +15,9 @@ from basic_memory.schemas.cloud import WorkspaceInfo import basic_memory.cli.commands.cloud as cloud_cmd # noqa: F401 import basic_memory.cli.commands.cloud.workspace as workspace_cmd # noqa: F401 +# Importing workspace registers the top-level redirect stub on app. +import basic_memory.cli.commands.workspace # noqa: F401 + def _workspace( *, @@ -209,3 +212,25 @@ class TestWorkspaceSetDefault: assert result.exit_code == 1 assert "OAuth login" in result.stdout + + +class TestWorkspaceRedirectStub: + """Tests for the top-level 'bm workspace' redirect stub.""" + + @pytest.fixture + def runner(self): + return CliRunner() + + def test_workspace_bare_prints_redirect_and_exits_nonzero(self, runner): + result = runner.invoke(app, ["workspace"]) + assert result.exit_code == 1 + assert "bm cloud workspace" in result.output + + def test_workspace_with_subcommand_prints_redirect_and_exits_nonzero(self, runner): + result = runner.invoke(app, ["workspace", "list"]) + assert result.exit_code == 1 + assert "bm cloud workspace list" in result.output + + def test_workspace_redirect_mentions_set_default(self, runner): + result = runner.invoke(app, ["workspace"]) + assert "bm cloud workspace set-default" in result.output