basic-memory 0.13.2__tar.gz → 0.13.4__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of basic-memory might be problematic. Click here for more details.

Files changed (311) hide show
  1. {basic_memory-0.13.2 → basic_memory-0.13.4}/.claude/commands/release/release.md +6 -0
  2. {basic_memory-0.13.2 → basic_memory-0.13.4}/CHANGELOG.md +55 -0
  3. {basic_memory-0.13.2 → basic_memory-0.13.4}/PKG-INFO +1 -1
  4. {basic_memory-0.13.2 → basic_memory-0.13.4}/src/basic_memory/__init__.py +1 -1
  5. {basic_memory-0.13.2 → basic_memory-0.13.4}/src/basic_memory/config.py +24 -9
  6. {basic_memory-0.13.2 → basic_memory-0.13.4}/src/basic_memory/mcp/tools/__init__.py +1 -1
  7. {basic_memory-0.13.2 → basic_memory-0.13.4}/src/basic_memory/mcp/tools/project_management.py +27 -17
  8. {basic_memory-0.13.2 → basic_memory-0.13.4}/src/basic_memory/schemas/project_info.py +2 -2
  9. {basic_memory-0.13.2 → basic_memory-0.13.4}/src/basic_memory/services/project_service.py +14 -8
  10. {basic_memory-0.13.2 → basic_memory-0.13.4}/test-int/mcp/test_project_management_integration.py +274 -9
  11. {basic_memory-0.13.2 → basic_memory-0.13.4}/.claude/commands/check-health.md +0 -0
  12. {basic_memory-0.13.2 → basic_memory-0.13.4}/.claude/commands/commands.md +0 -0
  13. {basic_memory-0.13.2 → basic_memory-0.13.4}/.claude/commands/lint-fix.md +0 -0
  14. {basic_memory-0.13.2 → basic_memory-0.13.4}/.claude/commands/release/beta.md +0 -0
  15. {basic_memory-0.13.2 → basic_memory-0.13.4}/.claude/commands/release/changelog.md +0 -0
  16. {basic_memory-0.13.2 → basic_memory-0.13.4}/.claude/commands/release/release-check.md +0 -0
  17. {basic_memory-0.13.2 → basic_memory-0.13.4}/.claude/commands/test-coverage.md +0 -0
  18. {basic_memory-0.13.2 → basic_memory-0.13.4}/.claude/commands/test-live.md +0 -0
  19. {basic_memory-0.13.2 → basic_memory-0.13.4}/.env.oauth.example +0 -0
  20. {basic_memory-0.13.2 → basic_memory-0.13.4}/.github/ISSUE_TEMPLATE/bug_report.md +0 -0
  21. {basic_memory-0.13.2 → basic_memory-0.13.4}/.github/ISSUE_TEMPLATE/config.yml +0 -0
  22. {basic_memory-0.13.2 → basic_memory-0.13.4}/.github/ISSUE_TEMPLATE/documentation.md +0 -0
  23. {basic_memory-0.13.2 → basic_memory-0.13.4}/.github/ISSUE_TEMPLATE/feature_request.md +0 -0
  24. {basic_memory-0.13.2 → basic_memory-0.13.4}/.github/dependabot.yml +0 -0
  25. {basic_memory-0.13.2 → basic_memory-0.13.4}/.github/workflows/claude.yml +0 -0
  26. {basic_memory-0.13.2 → basic_memory-0.13.4}/.github/workflows/dev-release.yml +0 -0
  27. {basic_memory-0.13.2 → basic_memory-0.13.4}/.github/workflows/pr-title.yml +0 -0
  28. {basic_memory-0.13.2 → basic_memory-0.13.4}/.github/workflows/release.yml +0 -0
  29. {basic_memory-0.13.2 → basic_memory-0.13.4}/.github/workflows/test.yml +0 -0
  30. {basic_memory-0.13.2 → basic_memory-0.13.4}/.gitignore +0 -0
  31. {basic_memory-0.13.2 → basic_memory-0.13.4}/.mcp.json +0 -0
  32. {basic_memory-0.13.2 → basic_memory-0.13.4}/.python-version +0 -0
  33. {basic_memory-0.13.2 → basic_memory-0.13.4}/AUTH.md +0 -0
  34. {basic_memory-0.13.2 → basic_memory-0.13.4}/CITATION.cff +0 -0
  35. {basic_memory-0.13.2 → basic_memory-0.13.4}/CLA.md +0 -0
  36. {basic_memory-0.13.2 → basic_memory-0.13.4}/CLAUDE.md +0 -0
  37. {basic_memory-0.13.2 → basic_memory-0.13.4}/CODE_OF_CONDUCT.md +0 -0
  38. {basic_memory-0.13.2 → basic_memory-0.13.4}/CONTRIBUTING.md +0 -0
  39. {basic_memory-0.13.2 → basic_memory-0.13.4}/Dockerfile +0 -0
  40. {basic_memory-0.13.2 → basic_memory-0.13.4}/LICENSE +0 -0
  41. {basic_memory-0.13.2 → basic_memory-0.13.4}/README.md +0 -0
  42. {basic_memory-0.13.2 → basic_memory-0.13.4}/SECURITY.md +0 -0
  43. {basic_memory-0.13.2 → basic_memory-0.13.4}/basic-memory.md +0 -0
  44. {basic_memory-0.13.2 → basic_memory-0.13.4}/docs/AI Assistant Guide.md +0 -0
  45. {basic_memory-0.13.2 → basic_memory-0.13.4}/docs/CLI Reference.md +0 -0
  46. {basic_memory-0.13.2 → basic_memory-0.13.4}/docs/Canvas.md +0 -0
  47. {basic_memory-0.13.2 → basic_memory-0.13.4}/docs/Claude.ai Integration.md +0 -0
  48. {basic_memory-0.13.2 → basic_memory-0.13.4}/docs/Getting Started with Basic Memory.md +0 -0
  49. {basic_memory-0.13.2 → basic_memory-0.13.4}/docs/Knowledge Format.md +0 -0
  50. {basic_memory-0.13.2 → basic_memory-0.13.4}/docs/OAuth Authentication Guide.md +0 -0
  51. {basic_memory-0.13.2 → basic_memory-0.13.4}/docs/Obsidian Integration.md +0 -0
  52. {basic_memory-0.13.2 → basic_memory-0.13.4}/docs/Supabase OAuth Setup.md +0 -0
  53. {basic_memory-0.13.2 → basic_memory-0.13.4}/docs/Technical Information.md +0 -0
  54. {basic_memory-0.13.2 → basic_memory-0.13.4}/docs/User Guide.md +0 -0
  55. {basic_memory-0.13.2 → basic_memory-0.13.4}/docs/Welcome to Basic memory.md +0 -0
  56. {basic_memory-0.13.2 → basic_memory-0.13.4}/docs/attachments/Canvas.png +0 -0
  57. {basic_memory-0.13.2 → basic_memory-0.13.4}/docs/attachments/Claude-Obsidian-Demo.mp4 +0 -0
  58. {basic_memory-0.13.2 → basic_memory-0.13.4}/docs/attachments/Prompt.png +0 -0
  59. {basic_memory-0.13.2 → basic_memory-0.13.4}/docs/attachments/disk-ai-logo-400x400.png +0 -0
  60. {basic_memory-0.13.2 → basic_memory-0.13.4}/docs/attachments/disk-ai-logo.png +0 -0
  61. {basic_memory-0.13.2 → basic_memory-0.13.4}/docs/attachments/prompt 1.png +0 -0
  62. {basic_memory-0.13.2 → basic_memory-0.13.4}/docs/attachments/prompt2.png +0 -0
  63. {basic_memory-0.13.2 → basic_memory-0.13.4}/docs/attachments/prompt3.png +0 -0
  64. {basic_memory-0.13.2 → basic_memory-0.13.4}/docs/attachments/prompt4.png +0 -0
  65. {basic_memory-0.13.2 → basic_memory-0.13.4}/docs/publish.js +0 -0
  66. {basic_memory-0.13.2 → basic_memory-0.13.4}/examples/Coffee Notes/Brewing Equipment.md +0 -0
  67. {basic_memory-0.13.2 → basic_memory-0.13.4}/examples/Coffee Notes/Coffee Bean Origins.md +0 -0
  68. {basic_memory-0.13.2 → basic_memory-0.13.4}/examples/Coffee Notes/Coffee Brewing Methods.md +0 -0
  69. {basic_memory-0.13.2 → basic_memory-0.13.4}/examples/Coffee Notes/Coffee Flavor Map.md +0 -0
  70. {basic_memory-0.13.2 → basic_memory-0.13.4}/examples/Coffee Notes/Coffee Knowledge Base.md +0 -0
  71. {basic_memory-0.13.2 → basic_memory-0.13.4}/examples/Coffee Notes/Flavor Extraction.md +0 -0
  72. {basic_memory-0.13.2 → basic_memory-0.13.4}/examples/Coffee Notes/Perfect Pour Over Coffee Method.canvas +0 -0
  73. {basic_memory-0.13.2 → basic_memory-0.13.4}/examples/Coffee Notes/Tasting Notes.md +0 -0
  74. {basic_memory-0.13.2 → basic_memory-0.13.4}/examples/testing/Test Note Creation - Basic Functionality.md +0 -0
  75. {basic_memory-0.13.2 → basic_memory-0.13.4}/justfile +0 -0
  76. {basic_memory-0.13.2 → basic_memory-0.13.4}/llms-install.md +0 -0
  77. {basic_memory-0.13.2 → basic_memory-0.13.4}/memory.json +0 -0
  78. {basic_memory-0.13.2 → basic_memory-0.13.4}/pyproject.toml +0 -0
  79. {basic_memory-0.13.2 → basic_memory-0.13.4}/scripts/install.sh +0 -0
  80. {basic_memory-0.13.2 → basic_memory-0.13.4}/smithery.yaml +0 -0
  81. {basic_memory-0.13.2 → basic_memory-0.13.4}/src/basic_memory/alembic/alembic.ini +0 -0
  82. {basic_memory-0.13.2 → basic_memory-0.13.4}/src/basic_memory/alembic/env.py +0 -0
  83. {basic_memory-0.13.2 → basic_memory-0.13.4}/src/basic_memory/alembic/migrations.py +0 -0
  84. {basic_memory-0.13.2 → basic_memory-0.13.4}/src/basic_memory/alembic/script.py.mako +0 -0
  85. {basic_memory-0.13.2 → basic_memory-0.13.4}/src/basic_memory/alembic/versions/3dae7c7b1564_initial_schema.py +0 -0
  86. {basic_memory-0.13.2 → basic_memory-0.13.4}/src/basic_memory/alembic/versions/502b60eaa905_remove_required_from_entity_permalink.py +0 -0
  87. {basic_memory-0.13.2 → basic_memory-0.13.4}/src/basic_memory/alembic/versions/5fe1ab1ccebe_add_projects_table.py +0 -0
  88. {basic_memory-0.13.2 → basic_memory-0.13.4}/src/basic_memory/alembic/versions/647e7a75e2cd_project_constraint_fix.py +0 -0
  89. {basic_memory-0.13.2 → basic_memory-0.13.4}/src/basic_memory/alembic/versions/b3c3938bacdb_relation_to_name_unique_index.py +0 -0
  90. {basic_memory-0.13.2 → basic_memory-0.13.4}/src/basic_memory/alembic/versions/cc7172b46608_update_search_index_schema.py +0 -0
  91. {basic_memory-0.13.2 → basic_memory-0.13.4}/src/basic_memory/api/__init__.py +0 -0
  92. {basic_memory-0.13.2 → basic_memory-0.13.4}/src/basic_memory/api/app.py +0 -0
  93. {basic_memory-0.13.2 → basic_memory-0.13.4}/src/basic_memory/api/routers/__init__.py +0 -0
  94. {basic_memory-0.13.2 → basic_memory-0.13.4}/src/basic_memory/api/routers/directory_router.py +0 -0
  95. {basic_memory-0.13.2 → basic_memory-0.13.4}/src/basic_memory/api/routers/importer_router.py +0 -0
  96. {basic_memory-0.13.2 → basic_memory-0.13.4}/src/basic_memory/api/routers/knowledge_router.py +0 -0
  97. {basic_memory-0.13.2 → basic_memory-0.13.4}/src/basic_memory/api/routers/management_router.py +0 -0
  98. {basic_memory-0.13.2 → basic_memory-0.13.4}/src/basic_memory/api/routers/memory_router.py +0 -0
  99. {basic_memory-0.13.2 → basic_memory-0.13.4}/src/basic_memory/api/routers/project_router.py +0 -0
  100. {basic_memory-0.13.2 → basic_memory-0.13.4}/src/basic_memory/api/routers/prompt_router.py +0 -0
  101. {basic_memory-0.13.2 → basic_memory-0.13.4}/src/basic_memory/api/routers/resource_router.py +0 -0
  102. {basic_memory-0.13.2 → basic_memory-0.13.4}/src/basic_memory/api/routers/search_router.py +0 -0
  103. {basic_memory-0.13.2 → basic_memory-0.13.4}/src/basic_memory/api/routers/utils.py +0 -0
  104. {basic_memory-0.13.2 → basic_memory-0.13.4}/src/basic_memory/api/template_loader.py +0 -0
  105. {basic_memory-0.13.2 → basic_memory-0.13.4}/src/basic_memory/cli/__init__.py +0 -0
  106. {basic_memory-0.13.2 → basic_memory-0.13.4}/src/basic_memory/cli/app.py +0 -0
  107. {basic_memory-0.13.2 → basic_memory-0.13.4}/src/basic_memory/cli/commands/__init__.py +0 -0
  108. {basic_memory-0.13.2 → basic_memory-0.13.4}/src/basic_memory/cli/commands/auth.py +0 -0
  109. {basic_memory-0.13.2 → basic_memory-0.13.4}/src/basic_memory/cli/commands/db.py +0 -0
  110. {basic_memory-0.13.2 → basic_memory-0.13.4}/src/basic_memory/cli/commands/import_chatgpt.py +0 -0
  111. {basic_memory-0.13.2 → basic_memory-0.13.4}/src/basic_memory/cli/commands/import_claude_conversations.py +0 -0
  112. {basic_memory-0.13.2 → basic_memory-0.13.4}/src/basic_memory/cli/commands/import_claude_projects.py +0 -0
  113. {basic_memory-0.13.2 → basic_memory-0.13.4}/src/basic_memory/cli/commands/import_memory_json.py +0 -0
  114. {basic_memory-0.13.2 → basic_memory-0.13.4}/src/basic_memory/cli/commands/mcp.py +0 -0
  115. {basic_memory-0.13.2 → basic_memory-0.13.4}/src/basic_memory/cli/commands/project.py +0 -0
  116. {basic_memory-0.13.2 → basic_memory-0.13.4}/src/basic_memory/cli/commands/status.py +0 -0
  117. {basic_memory-0.13.2 → basic_memory-0.13.4}/src/basic_memory/cli/commands/sync.py +0 -0
  118. {basic_memory-0.13.2 → basic_memory-0.13.4}/src/basic_memory/cli/commands/tool.py +0 -0
  119. {basic_memory-0.13.2 → basic_memory-0.13.4}/src/basic_memory/cli/main.py +0 -0
  120. {basic_memory-0.13.2 → basic_memory-0.13.4}/src/basic_memory/db.py +0 -0
  121. {basic_memory-0.13.2 → basic_memory-0.13.4}/src/basic_memory/deps.py +0 -0
  122. {basic_memory-0.13.2 → basic_memory-0.13.4}/src/basic_memory/file_utils.py +0 -0
  123. {basic_memory-0.13.2 → basic_memory-0.13.4}/src/basic_memory/importers/__init__.py +0 -0
  124. {basic_memory-0.13.2 → basic_memory-0.13.4}/src/basic_memory/importers/base.py +0 -0
  125. {basic_memory-0.13.2 → basic_memory-0.13.4}/src/basic_memory/importers/chatgpt_importer.py +0 -0
  126. {basic_memory-0.13.2 → basic_memory-0.13.4}/src/basic_memory/importers/claude_conversations_importer.py +0 -0
  127. {basic_memory-0.13.2 → basic_memory-0.13.4}/src/basic_memory/importers/claude_projects_importer.py +0 -0
  128. {basic_memory-0.13.2 → basic_memory-0.13.4}/src/basic_memory/importers/memory_json_importer.py +0 -0
  129. {basic_memory-0.13.2 → basic_memory-0.13.4}/src/basic_memory/importers/utils.py +0 -0
  130. {basic_memory-0.13.2 → basic_memory-0.13.4}/src/basic_memory/markdown/__init__.py +0 -0
  131. {basic_memory-0.13.2 → basic_memory-0.13.4}/src/basic_memory/markdown/entity_parser.py +0 -0
  132. {basic_memory-0.13.2 → basic_memory-0.13.4}/src/basic_memory/markdown/markdown_processor.py +0 -0
  133. {basic_memory-0.13.2 → basic_memory-0.13.4}/src/basic_memory/markdown/plugins.py +0 -0
  134. {basic_memory-0.13.2 → basic_memory-0.13.4}/src/basic_memory/markdown/schemas.py +0 -0
  135. {basic_memory-0.13.2 → basic_memory-0.13.4}/src/basic_memory/markdown/utils.py +0 -0
  136. {basic_memory-0.13.2 → basic_memory-0.13.4}/src/basic_memory/mcp/__init__.py +0 -0
  137. {basic_memory-0.13.2 → basic_memory-0.13.4}/src/basic_memory/mcp/async_client.py +0 -0
  138. {basic_memory-0.13.2 → basic_memory-0.13.4}/src/basic_memory/mcp/auth_provider.py +0 -0
  139. {basic_memory-0.13.2 → basic_memory-0.13.4}/src/basic_memory/mcp/external_auth_provider.py +0 -0
  140. {basic_memory-0.13.2 → basic_memory-0.13.4}/src/basic_memory/mcp/project_session.py +0 -0
  141. {basic_memory-0.13.2 → basic_memory-0.13.4}/src/basic_memory/mcp/prompts/__init__.py +0 -0
  142. {basic_memory-0.13.2 → basic_memory-0.13.4}/src/basic_memory/mcp/prompts/ai_assistant_guide.py +0 -0
  143. {basic_memory-0.13.2 → basic_memory-0.13.4}/src/basic_memory/mcp/prompts/continue_conversation.py +0 -0
  144. {basic_memory-0.13.2 → basic_memory-0.13.4}/src/basic_memory/mcp/prompts/recent_activity.py +0 -0
  145. {basic_memory-0.13.2 → basic_memory-0.13.4}/src/basic_memory/mcp/prompts/search.py +0 -0
  146. {basic_memory-0.13.2 → basic_memory-0.13.4}/src/basic_memory/mcp/prompts/sync_status.py +0 -0
  147. {basic_memory-0.13.2 → basic_memory-0.13.4}/src/basic_memory/mcp/prompts/utils.py +0 -0
  148. {basic_memory-0.13.2 → basic_memory-0.13.4}/src/basic_memory/mcp/resources/ai_assistant_guide.md +0 -0
  149. {basic_memory-0.13.2 → basic_memory-0.13.4}/src/basic_memory/mcp/resources/project_info.py +0 -0
  150. {basic_memory-0.13.2 → basic_memory-0.13.4}/src/basic_memory/mcp/server.py +0 -0
  151. {basic_memory-0.13.2 → basic_memory-0.13.4}/src/basic_memory/mcp/supabase_auth_provider.py +0 -0
  152. {basic_memory-0.13.2 → basic_memory-0.13.4}/src/basic_memory/mcp/tools/build_context.py +0 -0
  153. {basic_memory-0.13.2 → basic_memory-0.13.4}/src/basic_memory/mcp/tools/canvas.py +0 -0
  154. {basic_memory-0.13.2 → basic_memory-0.13.4}/src/basic_memory/mcp/tools/delete_note.py +0 -0
  155. {basic_memory-0.13.2 → basic_memory-0.13.4}/src/basic_memory/mcp/tools/edit_note.py +0 -0
  156. {basic_memory-0.13.2 → basic_memory-0.13.4}/src/basic_memory/mcp/tools/list_directory.py +0 -0
  157. {basic_memory-0.13.2 → basic_memory-0.13.4}/src/basic_memory/mcp/tools/move_note.py +0 -0
  158. {basic_memory-0.13.2 → basic_memory-0.13.4}/src/basic_memory/mcp/tools/read_content.py +0 -0
  159. {basic_memory-0.13.2 → basic_memory-0.13.4}/src/basic_memory/mcp/tools/read_note.py +0 -0
  160. {basic_memory-0.13.2 → basic_memory-0.13.4}/src/basic_memory/mcp/tools/recent_activity.py +0 -0
  161. {basic_memory-0.13.2 → basic_memory-0.13.4}/src/basic_memory/mcp/tools/search.py +0 -0
  162. {basic_memory-0.13.2 → basic_memory-0.13.4}/src/basic_memory/mcp/tools/sync_status.py +0 -0
  163. {basic_memory-0.13.2 → basic_memory-0.13.4}/src/basic_memory/mcp/tools/utils.py +0 -0
  164. {basic_memory-0.13.2 → basic_memory-0.13.4}/src/basic_memory/mcp/tools/view_note.py +0 -0
  165. {basic_memory-0.13.2 → basic_memory-0.13.4}/src/basic_memory/mcp/tools/write_note.py +0 -0
  166. {basic_memory-0.13.2 → basic_memory-0.13.4}/src/basic_memory/models/__init__.py +0 -0
  167. {basic_memory-0.13.2 → basic_memory-0.13.4}/src/basic_memory/models/base.py +0 -0
  168. {basic_memory-0.13.2 → basic_memory-0.13.4}/src/basic_memory/models/knowledge.py +0 -0
  169. {basic_memory-0.13.2 → basic_memory-0.13.4}/src/basic_memory/models/project.py +0 -0
  170. {basic_memory-0.13.2 → basic_memory-0.13.4}/src/basic_memory/models/search.py +0 -0
  171. {basic_memory-0.13.2 → basic_memory-0.13.4}/src/basic_memory/repository/__init__.py +0 -0
  172. {basic_memory-0.13.2 → basic_memory-0.13.4}/src/basic_memory/repository/entity_repository.py +0 -0
  173. {basic_memory-0.13.2 → basic_memory-0.13.4}/src/basic_memory/repository/observation_repository.py +0 -0
  174. {basic_memory-0.13.2 → basic_memory-0.13.4}/src/basic_memory/repository/project_info_repository.py +0 -0
  175. {basic_memory-0.13.2 → basic_memory-0.13.4}/src/basic_memory/repository/project_repository.py +0 -0
  176. {basic_memory-0.13.2 → basic_memory-0.13.4}/src/basic_memory/repository/relation_repository.py +0 -0
  177. {basic_memory-0.13.2 → basic_memory-0.13.4}/src/basic_memory/repository/repository.py +0 -0
  178. {basic_memory-0.13.2 → basic_memory-0.13.4}/src/basic_memory/repository/search_repository.py +0 -0
  179. {basic_memory-0.13.2 → basic_memory-0.13.4}/src/basic_memory/schemas/__init__.py +0 -0
  180. {basic_memory-0.13.2 → basic_memory-0.13.4}/src/basic_memory/schemas/base.py +0 -0
  181. {basic_memory-0.13.2 → basic_memory-0.13.4}/src/basic_memory/schemas/delete.py +0 -0
  182. {basic_memory-0.13.2 → basic_memory-0.13.4}/src/basic_memory/schemas/directory.py +0 -0
  183. {basic_memory-0.13.2 → basic_memory-0.13.4}/src/basic_memory/schemas/importer.py +0 -0
  184. {basic_memory-0.13.2 → basic_memory-0.13.4}/src/basic_memory/schemas/memory.py +0 -0
  185. {basic_memory-0.13.2 → basic_memory-0.13.4}/src/basic_memory/schemas/prompt.py +0 -0
  186. {basic_memory-0.13.2 → basic_memory-0.13.4}/src/basic_memory/schemas/request.py +0 -0
  187. {basic_memory-0.13.2 → basic_memory-0.13.4}/src/basic_memory/schemas/response.py +0 -0
  188. {basic_memory-0.13.2 → basic_memory-0.13.4}/src/basic_memory/schemas/search.py +0 -0
  189. {basic_memory-0.13.2 → basic_memory-0.13.4}/src/basic_memory/services/__init__.py +0 -0
  190. {basic_memory-0.13.2 → basic_memory-0.13.4}/src/basic_memory/services/context_service.py +0 -0
  191. {basic_memory-0.13.2 → basic_memory-0.13.4}/src/basic_memory/services/directory_service.py +0 -0
  192. {basic_memory-0.13.2 → basic_memory-0.13.4}/src/basic_memory/services/entity_service.py +0 -0
  193. {basic_memory-0.13.2 → basic_memory-0.13.4}/src/basic_memory/services/exceptions.py +0 -0
  194. {basic_memory-0.13.2 → basic_memory-0.13.4}/src/basic_memory/services/file_service.py +0 -0
  195. {basic_memory-0.13.2 → basic_memory-0.13.4}/src/basic_memory/services/initialization.py +0 -0
  196. {basic_memory-0.13.2 → basic_memory-0.13.4}/src/basic_memory/services/link_resolver.py +0 -0
  197. {basic_memory-0.13.2 → basic_memory-0.13.4}/src/basic_memory/services/migration_service.py +0 -0
  198. {basic_memory-0.13.2 → basic_memory-0.13.4}/src/basic_memory/services/search_service.py +0 -0
  199. {basic_memory-0.13.2 → basic_memory-0.13.4}/src/basic_memory/services/service.py +0 -0
  200. {basic_memory-0.13.2 → basic_memory-0.13.4}/src/basic_memory/services/sync_status_service.py +0 -0
  201. {basic_memory-0.13.2 → basic_memory-0.13.4}/src/basic_memory/sync/__init__.py +0 -0
  202. {basic_memory-0.13.2 → basic_memory-0.13.4}/src/basic_memory/sync/background_sync.py +0 -0
  203. {basic_memory-0.13.2 → basic_memory-0.13.4}/src/basic_memory/sync/sync_service.py +0 -0
  204. {basic_memory-0.13.2 → basic_memory-0.13.4}/src/basic_memory/sync/watch_service.py +0 -0
  205. {basic_memory-0.13.2 → basic_memory-0.13.4}/src/basic_memory/templates/prompts/continue_conversation.hbs +0 -0
  206. {basic_memory-0.13.2 → basic_memory-0.13.4}/src/basic_memory/templates/prompts/search.hbs +0 -0
  207. {basic_memory-0.13.2 → basic_memory-0.13.4}/src/basic_memory/utils.py +0 -0
  208. {basic_memory-0.13.2 → basic_memory-0.13.4}/static/ai_assistant_guide.md +0 -0
  209. {basic_memory-0.13.2 → basic_memory-0.13.4}/static/json_canvas_spec_1_0.md +0 -0
  210. {basic_memory-0.13.2 → basic_memory-0.13.4}/test-int/conftest.py +0 -0
  211. {basic_memory-0.13.2 → basic_memory-0.13.4}/test-int/mcp/test_build_context_validation.py +0 -0
  212. {basic_memory-0.13.2 → basic_memory-0.13.4}/test-int/mcp/test_delete_note_integration.py +0 -0
  213. {basic_memory-0.13.2 → basic_memory-0.13.4}/test-int/mcp/test_edit_note_integration.py +0 -0
  214. {basic_memory-0.13.2 → basic_memory-0.13.4}/test-int/mcp/test_list_directory_integration.py +0 -0
  215. {basic_memory-0.13.2 → basic_memory-0.13.4}/test-int/mcp/test_move_note_integration.py +0 -0
  216. {basic_memory-0.13.2 → basic_memory-0.13.4}/test-int/mcp/test_read_content_integration.py +0 -0
  217. {basic_memory-0.13.2 → basic_memory-0.13.4}/test-int/mcp/test_read_note_integration.py +0 -0
  218. {basic_memory-0.13.2 → basic_memory-0.13.4}/test-int/mcp/test_search_integration.py +0 -0
  219. {basic_memory-0.13.2 → basic_memory-0.13.4}/test-int/mcp/test_write_note_integration.py +0 -0
  220. {basic_memory-0.13.2 → basic_memory-0.13.4}/tests/Non-MarkdownFileSupport.pdf +0 -0
  221. {basic_memory-0.13.2 → basic_memory-0.13.4}/tests/Screenshot.png +0 -0
  222. {basic_memory-0.13.2 → basic_memory-0.13.4}/tests/__init__.py +0 -0
  223. {basic_memory-0.13.2 → basic_memory-0.13.4}/tests/api/conftest.py +0 -0
  224. {basic_memory-0.13.2 → basic_memory-0.13.4}/tests/api/test_continue_conversation_template.py +0 -0
  225. {basic_memory-0.13.2 → basic_memory-0.13.4}/tests/api/test_directory_router.py +0 -0
  226. {basic_memory-0.13.2 → basic_memory-0.13.4}/tests/api/test_importer_router.py +0 -0
  227. {basic_memory-0.13.2 → basic_memory-0.13.4}/tests/api/test_knowledge_router.py +0 -0
  228. {basic_memory-0.13.2 → basic_memory-0.13.4}/tests/api/test_management_router.py +0 -0
  229. {basic_memory-0.13.2 → basic_memory-0.13.4}/tests/api/test_memory_router.py +0 -0
  230. {basic_memory-0.13.2 → basic_memory-0.13.4}/tests/api/test_project_router.py +0 -0
  231. {basic_memory-0.13.2 → basic_memory-0.13.4}/tests/api/test_project_router_operations.py +0 -0
  232. {basic_memory-0.13.2 → basic_memory-0.13.4}/tests/api/test_prompt_router.py +0 -0
  233. {basic_memory-0.13.2 → basic_memory-0.13.4}/tests/api/test_resource_router.py +0 -0
  234. {basic_memory-0.13.2 → basic_memory-0.13.4}/tests/api/test_search_router.py +0 -0
  235. {basic_memory-0.13.2 → basic_memory-0.13.4}/tests/api/test_search_template.py +0 -0
  236. {basic_memory-0.13.2 → basic_memory-0.13.4}/tests/api/test_template_loader.py +0 -0
  237. {basic_memory-0.13.2 → basic_memory-0.13.4}/tests/api/test_template_loader_helpers.py +0 -0
  238. {basic_memory-0.13.2 → basic_memory-0.13.4}/tests/cli/conftest.py +0 -0
  239. {basic_memory-0.13.2 → basic_memory-0.13.4}/tests/cli/test_auth_commands.py +0 -0
  240. {basic_memory-0.13.2 → basic_memory-0.13.4}/tests/cli/test_cli_tools.py +0 -0
  241. {basic_memory-0.13.2 → basic_memory-0.13.4}/tests/cli/test_import_chatgpt.py +0 -0
  242. {basic_memory-0.13.2 → basic_memory-0.13.4}/tests/cli/test_import_claude_conversations.py +0 -0
  243. {basic_memory-0.13.2 → basic_memory-0.13.4}/tests/cli/test_import_claude_projects.py +0 -0
  244. {basic_memory-0.13.2 → basic_memory-0.13.4}/tests/cli/test_import_memory_json.py +0 -0
  245. {basic_memory-0.13.2 → basic_memory-0.13.4}/tests/cli/test_project_commands.py +0 -0
  246. {basic_memory-0.13.2 → basic_memory-0.13.4}/tests/cli/test_project_info.py +0 -0
  247. {basic_memory-0.13.2 → basic_memory-0.13.4}/tests/cli/test_status.py +0 -0
  248. {basic_memory-0.13.2 → basic_memory-0.13.4}/tests/cli/test_sync.py +0 -0
  249. {basic_memory-0.13.2 → basic_memory-0.13.4}/tests/cli/test_version.py +0 -0
  250. {basic_memory-0.13.2 → basic_memory-0.13.4}/tests/conftest.py +0 -0
  251. {basic_memory-0.13.2 → basic_memory-0.13.4}/tests/importers/test_importer_base.py +0 -0
  252. {basic_memory-0.13.2 → basic_memory-0.13.4}/tests/importers/test_importer_utils.py +0 -0
  253. {basic_memory-0.13.2 → basic_memory-0.13.4}/tests/markdown/__init__.py +0 -0
  254. {basic_memory-0.13.2 → basic_memory-0.13.4}/tests/markdown/test_entity_parser.py +0 -0
  255. {basic_memory-0.13.2 → basic_memory-0.13.4}/tests/markdown/test_markdown_plugins.py +0 -0
  256. {basic_memory-0.13.2 → basic_memory-0.13.4}/tests/markdown/test_markdown_processor.py +0 -0
  257. {basic_memory-0.13.2 → basic_memory-0.13.4}/tests/markdown/test_observation_edge_cases.py +0 -0
  258. {basic_memory-0.13.2 → basic_memory-0.13.4}/tests/markdown/test_parser_edge_cases.py +0 -0
  259. {basic_memory-0.13.2 → basic_memory-0.13.4}/tests/markdown/test_relation_edge_cases.py +0 -0
  260. {basic_memory-0.13.2 → basic_memory-0.13.4}/tests/markdown/test_task_detection.py +0 -0
  261. {basic_memory-0.13.2 → basic_memory-0.13.4}/tests/mcp/conftest.py +0 -0
  262. {basic_memory-0.13.2 → basic_memory-0.13.4}/tests/mcp/test_auth_provider.py +0 -0
  263. {basic_memory-0.13.2 → basic_memory-0.13.4}/tests/mcp/test_prompts.py +0 -0
  264. {basic_memory-0.13.2 → basic_memory-0.13.4}/tests/mcp/test_resource_project_info.py +0 -0
  265. {basic_memory-0.13.2 → basic_memory-0.13.4}/tests/mcp/test_resources.py +0 -0
  266. {basic_memory-0.13.2 → basic_memory-0.13.4}/tests/mcp/test_server.py +0 -0
  267. {basic_memory-0.13.2 → basic_memory-0.13.4}/tests/mcp/test_tool_build_context.py +0 -0
  268. {basic_memory-0.13.2 → basic_memory-0.13.4}/tests/mcp/test_tool_canvas.py +0 -0
  269. {basic_memory-0.13.2 → basic_memory-0.13.4}/tests/mcp/test_tool_delete_note.py +0 -0
  270. {basic_memory-0.13.2 → basic_memory-0.13.4}/tests/mcp/test_tool_edit_note.py +0 -0
  271. {basic_memory-0.13.2 → basic_memory-0.13.4}/tests/mcp/test_tool_list_directory.py +0 -0
  272. {basic_memory-0.13.2 → basic_memory-0.13.4}/tests/mcp/test_tool_move_note.py +0 -0
  273. {basic_memory-0.13.2 → basic_memory-0.13.4}/tests/mcp/test_tool_read_note.py +0 -0
  274. {basic_memory-0.13.2 → basic_memory-0.13.4}/tests/mcp/test_tool_recent_activity.py +0 -0
  275. {basic_memory-0.13.2 → basic_memory-0.13.4}/tests/mcp/test_tool_resource.py +0 -0
  276. {basic_memory-0.13.2 → basic_memory-0.13.4}/tests/mcp/test_tool_search.py +0 -0
  277. {basic_memory-0.13.2 → basic_memory-0.13.4}/tests/mcp/test_tool_sync_status.py +0 -0
  278. {basic_memory-0.13.2 → basic_memory-0.13.4}/tests/mcp/test_tool_utils.py +0 -0
  279. {basic_memory-0.13.2 → basic_memory-0.13.4}/tests/mcp/test_tool_view_note.py +0 -0
  280. {basic_memory-0.13.2 → basic_memory-0.13.4}/tests/mcp/test_tool_write_note.py +0 -0
  281. {basic_memory-0.13.2 → basic_memory-0.13.4}/tests/repository/test_entity_repository.py +0 -0
  282. {basic_memory-0.13.2 → basic_memory-0.13.4}/tests/repository/test_observation_repository.py +0 -0
  283. {basic_memory-0.13.2 → basic_memory-0.13.4}/tests/repository/test_project_info_repository.py +0 -0
  284. {basic_memory-0.13.2 → basic_memory-0.13.4}/tests/repository/test_project_repository.py +0 -0
  285. {basic_memory-0.13.2 → basic_memory-0.13.4}/tests/repository/test_relation_repository.py +0 -0
  286. {basic_memory-0.13.2 → basic_memory-0.13.4}/tests/repository/test_repository.py +0 -0
  287. {basic_memory-0.13.2 → basic_memory-0.13.4}/tests/repository/test_search_repository.py +0 -0
  288. {basic_memory-0.13.2 → basic_memory-0.13.4}/tests/schemas/test_memory_url.py +0 -0
  289. {basic_memory-0.13.2 → basic_memory-0.13.4}/tests/schemas/test_memory_url_validation.py +0 -0
  290. {basic_memory-0.13.2 → basic_memory-0.13.4}/tests/schemas/test_schemas.py +0 -0
  291. {basic_memory-0.13.2 → basic_memory-0.13.4}/tests/schemas/test_search.py +0 -0
  292. {basic_memory-0.13.2 → basic_memory-0.13.4}/tests/services/test_context_service.py +0 -0
  293. {basic_memory-0.13.2 → basic_memory-0.13.4}/tests/services/test_directory_service.py +0 -0
  294. {basic_memory-0.13.2 → basic_memory-0.13.4}/tests/services/test_entity_service.py +0 -0
  295. {basic_memory-0.13.2 → basic_memory-0.13.4}/tests/services/test_file_service.py +0 -0
  296. {basic_memory-0.13.2 → basic_memory-0.13.4}/tests/services/test_initialization.py +0 -0
  297. {basic_memory-0.13.2 → basic_memory-0.13.4}/tests/services/test_link_resolver.py +0 -0
  298. {basic_memory-0.13.2 → basic_memory-0.13.4}/tests/services/test_project_service.py +0 -0
  299. {basic_memory-0.13.2 → basic_memory-0.13.4}/tests/services/test_project_service_operations.py +0 -0
  300. {basic_memory-0.13.2 → basic_memory-0.13.4}/tests/services/test_search_service.py +0 -0
  301. {basic_memory-0.13.2 → basic_memory-0.13.4}/tests/services/test_sync_status_service.py +0 -0
  302. {basic_memory-0.13.2 → basic_memory-0.13.4}/tests/sync/test_sync_service.py +0 -0
  303. {basic_memory-0.13.2 → basic_memory-0.13.4}/tests/sync/test_sync_wikilink_issue.py +0 -0
  304. {basic_memory-0.13.2 → basic_memory-0.13.4}/tests/sync/test_tmp_files.py +0 -0
  305. {basic_memory-0.13.2 → basic_memory-0.13.4}/tests/sync/test_watch_service.py +0 -0
  306. {basic_memory-0.13.2 → basic_memory-0.13.4}/tests/sync/test_watch_service_edge_cases.py +0 -0
  307. {basic_memory-0.13.2 → basic_memory-0.13.4}/tests/utils/test_file_utils.py +0 -0
  308. {basic_memory-0.13.2 → basic_memory-0.13.4}/tests/utils/test_parse_tags.py +0 -0
  309. {basic_memory-0.13.2 → basic_memory-0.13.4}/tests/utils/test_permalink_formatting.py +0 -0
  310. {basic_memory-0.13.2 → basic_memory-0.13.4}/tests/utils/test_utf8_handling.py +0 -0
  311. {basic_memory-0.13.2 → basic_memory-0.13.4}/uv.lock +0 -0
