basic-memory 0.13.0b5__tar.gz → 0.13.1__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 (313) hide show
  1. {basic_memory-0.13.0b5 → basic_memory-0.13.1}/.github/workflows/release.yml +4 -10
  2. {basic_memory-0.13.0b5 → basic_memory-0.13.1}/CHANGELOG.md +223 -57
  3. {basic_memory-0.13.0b5 → basic_memory-0.13.1}/PKG-INFO +1 -1
  4. {basic_memory-0.13.0b5 → basic_memory-0.13.1}/docs/AI Assistant Guide.md +7 -0
  5. {basic_memory-0.13.0b5 → basic_memory-0.13.1}/src/basic_memory/__init__.py +2 -1
  6. {basic_memory-0.13.0b5 → basic_memory-0.13.1}/src/basic_memory/cli/commands/project.py +1 -1
  7. {basic_memory-0.13.0b5 → basic_memory-0.13.1}/src/basic_memory/cli/commands/tool.py +6 -6
  8. {basic_memory-0.13.0b5 → basic_memory-0.13.1}/src/basic_memory/mcp/prompts/recent_activity.py +1 -1
  9. {basic_memory-0.13.0b5 → basic_memory-0.13.1}/src/basic_memory/mcp/tools/read_note.py +2 -2
  10. {basic_memory-0.13.0b5 → basic_memory-0.13.1}/src/basic_memory/mcp/tools/view_note.py +1 -1
  11. {basic_memory-0.13.0b5 → basic_memory-0.13.1}/src/basic_memory/repository/search_repository.py +17 -12
  12. {basic_memory-0.13.0b5 → basic_memory-0.13.1}/src/basic_memory/services/entity_service.py +14 -1
  13. {basic_memory-0.13.0b5 → basic_memory-0.13.1}/src/basic_memory/services/project_service.py +24 -3
  14. {basic_memory-0.13.0b5 → basic_memory-0.13.1}/src/basic_memory/sync/sync_service.py +36 -11
  15. {basic_memory-0.13.0b5 → basic_memory-0.13.1}/static/ai_assistant_guide.md +7 -0
  16. {basic_memory-0.13.0b5 → basic_memory-0.13.1}/tests/cli/test_project_info.py +2 -2
  17. {basic_memory-0.13.0b5 → basic_memory-0.13.1}/tests/mcp/test_prompts.py +9 -9
  18. {basic_memory-0.13.0b5 → basic_memory-0.13.1}/tests/mcp/test_resource_project_info.py +2 -2
  19. {basic_memory-0.13.0b5 → basic_memory-0.13.1}/tests/mcp/test_resources.py +1 -1
  20. {basic_memory-0.13.0b5 → basic_memory-0.13.1}/tests/mcp/test_tool_build_context.py +7 -7
  21. {basic_memory-0.13.0b5 → basic_memory-0.13.1}/tests/mcp/test_tool_canvas.py +6 -6
  22. {basic_memory-0.13.0b5 → basic_memory-0.13.1}/tests/mcp/test_tool_edit_note.py +33 -31
  23. {basic_memory-0.13.0b5 → basic_memory-0.13.1}/tests/mcp/test_tool_list_directory.py +17 -17
  24. {basic_memory-0.13.0b5 → basic_memory-0.13.1}/tests/mcp/test_tool_move_note.py +46 -46
  25. {basic_memory-0.13.0b5 → basic_memory-0.13.1}/tests/mcp/test_tool_read_note.py +17 -17
  26. {basic_memory-0.13.0b5 → basic_memory-0.13.1}/tests/mcp/test_tool_recent_activity.py +10 -10
  27. {basic_memory-0.13.0b5 → basic_memory-0.13.1}/tests/mcp/test_tool_resource.py +10 -10
  28. {basic_memory-0.13.0b5 → basic_memory-0.13.1}/tests/mcp/test_tool_search.py +18 -18
  29. {basic_memory-0.13.0b5 → basic_memory-0.13.1}/tests/mcp/test_tool_sync_status.py +7 -7
  30. {basic_memory-0.13.0b5 → basic_memory-0.13.1}/tests/mcp/test_tool_view_note.py +30 -26
  31. {basic_memory-0.13.0b5 → basic_memory-0.13.1}/tests/mcp/test_tool_write_note.py +21 -21
  32. {basic_memory-0.13.0b5 → basic_memory-0.13.1}/tests/repository/test_search_repository.py +34 -0
  33. {basic_memory-0.13.0b5 → basic_memory-0.13.1}/tests/services/test_entity_service.py +113 -0
  34. {basic_memory-0.13.0b5 → basic_memory-0.13.1}/tests/services/test_project_service.py +132 -0
  35. {basic_memory-0.13.0b5 → basic_memory-0.13.1}/tests/sync/test_sync_service.py +222 -0
  36. {basic_memory-0.13.0b5 → basic_memory-0.13.1}/uv.lock +3 -3
  37. basic_memory-0.13.0b5/RELEASE_NOTES_v0.13.0.md +0 -240
  38. basic_memory-0.13.0b5/TESTING.md +0 -337
  39. {basic_memory-0.13.0b5 → basic_memory-0.13.1}/.claude/commands/check-health.md +0 -0
  40. {basic_memory-0.13.0b5 → basic_memory-0.13.1}/.claude/commands/commands.md +0 -0
  41. {basic_memory-0.13.0b5 → basic_memory-0.13.1}/.claude/commands/lint-fix.md +0 -0
  42. {basic_memory-0.13.0b5 → basic_memory-0.13.1}/.claude/commands/release/beta.md +0 -0
  43. {basic_memory-0.13.0b5 → basic_memory-0.13.1}/.claude/commands/release/changelog.md +0 -0
  44. {basic_memory-0.13.0b5 → basic_memory-0.13.1}/.claude/commands/release/release-check.md +0 -0
  45. {basic_memory-0.13.0b5 → basic_memory-0.13.1}/.claude/commands/release/release.md +0 -0
  46. {basic_memory-0.13.0b5 → basic_memory-0.13.1}/.claude/commands/test-coverage.md +0 -0
  47. {basic_memory-0.13.0b5 → basic_memory-0.13.1}/.claude/commands/test-live.md +0 -0
  48. {basic_memory-0.13.0b5 → basic_memory-0.13.1}/.env.oauth.example +0 -0
  49. {basic_memory-0.13.0b5 → basic_memory-0.13.1}/.github/ISSUE_TEMPLATE/bug_report.md +0 -0
  50. {basic_memory-0.13.0b5 → basic_memory-0.13.1}/.github/ISSUE_TEMPLATE/config.yml +0 -0
  51. {basic_memory-0.13.0b5 → basic_memory-0.13.1}/.github/ISSUE_TEMPLATE/documentation.md +0 -0
  52. {basic_memory-0.13.0b5 → basic_memory-0.13.1}/.github/ISSUE_TEMPLATE/feature_request.md +0 -0
  53. {basic_memory-0.13.0b5 → basic_memory-0.13.1}/.github/dependabot.yml +0 -0
  54. {basic_memory-0.13.0b5 → basic_memory-0.13.1}/.github/workflows/claude.yml +0 -0
  55. {basic_memory-0.13.0b5 → basic_memory-0.13.1}/.github/workflows/dev-release.yml +0 -0
  56. {basic_memory-0.13.0b5 → basic_memory-0.13.1}/.github/workflows/pr-title.yml +0 -0
  57. {basic_memory-0.13.0b5 → basic_memory-0.13.1}/.github/workflows/test.yml +0 -0
  58. {basic_memory-0.13.0b5 → basic_memory-0.13.1}/.gitignore +0 -0
  59. {basic_memory-0.13.0b5 → basic_memory-0.13.1}/.mcp.json +0 -0
  60. {basic_memory-0.13.0b5 → basic_memory-0.13.1}/.python-version +0 -0
  61. {basic_memory-0.13.0b5 → basic_memory-0.13.1}/AUTH.md +0 -0
  62. {basic_memory-0.13.0b5 → basic_memory-0.13.1}/CITATION.cff +0 -0
  63. {basic_memory-0.13.0b5 → basic_memory-0.13.1}/CLA.md +0 -0
  64. {basic_memory-0.13.0b5 → basic_memory-0.13.1}/CLAUDE.md +0 -0
  65. {basic_memory-0.13.0b5 → basic_memory-0.13.1}/CODE_OF_CONDUCT.md +0 -0
  66. {basic_memory-0.13.0b5 → basic_memory-0.13.1}/CONTRIBUTING.md +0 -0
  67. {basic_memory-0.13.0b5 → basic_memory-0.13.1}/Dockerfile +0 -0
  68. {basic_memory-0.13.0b5 → basic_memory-0.13.1}/LICENSE +0 -0
  69. {basic_memory-0.13.0b5 → basic_memory-0.13.1}/README.md +0 -0
  70. {basic_memory-0.13.0b5 → basic_memory-0.13.1}/SECURITY.md +0 -0
  71. {basic_memory-0.13.0b5 → basic_memory-0.13.1}/basic-memory.md +0 -0
  72. {basic_memory-0.13.0b5 → basic_memory-0.13.1}/docs/CLI Reference.md +0 -0
  73. {basic_memory-0.13.0b5 → basic_memory-0.13.1}/docs/Canvas.md +0 -0
  74. {basic_memory-0.13.0b5 → basic_memory-0.13.1}/docs/Claude.ai Integration.md +0 -0
  75. {basic_memory-0.13.0b5 → basic_memory-0.13.1}/docs/Getting Started with Basic Memory.md +0 -0
  76. {basic_memory-0.13.0b5 → basic_memory-0.13.1}/docs/Knowledge Format.md +0 -0
  77. {basic_memory-0.13.0b5 → basic_memory-0.13.1}/docs/OAuth Authentication Guide.md +0 -0
  78. {basic_memory-0.13.0b5 → basic_memory-0.13.1}/docs/Obsidian Integration.md +0 -0
  79. {basic_memory-0.13.0b5 → basic_memory-0.13.1}/docs/Supabase OAuth Setup.md +0 -0
  80. {basic_memory-0.13.0b5 → basic_memory-0.13.1}/docs/Technical Information.md +0 -0
  81. {basic_memory-0.13.0b5 → basic_memory-0.13.1}/docs/User Guide.md +0 -0
  82. {basic_memory-0.13.0b5 → basic_memory-0.13.1}/docs/Welcome to Basic memory.md +0 -0
  83. {basic_memory-0.13.0b5 → basic_memory-0.13.1}/docs/attachments/Canvas.png +0 -0
  84. {basic_memory-0.13.0b5 → basic_memory-0.13.1}/docs/attachments/Claude-Obsidian-Demo.mp4 +0 -0
  85. {basic_memory-0.13.0b5 → basic_memory-0.13.1}/docs/attachments/Prompt.png +0 -0
  86. {basic_memory-0.13.0b5 → basic_memory-0.13.1}/docs/attachments/disk-ai-logo-400x400.png +0 -0
  87. {basic_memory-0.13.0b5 → basic_memory-0.13.1}/docs/attachments/disk-ai-logo.png +0 -0
  88. {basic_memory-0.13.0b5 → basic_memory-0.13.1}/docs/attachments/prompt 1.png +0 -0
  89. {basic_memory-0.13.0b5 → basic_memory-0.13.1}/docs/attachments/prompt2.png +0 -0
  90. {basic_memory-0.13.0b5 → basic_memory-0.13.1}/docs/attachments/prompt3.png +0 -0
  91. {basic_memory-0.13.0b5 → basic_memory-0.13.1}/docs/attachments/prompt4.png +0 -0
  92. {basic_memory-0.13.0b5 → basic_memory-0.13.1}/docs/publish.js +0 -0
  93. {basic_memory-0.13.0b5 → basic_memory-0.13.1}/examples/Coffee Notes/Brewing Equipment.md +0 -0
  94. {basic_memory-0.13.0b5 → basic_memory-0.13.1}/examples/Coffee Notes/Coffee Bean Origins.md +0 -0
  95. {basic_memory-0.13.0b5 → basic_memory-0.13.1}/examples/Coffee Notes/Coffee Brewing Methods.md +0 -0
  96. {basic_memory-0.13.0b5 → basic_memory-0.13.1}/examples/Coffee Notes/Coffee Flavor Map.md +0 -0
  97. {basic_memory-0.13.0b5 → basic_memory-0.13.1}/examples/Coffee Notes/Coffee Knowledge Base.md +0 -0
  98. {basic_memory-0.13.0b5 → basic_memory-0.13.1}/examples/Coffee Notes/Flavor Extraction.md +0 -0
  99. {basic_memory-0.13.0b5 → basic_memory-0.13.1}/examples/Coffee Notes/Perfect Pour Over Coffee Method.canvas +0 -0
  100. {basic_memory-0.13.0b5 → basic_memory-0.13.1}/examples/Coffee Notes/Tasting Notes.md +0 -0
  101. {basic_memory-0.13.0b5 → basic_memory-0.13.1}/examples/testing/Test Note Creation - Basic Functionality.md +0 -0
  102. {basic_memory-0.13.0b5 → basic_memory-0.13.1}/justfile +0 -0
  103. {basic_memory-0.13.0b5 → basic_memory-0.13.1}/llms-install.md +0 -0
  104. {basic_memory-0.13.0b5 → basic_memory-0.13.1}/memory.json +0 -0
  105. {basic_memory-0.13.0b5 → basic_memory-0.13.1}/pyproject.toml +0 -0
  106. {basic_memory-0.13.0b5 → basic_memory-0.13.1}/scripts/install.sh +0 -0
  107. {basic_memory-0.13.0b5 → basic_memory-0.13.1}/smithery.yaml +0 -0
  108. {basic_memory-0.13.0b5 → basic_memory-0.13.1}/src/basic_memory/alembic/alembic.ini +0 -0
  109. {basic_memory-0.13.0b5 → basic_memory-0.13.1}/src/basic_memory/alembic/env.py +0 -0
  110. {basic_memory-0.13.0b5 → basic_memory-0.13.1}/src/basic_memory/alembic/migrations.py +0 -0
  111. {basic_memory-0.13.0b5 → basic_memory-0.13.1}/src/basic_memory/alembic/script.py.mako +0 -0
  112. {basic_memory-0.13.0b5 → basic_memory-0.13.1}/src/basic_memory/alembic/versions/3dae7c7b1564_initial_schema.py +0 -0
  113. {basic_memory-0.13.0b5 → basic_memory-0.13.1}/src/basic_memory/alembic/versions/502b60eaa905_remove_required_from_entity_permalink.py +0 -0
  114. {basic_memory-0.13.0b5 → basic_memory-0.13.1}/src/basic_memory/alembic/versions/5fe1ab1ccebe_add_projects_table.py +0 -0
  115. {basic_memory-0.13.0b5 → basic_memory-0.13.1}/src/basic_memory/alembic/versions/647e7a75e2cd_project_constraint_fix.py +0 -0
  116. {basic_memory-0.13.0b5 → basic_memory-0.13.1}/src/basic_memory/alembic/versions/b3c3938bacdb_relation_to_name_unique_index.py +0 -0
  117. {basic_memory-0.13.0b5 → basic_memory-0.13.1}/src/basic_memory/alembic/versions/cc7172b46608_update_search_index_schema.py +0 -0
  118. {basic_memory-0.13.0b5 → basic_memory-0.13.1}/src/basic_memory/api/__init__.py +0 -0
  119. {basic_memory-0.13.0b5 → basic_memory-0.13.1}/src/basic_memory/api/app.py +0 -0
  120. {basic_memory-0.13.0b5 → basic_memory-0.13.1}/src/basic_memory/api/routers/__init__.py +0 -0
  121. {basic_memory-0.13.0b5 → basic_memory-0.13.1}/src/basic_memory/api/routers/directory_router.py +0 -0
  122. {basic_memory-0.13.0b5 → basic_memory-0.13.1}/src/basic_memory/api/routers/importer_router.py +0 -0
  123. {basic_memory-0.13.0b5 → basic_memory-0.13.1}/src/basic_memory/api/routers/knowledge_router.py +0 -0
  124. {basic_memory-0.13.0b5 → basic_memory-0.13.1}/src/basic_memory/api/routers/management_router.py +0 -0
  125. {basic_memory-0.13.0b5 → basic_memory-0.13.1}/src/basic_memory/api/routers/memory_router.py +0 -0
  126. {basic_memory-0.13.0b5 → basic_memory-0.13.1}/src/basic_memory/api/routers/project_router.py +0 -0
  127. {basic_memory-0.13.0b5 → basic_memory-0.13.1}/src/basic_memory/api/routers/prompt_router.py +0 -0
  128. {basic_memory-0.13.0b5 → basic_memory-0.13.1}/src/basic_memory/api/routers/resource_router.py +0 -0
  129. {basic_memory-0.13.0b5 → basic_memory-0.13.1}/src/basic_memory/api/routers/search_router.py +0 -0
  130. {basic_memory-0.13.0b5 → basic_memory-0.13.1}/src/basic_memory/api/routers/utils.py +0 -0
  131. {basic_memory-0.13.0b5 → basic_memory-0.13.1}/src/basic_memory/api/template_loader.py +0 -0
  132. {basic_memory-0.13.0b5 → basic_memory-0.13.1}/src/basic_memory/cli/__init__.py +0 -0
  133. {basic_memory-0.13.0b5 → basic_memory-0.13.1}/src/basic_memory/cli/app.py +0 -0
  134. {basic_memory-0.13.0b5 → basic_memory-0.13.1}/src/basic_memory/cli/commands/__init__.py +0 -0
  135. {basic_memory-0.13.0b5 → basic_memory-0.13.1}/src/basic_memory/cli/commands/auth.py +0 -0
  136. {basic_memory-0.13.0b5 → basic_memory-0.13.1}/src/basic_memory/cli/commands/db.py +0 -0
  137. {basic_memory-0.13.0b5 → basic_memory-0.13.1}/src/basic_memory/cli/commands/import_chatgpt.py +0 -0
  138. {basic_memory-0.13.0b5 → basic_memory-0.13.1}/src/basic_memory/cli/commands/import_claude_conversations.py +0 -0
  139. {basic_memory-0.13.0b5 → basic_memory-0.13.1}/src/basic_memory/cli/commands/import_claude_projects.py +0 -0
  140. {basic_memory-0.13.0b5 → basic_memory-0.13.1}/src/basic_memory/cli/commands/import_memory_json.py +0 -0
  141. {basic_memory-0.13.0b5 → basic_memory-0.13.1}/src/basic_memory/cli/commands/mcp.py +0 -0
  142. {basic_memory-0.13.0b5 → basic_memory-0.13.1}/src/basic_memory/cli/commands/status.py +0 -0
  143. {basic_memory-0.13.0b5 → basic_memory-0.13.1}/src/basic_memory/cli/commands/sync.py +0 -0
  144. {basic_memory-0.13.0b5 → basic_memory-0.13.1}/src/basic_memory/cli/main.py +0 -0
  145. {basic_memory-0.13.0b5 → basic_memory-0.13.1}/src/basic_memory/config.py +0 -0
  146. {basic_memory-0.13.0b5 → basic_memory-0.13.1}/src/basic_memory/db.py +0 -0
  147. {basic_memory-0.13.0b5 → basic_memory-0.13.1}/src/basic_memory/deps.py +0 -0
  148. {basic_memory-0.13.0b5 → basic_memory-0.13.1}/src/basic_memory/file_utils.py +0 -0
  149. {basic_memory-0.13.0b5 → basic_memory-0.13.1}/src/basic_memory/importers/__init__.py +0 -0
  150. {basic_memory-0.13.0b5 → basic_memory-0.13.1}/src/basic_memory/importers/base.py +0 -0
  151. {basic_memory-0.13.0b5 → basic_memory-0.13.1}/src/basic_memory/importers/chatgpt_importer.py +0 -0
  152. {basic_memory-0.13.0b5 → basic_memory-0.13.1}/src/basic_memory/importers/claude_conversations_importer.py +0 -0
  153. {basic_memory-0.13.0b5 → basic_memory-0.13.1}/src/basic_memory/importers/claude_projects_importer.py +0 -0
  154. {basic_memory-0.13.0b5 → basic_memory-0.13.1}/src/basic_memory/importers/memory_json_importer.py +0 -0
  155. {basic_memory-0.13.0b5 → basic_memory-0.13.1}/src/basic_memory/importers/utils.py +0 -0
  156. {basic_memory-0.13.0b5 → basic_memory-0.13.1}/src/basic_memory/markdown/__init__.py +0 -0
  157. {basic_memory-0.13.0b5 → basic_memory-0.13.1}/src/basic_memory/markdown/entity_parser.py +0 -0
  158. {basic_memory-0.13.0b5 → basic_memory-0.13.1}/src/basic_memory/markdown/markdown_processor.py +0 -0
  159. {basic_memory-0.13.0b5 → basic_memory-0.13.1}/src/basic_memory/markdown/plugins.py +0 -0
  160. {basic_memory-0.13.0b5 → basic_memory-0.13.1}/src/basic_memory/markdown/schemas.py +0 -0
  161. {basic_memory-0.13.0b5 → basic_memory-0.13.1}/src/basic_memory/markdown/utils.py +0 -0
  162. {basic_memory-0.13.0b5 → basic_memory-0.13.1}/src/basic_memory/mcp/__init__.py +0 -0
  163. {basic_memory-0.13.0b5 → basic_memory-0.13.1}/src/basic_memory/mcp/async_client.py +0 -0
  164. {basic_memory-0.13.0b5 → basic_memory-0.13.1}/src/basic_memory/mcp/auth_provider.py +0 -0
  165. {basic_memory-0.13.0b5 → basic_memory-0.13.1}/src/basic_memory/mcp/external_auth_provider.py +0 -0
  166. {basic_memory-0.13.0b5 → basic_memory-0.13.1}/src/basic_memory/mcp/project_session.py +0 -0
  167. {basic_memory-0.13.0b5 → basic_memory-0.13.1}/src/basic_memory/mcp/prompts/__init__.py +0 -0
  168. {basic_memory-0.13.0b5 → basic_memory-0.13.1}/src/basic_memory/mcp/prompts/ai_assistant_guide.py +0 -0
  169. {basic_memory-0.13.0b5 → basic_memory-0.13.1}/src/basic_memory/mcp/prompts/continue_conversation.py +0 -0
  170. {basic_memory-0.13.0b5 → basic_memory-0.13.1}/src/basic_memory/mcp/prompts/search.py +0 -0
  171. {basic_memory-0.13.0b5 → basic_memory-0.13.1}/src/basic_memory/mcp/prompts/sync_status.py +0 -0
  172. {basic_memory-0.13.0b5 → basic_memory-0.13.1}/src/basic_memory/mcp/prompts/utils.py +0 -0
  173. {basic_memory-0.13.0b5 → basic_memory-0.13.1}/src/basic_memory/mcp/resources/ai_assistant_guide.md +0 -0
  174. {basic_memory-0.13.0b5 → basic_memory-0.13.1}/src/basic_memory/mcp/resources/project_info.py +0 -0
  175. {basic_memory-0.13.0b5 → basic_memory-0.13.1}/src/basic_memory/mcp/server.py +0 -0
  176. {basic_memory-0.13.0b5 → basic_memory-0.13.1}/src/basic_memory/mcp/supabase_auth_provider.py +0 -0
  177. {basic_memory-0.13.0b5 → basic_memory-0.13.1}/src/basic_memory/mcp/tools/__init__.py +0 -0
  178. {basic_memory-0.13.0b5 → basic_memory-0.13.1}/src/basic_memory/mcp/tools/build_context.py +0 -0
  179. {basic_memory-0.13.0b5 → basic_memory-0.13.1}/src/basic_memory/mcp/tools/canvas.py +0 -0
  180. {basic_memory-0.13.0b5 → basic_memory-0.13.1}/src/basic_memory/mcp/tools/delete_note.py +0 -0
  181. {basic_memory-0.13.0b5 → basic_memory-0.13.1}/src/basic_memory/mcp/tools/edit_note.py +0 -0
  182. {basic_memory-0.13.0b5 → basic_memory-0.13.1}/src/basic_memory/mcp/tools/list_directory.py +0 -0
  183. {basic_memory-0.13.0b5 → basic_memory-0.13.1}/src/basic_memory/mcp/tools/move_note.py +0 -0
  184. {basic_memory-0.13.0b5 → basic_memory-0.13.1}/src/basic_memory/mcp/tools/project_management.py +0 -0
  185. {basic_memory-0.13.0b5 → basic_memory-0.13.1}/src/basic_memory/mcp/tools/read_content.py +0 -0
  186. {basic_memory-0.13.0b5 → basic_memory-0.13.1}/src/basic_memory/mcp/tools/recent_activity.py +0 -0
  187. {basic_memory-0.13.0b5 → basic_memory-0.13.1}/src/basic_memory/mcp/tools/search.py +0 -0
  188. {basic_memory-0.13.0b5 → basic_memory-0.13.1}/src/basic_memory/mcp/tools/sync_status.py +0 -0
  189. {basic_memory-0.13.0b5 → basic_memory-0.13.1}/src/basic_memory/mcp/tools/utils.py +0 -0
  190. {basic_memory-0.13.0b5 → basic_memory-0.13.1}/src/basic_memory/mcp/tools/write_note.py +0 -0
  191. {basic_memory-0.13.0b5 → basic_memory-0.13.1}/src/basic_memory/models/__init__.py +0 -0
  192. {basic_memory-0.13.0b5 → basic_memory-0.13.1}/src/basic_memory/models/base.py +0 -0
  193. {basic_memory-0.13.0b5 → basic_memory-0.13.1}/src/basic_memory/models/knowledge.py +0 -0
  194. {basic_memory-0.13.0b5 → basic_memory-0.13.1}/src/basic_memory/models/project.py +0 -0
  195. {basic_memory-0.13.0b5 → basic_memory-0.13.1}/src/basic_memory/models/search.py +0 -0
  196. {basic_memory-0.13.0b5 → basic_memory-0.13.1}/src/basic_memory/repository/__init__.py +0 -0
  197. {basic_memory-0.13.0b5 → basic_memory-0.13.1}/src/basic_memory/repository/entity_repository.py +0 -0
  198. {basic_memory-0.13.0b5 → basic_memory-0.13.1}/src/basic_memory/repository/observation_repository.py +0 -0
  199. {basic_memory-0.13.0b5 → basic_memory-0.13.1}/src/basic_memory/repository/project_info_repository.py +0 -0
  200. {basic_memory-0.13.0b5 → basic_memory-0.13.1}/src/basic_memory/repository/project_repository.py +0 -0
  201. {basic_memory-0.13.0b5 → basic_memory-0.13.1}/src/basic_memory/repository/relation_repository.py +0 -0
  202. {basic_memory-0.13.0b5 → basic_memory-0.13.1}/src/basic_memory/repository/repository.py +0 -0
  203. {basic_memory-0.13.0b5 → basic_memory-0.13.1}/src/basic_memory/schemas/__init__.py +0 -0
  204. {basic_memory-0.13.0b5 → basic_memory-0.13.1}/src/basic_memory/schemas/base.py +0 -0
  205. {basic_memory-0.13.0b5 → basic_memory-0.13.1}/src/basic_memory/schemas/delete.py +0 -0
  206. {basic_memory-0.13.0b5 → basic_memory-0.13.1}/src/basic_memory/schemas/directory.py +0 -0
  207. {basic_memory-0.13.0b5 → basic_memory-0.13.1}/src/basic_memory/schemas/importer.py +0 -0
  208. {basic_memory-0.13.0b5 → basic_memory-0.13.1}/src/basic_memory/schemas/memory.py +0 -0
  209. {basic_memory-0.13.0b5 → basic_memory-0.13.1}/src/basic_memory/schemas/project_info.py +0 -0
  210. {basic_memory-0.13.0b5 → basic_memory-0.13.1}/src/basic_memory/schemas/prompt.py +0 -0
  211. {basic_memory-0.13.0b5 → basic_memory-0.13.1}/src/basic_memory/schemas/request.py +0 -0
  212. {basic_memory-0.13.0b5 → basic_memory-0.13.1}/src/basic_memory/schemas/response.py +0 -0
  213. {basic_memory-0.13.0b5 → basic_memory-0.13.1}/src/basic_memory/schemas/search.py +0 -0
  214. {basic_memory-0.13.0b5 → basic_memory-0.13.1}/src/basic_memory/services/__init__.py +0 -0
  215. {basic_memory-0.13.0b5 → basic_memory-0.13.1}/src/basic_memory/services/context_service.py +0 -0
  216. {basic_memory-0.13.0b5 → basic_memory-0.13.1}/src/basic_memory/services/directory_service.py +0 -0
  217. {basic_memory-0.13.0b5 → basic_memory-0.13.1}/src/basic_memory/services/exceptions.py +0 -0
  218. {basic_memory-0.13.0b5 → basic_memory-0.13.1}/src/basic_memory/services/file_service.py +0 -0
  219. {basic_memory-0.13.0b5 → basic_memory-0.13.1}/src/basic_memory/services/initialization.py +0 -0
  220. {basic_memory-0.13.0b5 → basic_memory-0.13.1}/src/basic_memory/services/link_resolver.py +0 -0
  221. {basic_memory-0.13.0b5 → basic_memory-0.13.1}/src/basic_memory/services/migration_service.py +0 -0
  222. {basic_memory-0.13.0b5 → basic_memory-0.13.1}/src/basic_memory/services/search_service.py +0 -0
  223. {basic_memory-0.13.0b5 → basic_memory-0.13.1}/src/basic_memory/services/service.py +0 -0
  224. {basic_memory-0.13.0b5 → basic_memory-0.13.1}/src/basic_memory/services/sync_status_service.py +0 -0
  225. {basic_memory-0.13.0b5 → basic_memory-0.13.1}/src/basic_memory/sync/__init__.py +0 -0
  226. {basic_memory-0.13.0b5 → basic_memory-0.13.1}/src/basic_memory/sync/background_sync.py +0 -0
  227. {basic_memory-0.13.0b5 → basic_memory-0.13.1}/src/basic_memory/sync/watch_service.py +0 -0
  228. {basic_memory-0.13.0b5 → basic_memory-0.13.1}/src/basic_memory/templates/prompts/continue_conversation.hbs +0 -0
  229. {basic_memory-0.13.0b5 → basic_memory-0.13.1}/src/basic_memory/templates/prompts/search.hbs +0 -0
  230. {basic_memory-0.13.0b5 → basic_memory-0.13.1}/src/basic_memory/utils.py +0 -0
  231. {basic_memory-0.13.0b5 → basic_memory-0.13.1}/static/json_canvas_spec_1_0.md +0 -0
  232. {basic_memory-0.13.0b5 → basic_memory-0.13.1}/test-int/conftest.py +0 -0
  233. {basic_memory-0.13.0b5 → basic_memory-0.13.1}/test-int/mcp/test_build_context_validation.py +0 -0
  234. {basic_memory-0.13.0b5 → basic_memory-0.13.1}/test-int/mcp/test_delete_note_integration.py +0 -0
  235. {basic_memory-0.13.0b5 → basic_memory-0.13.1}/test-int/mcp/test_edit_note_integration.py +0 -0
  236. {basic_memory-0.13.0b5 → basic_memory-0.13.1}/test-int/mcp/test_list_directory_integration.py +0 -0
  237. {basic_memory-0.13.0b5 → basic_memory-0.13.1}/test-int/mcp/test_move_note_integration.py +0 -0
  238. {basic_memory-0.13.0b5 → basic_memory-0.13.1}/test-int/mcp/test_project_management_integration.py +0 -0
  239. {basic_memory-0.13.0b5 → basic_memory-0.13.1}/test-int/mcp/test_read_content_integration.py +0 -0
  240. {basic_memory-0.13.0b5 → basic_memory-0.13.1}/test-int/mcp/test_read_note_integration.py +0 -0
  241. {basic_memory-0.13.0b5 → basic_memory-0.13.1}/test-int/mcp/test_search_integration.py +0 -0
  242. {basic_memory-0.13.0b5 → basic_memory-0.13.1}/test-int/mcp/test_write_note_integration.py +0 -0
  243. {basic_memory-0.13.0b5 → basic_memory-0.13.1}/tests/Non-MarkdownFileSupport.pdf +0 -0
  244. {basic_memory-0.13.0b5 → basic_memory-0.13.1}/tests/Screenshot.png +0 -0
  245. {basic_memory-0.13.0b5 → basic_memory-0.13.1}/tests/__init__.py +0 -0
  246. {basic_memory-0.13.0b5 → basic_memory-0.13.1}/tests/api/conftest.py +0 -0
  247. {basic_memory-0.13.0b5 → basic_memory-0.13.1}/tests/api/test_continue_conversation_template.py +0 -0
  248. {basic_memory-0.13.0b5 → basic_memory-0.13.1}/tests/api/test_directory_router.py +0 -0
  249. {basic_memory-0.13.0b5 → basic_memory-0.13.1}/tests/api/test_importer_router.py +0 -0
  250. {basic_memory-0.13.0b5 → basic_memory-0.13.1}/tests/api/test_knowledge_router.py +0 -0
  251. {basic_memory-0.13.0b5 → basic_memory-0.13.1}/tests/api/test_management_router.py +0 -0
  252. {basic_memory-0.13.0b5 → basic_memory-0.13.1}/tests/api/test_memory_router.py +0 -0
  253. {basic_memory-0.13.0b5 → basic_memory-0.13.1}/tests/api/test_project_router.py +0 -0
  254. {basic_memory-0.13.0b5 → basic_memory-0.13.1}/tests/api/test_project_router_operations.py +0 -0
  255. {basic_memory-0.13.0b5 → basic_memory-0.13.1}/tests/api/test_prompt_router.py +0 -0
  256. {basic_memory-0.13.0b5 → basic_memory-0.13.1}/tests/api/test_resource_router.py +0 -0
  257. {basic_memory-0.13.0b5 → basic_memory-0.13.1}/tests/api/test_search_router.py +0 -0
  258. {basic_memory-0.13.0b5 → basic_memory-0.13.1}/tests/api/test_search_template.py +0 -0
  259. {basic_memory-0.13.0b5 → basic_memory-0.13.1}/tests/api/test_template_loader.py +0 -0
  260. {basic_memory-0.13.0b5 → basic_memory-0.13.1}/tests/api/test_template_loader_helpers.py +0 -0
  261. {basic_memory-0.13.0b5 → basic_memory-0.13.1}/tests/cli/conftest.py +0 -0
  262. {basic_memory-0.13.0b5 → basic_memory-0.13.1}/tests/cli/test_auth_commands.py +0 -0
  263. {basic_memory-0.13.0b5 → basic_memory-0.13.1}/tests/cli/test_cli_tools.py +0 -0
  264. {basic_memory-0.13.0b5 → basic_memory-0.13.1}/tests/cli/test_import_chatgpt.py +0 -0
  265. {basic_memory-0.13.0b5 → basic_memory-0.13.1}/tests/cli/test_import_claude_conversations.py +0 -0
  266. {basic_memory-0.13.0b5 → basic_memory-0.13.1}/tests/cli/test_import_claude_projects.py +0 -0
  267. {basic_memory-0.13.0b5 → basic_memory-0.13.1}/tests/cli/test_import_memory_json.py +0 -0
  268. {basic_memory-0.13.0b5 → basic_memory-0.13.1}/tests/cli/test_project_commands.py +0 -0
  269. {basic_memory-0.13.0b5 → basic_memory-0.13.1}/tests/cli/test_status.py +0 -0
  270. {basic_memory-0.13.0b5 → basic_memory-0.13.1}/tests/cli/test_sync.py +0 -0
  271. {basic_memory-0.13.0b5 → basic_memory-0.13.1}/tests/cli/test_version.py +0 -0
  272. {basic_memory-0.13.0b5 → basic_memory-0.13.1}/tests/conftest.py +0 -0
  273. {basic_memory-0.13.0b5 → basic_memory-0.13.1}/tests/importers/test_importer_base.py +0 -0
  274. {basic_memory-0.13.0b5 → basic_memory-0.13.1}/tests/importers/test_importer_utils.py +0 -0
  275. {basic_memory-0.13.0b5 → basic_memory-0.13.1}/tests/markdown/__init__.py +0 -0
  276. {basic_memory-0.13.0b5 → basic_memory-0.13.1}/tests/markdown/test_entity_parser.py +0 -0
  277. {basic_memory-0.13.0b5 → basic_memory-0.13.1}/tests/markdown/test_markdown_plugins.py +0 -0
  278. {basic_memory-0.13.0b5 → basic_memory-0.13.1}/tests/markdown/test_markdown_processor.py +0 -0
  279. {basic_memory-0.13.0b5 → basic_memory-0.13.1}/tests/markdown/test_observation_edge_cases.py +0 -0
  280. {basic_memory-0.13.0b5 → basic_memory-0.13.1}/tests/markdown/test_parser_edge_cases.py +0 -0
  281. {basic_memory-0.13.0b5 → basic_memory-0.13.1}/tests/markdown/test_relation_edge_cases.py +0 -0
  282. {basic_memory-0.13.0b5 → basic_memory-0.13.1}/tests/markdown/test_task_detection.py +0 -0
  283. {basic_memory-0.13.0b5 → basic_memory-0.13.1}/tests/mcp/conftest.py +0 -0
  284. {basic_memory-0.13.0b5 → basic_memory-0.13.1}/tests/mcp/test_auth_provider.py +0 -0
  285. {basic_memory-0.13.0b5 → basic_memory-0.13.1}/tests/mcp/test_server.py +0 -0
  286. {basic_memory-0.13.0b5 → basic_memory-0.13.1}/tests/mcp/test_tool_delete_note.py +0 -0
  287. {basic_memory-0.13.0b5 → basic_memory-0.13.1}/tests/mcp/test_tool_utils.py +0 -0
  288. {basic_memory-0.13.0b5 → basic_memory-0.13.1}/tests/repository/test_entity_repository.py +0 -0
  289. {basic_memory-0.13.0b5 → basic_memory-0.13.1}/tests/repository/test_observation_repository.py +0 -0
  290. {basic_memory-0.13.0b5 → basic_memory-0.13.1}/tests/repository/test_project_info_repository.py +0 -0
  291. {basic_memory-0.13.0b5 → basic_memory-0.13.1}/tests/repository/test_project_repository.py +0 -0
  292. {basic_memory-0.13.0b5 → basic_memory-0.13.1}/tests/repository/test_relation_repository.py +0 -0
  293. {basic_memory-0.13.0b5 → basic_memory-0.13.1}/tests/repository/test_repository.py +0 -0
  294. {basic_memory-0.13.0b5 → basic_memory-0.13.1}/tests/schemas/test_memory_url.py +0 -0
  295. {basic_memory-0.13.0b5 → basic_memory-0.13.1}/tests/schemas/test_memory_url_validation.py +0 -0
  296. {basic_memory-0.13.0b5 → basic_memory-0.13.1}/tests/schemas/test_schemas.py +0 -0
  297. {basic_memory-0.13.0b5 → basic_memory-0.13.1}/tests/schemas/test_search.py +0 -0
  298. {basic_memory-0.13.0b5 → basic_memory-0.13.1}/tests/services/test_context_service.py +0 -0
  299. {basic_memory-0.13.0b5 → basic_memory-0.13.1}/tests/services/test_directory_service.py +0 -0
  300. {basic_memory-0.13.0b5 → basic_memory-0.13.1}/tests/services/test_file_service.py +0 -0
  301. {basic_memory-0.13.0b5 → basic_memory-0.13.1}/tests/services/test_initialization.py +0 -0
  302. {basic_memory-0.13.0b5 → basic_memory-0.13.1}/tests/services/test_link_resolver.py +0 -0
  303. {basic_memory-0.13.0b5 → basic_memory-0.13.1}/tests/services/test_project_service_operations.py +0 -0
  304. {basic_memory-0.13.0b5 → basic_memory-0.13.1}/tests/services/test_search_service.py +0 -0
  305. {basic_memory-0.13.0b5 → basic_memory-0.13.1}/tests/services/test_sync_status_service.py +0 -0
  306. {basic_memory-0.13.0b5 → basic_memory-0.13.1}/tests/sync/test_sync_wikilink_issue.py +0 -0
  307. {basic_memory-0.13.0b5 → basic_memory-0.13.1}/tests/sync/test_tmp_files.py +0 -0
  308. {basic_memory-0.13.0b5 → basic_memory-0.13.1}/tests/sync/test_watch_service.py +0 -0
  309. {basic_memory-0.13.0b5 → basic_memory-0.13.1}/tests/sync/test_watch_service_edge_cases.py +0 -0
  310. {basic_memory-0.13.0b5 → basic_memory-0.13.1}/tests/utils/test_file_utils.py +0 -0
  311. {basic_memory-0.13.0b5 → basic_memory-0.13.1}/tests/utils/test_parse_tags.py +0 -0
  312. {basic_memory-0.13.0b5 → basic_memory-0.13.1}/tests/utils/test_permalink_formatting.py +0 -0
  313. {basic_memory-0.13.0b5 → basic_memory-0.13.1}/tests/utils/test_utf8_handling.py +0 -0
