Compare commits

...

1 Commits

Author SHA1 Message Date
claude[bot] 8d90abb64c fix: add missing 'project create' command to match v0.13.0 documentation
The v0.13.0 documentation references `basic-memory project create` in multiple places
but only `project add` was implemented. This commit adds the missing `create` command
with the same functionality as `add` to match the documented behavior.

Changes:
- Add project create command with name, path, and --default option
- Add test coverage for the new command
- Update error handling tests to include create command

Fixes #129

Co-authored-by: phernandez <phernandez@users.noreply.github.com>
2025-06-11 19:28:06 +00:00
2 changed files with 54 additions and 0 deletions
+30
View File
@@ -99,6 +99,36 @@ def add_project(
console.print(f" basic-memory project default {name}")
@project_app.command("create")
def create_project(
name: str = typer.Argument(..., help="Name of the project"),
path: str = typer.Argument(..., help="Path to the project directory"),
set_default: bool = typer.Option(False, "--default", help="Set as default project"),
) -> None:
"""Create a new project."""
# Resolve to absolute path
resolved_path = os.path.abspath(os.path.expanduser(path))
try:
project_url = config.project_url
data = {"name": name, "path": resolved_path, "set_default": set_default}
response = asyncio.run(call_post(client, f"{project_url}/project/projects", json=data))
result = ProjectStatusResponse.model_validate(response.json())
console.print(f"[green]{result.message}[/green]")
except Exception as e:
console.print(f"[red]Error creating project: {str(e)}[/red]")
console.print("[yellow]Note: Make sure the Basic Memory server is running.[/yellow]")
raise typer.Exit(1)
# Display usage hint
console.print("\nTo use this project:")
console.print(f" basic-memory --project={name} <command>")
console.print(" # or")
console.print(f" basic-memory project default {name}")
@project_app.command("remove")
def remove_project(
name: str = typer.Argument(..., help="Name of the project to remove"),
+24
View File
@@ -47,6 +47,26 @@ def test_project_add_command(mock_run, cli_env):
assert result.exit_code == 0
@patch("basic_memory.cli.commands.project.asyncio.run")
def test_project_create_command(mock_run, cli_env):
"""Test the 'project create' command with mocked API."""
# Mock the API response
mock_response = MagicMock()
mock_response.status_code = 200
mock_response.json.return_value = {
"message": "Project 'test-project' added successfully",
"status": "success",
"default": False,
}
mock_run.return_value = mock_response
runner = CliRunner()
result = runner.invoke(cli_app, ["project", "create", "test-project", "/path/to/project"])
# Just verify it runs without exception
assert result.exit_code == 0
@patch("basic_memory.cli.commands.project.asyncio.run")
def test_project_remove_command(mock_run, cli_env):
"""Test the 'project remove' command with mocked API."""
@@ -128,6 +148,7 @@ def test_project_failure_exits_with_error(mock_run, cli_env):
# Test various commands for proper error handling
list_result = runner.invoke(cli_app, ["project", "list"])
add_result = runner.invoke(cli_app, ["project", "add", "test-project", "/path/to/project"])
create_result = runner.invoke(cli_app, ["project", "create", "test-project", "/path/to/project"])
remove_result = runner.invoke(cli_app, ["project", "remove", "test-project"])
default_result = runner.invoke(cli_app, ["project", "default", "test-project"])
@@ -139,6 +160,9 @@ def test_project_failure_exits_with_error(mock_run, cli_env):
assert add_result.exit_code == 1
assert "Error adding project" in add_result.output
assert create_result.exit_code == 1
assert "Error creating project" in create_result.output
assert remove_result.exit_code == 1
assert "Error removing project" in remove_result.output