mirror of
https://github.com/basicmachines-co/basic-memory
synced 2026-06-21 13:47:35 +00:00
Compare commits
4 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| bc3557f000 | |||
| 611f5cd305 | |||
| 4ea392d284 | |||
| d491757980 |
@@ -20,6 +20,12 @@ You are an expert release manager for the Basic Memory project. When the user ru
|
||||
3. Verify we're on the `main` branch
|
||||
4. Confirm no existing tag with this version
|
||||
|
||||
#### Documentation Validation
|
||||
1. **Changelog Check**
|
||||
- CHANGELOG.md contains entry for target version
|
||||
- Entry includes all major features and fixes
|
||||
- Breaking changes are documented
|
||||
|
||||
### Step 2: Use Justfile Automation
|
||||
Execute the automated release process:
|
||||
```bash
|
||||
|
||||
@@ -1,5 +1,60 @@
|
||||
# CHANGELOG
|
||||
|
||||
## v0.13.4 (2025-06-11)
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
- **MCP Tools**: Renamed `list_projects` tool to `list_memory_projects` to avoid naming conflicts with other MCP servers
|
||||
- **Namespace**: Improved tool naming specificity for better MCP server integration and isolation
|
||||
|
||||
### Changes
|
||||
|
||||
- Tool functionality remains identical - only the name changed from `list_projects` to `list_memory_projects`
|
||||
- All integration tests updated to use the new tool name
|
||||
- Better namespace isolation for Basic Memory MCP tools
|
||||
|
||||
## v0.13.3 (2025-06-11)
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
- **Projects**: Fixed case-insensitive project switching where switching succeeded but subsequent operations failed due to session state inconsistency
|
||||
- **Config**: Enhanced config manager with case-insensitive project lookup using permalink-based matching
|
||||
- **MCP Tools**: Updated project management tools to store canonical project names from database instead of user input
|
||||
- **API**: Improved project service to handle both name and permalink lookups consistently
|
||||
|
||||
### Technical Improvements
|
||||
|
||||
- Added comprehensive case-insensitive project switching test coverage with 5 new integration test scenarios
|
||||
- Fixed permalink generation inconsistencies where different case inputs could generate different permalinks
|
||||
- Enhanced project URL construction to use permalinks consistently across all API calls
|
||||
- Improved error handling and session state management for project operations
|
||||
|
||||
### Changes
|
||||
|
||||
- Project switching now preserves canonical project names from database in session state
|
||||
- All project operations use permalink-based lookups for case-insensitive matching
|
||||
- Enhanced test coverage ensures reliable case-insensitive project operations
|
||||
|
||||
## v0.13.2 (2025-06-11)
|
||||
|
||||
### Features
|
||||
|
||||
- **Release Management**: Added automated release management system with version control in `__init__.py`
|
||||
- **Automation**: Implemented justfile targets for `release` and `beta` commands with comprehensive quality gates
|
||||
- **CI/CD**: Enhanced release process with automatic version updates, git tagging, and GitHub release creation
|
||||
|
||||
### Development Experience
|
||||
|
||||
- Added `.claude/commands/release/` directory with automation documentation
|
||||
- Implemented release validation including lint, type-check, and test execution
|
||||
- Streamlined release workflow from manual process to single-command automation
|
||||
|
||||
### Technical Improvements
|
||||
|
||||
- Updated package version management to use actual version numbers instead of dynamic versioning
|
||||
- Added release process documentation and command references
|
||||
- Enhanced justfile with comprehensive release automation targets
|
||||
|
||||
## v0.13.1 (2025-06-11)
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
"""basic-memory - Local-first knowledge management combining Zettelkasten with knowledge graphs"""
|
||||
|
||||
# Package version - updated by release automation
|
||||
__version__ = "0.13.3"
|
||||
__version__ = "0.13.4"
|
||||
|
||||
# API version for FastAPI - independent of package version
|
||||
__api_version__ = "v0"
|
||||
|
||||
@@ -275,7 +275,7 @@ def get_project_config(project_name: Optional[str] = None) -> ProjectConfig:
|
||||
return ProjectConfig(name=name, home=Path(path))
|
||||
|
||||
# otherwise raise error
|
||||
raise ValueError(f"Project '{actual_project_name}' not found")
|
||||
raise ValueError(f"Project '{actual_project_name}' not found") # pragma: no cover
|
||||
|
||||
|
||||
# Create config manager
|
||||
|
||||
@@ -48,4 +48,4 @@ __all__ = [
|
||||
"sync_status",
|
||||
"view_note",
|
||||
"write_note",
|
||||
]
|
||||
]
|
||||
@@ -18,7 +18,7 @@ from basic_memory.schemas.project_info import ProjectList, ProjectStatusResponse
|
||||
from basic_memory.utils import generate_permalink
|
||||
|
||||
|
||||
@mcp.tool()
|
||||
@mcp.tool("list_memory_projects")
|
||||
async def list_projects(ctx: Context | None = None) -> str:
|
||||
"""List all available projects with their status.
|
||||
|
||||
@@ -341,4 +341,4 @@ async def delete_project(project_name: str, ctx: Context | None = None) -> str:
|
||||
result += "Files remain on disk but project is no longer tracked by Basic Memory.\n"
|
||||
result += "Re-add the project to access its content again.\n"
|
||||
|
||||
return add_project_metadata(result, session.get_current_project())
|
||||
return add_project_metadata(result, session.get_current_project())
|
||||
@@ -15,7 +15,7 @@ async def test_list_projects_basic_operation(mcp_server, app):
|
||||
async with Client(mcp_server) as client:
|
||||
# List all available projects
|
||||
list_result = await client.call_tool(
|
||||
"list_projects",
|
||||
"list_memory_projects",
|
||||
{},
|
||||
)
|
||||
|
||||
@@ -248,7 +248,7 @@ async def test_project_management_workflow(mcp_server, app):
|
||||
assert "test-project" in current_result[0].text
|
||||
|
||||
# 2. List all projects
|
||||
list_result = await client.call_tool("list_projects", {})
|
||||
list_result = await client.call_tool("list_memory_projects", {})
|
||||
assert "Available projects:" in list_result[0].text
|
||||
assert "test-project" in list_result[0].text
|
||||
|
||||
@@ -269,7 +269,7 @@ async def test_project_metadata_consistency(mcp_server, app):
|
||||
# Test all project management tools and verify they include project metadata
|
||||
|
||||
# list_projects
|
||||
list_result = await client.call_tool("list_projects", {})
|
||||
list_result = await client.call_tool("list_memory_projects", {})
|
||||
assert "Project: test-project" in list_result[0].text
|
||||
|
||||
# get_current_project
|
||||
@@ -370,7 +370,7 @@ async def test_create_project_basic_operation(mcp_server, app):
|
||||
assert "Project: test-project" in create_text # Should still show current project
|
||||
|
||||
# Verify project appears in project list
|
||||
list_result = await client.call_tool("list_projects", {})
|
||||
list_result = await client.call_tool("list_memory_projects", {})
|
||||
list_text = list_result[0].text
|
||||
assert "test-new-project" in list_text
|
||||
|
||||
@@ -454,7 +454,7 @@ async def test_delete_project_basic_operation(mcp_server, app):
|
||||
)
|
||||
|
||||
# Verify it exists
|
||||
list_result = await client.call_tool("list_projects", {})
|
||||
list_result = await client.call_tool("list_memory_projects", {})
|
||||
assert "to-be-deleted" in list_result[0].text
|
||||
|
||||
# Delete the project
|
||||
@@ -478,7 +478,7 @@ async def test_delete_project_basic_operation(mcp_server, app):
|
||||
assert "Project: test-project" in delete_text # Should show current project
|
||||
|
||||
# Verify project no longer appears in list
|
||||
list_result_after = await client.call_tool("list_projects", {})
|
||||
list_result_after = await client.call_tool("list_memory_projects", {})
|
||||
assert "to-be-deleted" not in list_result_after[0].text
|
||||
|
||||
|
||||
@@ -595,7 +595,7 @@ async def test_project_lifecycle_workflow(mcp_server, app):
|
||||
assert "removed successfully" in delete_result[0].text
|
||||
|
||||
# 7. Verify project is gone from list
|
||||
list_result = await client.call_tool("list_projects", {})
|
||||
list_result = await client.call_tool("list_memory_projects", {})
|
||||
assert project_name not in list_result[0].text
|
||||
|
||||
|
||||
@@ -619,7 +619,7 @@ async def test_create_delete_project_edge_cases(mcp_server, app):
|
||||
assert special_name in create_result[0].text
|
||||
|
||||
# Verify it appears in list
|
||||
list_result = await client.call_tool("list_projects", {})
|
||||
list_result = await client.call_tool("list_memory_projects", {})
|
||||
assert special_name in list_result[0].text
|
||||
|
||||
# Delete it
|
||||
@@ -633,7 +633,7 @@ async def test_create_delete_project_edge_cases(mcp_server, app):
|
||||
assert special_name in delete_result[0].text
|
||||
|
||||
# Verify it's gone
|
||||
list_result_after = await client.call_tool("list_projects", {})
|
||||
list_result_after = await client.call_tool("list_memory_projects", {})
|
||||
assert special_name not in list_result_after[0].text
|
||||
|
||||
|
||||
@@ -655,7 +655,7 @@ async def test_case_insensitive_project_switching(mcp_server, app):
|
||||
assert project_name in create_result[0].text
|
||||
|
||||
# Verify project was created with canonical name
|
||||
list_result = await client.call_tool("list_projects", {})
|
||||
list_result = await client.call_tool("list_memory_projects", {})
|
||||
assert project_name in list_result[0].text
|
||||
|
||||
# Test switching with different case variations
|
||||
@@ -817,7 +817,7 @@ async def test_case_preservation_in_project_list(mcp_server, app):
|
||||
)
|
||||
|
||||
# List projects and verify each appears with its original case
|
||||
list_result = await client.call_tool("list_projects", {})
|
||||
list_result = await client.call_tool("list_memory_projects", {})
|
||||
list_text = list_result[0].text
|
||||
|
||||
for project_name in test_projects:
|
||||
@@ -880,7 +880,7 @@ async def test_session_state_consistency_after_case_switch(mcp_server, app):
|
||||
),
|
||||
("get_current_project", {}),
|
||||
("search_notes", {"query": "session"}),
|
||||
("list_projects", {}),
|
||||
("list_memory_projects", {}),
|
||||
]
|
||||
|
||||
for op_name, op_params in operations:
|
||||
@@ -889,7 +889,7 @@ async def test_session_state_consistency_after_case_switch(mcp_server, app):
|
||||
# All operations should work and reference the canonical project name
|
||||
if op_name == "get_current_project":
|
||||
assert f"Current project: {project_name}" in result[0].text
|
||||
elif op_name == "list_projects":
|
||||
elif op_name == "list_memory_projects":
|
||||
assert project_name in result[0].text
|
||||
assert "(current)" in result[0].text or "current" in result[0].text.lower()
|
||||
|
||||
@@ -899,4 +899,4 @@ async def test_session_state_consistency_after_case_switch(mcp_server, app):
|
||||
|
||||
# Clean up
|
||||
await client.call_tool("switch_project", {"project_name": "test-project"})
|
||||
await client.call_tool("delete_project", {"project_name": project_name})
|
||||
await client.call_tool("delete_project", {"project_name": project_name})
|
||||
Reference in New Issue
Block a user