@@ -32,17 +32,11 @@ jobs:
32
32
  uv sync
33
33
  uv build
34
34
 
35
- - name: Verify version matches tag
35
+ - name: Verify build succeeded
36
36
  run: |
37
- # Get version from built package
38
- PACKAGE_VERSION=$(uv run python -c "import basic_memory; print(basic_memory.__version__)")
39
- TAG_VERSION=${GITHUB_REF_NAME#v} # Remove 'v' prefix from tag
40
- echo "Package version: $PACKAGE_VERSION"
41
- echo "Tag version: $TAG_VERSION"
42
- if [ "$PACKAGE_VERSION" != "$TAG_VERSION" ]; then
43
- echo "Version mismatch! Package: $PACKAGE_VERSION, Tag: $TAG_VERSION"
44
- exit 1
45
- fi
37
+ # Verify that build artifacts exist
38
+ ls -la dist/
39
+ echo "Build completed successfully"
46
40
 
47
41
  - name: Create GitHub Release
48
42
  uses: softprops/action-gh-release@v2
@@ -1,80 +1,246 @@
1
1
  # CHANGELOG
2
2
 
3
+ ## v0.13.1 (2025-06-11)
3
4
 
4
- ## v0.13.0 (2025-06-03)
5
+ ### Bug Fixes
5
6
 
6
- ### Features
7
+ - **CLI**: Fixed `basic-memory project` project management commands that were not working in v0.13.0 (#129)
8
+ - **Projects**: Resolved case sensitivity issues when switching between projects that caused "Project not found" errors (#127)
9
+ - **API**: Standardized CLI project command endpoints and improved error handling
10
+ - **Core**: Implemented consistent project name handling using permalinks to avoid case-related conflicts
7
11
 
8
- - **Multi-Project Management System** - Switch between projects instantly during conversations
9
- ([`993e88a`](https://github.com/basicmachines-co/basic-memory/commit/993e88a))
10
- - Instant project switching with session context
11
- - Project-specific operations and isolation
12
- - Project discovery and management tools
12
+ ### Changes
13
13
 
14
- - **Advanced Note Editing** - Incremental editing with append, prepend, find/replace, and section operations
15
- ([`6fc3904`](https://github.com/basicmachines-co/basic-memory/commit/6fc3904))
16
- - `edit_note` tool with multiple operation types
17
- - Smart frontmatter-aware editing
18
- - Validation and error handling
14
+ - Renamed `basic-memory project sync` command to `basic-memory project sync-config` for clarity
15
+ - Improved project switching reliability across different case variations
16
+ - Removed redundant server status messages from CLI error outputs
19
17
 
20
- - **Smart File Management** - Move notes with database consistency and search reindexing
21
- ([`9fb931c`](https://github.com/basicmachines-co/basic-memory/commit/9fb931c))
22
- - `move_note` tool with rollback protection
23
- - Automatic folder creation and permalink updates
24
- - Full database consistency maintenance
18
+ ## v0.13.0 (2025-06-11)
25
19
 
26
- - **Enhanced Search Capabilities** - Frontmatter tags now searchable, improved content discovery
27
- ([`3f5368e`](https://github.com/basicmachines-co/basic-memory/commit/3f5368e))
28
- - YAML frontmatter tag indexing
29
- - Improved FTS5 search functionality
30
- - Project-scoped search operations
20
+ ### Overview
31
21
 
32
- - **Production Features** - OAuth authentication, development builds, comprehensive testing
33
- ([`5f8d945`](https://github.com/basicmachines-co/basic-memory/commit/5f8d945))
34
- - Development build automation
35
- - MCP integration testing framework
36
- - Enhanced CI/CD pipeline
22
+ Basic Memory v0.13.0 is a **major release** that transforms Basic Memory into a true multi-project knowledge management system. This release introduces fluid project switching, advanced note editing capabilities, robust file management, and production-ready OAuth authentication - all while maintaining full backward compatibility.
37
23
 
38
- ### Bug Fixes
24
+ **What's New for Users:**
25
+ - 🎯 **Switch between projects instantly** during conversations with Claude
26
+ - ✏️ **Edit notes incrementally** without rewriting entire documents
27
+ - 📁 **Move and organize notes** with full database consistency
28
+ - 📖 **View notes as formatted artifacts** for better readability in Claude Desktop
29
+ - 🔍 **Search frontmatter tags** to discover content more easily
30
+ - 🔐 **OAuth authentication** for secure remote access
31
+ - ⚡ **Development builds** automatically published for beta testing
39
32
 
40
- - **#118**: Fix YAML tag formatting to follow standard specification
41
- ([`2dc7e27`](https://github.com/basicmachines-co/basic-memory/commit/2dc7e27))
33
+ **Key v0.13.0 Accomplishments:**
34
+ - ✅ **Complete Project Management System** - Project switching and project-specific operations
35
+ - ✅ **Advanced Note Editing** - Incremental editing with append, prepend, find/replace, and section operations
36
+ - ✅ **View Notes as Artifacts in Claude Desktop/Web** - Use the view_note tool to view a note as an artifact
37
+ - ✅ **File Management System** - Full move operations with database consistency and rollback protection
38
+ - ✅ **Enhanced Search Capabilities** - Frontmatter tags now searchable, improved content discoverability
39
+ - ✅ **Unified Database Architecture** - Single app-level database for better performance and project management
42
40
 
43
- - **#110**: Make --project flag work consistently across CLI commands
44
- ([`02dd91a`](https://github.com/basicmachines-co/basic-memory/commit/02dd91a))
41
+ ### Major Features
45
42
 
46
- - **#93**: Respect custom permalinks in frontmatter for write_note
47
- ([`6b6fd76`](https://github.com/basicmachines-co/basic-memory/commit/6b6fd76))
43
+ #### 1. Multiple Project Management
48
44
 
49
- - Fix list_directory path display to not include leading slash
50
- ([`6057126`](https://github.com/basicmachines-co/basic-memory/commit/6057126))
45
+ **Switch between projects instantly during conversations:**
51
46
 
52
- ### Technical Improvements
47
+ ```
48
+ 💬 "What projects do I have?"
49
+ 🤖 Available projects:
50
+ • main (current, default)
51
+ • work-notes
52
+ • personal-journal
53
+ • code-snippets
53
54
 
54
- - **Unified Database Architecture** - Single app-level database for better performance
55
- - Migration from per-project databases to unified structure
56
- - Project isolation with foreign key relationships
57
- - Optimized queries and reduced file I/O
55
+ 💬 "Switch to work-notes"
56
+ 🤖 Switched to work-notes project
57
+
58
+ Project Summary:
59
+ • 47 entities
60
+ • 125 observations
61
+ • 23 relations
58
62
 
59
- - **Comprehensive Testing** - 100% test coverage with integration testing
60
- ([`468a22f`](https://github.com/basicmachines-co/basic-memory/commit/468a22f))
61
- - MCP integration test suite
62
- - End-to-end testing framework
63
- - Performance and edge case validation
63
+ 💬 "What did I work on yesterday?"
64
+ 🤖 [Shows recent activity from work-notes project]
65
+ ```
66
+
67
+ **Key Capabilities:**
68
+ - **Instant Project Switching**: Change project context mid-conversation without restart
69
+ - **Project-Specific Operations**: Operations work within the currently active project context
70
+ - **Project Discovery**: List all available projects with status indicators
71
+ - **Session Context**: Maintains active project throughout conversation
72
+ - **Backward Compatibility**: Existing single-project setups continue to work seamlessly
64
73
 
65
- ### Documentation
74
+ #### 2. Advanced Note Editing
75
+
76
+ **Edit notes incrementally without rewriting entire documents:**
77
+
78
+ ```python
79
+ # Append new sections to existing notes
80
+ edit_note("project-planning", "append", "\n## New Requirements\n- Feature X\n- Feature Y")
81
+
82
+ # Prepend timestamps to meeting notes
83
+ edit_note("meeting-notes", "prepend", "## 2025-05-27 Update\n- Progress update...")
84
+
85
+ # Replace specific sections under headers
86
+ edit_note("api-spec", "replace_section", "New implementation details", section="## Implementation")
87
+
88
+ # Find and replace with validation
89
+ edit_note("config", "find_replace", "v0.13.0", find_text="v0.12.0", expected_replacements=2)
90
+ ```
91
+
92
+ **Key Capabilities:**
93
+ - **Append Operations**: Add content to end of notes (most common use case)
94
+ - **Prepend Operations**: Add content to beginning of notes
95
+ - **Section Replacement**: Replace content under specific markdown headers
96
+ - **Find & Replace**: Simple text replacements with occurrence counting
97
+ - **Smart Error Handling**: Helpful guidance when operations fail
98
+ - **Project Context**: Works within the active project with session awareness
99
+
100
+ #### 3. Smart File Management
101
+
102
+ **Move and organize notes:**
103
+
104
+ ```python
105
+ # Simple moves with automatic folder creation
106
+ move_note("my-note", "work/projects/my-note.md")
107
+
108
+ # Organize within the active project
109
+ move_note("shared-doc", "archive/old-docs/shared-doc.md")
110
+
111
+ # Rename operations
112
+ move_note("old-name", "same-folder/new-name.md")
113
+ ```
114
+
115
+ **Key Capabilities:**
116
+ - **Database Consistency**: Updates file paths, permalinks, and checksums automatically
117
+ - **Search Reindexing**: Maintains search functionality after moves
118
+ - **Folder Creation**: Automatically creates destination directories
119
+ - **Project Isolation**: Operates within the currently active project
120
+ - **Link Preservation**: Maintains internal links and references
121
+
122
+ #### 4. Enhanced Search & Discovery
123
+
124
+ **Find content more easily with improved search capabilities:**
125
+
126
+ - **Frontmatter Tag Search**: Tags from YAML frontmatter are now indexed and searchable
127
+ - **Improved Content Discovery**: Search across titles, content, tags, and metadata
128
+ - **Project-Scoped Search**: Search within the currently active project
129
+ - **Better Search Quality**: Enhanced FTS5 indexing with tag content inclusion
130
+
131
+ **Example:**
132
+ ```yaml
133
+ ---
134
+ title: Coffee Brewing Methods
135
+ tags: [coffee, brewing, equipment]
136
+ ---
137
+ ```
138
+ Now searchable by: "coffee", "brewing", "equipment", or "Coffee Brewing Methods"
139
+
140
+ #### 5. Unified Database Architecture
141
+
142
+ **Single app-level database for better performance and project management:**
143
+
144
+ - **Migration from Per-Project DBs**: Moved from multiple SQLite files to single app database
145
+ - **Project Isolation**: Proper data separation with project_id foreign keys
146
+ - **Better Performance**: Optimized queries and reduced file I/O
147
+
148
+ ### Complete MCP Tool Suite
149
+
150
+ #### New Project Management Tools
151
+ - **`list_projects()`** - Discover and list all available projects with status
152
+ - **`switch_project(project_name)`** - Change active project context during conversations
153
+ - **`get_current_project()`** - Show currently active project with statistics
154
+ - **`set_default_project(project_name)`** - Update default project configuration
155
+ - **`sync_status()`** - Check file synchronization status and background operations
156
+
157
+ #### New Note Operations Tools
158
+ - **`edit_note()`** - Incremental note editing (append, prepend, find/replace, section replace)
159
+ - **`move_note()`** - Move notes with database consistency and search reindexing
160
+ - **`view_note()`** - Display notes as formatted artifacts for better readability in Claude Desktop
161
+
162
+ #### Enhanced Existing Tools
163
+ All existing tools now support:
164
+ - **Session context awareness** (operates within the currently active project)
165
+ - **Enhanced error messages** with project context metadata
166
+ - **Improved response formatting** with project information footers
167
+ - **Project isolation** ensures operations stay within the correct project boundaries
168
+
169
+
170
+ ### User Experience Improvements
171
+
172
+ #### Installation Options
173
+
174
+ **Multiple ways to install and test Basic Memory:**
175
+
176
+ ```bash
177
+ # Stable release
178
+ uv tool install basic-memory
179
+
180
+ # Beta/pre-releases
181
+ uv tool install basic-memory --pre
182
+ ```
183
+
184
+
185
+ #### Bug Fixes & Quality Improvements
186
+
187
+ **Major issues resolved in v0.13.0:**
188
+
189
+ - **#118**: Fixed YAML tag formatting to follow standard specification
190
+ - **#110**: Fixed `--project` flag consistency across all CLI commands
191
+ - **#107**: Fixed write_note update failures with existing notes
192
+ - **#93**: Fixed custom permalink handling in frontmatter
193
+ - **#52**: Enhanced search capabilities with frontmatter tag indexing
194
+ - **FTS5 Search**: Fixed special character handling in search queries
195
+ - **Error Handling**: Improved error messages and validation across all tools
196
+
197
+ ### Breaking Changes & Migration
198
+
199
+ #### For Existing Users
200
+
201
+ **Automatic Migration**: First run will automatically migrate existing data to the new unified database structure. No manual action required.
202
+
203
+ **What Changes:**
204
+ - Database location: Moved to `~/.basic-memory/memory.db` (unified across projects)
205
+ - Configuration: Projects defined in `~/.basic-memory/config.json` are synced with database
206
+
207
+ **What Stays the Same:**
208
+ - All existing notes and data remain unchanged
209
+ - Default project behavior maintained for single-project users
210
+ - All existing MCP tools continue to work without modification
211
+
212
+ ### Documentation & Resources
213
+
214
+ #### New Documentation
215
+ - [Project Management Guide](docs/Project%20Management.md) - Multi-project workflows
216
+ - [Note Editing Guide](docs/Note%20Editing.md) - Advanced editing techniques
217
+
218
+ #### Updated Documentation
219
+ - [README.md](README.md) - Installation options and beta build instructions
220
+ - [CONTRIBUTING.md](CONTRIBUTING.md) - Release process and version management
221
+ - [CLAUDE.md](CLAUDE.md) - Development workflow and CI/CD documentation
222
+ - [Claude.ai Integration](docs/Claude.ai%20Integration.md) - Updated MCP tool examples
223
+
224
+ #### Quick Start Examples
225
+
226
+ **Project Switching:**
227
+ ```
228
+ 💬 "Switch to my work project and show recent activity"
229
+ 🤖 [Calls switch_project("work") then recent_activity()]
230
+ ```
66
231
 
67
- - Add comprehensive testing documentation (TESTING.md)
68
- - Update project management guides (PROJECT_MANAGEMENT.md)
69
- - Enhanced note editing documentation (EDIT_NOTE.md)
70
- - Updated release workflow documentation
232
+ **Note Editing:**
233
+ ```
234
+ 💬 "Add a section about deployment to my API docs"
235
+ 🤖 [Calls edit_note("api-docs", "append", "## Deployment\n...")]
236
+ ```
71
237
 
72
- ### Breaking Changes
238
+ **File Organization:**
239
+ ```
240
+ 💬 "Move my old meeting notes to the archive folder"
241
+ 🤖 [Calls move_note("meeting-notes", "archive/old-meetings.md")]
242
+ ```
73
243
 
74
- - **Database Migration**: Automatic migration from per-project to unified database.
75
- Data will be re-index from the filesystem, resulting in no data loss.
76
- - **Configuration Changes**: Projects now synced between config.json and database
77
- - **Full Backward Compatibility**: All existing setups continue to work seamlessly
78
244
 
79
245
 
80
246
  ## v0.12.3 (2025-04-17)
@@ -861,4 +1027,4 @@ Co-authored-by: phernandez <phernandez@basicmachines.co>
861
1027
  ### Chores
862
1028
 
863
1029
  - Remove basic-foundation src ref in pyproject.toml
864
- ([`29fce8b`](https://github.com/basicmachines-co/basic-memory/commit/29fce8b0b922d54d7799bf2534107ee6cfb961b8))
1030
+ ([`29fce8b`](https://github.com/basicmachines-co/basic-memory/commit/29fce8b0b922d54d7799bf2534107ee6cfb961b8))
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: basic-memory
3
- Version: 0.13.0b5
3
+ Version: 0.13.1
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
@@ -77,6 +77,13 @@ read_note("specs/search-design") # By path
77
77
  read_note("memory://specs/search") # By memory URL
78
78
  ```
79
79
 
80
+ **Viewing notes as formatted artifacts (Claude Desktop):**
81
+ ```
82
+ view_note("Search Design") # Creates readable artifact
83
+ view_note("specs/search-design") # By permalink
84
+ view_note("memory://specs/search") # By memory URL
85
+ ```
86
+
80
87
  **Incremental editing** (v0.13.0):
81
88
  ```
82
89
  edit_note(
@@ -1,3 +1,4 @@
1
1
  """basic-memory - Local-first knowledge management combining Zettelkasten with knowledge graphs"""
2
2
 
3
- __version__ = "0.13.0b5"
3
+ # API version for FastAPI - independent of package version
4
+ __version__ = "v0"
@@ -174,7 +174,7 @@ def display_project_info(
174
174
  """Display detailed information and statistics about the current project."""
175
175
  try:
176
176
  # Get project info
177
- info = asyncio.run(project_info())
177
+ info = asyncio.run(project_info.fn()) # type: ignore # pyright: ignore [reportAttributeAccessIssue]
178
178
 
179
179
  if json_output:
180
180
  # Convert to JSON and print
@@ -90,7 +90,7 @@ def write_note(
90
90
  typer.echo("Empty content provided. Please provide non-empty content.", err=True)
91
91
  raise typer.Exit(1)
92
92
 
93
- note = asyncio.run(mcp_write_note(title, content, folder, tags))
93
+ note = asyncio.run(mcp_write_note.fn(title, content, folder, tags))
94
94
  rprint(note)
95
95
  except Exception as e: # pragma: no cover
96
96
  if not isinstance(e, typer.Exit):
@@ -103,7 +103,7 @@ def write_note(
103
103
  def read_note(identifier: str, page: int = 1, page_size: int = 10):
104
104
  """Read a markdown note from the knowledge base."""
105
105
  try:
106
- note = asyncio.run(mcp_read_note(identifier, page, page_size))
106
+ note = asyncio.run(mcp_read_note.fn(identifier, page, page_size))
107
107
  rprint(note)
108
108
  except Exception as e: # pragma: no cover
109
109
  if not isinstance(e, typer.Exit):
@@ -124,7 +124,7 @@ def build_context(
124
124
  """Get context needed to continue a discussion."""
125
125
  try:
126
126
  context = asyncio.run(
127
- mcp_build_context(
127
+ mcp_build_context.fn(
128
128
  url=url,
129
129
  depth=depth,
130
130
  timeframe=timeframe,
@@ -157,7 +157,7 @@ def recent_activity(
157
157
  """Get recent activity across the knowledge base."""
158
158
  try:
159
159
  context = asyncio.run(
160
- mcp_recent_activity(
160
+ mcp_recent_activity.fn(
161
161
  type=type, # pyright: ignore [reportArgumentType]
162
162
  depth=depth,
163
163
  timeframe=timeframe,
@@ -210,7 +210,7 @@ def search_notes(
210
210
  search_type = "text" if search_type is None else search_type
211
211
 
212
212
  results = asyncio.run(
213
- mcp_search(
213
+ mcp_search.fn(
214
214
  query,
215
215
  search_type=search_type,
216
216
  page=page,
@@ -241,7 +241,7 @@ def continue_conversation(
241
241
  """Prompt to continue a previous conversation or work session."""
242
242
  try:
243
243
  # Prompt functions return formatted strings directly
244
- session = asyncio.run(mcp_continue_conversation(topic=topic, timeframe=timeframe))
244
+ session = asyncio.run(mcp_continue_conversation.fn(topic=topic, timeframe=timeframe)) # type: ignore
245
245
  rprint(session)
246
246
  except Exception as e: # pragma: no cover
247
247
  if not isinstance(e, typer.Exit):
@@ -38,7 +38,7 @@ async def recent_activity_prompt(
38
38
  """
39
39
  logger.info(f"Getting recent activity, timeframe: {timeframe}")
40
40
 
41
- recent = await recent_activity(timeframe=timeframe, type=[SearchItemType.ENTITY])
41
+ recent = await recent_activity.fn(timeframe=timeframe, type=[SearchItemType.ENTITY])
42
42
 
43
43
  # Extract primary results from the hierarchical structure
44
44
  primary_results = []
@@ -81,7 +81,7 @@ async def read_note(
81
81
 
82
82
  # Fallback 1: Try title search via API
83
83
  logger.info(f"Search title for: {identifier}")
84
- title_results = await search_notes(query=identifier, search_type="title", project=project)
84
+ title_results = await search_notes.fn(query=identifier, search_type="title", project=project)
85
85
 
86
86
  if title_results and title_results.results:
87
87
  result = title_results.results[0] # Get the first/best match
@@ -105,7 +105,7 @@ async def read_note(
105
105
 
106
106
  # Fallback 2: Text search as a last resort
107
107
  logger.info(f"Title search failed, trying text search for: {identifier}")
108
- text_results = await search_notes(query=identifier, search_type="text", project=project)
108
+ text_results = await search_notes.fn(query=identifier, search_type="text", project=project)
109
109
 
110
110
  # We didn't find a direct match, construct a helpful error message
111
111
  if not text_results or not text_results.results:
@@ -37,7 +37,7 @@ async def view_note(
37
37
  logger.info(f"Viewing note: {identifier}")
38
38
 
39
39
  # Call the existing read_note logic
40
- content = await read_note(identifier, page, page_size, project)
40
+ content = await read_note.fn(identifier, page, page_size, project)
41
41
 
42
42
  # Check if this is an error message (note not found)
43
43
  if "# Note Not Found:" in content:
@@ -237,19 +237,24 @@ class SearchRepository:
237
237
 
238
238
  # Handle text search for title and content
239
239
  if search_text:
240
- # Check for explicit boolean operators - only detect them in proper boolean contexts
241
- has_boolean = any(op in f" {search_text} " for op in [" AND ", " OR ", " NOT "])
242
-
243
- if has_boolean:
244
- # If boolean operators are present, use the raw query
245
- # No need to prepare it, FTS5 will understand the operators
246
- params["text"] = search_text
247
- conditions.append("(title MATCH :text OR content_stems MATCH :text)")
240
+ # Skip FTS for wildcard-only queries that would cause "unknown special query" errors
241
+ if search_text.strip() == "*" or search_text.strip() == "":
242
+ # For wildcard searches, don't add any text conditions - return all results
243
+ pass
248
244
  else:
249
- # Standard search with term preparation
250
- processed_text = self._prepare_search_term(search_text.strip())
251
- params["text"] = processed_text
252
- conditions.append("(title MATCH :text OR content_stems MATCH :text)")
245
+ # Check for explicit boolean operators - only detect them in proper boolean contexts
246
+ has_boolean = any(op in f" {search_text} " for op in [" AND ", " OR ", " NOT "])
247
+
248
+ if has_boolean:
249
+ # If boolean operators are present, use the raw query
250
+ # No need to prepare it, FTS5 will understand the operators
251
+ params["text"] = search_text
252
+ conditions.append("(title MATCH :text OR content_stems MATCH :text)")
253
+ else:
254
+ # Standard search with term preparation
255
+ processed_text = self._prepare_search_term(search_text.strip())
256
+ params["text"] = processed_text
257
+ conditions.append("(title MATCH :text OR content_stems MATCH :text)")
253
258
 
254
259
  # Handle title match search
255
260
  if title:
@@ -299,7 +299,20 @@ class EntityService(BaseService[EntityModel]):
299
299
  # Mark as incomplete because we still need to add relations
300
300
  model.checksum = None
301
301
  # Repository will set project_id automatically
302
- return await self.repository.add(model)
302
+ try:
303
+ return await self.repository.add(model)
304
+ except IntegrityError as e:
305
+ # Handle race condition where entity was created by another process
306
+ if "UNIQUE constraint failed: entity.file_path" in str(
307
+ e
308
+ ) or "UNIQUE constraint failed: entity.permalink" in str(e):
309
+ logger.info(
310
+ f"Entity already exists for file_path={file_path} (file_path or permalink conflict), updating instead of creating"
311
+ )
312
+ return await self.update_entity_and_observations(file_path, markdown)
313
+ else:
314
+ # Re-raise if it's a different integrity error
315
+ raise
303
316
 
304
317
  async def update_entity_and_observations(
305
318
  self, file_path: Path, markdown: EntityMarkdown
@@ -209,8 +209,29 @@ class ProjectService:
209
209
  db_projects = await self.repository.get_active_projects()
210
210
  db_projects_by_name = {p.name: p for p in db_projects}
211
211
 
212
- # Get all projects from configuration
213
- config_projects = config_manager.projects
212
+ # Get all projects from configuration and normalize names if needed
213
+ config_projects = config_manager.projects.copy()
214
+ updated_config = {}
215
+ config_updated = False
216
+
217
+ for name, path in config_projects.items():
218
+ # Generate normalized name (what the database expects)
219
+ normalized_name = generate_permalink(name)
220
+
221
+ if normalized_name != name:
222
+ logger.info(f"Normalizing project name in config: '{name}' -> '{normalized_name}'")
223
+ config_updated = True
224
+
225
+ updated_config[normalized_name] = path
226
+
227
+ # Update the configuration if any changes were made
228
+ if config_updated:
229
+ config_manager.config.projects = updated_config
230
+ config_manager.save_config(config_manager.config)
231
+ logger.info("Config updated with normalized project names")
232
+
233
+ # Use the normalized config for further processing
234
+ config_projects = updated_config
214
235
 
215
236
  # Add projects that exist in config but not in DB
216
237
  for name, path in config_projects.items():
@@ -219,7 +240,7 @@ class ProjectService:
219
240
  project_data = {
220
241
  "name": name,
221
242
  "path": path,
222
- "permalink": name.lower().replace(" ", "-"),
243
+ "permalink": generate_permalink(name),
223
244
  "is_active": True,
224
245
  # Don't set is_default here - let the enforcement logic handle it
225
246
  }
@@ -364,18 +364,43 @@ class SyncService:
364
364
  content_type = self.file_service.content_type(path)
365
365
 
366
366
  file_path = Path(path)
367
- entity = await self.entity_repository.add(
368
- Entity(
369
- entity_type="file",
370
- file_path=path,
371
- checksum=checksum,
372
- title=file_path.name,
373
- created_at=created,
374
- updated_at=modified,
375
- content_type=content_type,
367
+ try:
368
+ entity = await self.entity_repository.add(
369
+ Entity(
370
+ entity_type="file",
371
+ file_path=path,
372
+ checksum=checksum,
373
+ title=file_path.name,
374
+ created_at=created,
375
+ updated_at=modified,
376
+ content_type=content_type,
377
+ )
376
378
  )
377
- )
378
- return entity, checksum
379
+ return entity, checksum
380
+ except IntegrityError as e:
381
+ # Handle race condition where entity was created by another process
382
+ if "UNIQUE constraint failed: entity.file_path" in str(e):
383
+ logger.info(
384
+ f"Entity already exists for file_path={path}, updating instead of creating"
385
+ )
386
+ # Treat as update instead of create
387
+ entity = await self.entity_repository.get_by_file_path(path)
388
+ if entity is None: # pragma: no cover
389
+ logger.error(f"Entity not found after constraint violation, path={path}")
390
+ raise ValueError(f"Entity not found after constraint violation: {path}")
391
+
392
+ updated = await self.entity_repository.update(
393
+ entity.id, {"file_path": path, "checksum": checksum}
394
+ )
395
+
396
+ if updated is None: # pragma: no cover
397
+ logger.error(f"Failed to update entity, entity_id={entity.id}, path={path}")
398
+ raise ValueError(f"Failed to update entity with ID {entity.id}")
399
+
400
+ return updated, checksum
401
+ else:
402
+ # Re-raise if it's a different integrity error
403
+ raise
379
404
  else:
380
405
  entity = await self.entity_repository.get_by_file_path(path)
381
406
  if entity is None: # pragma: no cover
@@ -50,6 +50,13 @@ read_note("specs/search-design") # By permalink
50
50
  read_note("memory://specs/search") # By memory URL
51
51
  ```
52
52
 
53
+ **Viewing notes as formatted artifacts (Claude Desktop):**
54
+ ```
55
+ view_note("Search Design") # Creates readable artifact
56
+ view_note("specs/search-design") # By permalink
57
+ view_note("memory://specs/search") # By memory URL
58
+ ```
59
+
53
60
  **Incremental editing (v0.13.0) - REQUIRES EXACT IDENTIFIERS:**
54
61
  ```
55
62
  edit_note(