@@ -20,6 +20,12 @@ You are an expert release manager for the Basic Memory project. When the user ru
20
20
  3. Verify we're on the `main` branch
21
21
  4. Confirm no existing tag with this version
22
22
 
23
+ #### Documentation Validation
24
+ 1. **Changelog Check**
25
+ - CHANGELOG.md contains entry for target version
26
+ - Entry includes all major features and fixes
27
+ - Breaking changes are documented
28
+
23
29
  ### Step 2: Use Justfile Automation
24
30
  Execute the automated release process:
25
31
  ```bash
@@ -1,5 +1,60 @@
1
1
  # CHANGELOG
2
2
 
3
+ ## v0.13.4 (2025-06-11)
4
+
5
+ ### Bug Fixes
6
+
7
+ - **MCP Tools**: Renamed `list_projects` tool to `list_memory_projects` to avoid naming conflicts with other MCP servers
8
+ - **Namespace**: Improved tool naming specificity for better MCP server integration and isolation
9
+
10
+ ### Changes
11
+
12
+ - Tool functionality remains identical - only the name changed from `list_projects` to `list_memory_projects`
13
+ - All integration tests updated to use the new tool name
14
+ - Better namespace isolation for Basic Memory MCP tools
15
+
16
+ ## v0.13.3 (2025-06-11)
17
+
18
+ ### Bug Fixes
19
+
20
+ - **Projects**: Fixed case-insensitive project switching where switching succeeded but subsequent operations failed due to session state inconsistency
21
+ - **Config**: Enhanced config manager with case-insensitive project lookup using permalink-based matching
22
+ - **MCP Tools**: Updated project management tools to store canonical project names from database instead of user input
23
+ - **API**: Improved project service to handle both name and permalink lookups consistently
24
+
25
+ ### Technical Improvements
26
+
27
+ - Added comprehensive case-insensitive project switching test coverage with 5 new integration test scenarios
28
+ - Fixed permalink generation inconsistencies where different case inputs could generate different permalinks
29
+ - Enhanced project URL construction to use permalinks consistently across all API calls
30
+ - Improved error handling and session state management for project operations
31
+
32
+ ### Changes
33
+
34
+ - Project switching now preserves canonical project names from database in session state
35
+ - All project operations use permalink-based lookups for case-insensitive matching
36
+ - Enhanced test coverage ensures reliable case-insensitive project operations
37
+
38
+ ## v0.13.2 (2025-06-11)
39
+
40
+ ### Features
41
+
42
+ - **Release Management**: Added automated release management system with version control in `__init__.py`
43
+ - **Automation**: Implemented justfile targets for `release` and `beta` commands with comprehensive quality gates
44
+ - **CI/CD**: Enhanced release process with automatic version updates, git tagging, and GitHub release creation
45
+
46
+ ### Development Experience
47
+
48
+ - Added `.claude/commands/release/` directory with automation documentation
49
+ - Implemented release validation including lint, type-check, and test execution
50
+ - Streamlined release workflow from manual process to single-command automation
51
+
52
+ ### Technical Improvements
53
+
54
+ - Updated package version management to use actual version numbers instead of dynamic versioning
55
+ - Added release process documentation and command references
56
+ - Enhanced justfile with comprehensive release automation targets
57
+
3
58
  ## v0.13.1 (2025-06-11)
4
59
 
5
60
  ### Bug Fixes
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: basic-memory
3
- Version: 0.13.2
3
+ Version: 0.13.4
4
4
  Summary: Local-first knowledge management combining Zettelkasten with knowledge graphs
5
5
  Project-URL: Homepage, https://github.com/basicmachines-co/basic-memory
6
6
  Project-URL: Repository, https://github.com/basicmachines-co/basic-memory
@@ -1,7 +1,7 @@
1
1
  """basic-memory - Local-first knowledge management combining Zettelkasten with knowledge graphs"""
2
2
 
3
3
  # Package version - updated by release automation
4
- __version__ = "0.13.2"
4
+ __version__ = "0.13.4"
5
5
 
6
6
  # API version for FastAPI - independent of package version
7
7
  __api_version__ = "v0"
@@ -4,7 +4,7 @@ import json
4
4
  import os
5
5
  from dataclasses import dataclass
6
6
  from pathlib import Path
7
- from typing import Any, Dict, Literal, Optional, List
7
+ from typing import Any, Dict, Literal, Optional, List, Tuple
8
8
 
9
9
  from loguru import logger
10
10
  from pydantic import Field, field_validator
@@ -196,7 +196,8 @@ class ConfigManager:
196
196
 
197
197
  def add_project(self, name: str, path: str) -> ProjectConfig:
198
198
  """Add a new project to the configuration."""
199
- if name in self.config.projects: # pragma: no cover
199
+ project_name, _ = self.get_project(name)
200
+ if project_name: # pragma: no cover
200
201
  raise ValueError(f"Project '{name}' already exists")
201
202
 
202
203
  # Ensure the path exists
@@ -209,10 +210,12 @@ class ConfigManager:
209
210
 
210
211
  def remove_project(self, name: str) -> None:
211
212
  """Remove a project from the configuration."""
212
- if name not in self.config.projects: # pragma: no cover
213
+
214
+ project_name, path = self.get_project(name)
215
+ if not project_name: # pragma: no cover
213
216
  raise ValueError(f"Project '{name}' not found")
214
217
 
215
- if name == self.config.default_project: # pragma: no cover
218
+ if project_name == self.config.default_project: # pragma: no cover
216
219
  raise ValueError(f"Cannot remove the default project '{name}'")
217
220
 
218
221
  del self.config.projects[name]
@@ -220,12 +223,21 @@ class ConfigManager:
220
223
 
221
224
  def set_default_project(self, name: str) -> None:
222
225
  """Set the default project."""
223
- if name not in self.config.projects: # pragma: no cover
226
+ project_name, path = self.get_project(name)
227
+ if not project_name: # pragma: no cover
224
228
  raise ValueError(f"Project '{name}' not found")
225
229
 
226
230
  self.config.default_project = name
227
231
  self.save_config(self.config)
228
232
 
233
+ def get_project(self, name: str) -> Tuple[str, str] | Tuple[None, None]:
234
+ """Look up a project from the configuration by name or permalink"""
235
+ project_permalink = generate_permalink(name)
236
+ for name, path in app_config.projects.items():
237
+ if project_permalink == generate_permalink(name):
238
+ return name, path
239
+ return None, None
240
+
229
241
 
230
242
  def get_project_config(project_name: Optional[str] = None) -> ProjectConfig:
231
243
  """
@@ -256,11 +268,14 @@ def get_project_config(project_name: Optional[str] = None) -> ProjectConfig:
256
268
  # the config contains a dict[str,str] of project names and absolute paths
257
269
  assert actual_project_name is not None, "actual_project_name cannot be None"
258
270
 
259
- project_path = app_config.projects.get(actual_project_name)
260
- if not project_path: # pragma: no cover
261
- raise ValueError(f"Project '{actual_project_name}' not found")
271
+ project_permalink = generate_permalink(actual_project_name)
272
+
273
+ for name, path in app_config.projects.items():
274
+ if project_permalink == generate_permalink(name):
275
+ return ProjectConfig(name=name, home=Path(path))
262
276
 
263
- return ProjectConfig(name=actual_project_name, home=Path(project_path))
277
+ # otherwise raise error
278
+ raise ValueError(f"Project '{actual_project_name}' not found") # pragma: no cover
264
279
 
265
280
 
266
281
  # Create config manager
@@ -48,4 +48,4 @@ __all__ = [
48
48
  "sync_status",
49
49
  "view_note",
50
50
  "write_note",
51
- ]
51
+ ]
@@ -9,7 +9,6 @@ from textwrap import dedent
9
9
  from fastmcp import Context
10
10
  from loguru import logger
11
11
 
12
- from basic_memory.config import get_project_config
13
12
  from basic_memory.mcp.async_client import client
14
13
  from basic_memory.mcp.project_session import session, add_project_metadata
15
14
  from basic_memory.mcp.server import mcp
@@ -19,7 +18,7 @@ from basic_memory.schemas.project_info import ProjectList, ProjectStatusResponse
19
18
  from basic_memory.utils import generate_permalink
20
19
 
21
20
 
22
- @mcp.tool()
21
+ @mcp.tool("list_memory_projects")
23
22
  async def list_projects(ctx: Context | None = None) -> str:
24
23
  """List all available projects with their status.
25
24
 
@@ -85,27 +84,38 @@ async def switch_project(project_name: str, ctx: Context | None = None) -> str:
85
84
  response = await call_get(client, "/projects/projects")
86
85
  project_list = ProjectList.model_validate(response.json())
87
86
 
88
- # Check if project exists
89
- project_exists = any(p.permalink == project_permalink for p in project_list.projects)
90
- if not project_exists:
87
+ # Find the project by name (case-insensitive) or permalink
88
+ target_project = None
89
+ for p in project_list.projects:
90
+ # Match by permalink (handles case-insensitive input)
91
+ if p.permalink == project_permalink:
92
+ target_project = p
93
+ break
94
+ # Also match by name comparison (case-insensitive)
95
+ if p.name.lower() == project_name.lower():
96
+ target_project = p
97
+ break
98
+
99
+ if not target_project:
91
100
  available_projects = [p.name for p in project_list.projects]
92
101
  return f"Error: Project '{project_name}' not found. Available projects: {', '.join(available_projects)}"
93
102
 
94
- # Switch to the project
95
- session.set_current_project(project_permalink)
103
+ # Switch to the project using the canonical name from database
104
+ canonical_name = target_project.name
105
+ session.set_current_project(canonical_name)
96
106
  current_project = session.get_current_project()
97
- project_config = get_project_config(current_project)
98
107
 
99
108
  # Get project info to show summary
100
109
  try:
110
+ current_project_permalink = generate_permalink(canonical_name)
101
111
  response = await call_get(
102
112
  client,
103
- f"{project_config.project_url}/project/info",
104
- params={"project_name": project_permalink},
113
+ f"/{current_project_permalink}/project/info",
114
+ params={"project_name": canonical_name},
105
115
  )
106
116
  project_info = ProjectInfoResponse.model_validate(response.json())
107
117
 
108
- result = f"✓ Switched to {project_permalink} project\n\n"
118
+ result = f"✓ Switched to {canonical_name} project\n\n"
109
119
  result += "Project Summary:\n"
110
120
  result += f"• {project_info.statistics.total_entities} entities\n"
111
121
  result += f"• {project_info.statistics.total_observations} observations\n"
@@ -113,11 +123,11 @@ async def switch_project(project_name: str, ctx: Context | None = None) -> str:
113
123
 
114
124
  except Exception as e:
115
125
  # If we can't get project info, still confirm the switch
116
- logger.warning(f"Could not get project info for {project_name}: {e}")
117
- result = f"✓ Switched to {project_name} project\n\n"
126
+ logger.warning(f"Could not get project info for {canonical_name}: {e}")
127
+ result = f"✓ Switched to {canonical_name} project\n\n"
118
128
  result += "Project summary unavailable.\n"
119
129
 
120
- return add_project_metadata(result, project_name)
130
+ return add_project_metadata(result, canonical_name)
121
131
 
122
132
  except Exception as e:
123
133
  logger.error(f"Error switching to project {project_name}: {e}")
@@ -165,13 +175,13 @@ async def get_current_project(ctx: Context | None = None) -> str:
165
175
  await ctx.info("Getting current project information")
166
176
 
167
177
  current_project = session.get_current_project()
168
- project_config = get_project_config(current_project)
169
178
  result = f"Current project: {current_project}\n\n"
170
179
 
171
- # get project stats
180
+ # get project stats (use permalink in URL path)
181
+ current_project_permalink = generate_permalink(current_project)
172
182
  response = await call_get(
173
183
  client,
174
- f"{project_config.project_url}/project/info",
184
+ f"/{current_project_permalink}/project/info",
175
185
  params={"project_name": current_project},
176
186
  )
177
187
  project_info = ProjectInfoResponse.model_validate(response.json())
@@ -185,9 +185,9 @@ class ProjectItem(BaseModel):
185
185
  name: str
186
186
  path: str
187
187
  is_default: bool = False
188
-
188
+
189
189
  @property
190
- def permalink(self) -> str: # pragma: no cover
190
+ def permalink(self) -> str: # pragma: no cover
191
191
  return generate_permalink(self.name)
192
192
 
193
193
 
@@ -64,8 +64,10 @@ class ProjectService:
64
64
  return await self.repository.find_all()
65
65
 
66
66
  async def get_project(self, name: str) -> Optional[Project]:
67
- """Get the file path for a project by name."""
68
- return await self.repository.get_by_name(name)
67
+ """Get the file path for a project by name or permalink."""
68
+ return await self.repository.get_by_name(name) or await self.repository.get_by_permalink(
69
+ name
70
+ )
69
71
 
70
72
  async def add_project(self, name: str, path: str, set_default: bool = False) -> None:
71
73
  """Add a new project to the configuration and database.
@@ -347,12 +349,15 @@ class ProjectService:
347
349
  # Use specified project or fall back to config project
348
350
  project_name = project_name or config.project
349
351
  # Get project path from configuration
350
- project_path = config_manager.projects.get(project_name)
351
- if not project_path: # pragma: no cover
352
+ name, project_path = config_manager.get_project(project_name)
353
+ if not name: # pragma: no cover
352
354
  raise ValueError(f"Project '{project_name}' not found in configuration")
353
355
 
356
+ assert project_path is not None
357
+ project_permalink = generate_permalink(project_name)
358
+
354
359
  # Get project from database to get project_id
355
- db_project = await self.repository.get_by_name(project_name)
360
+ db_project = await self.repository.get_by_permalink(project_permalink)
356
361
  if not db_project: # pragma: no cover
357
362
  raise ValueError(f"Project '{project_name}' not found in database")
358
363
 
@@ -367,7 +372,7 @@ class ProjectService:
367
372
 
368
373
  # Get enhanced project information from database
369
374
  db_projects = await self.repository.get_active_projects()
370
- db_projects_by_name = {p.name: p for p in db_projects}
375
+ db_projects_by_permalink = {p.permalink: p for p in db_projects}
371
376
 
372
377
  # Get default project info
373
378
  default_project = config_manager.default_project
@@ -375,7 +380,8 @@ class ProjectService:
375
380
  # Convert config projects to include database info
376
381
  enhanced_projects = {}
377
382
  for name, path in config_manager.projects.items():
378
- db_project = db_projects_by_name.get(name)
383
+ config_permalink = generate_permalink(name)
384
+ db_project = db_projects_by_permalink.get(config_permalink)
379
385
  enhanced_projects[name] = {
380
386
  "path": path,
381
387
  "active": db_project.is_active if db_project else True,
@@ -668,4 +674,4 @@ class ProjectService:
668
674
  database_size=db_size_readable,
669
675
  watch_status=watch_status,
670
676
  timestamp=datetime.now(),
671
- )
677
+ )