basic-memory 0.13.1__tar.gz → 0.13.3__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 (314) hide show
  1. basic_memory-0.13.3/.claude/commands/release/beta.md +95 -0
  2. basic_memory-0.13.3/.claude/commands/release/release.md +86 -0
  3. {basic_memory-0.13.1 → basic_memory-0.13.3}/PKG-INFO +1 -1
  4. basic_memory-0.13.3/justfile +182 -0
  5. {basic_memory-0.13.1 → basic_memory-0.13.3}/src/basic_memory/__init__.py +4 -1
  6. {basic_memory-0.13.1 → basic_memory-0.13.3}/src/basic_memory/cli/commands/project.py +10 -25
  7. {basic_memory-0.13.1 → basic_memory-0.13.3}/src/basic_memory/config.py +24 -9
  8. {basic_memory-0.13.1 → basic_memory-0.13.3}/src/basic_memory/mcp/tools/project_management.py +28 -16
  9. {basic_memory-0.13.1 → basic_memory-0.13.3}/src/basic_memory/schemas/project_info.py +6 -0
  10. {basic_memory-0.13.1 → basic_memory-0.13.3}/src/basic_memory/services/project_service.py +16 -10
  11. {basic_memory-0.13.1 → basic_memory-0.13.3}/test-int/mcp/test_project_management_integration.py +265 -0
  12. {basic_memory-0.13.1 → basic_memory-0.13.3}/tests/cli/test_project_commands.py +1 -4
  13. {basic_memory-0.13.1 → basic_memory-0.13.3}/tests/conftest.py +0 -1
  14. basic_memory-0.13.1/.claude/commands/release/beta.md +0 -69
  15. basic_memory-0.13.1/.claude/commands/release/release.md +0 -84
  16. basic_memory-0.13.1/justfile +0 -63
  17. {basic_memory-0.13.1 → basic_memory-0.13.3}/.claude/commands/check-health.md +0 -0
  18. {basic_memory-0.13.1 → basic_memory-0.13.3}/.claude/commands/commands.md +0 -0
  19. {basic_memory-0.13.1 → basic_memory-0.13.3}/.claude/commands/lint-fix.md +0 -0
  20. {basic_memory-0.13.1 → basic_memory-0.13.3}/.claude/commands/release/changelog.md +0 -0
  21. {basic_memory-0.13.1 → basic_memory-0.13.3}/.claude/commands/release/release-check.md +0 -0
  22. {basic_memory-0.13.1 → basic_memory-0.13.3}/.claude/commands/test-coverage.md +0 -0
  23. {basic_memory-0.13.1 → basic_memory-0.13.3}/.claude/commands/test-live.md +0 -0
  24. {basic_memory-0.13.1 → basic_memory-0.13.3}/.env.oauth.example +0 -0
  25. {basic_memory-0.13.1 → basic_memory-0.13.3}/.github/ISSUE_TEMPLATE/bug_report.md +0 -0
  26. {basic_memory-0.13.1 → basic_memory-0.13.3}/.github/ISSUE_TEMPLATE/config.yml +0 -0
  27. {basic_memory-0.13.1 → basic_memory-0.13.3}/.github/ISSUE_TEMPLATE/documentation.md +0 -0
  28. {basic_memory-0.13.1 → basic_memory-0.13.3}/.github/ISSUE_TEMPLATE/feature_request.md +0 -0
  29. {basic_memory-0.13.1 → basic_memory-0.13.3}/.github/dependabot.yml +0 -0
  30. {basic_memory-0.13.1 → basic_memory-0.13.3}/.github/workflows/claude.yml +0 -0
  31. {basic_memory-0.13.1 → basic_memory-0.13.3}/.github/workflows/dev-release.yml +0 -0
  32. {basic_memory-0.13.1 → basic_memory-0.13.3}/.github/workflows/pr-title.yml +0 -0
  33. {basic_memory-0.13.1 → basic_memory-0.13.3}/.github/workflows/release.yml +0 -0
  34. {basic_memory-0.13.1 → basic_memory-0.13.3}/.github/workflows/test.yml +0 -0
  35. {basic_memory-0.13.1 → basic_memory-0.13.3}/.gitignore +0 -0
  36. {basic_memory-0.13.1 → basic_memory-0.13.3}/.mcp.json +0 -0
  37. {basic_memory-0.13.1 → basic_memory-0.13.3}/.python-version +0 -0
  38. {basic_memory-0.13.1 → basic_memory-0.13.3}/AUTH.md +0 -0
  39. {basic_memory-0.13.1 → basic_memory-0.13.3}/CHANGELOG.md +0 -0
  40. {basic_memory-0.13.1 → basic_memory-0.13.3}/CITATION.cff +0 -0
  41. {basic_memory-0.13.1 → basic_memory-0.13.3}/CLA.md +0 -0
  42. {basic_memory-0.13.1 → basic_memory-0.13.3}/CLAUDE.md +0 -0
  43. {basic_memory-0.13.1 → basic_memory-0.13.3}/CODE_OF_CONDUCT.md +0 -0
  44. {basic_memory-0.13.1 → basic_memory-0.13.3}/CONTRIBUTING.md +0 -0
  45. {basic_memory-0.13.1 → basic_memory-0.13.3}/Dockerfile +0 -0
  46. {basic_memory-0.13.1 → basic_memory-0.13.3}/LICENSE +0 -0
  47. {basic_memory-0.13.1 → basic_memory-0.13.3}/README.md +0 -0
  48. {basic_memory-0.13.1 → basic_memory-0.13.3}/SECURITY.md +0 -0
  49. {basic_memory-0.13.1 → basic_memory-0.13.3}/basic-memory.md +0 -0
  50. {basic_memory-0.13.1 → basic_memory-0.13.3}/docs/AI Assistant Guide.md +0 -0
  51. {basic_memory-0.13.1 → basic_memory-0.13.3}/docs/CLI Reference.md +0 -0
  52. {basic_memory-0.13.1 → basic_memory-0.13.3}/docs/Canvas.md +0 -0
  53. {basic_memory-0.13.1 → basic_memory-0.13.3}/docs/Claude.ai Integration.md +0 -0
  54. {basic_memory-0.13.1 → basic_memory-0.13.3}/docs/Getting Started with Basic Memory.md +0 -0
  55. {basic_memory-0.13.1 → basic_memory-0.13.3}/docs/Knowledge Format.md +0 -0
  56. {basic_memory-0.13.1 → basic_memory-0.13.3}/docs/OAuth Authentication Guide.md +0 -0
  57. {basic_memory-0.13.1 → basic_memory-0.13.3}/docs/Obsidian Integration.md +0 -0
  58. {basic_memory-0.13.1 → basic_memory-0.13.3}/docs/Supabase OAuth Setup.md +0 -0
  59. {basic_memory-0.13.1 → basic_memory-0.13.3}/docs/Technical Information.md +0 -0
  60. {basic_memory-0.13.1 → basic_memory-0.13.3}/docs/User Guide.md +0 -0
  61. {basic_memory-0.13.1 → basic_memory-0.13.3}/docs/Welcome to Basic memory.md +0 -0
  62. {basic_memory-0.13.1 → basic_memory-0.13.3}/docs/attachments/Canvas.png +0 -0
  63. {basic_memory-0.13.1 → basic_memory-0.13.3}/docs/attachments/Claude-Obsidian-Demo.mp4 +0 -0
  64. {basic_memory-0.13.1 → basic_memory-0.13.3}/docs/attachments/Prompt.png +0 -0
  65. {basic_memory-0.13.1 → basic_memory-0.13.3}/docs/attachments/disk-ai-logo-400x400.png +0 -0
  66. {basic_memory-0.13.1 → basic_memory-0.13.3}/docs/attachments/disk-ai-logo.png +0 -0
  67. {basic_memory-0.13.1 → basic_memory-0.13.3}/docs/attachments/prompt 1.png +0 -0
  68. {basic_memory-0.13.1 → basic_memory-0.13.3}/docs/attachments/prompt2.png +0 -0
  69. {basic_memory-0.13.1 → basic_memory-0.13.3}/docs/attachments/prompt3.png +0 -0
  70. {basic_memory-0.13.1 → basic_memory-0.13.3}/docs/attachments/prompt4.png +0 -0
  71. {basic_memory-0.13.1 → basic_memory-0.13.3}/docs/publish.js +0 -0
  72. {basic_memory-0.13.1 → basic_memory-0.13.3}/examples/Coffee Notes/Brewing Equipment.md +0 -0
  73. {basic_memory-0.13.1 → basic_memory-0.13.3}/examples/Coffee Notes/Coffee Bean Origins.md +0 -0
  74. {basic_memory-0.13.1 → basic_memory-0.13.3}/examples/Coffee Notes/Coffee Brewing Methods.md +0 -0
  75. {basic_memory-0.13.1 → basic_memory-0.13.3}/examples/Coffee Notes/Coffee Flavor Map.md +0 -0
  76. {basic_memory-0.13.1 → basic_memory-0.13.3}/examples/Coffee Notes/Coffee Knowledge Base.md +0 -0
  77. {basic_memory-0.13.1 → basic_memory-0.13.3}/examples/Coffee Notes/Flavor Extraction.md +0 -0
  78. {basic_memory-0.13.1 → basic_memory-0.13.3}/examples/Coffee Notes/Perfect Pour Over Coffee Method.canvas +0 -0
  79. {basic_memory-0.13.1 → basic_memory-0.13.3}/examples/Coffee Notes/Tasting Notes.md +0 -0
  80. {basic_memory-0.13.1 → basic_memory-0.13.3}/examples/testing/Test Note Creation - Basic Functionality.md +0 -0
  81. {basic_memory-0.13.1 → basic_memory-0.13.3}/llms-install.md +0 -0
  82. {basic_memory-0.13.1 → basic_memory-0.13.3}/memory.json +0 -0
  83. {basic_memory-0.13.1 → basic_memory-0.13.3}/pyproject.toml +0 -0
  84. {basic_memory-0.13.1 → basic_memory-0.13.3}/scripts/install.sh +0 -0
  85. {basic_memory-0.13.1 → basic_memory-0.13.3}/smithery.yaml +0 -0
  86. {basic_memory-0.13.1 → basic_memory-0.13.3}/src/basic_memory/alembic/alembic.ini +0 -0
  87. {basic_memory-0.13.1 → basic_memory-0.13.3}/src/basic_memory/alembic/env.py +0 -0
  88. {basic_memory-0.13.1 → basic_memory-0.13.3}/src/basic_memory/alembic/migrations.py +0 -0
  89. {basic_memory-0.13.1 → basic_memory-0.13.3}/src/basic_memory/alembic/script.py.mako +0 -0
  90. {basic_memory-0.13.1 → basic_memory-0.13.3}/src/basic_memory/alembic/versions/3dae7c7b1564_initial_schema.py +0 -0
  91. {basic_memory-0.13.1 → basic_memory-0.13.3}/src/basic_memory/alembic/versions/502b60eaa905_remove_required_from_entity_permalink.py +0 -0
  92. {basic_memory-0.13.1 → basic_memory-0.13.3}/src/basic_memory/alembic/versions/5fe1ab1ccebe_add_projects_table.py +0 -0
  93. {basic_memory-0.13.1 → basic_memory-0.13.3}/src/basic_memory/alembic/versions/647e7a75e2cd_project_constraint_fix.py +0 -0
  94. {basic_memory-0.13.1 → basic_memory-0.13.3}/src/basic_memory/alembic/versions/b3c3938bacdb_relation_to_name_unique_index.py +0 -0
  95. {basic_memory-0.13.1 → basic_memory-0.13.3}/src/basic_memory/alembic/versions/cc7172b46608_update_search_index_schema.py +0 -0
  96. {basic_memory-0.13.1 → basic_memory-0.13.3}/src/basic_memory/api/__init__.py +0 -0
  97. {basic_memory-0.13.1 → basic_memory-0.13.3}/src/basic_memory/api/app.py +0 -0
  98. {basic_memory-0.13.1 → basic_memory-0.13.3}/src/basic_memory/api/routers/__init__.py +0 -0
  99. {basic_memory-0.13.1 → basic_memory-0.13.3}/src/basic_memory/api/routers/directory_router.py +0 -0
  100. {basic_memory-0.13.1 → basic_memory-0.13.3}/src/basic_memory/api/routers/importer_router.py +0 -0
  101. {basic_memory-0.13.1 → basic_memory-0.13.3}/src/basic_memory/api/routers/knowledge_router.py +0 -0
  102. {basic_memory-0.13.1 → basic_memory-0.13.3}/src/basic_memory/api/routers/management_router.py +0 -0
  103. {basic_memory-0.13.1 → basic_memory-0.13.3}/src/basic_memory/api/routers/memory_router.py +0 -0
  104. {basic_memory-0.13.1 → basic_memory-0.13.3}/src/basic_memory/api/routers/project_router.py +0 -0
  105. {basic_memory-0.13.1 → basic_memory-0.13.3}/src/basic_memory/api/routers/prompt_router.py +0 -0
  106. {basic_memory-0.13.1 → basic_memory-0.13.3}/src/basic_memory/api/routers/resource_router.py +0 -0
  107. {basic_memory-0.13.1 → basic_memory-0.13.3}/src/basic_memory/api/routers/search_router.py +0 -0
  108. {basic_memory-0.13.1 → basic_memory-0.13.3}/src/basic_memory/api/routers/utils.py +0 -0
  109. {basic_memory-0.13.1 → basic_memory-0.13.3}/src/basic_memory/api/template_loader.py +0 -0
  110. {basic_memory-0.13.1 → basic_memory-0.13.3}/src/basic_memory/cli/__init__.py +0 -0
  111. {basic_memory-0.13.1 → basic_memory-0.13.3}/src/basic_memory/cli/app.py +0 -0
  112. {basic_memory-0.13.1 → basic_memory-0.13.3}/src/basic_memory/cli/commands/__init__.py +0 -0
  113. {basic_memory-0.13.1 → basic_memory-0.13.3}/src/basic_memory/cli/commands/auth.py +0 -0
  114. {basic_memory-0.13.1 → basic_memory-0.13.3}/src/basic_memory/cli/commands/db.py +0 -0
  115. {basic_memory-0.13.1 → basic_memory-0.13.3}/src/basic_memory/cli/commands/import_chatgpt.py +0 -0
  116. {basic_memory-0.13.1 → basic_memory-0.13.3}/src/basic_memory/cli/commands/import_claude_conversations.py +0 -0
  117. {basic_memory-0.13.1 → basic_memory-0.13.3}/src/basic_memory/cli/commands/import_claude_projects.py +0 -0
  118. {basic_memory-0.13.1 → basic_memory-0.13.3}/src/basic_memory/cli/commands/import_memory_json.py +0 -0
  119. {basic_memory-0.13.1 → basic_memory-0.13.3}/src/basic_memory/cli/commands/mcp.py +0 -0
  120. {basic_memory-0.13.1 → basic_memory-0.13.3}/src/basic_memory/cli/commands/status.py +0 -0
  121. {basic_memory-0.13.1 → basic_memory-0.13.3}/src/basic_memory/cli/commands/sync.py +0 -0
  122. {basic_memory-0.13.1 → basic_memory-0.13.3}/src/basic_memory/cli/commands/tool.py +0 -0
  123. {basic_memory-0.13.1 → basic_memory-0.13.3}/src/basic_memory/cli/main.py +0 -0
  124. {basic_memory-0.13.1 → basic_memory-0.13.3}/src/basic_memory/db.py +0 -0
  125. {basic_memory-0.13.1 → basic_memory-0.13.3}/src/basic_memory/deps.py +0 -0
  126. {basic_memory-0.13.1 → basic_memory-0.13.3}/src/basic_memory/file_utils.py +0 -0
  127. {basic_memory-0.13.1 → basic_memory-0.13.3}/src/basic_memory/importers/__init__.py +0 -0
  128. {basic_memory-0.13.1 → basic_memory-0.13.3}/src/basic_memory/importers/base.py +0 -0
  129. {basic_memory-0.13.1 → basic_memory-0.13.3}/src/basic_memory/importers/chatgpt_importer.py +0 -0
  130. {basic_memory-0.13.1 → basic_memory-0.13.3}/src/basic_memory/importers/claude_conversations_importer.py +0 -0
  131. {basic_memory-0.13.1 → basic_memory-0.13.3}/src/basic_memory/importers/claude_projects_importer.py +0 -0
  132. {basic_memory-0.13.1 → basic_memory-0.13.3}/src/basic_memory/importers/memory_json_importer.py +0 -0
  133. {basic_memory-0.13.1 → basic_memory-0.13.3}/src/basic_memory/importers/utils.py +0 -0
  134. {basic_memory-0.13.1 → basic_memory-0.13.3}/src/basic_memory/markdown/__init__.py +0 -0
  135. {basic_memory-0.13.1 → basic_memory-0.13.3}/src/basic_memory/markdown/entity_parser.py +0 -0
  136. {basic_memory-0.13.1 → basic_memory-0.13.3}/src/basic_memory/markdown/markdown_processor.py +0 -0
  137. {basic_memory-0.13.1 → basic_memory-0.13.3}/src/basic_memory/markdown/plugins.py +0 -0
  138. {basic_memory-0.13.1 → basic_memory-0.13.3}/src/basic_memory/markdown/schemas.py +0 -0
  139. {basic_memory-0.13.1 → basic_memory-0.13.3}/src/basic_memory/markdown/utils.py +0 -0
  140. {basic_memory-0.13.1 → basic_memory-0.13.3}/src/basic_memory/mcp/__init__.py +0 -0
  141. {basic_memory-0.13.1 → basic_memory-0.13.3}/src/basic_memory/mcp/async_client.py +0 -0
  142. {basic_memory-0.13.1 → basic_memory-0.13.3}/src/basic_memory/mcp/auth_provider.py +0 -0
  143. {basic_memory-0.13.1 → basic_memory-0.13.3}/src/basic_memory/mcp/external_auth_provider.py +0 -0
  144. {basic_memory-0.13.1 → basic_memory-0.13.3}/src/basic_memory/mcp/project_session.py +0 -0
  145. {basic_memory-0.13.1 → basic_memory-0.13.3}/src/basic_memory/mcp/prompts/__init__.py +0 -0
  146. {basic_memory-0.13.1 → basic_memory-0.13.3}/src/basic_memory/mcp/prompts/ai_assistant_guide.py +0 -0
  147. {basic_memory-0.13.1 → basic_memory-0.13.3}/src/basic_memory/mcp/prompts/continue_conversation.py +0 -0
  148. {basic_memory-0.13.1 → basic_memory-0.13.3}/src/basic_memory/mcp/prompts/recent_activity.py +0 -0
  149. {basic_memory-0.13.1 → basic_memory-0.13.3}/src/basic_memory/mcp/prompts/search.py +0 -0
  150. {basic_memory-0.13.1 → basic_memory-0.13.3}/src/basic_memory/mcp/prompts/sync_status.py +0 -0
  151. {basic_memory-0.13.1 → basic_memory-0.13.3}/src/basic_memory/mcp/prompts/utils.py +0 -0
  152. {basic_memory-0.13.1 → basic_memory-0.13.3}/src/basic_memory/mcp/resources/ai_assistant_guide.md +0 -0
  153. {basic_memory-0.13.1 → basic_memory-0.13.3}/src/basic_memory/mcp/resources/project_info.py +0 -0
  154. {basic_memory-0.13.1 → basic_memory-0.13.3}/src/basic_memory/mcp/server.py +0 -0
  155. {basic_memory-0.13.1 → basic_memory-0.13.3}/src/basic_memory/mcp/supabase_auth_provider.py +0 -0
  156. {basic_memory-0.13.1 → basic_memory-0.13.3}/src/basic_memory/mcp/tools/__init__.py +0 -0
  157. {basic_memory-0.13.1 → basic_memory-0.13.3}/src/basic_memory/mcp/tools/build_context.py +0 -0
  158. {basic_memory-0.13.1 → basic_memory-0.13.3}/src/basic_memory/mcp/tools/canvas.py +0 -0
  159. {basic_memory-0.13.1 → basic_memory-0.13.3}/src/basic_memory/mcp/tools/delete_note.py +0 -0
  160. {basic_memory-0.13.1 → basic_memory-0.13.3}/src/basic_memory/mcp/tools/edit_note.py +0 -0
  161. {basic_memory-0.13.1 → basic_memory-0.13.3}/src/basic_memory/mcp/tools/list_directory.py +0 -0
  162. {basic_memory-0.13.1 → basic_memory-0.13.3}/src/basic_memory/mcp/tools/move_note.py +0 -0
  163. {basic_memory-0.13.1 → basic_memory-0.13.3}/src/basic_memory/mcp/tools/read_content.py +0 -0
  164. {basic_memory-0.13.1 → basic_memory-0.13.3}/src/basic_memory/mcp/tools/read_note.py +0 -0
  165. {basic_memory-0.13.1 → basic_memory-0.13.3}/src/basic_memory/mcp/tools/recent_activity.py +0 -0
  166. {basic_memory-0.13.1 → basic_memory-0.13.3}/src/basic_memory/mcp/tools/search.py +0 -0
  167. {basic_memory-0.13.1 → basic_memory-0.13.3}/src/basic_memory/mcp/tools/sync_status.py +0 -0
  168. {basic_memory-0.13.1 → basic_memory-0.13.3}/src/basic_memory/mcp/tools/utils.py +0 -0
  169. {basic_memory-0.13.1 → basic_memory-0.13.3}/src/basic_memory/mcp/tools/view_note.py +0 -0
  170. {basic_memory-0.13.1 → basic_memory-0.13.3}/src/basic_memory/mcp/tools/write_note.py +0 -0
  171. {basic_memory-0.13.1 → basic_memory-0.13.3}/src/basic_memory/models/__init__.py +0 -0
  172. {basic_memory-0.13.1 → basic_memory-0.13.3}/src/basic_memory/models/base.py +0 -0
  173. {basic_memory-0.13.1 → basic_memory-0.13.3}/src/basic_memory/models/knowledge.py +0 -0
  174. {basic_memory-0.13.1 → basic_memory-0.13.3}/src/basic_memory/models/project.py +0 -0
  175. {basic_memory-0.13.1 → basic_memory-0.13.3}/src/basic_memory/models/search.py +0 -0
  176. {basic_memory-0.13.1 → basic_memory-0.13.3}/src/basic_memory/repository/__init__.py +0 -0
  177. {basic_memory-0.13.1 → basic_memory-0.13.3}/src/basic_memory/repository/entity_repository.py +0 -0
  178. {basic_memory-0.13.1 → basic_memory-0.13.3}/src/basic_memory/repository/observation_repository.py +0 -0
  179. {basic_memory-0.13.1 → basic_memory-0.13.3}/src/basic_memory/repository/project_info_repository.py +0 -0
  180. {basic_memory-0.13.1 → basic_memory-0.13.3}/src/basic_memory/repository/project_repository.py +0 -0
  181. {basic_memory-0.13.1 → basic_memory-0.13.3}/src/basic_memory/repository/relation_repository.py +0 -0
  182. {basic_memory-0.13.1 → basic_memory-0.13.3}/src/basic_memory/repository/repository.py +0 -0
  183. {basic_memory-0.13.1 → basic_memory-0.13.3}/src/basic_memory/repository/search_repository.py +0 -0
  184. {basic_memory-0.13.1 → basic_memory-0.13.3}/src/basic_memory/schemas/__init__.py +0 -0
  185. {basic_memory-0.13.1 → basic_memory-0.13.3}/src/basic_memory/schemas/base.py +0 -0
  186. {basic_memory-0.13.1 → basic_memory-0.13.3}/src/basic_memory/schemas/delete.py +0 -0
  187. {basic_memory-0.13.1 → basic_memory-0.13.3}/src/basic_memory/schemas/directory.py +0 -0
  188. {basic_memory-0.13.1 → basic_memory-0.13.3}/src/basic_memory/schemas/importer.py +0 -0
  189. {basic_memory-0.13.1 → basic_memory-0.13.3}/src/basic_memory/schemas/memory.py +0 -0
  190. {basic_memory-0.13.1 → basic_memory-0.13.3}/src/basic_memory/schemas/prompt.py +0 -0
  191. {basic_memory-0.13.1 → basic_memory-0.13.3}/src/basic_memory/schemas/request.py +0 -0
  192. {basic_memory-0.13.1 → basic_memory-0.13.3}/src/basic_memory/schemas/response.py +0 -0
  193. {basic_memory-0.13.1 → basic_memory-0.13.3}/src/basic_memory/schemas/search.py +0 -0
  194. {basic_memory-0.13.1 → basic_memory-0.13.3}/src/basic_memory/services/__init__.py +0 -0
  195. {basic_memory-0.13.1 → basic_memory-0.13.3}/src/basic_memory/services/context_service.py +0 -0
  196. {basic_memory-0.13.1 → basic_memory-0.13.3}/src/basic_memory/services/directory_service.py +0 -0
  197. {basic_memory-0.13.1 → basic_memory-0.13.3}/src/basic_memory/services/entity_service.py +0 -0
  198. {basic_memory-0.13.1 → basic_memory-0.13.3}/src/basic_memory/services/exceptions.py +0 -0
  199. {basic_memory-0.13.1 → basic_memory-0.13.3}/src/basic_memory/services/file_service.py +0 -0
  200. {basic_memory-0.13.1 → basic_memory-0.13.3}/src/basic_memory/services/initialization.py +0 -0
  201. {basic_memory-0.13.1 → basic_memory-0.13.3}/src/basic_memory/services/link_resolver.py +0 -0
  202. {basic_memory-0.13.1 → basic_memory-0.13.3}/src/basic_memory/services/migration_service.py +0 -0
  203. {basic_memory-0.13.1 → basic_memory-0.13.3}/src/basic_memory/services/search_service.py +0 -0
  204. {basic_memory-0.13.1 → basic_memory-0.13.3}/src/basic_memory/services/service.py +0 -0
  205. {basic_memory-0.13.1 → basic_memory-0.13.3}/src/basic_memory/services/sync_status_service.py +0 -0
  206. {basic_memory-0.13.1 → basic_memory-0.13.3}/src/basic_memory/sync/__init__.py +0 -0
  207. {basic_memory-0.13.1 → basic_memory-0.13.3}/src/basic_memory/sync/background_sync.py +0 -0
  208. {basic_memory-0.13.1 → basic_memory-0.13.3}/src/basic_memory/sync/sync_service.py +0 -0
  209. {basic_memory-0.13.1 → basic_memory-0.13.3}/src/basic_memory/sync/watch_service.py +0 -0
  210. {basic_memory-0.13.1 → basic_memory-0.13.3}/src/basic_memory/templates/prompts/continue_conversation.hbs +0 -0
  211. {basic_memory-0.13.1 → basic_memory-0.13.3}/src/basic_memory/templates/prompts/search.hbs +0 -0
  212. {basic_memory-0.13.1 → basic_memory-0.13.3}/src/basic_memory/utils.py +0 -0
  213. {basic_memory-0.13.1 → basic_memory-0.13.3}/static/ai_assistant_guide.md +0 -0
  214. {basic_memory-0.13.1 → basic_memory-0.13.3}/static/json_canvas_spec_1_0.md +0 -0
  215. {basic_memory-0.13.1 → basic_memory-0.13.3}/test-int/conftest.py +0 -0
  216. {basic_memory-0.13.1 → basic_memory-0.13.3}/test-int/mcp/test_build_context_validation.py +0 -0
  217. {basic_memory-0.13.1 → basic_memory-0.13.3}/test-int/mcp/test_delete_note_integration.py +0 -0
  218. {basic_memory-0.13.1 → basic_memory-0.13.3}/test-int/mcp/test_edit_note_integration.py +0 -0
  219. {basic_memory-0.13.1 → basic_memory-0.13.3}/test-int/mcp/test_list_directory_integration.py +0 -0
  220. {basic_memory-0.13.1 → basic_memory-0.13.3}/test-int/mcp/test_move_note_integration.py +0 -0
  221. {basic_memory-0.13.1 → basic_memory-0.13.3}/test-int/mcp/test_read_content_integration.py +0 -0
  222. {basic_memory-0.13.1 → basic_memory-0.13.3}/test-int/mcp/test_read_note_integration.py +0 -0
  223. {basic_memory-0.13.1 → basic_memory-0.13.3}/test-int/mcp/test_search_integration.py +0 -0
  224. {basic_memory-0.13.1 → basic_memory-0.13.3}/test-int/mcp/test_write_note_integration.py +0 -0
  225. {basic_memory-0.13.1 → basic_memory-0.13.3}/tests/Non-MarkdownFileSupport.pdf +0 -0
  226. {basic_memory-0.13.1 → basic_memory-0.13.3}/tests/Screenshot.png +0 -0
  227. {basic_memory-0.13.1 → basic_memory-0.13.3}/tests/__init__.py +0 -0
  228. {basic_memory-0.13.1 → basic_memory-0.13.3}/tests/api/conftest.py +0 -0
  229. {basic_memory-0.13.1 → basic_memory-0.13.3}/tests/api/test_continue_conversation_template.py +0 -0
  230. {basic_memory-0.13.1 → basic_memory-0.13.3}/tests/api/test_directory_router.py +0 -0
  231. {basic_memory-0.13.1 → basic_memory-0.13.3}/tests/api/test_importer_router.py +0 -0
  232. {basic_memory-0.13.1 → basic_memory-0.13.3}/tests/api/test_knowledge_router.py +0 -0
  233. {basic_memory-0.13.1 → basic_memory-0.13.3}/tests/api/test_management_router.py +0 -0
  234. {basic_memory-0.13.1 → basic_memory-0.13.3}/tests/api/test_memory_router.py +0 -0
  235. {basic_memory-0.13.1 → basic_memory-0.13.3}/tests/api/test_project_router.py +0 -0
  236. {basic_memory-0.13.1 → basic_memory-0.13.3}/tests/api/test_project_router_operations.py +0 -0
  237. {basic_memory-0.13.1 → basic_memory-0.13.3}/tests/api/test_prompt_router.py +0 -0
  238. {basic_memory-0.13.1 → basic_memory-0.13.3}/tests/api/test_resource_router.py +0 -0
  239. {basic_memory-0.13.1 → basic_memory-0.13.3}/tests/api/test_search_router.py +0 -0
  240. {basic_memory-0.13.1 → basic_memory-0.13.3}/tests/api/test_search_template.py +0 -0
  241. {basic_memory-0.13.1 → basic_memory-0.13.3}/tests/api/test_template_loader.py +0 -0
  242. {basic_memory-0.13.1 → basic_memory-0.13.3}/tests/api/test_template_loader_helpers.py +0 -0
  243. {basic_memory-0.13.1 → basic_memory-0.13.3}/tests/cli/conftest.py +0 -0
  244. {basic_memory-0.13.1 → basic_memory-0.13.3}/tests/cli/test_auth_commands.py +0 -0
  245. {basic_memory-0.13.1 → basic_memory-0.13.3}/tests/cli/test_cli_tools.py +0 -0
  246. {basic_memory-0.13.1 → basic_memory-0.13.3}/tests/cli/test_import_chatgpt.py +0 -0
  247. {basic_memory-0.13.1 → basic_memory-0.13.3}/tests/cli/test_import_claude_conversations.py +0 -0
  248. {basic_memory-0.13.1 → basic_memory-0.13.3}/tests/cli/test_import_claude_projects.py +0 -0
  249. {basic_memory-0.13.1 → basic_memory-0.13.3}/tests/cli/test_import_memory_json.py +0 -0
  250. {basic_memory-0.13.1 → basic_memory-0.13.3}/tests/cli/test_project_info.py +0 -0
  251. {basic_memory-0.13.1 → basic_memory-0.13.3}/tests/cli/test_status.py +0 -0
  252. {basic_memory-0.13.1 → basic_memory-0.13.3}/tests/cli/test_sync.py +0 -0
  253. {basic_memory-0.13.1 → basic_memory-0.13.3}/tests/cli/test_version.py +0 -0
  254. {basic_memory-0.13.1 → basic_memory-0.13.3}/tests/importers/test_importer_base.py +0 -0
  255. {basic_memory-0.13.1 → basic_memory-0.13.3}/tests/importers/test_importer_utils.py +0 -0
  256. {basic_memory-0.13.1 → basic_memory-0.13.3}/tests/markdown/__init__.py +0 -0
  257. {basic_memory-0.13.1 → basic_memory-0.13.3}/tests/markdown/test_entity_parser.py +0 -0
  258. {basic_memory-0.13.1 → basic_memory-0.13.3}/tests/markdown/test_markdown_plugins.py +0 -0
  259. {basic_memory-0.13.1 → basic_memory-0.13.3}/tests/markdown/test_markdown_processor.py +0 -0
  260. {basic_memory-0.13.1 → basic_memory-0.13.3}/tests/markdown/test_observation_edge_cases.py +0 -0
  261. {basic_memory-0.13.1 → basic_memory-0.13.3}/tests/markdown/test_parser_edge_cases.py +0 -0
  262. {basic_memory-0.13.1 → basic_memory-0.13.3}/tests/markdown/test_relation_edge_cases.py +0 -0
  263. {basic_memory-0.13.1 → basic_memory-0.13.3}/tests/markdown/test_task_detection.py +0 -0
  264. {basic_memory-0.13.1 → basic_memory-0.13.3}/tests/mcp/conftest.py +0 -0
  265. {basic_memory-0.13.1 → basic_memory-0.13.3}/tests/mcp/test_auth_provider.py +0 -0
  266. {basic_memory-0.13.1 → basic_memory-0.13.3}/tests/mcp/test_prompts.py +0 -0
  267. {basic_memory-0.13.1 → basic_memory-0.13.3}/tests/mcp/test_resource_project_info.py +0 -0
  268. {basic_memory-0.13.1 → basic_memory-0.13.3}/tests/mcp/test_resources.py +0 -0
  269. {basic_memory-0.13.1 → basic_memory-0.13.3}/tests/mcp/test_server.py +0 -0
  270. {basic_memory-0.13.1 → basic_memory-0.13.3}/tests/mcp/test_tool_build_context.py +0 -0
  271. {basic_memory-0.13.1 → basic_memory-0.13.3}/tests/mcp/test_tool_canvas.py +0 -0
  272. {basic_memory-0.13.1 → basic_memory-0.13.3}/tests/mcp/test_tool_delete_note.py +0 -0
  273. {basic_memory-0.13.1 → basic_memory-0.13.3}/tests/mcp/test_tool_edit_note.py +0 -0
  274. {basic_memory-0.13.1 → basic_memory-0.13.3}/tests/mcp/test_tool_list_directory.py +0 -0
  275. {basic_memory-0.13.1 → basic_memory-0.13.3}/tests/mcp/test_tool_move_note.py +0 -0
  276. {basic_memory-0.13.1 → basic_memory-0.13.3}/tests/mcp/test_tool_read_note.py +0 -0
  277. {basic_memory-0.13.1 → basic_memory-0.13.3}/tests/mcp/test_tool_recent_activity.py +0 -0
  278. {basic_memory-0.13.1 → basic_memory-0.13.3}/tests/mcp/test_tool_resource.py +0 -0
  279. {basic_memory-0.13.1 → basic_memory-0.13.3}/tests/mcp/test_tool_search.py +0 -0
  280. {basic_memory-0.13.1 → basic_memory-0.13.3}/tests/mcp/test_tool_sync_status.py +0 -0
  281. {basic_memory-0.13.1 → basic_memory-0.13.3}/tests/mcp/test_tool_utils.py +0 -0
  282. {basic_memory-0.13.1 → basic_memory-0.13.3}/tests/mcp/test_tool_view_note.py +0 -0
  283. {basic_memory-0.13.1 → basic_memory-0.13.3}/tests/mcp/test_tool_write_note.py +0 -0
  284. {basic_memory-0.13.1 → basic_memory-0.13.3}/tests/repository/test_entity_repository.py +0 -0
  285. {basic_memory-0.13.1 → basic_memory-0.13.3}/tests/repository/test_observation_repository.py +0 -0
  286. {basic_memory-0.13.1 → basic_memory-0.13.3}/tests/repository/test_project_info_repository.py +0 -0
  287. {basic_memory-0.13.1 → basic_memory-0.13.3}/tests/repository/test_project_repository.py +0 -0
  288. {basic_memory-0.13.1 → basic_memory-0.13.3}/tests/repository/test_relation_repository.py +0 -0
  289. {basic_memory-0.13.1 → basic_memory-0.13.3}/tests/repository/test_repository.py +0 -0
  290. {basic_memory-0.13.1 → basic_memory-0.13.3}/tests/repository/test_search_repository.py +0 -0
  291. {basic_memory-0.13.1 → basic_memory-0.13.3}/tests/schemas/test_memory_url.py +0 -0
  292. {basic_memory-0.13.1 → basic_memory-0.13.3}/tests/schemas/test_memory_url_validation.py +0 -0
  293. {basic_memory-0.13.1 → basic_memory-0.13.3}/tests/schemas/test_schemas.py +0 -0
  294. {basic_memory-0.13.1 → basic_memory-0.13.3}/tests/schemas/test_search.py +0 -0
  295. {basic_memory-0.13.1 → basic_memory-0.13.3}/tests/services/test_context_service.py +0 -0
  296. {basic_memory-0.13.1 → basic_memory-0.13.3}/tests/services/test_directory_service.py +0 -0
  297. {basic_memory-0.13.1 → basic_memory-0.13.3}/tests/services/test_entity_service.py +0 -0
  298. {basic_memory-0.13.1 → basic_memory-0.13.3}/tests/services/test_file_service.py +0 -0
  299. {basic_memory-0.13.1 → basic_memory-0.13.3}/tests/services/test_initialization.py +0 -0
  300. {basic_memory-0.13.1 → basic_memory-0.13.3}/tests/services/test_link_resolver.py +0 -0
  301. {basic_memory-0.13.1 → basic_memory-0.13.3}/tests/services/test_project_service.py +0 -0
  302. {basic_memory-0.13.1 → basic_memory-0.13.3}/tests/services/test_project_service_operations.py +0 -0
  303. {basic_memory-0.13.1 → basic_memory-0.13.3}/tests/services/test_search_service.py +0 -0
  304. {basic_memory-0.13.1 → basic_memory-0.13.3}/tests/services/test_sync_status_service.py +0 -0
  305. {basic_memory-0.13.1 → basic_memory-0.13.3}/tests/sync/test_sync_service.py +0 -0
  306. {basic_memory-0.13.1 → basic_memory-0.13.3}/tests/sync/test_sync_wikilink_issue.py +0 -0
  307. {basic_memory-0.13.1 → basic_memory-0.13.3}/tests/sync/test_tmp_files.py +0 -0
  308. {basic_memory-0.13.1 → basic_memory-0.13.3}/tests/sync/test_watch_service.py +0 -0
  309. {basic_memory-0.13.1 → basic_memory-0.13.3}/tests/sync/test_watch_service_edge_cases.py +0 -0
  310. {basic_memory-0.13.1 → basic_memory-0.13.3}/tests/utils/test_file_utils.py +0 -0
  311. {basic_memory-0.13.1 → basic_memory-0.13.3}/tests/utils/test_parse_tags.py +0 -0
  312. {basic_memory-0.13.1 → basic_memory-0.13.3}/tests/utils/test_permalink_formatting.py +0 -0
  313. {basic_memory-0.13.1 → basic_memory-0.13.3}/tests/utils/test_utf8_handling.py +0 -0
  314. {basic_memory-0.13.1 → basic_memory-0.13.3}/uv.lock +0 -0
@@ -0,0 +1,95 @@
1
+ # /beta - Create Beta Release
2
+
3
+ Create a new beta release using the automated justfile target with quality checks and tagging.
4
+
5
+ ## Usage
6
+ ```
7
+ /beta <version>
8
+ ```
9
+
10
+ **Parameters:**
11
+ - `version` (required): Beta version like `v0.13.2b1` or `v0.13.2rc1`
12
+
13
+ ## Implementation
14
+
15
+ You are an expert release manager for the Basic Memory project. When the user runs `/beta`, execute the following steps:
16
+
17
+ ### Step 1: Pre-flight Validation
18
+ 1. Verify version format matches `v\d+\.\d+\.\d+(b\d+|rc\d+)` pattern
19
+ 2. Check current git status for uncommitted changes
20
+ 3. Verify we're on the `main` branch
21
+ 4. Confirm no existing tag with this version
22
+
23
+ ### Step 2: Use Justfile Automation
24
+ Execute the automated beta release process:
25
+ ```bash
26
+ just beta <version>
27
+ ```
28
+
29
+ The justfile target handles:
30
+ - ✅ Beta version format validation (supports b1, b2, rc1, etc.)
31
+ - ✅ Git status and branch checks
32
+ - ✅ Quality checks (`just check` - lint, format, type-check, tests)
33
+ - ✅ Version update in `src/basic_memory/__init__.py`
34
+ - ✅ Automatic commit with proper message
35
+ - ✅ Tag creation and pushing to GitHub
36
+ - ✅ Beta release workflow trigger
37
+
38
+ ### Step 3: Monitor Beta Release
39
+ 1. Check GitHub Actions workflow starts successfully
40
+ 2. Monitor workflow at: https://github.com/basicmachines-co/basic-memory/actions
41
+ 3. Verify PyPI pre-release publication
42
+ 4. Test beta installation: `uv tool install basic-memory --pre`
43
+
44
+ ### Step 4: Beta Testing Instructions
45
+ Provide users with beta testing instructions:
46
+
47
+ ```bash
48
+ # Install/upgrade to beta
49
+ uv tool install basic-memory --pre
50
+
51
+ # Or upgrade existing installation
52
+ uv tool upgrade basic-memory --prerelease=allow
53
+ ```
54
+
55
+ ## Version Guidelines
56
+ - **First beta**: `v0.13.2b1`
57
+ - **Subsequent betas**: `v0.13.2b2`, `v0.13.2b3`, etc.
58
+ - **Release candidates**: `v0.13.2rc1`, `v0.13.2rc2`, etc.
59
+ - **Final release**: `v0.13.2` (use `/release` command)
60
+
61
+ ## Error Handling
62
+ - If `just beta` fails, examine the error output for specific issues
63
+ - If quality checks fail, fix issues and retry
64
+ - If version format is invalid, correct and retry
65
+ - If tag already exists, increment version number
66
+
67
+ ## Success Output
68
+ ```
69
+ ✅ Beta Release v0.13.2b1 Created Successfully!
70
+
71
+ 🏷️ Tag: v0.13.2b1
72
+ 🚀 GitHub Actions: Running
73
+ 📦 PyPI: Will be available in ~5 minutes as pre-release
74
+
75
+ Install/test with:
76
+ uv tool install basic-memory --pre
77
+
78
+ Monitor release: https://github.com/basicmachines-co/basic-memory/actions
79
+ ```
80
+
81
+ ## Beta Testing Workflow
82
+ 1. **Create beta**: Use `/beta v0.13.2b1`
83
+ 2. **Test features**: Install and validate new functionality
84
+ 3. **Fix issues**: Address bugs found during testing
85
+ 4. **Iterate**: Create `v0.13.2b2` if needed
86
+ 5. **Release candidate**: Create `v0.13.2rc1` when stable
87
+ 6. **Final release**: Use `/release v0.13.2` when ready
88
+
89
+ ## Context
90
+ - Beta releases are pre-releases for testing new features
91
+ - Automatically published to PyPI with pre-release flag
92
+ - Uses the automated justfile target for consistency
93
+ - Version is automatically updated in `__init__.py`
94
+ - Ideal for validating changes before stable release
95
+ - Supports both beta (b1, b2) and release candidate (rc1, rc2) versions
@@ -0,0 +1,86 @@
1
+ # /release - Create Stable Release
2
+
3
+ Create a stable release using the automated justfile target with comprehensive validation.
4
+
5
+ ## Usage
6
+ ```
7
+ /release <version>
8
+ ```
9
+
10
+ **Parameters:**
11
+ - `version` (required): Release version like `v0.13.2`
12
+
13
+ ## Implementation
14
+
15
+ You are an expert release manager for the Basic Memory project. When the user runs `/release`, execute the following steps:
16
+
17
+ ### Step 1: Pre-flight Validation
18
+ 1. Verify version format matches `v\d+\.\d+\.\d+` pattern
19
+ 2. Check current git status for uncommitted changes
20
+ 3. Verify we're on the `main` branch
21
+ 4. Confirm no existing tag with this version
22
+
23
+ ### Step 2: Use Justfile Automation
24
+ Execute the automated release process:
25
+ ```bash
26
+ just release <version>
27
+ ```
28
+
29
+ The justfile target handles:
30
+ - ✅ Version format validation
31
+ - ✅ Git status and branch checks
32
+ - ✅ Quality checks (`just check` - lint, format, type-check, tests)
33
+ - ✅ Version update in `src/basic_memory/__init__.py`
34
+ - ✅ Automatic commit with proper message
35
+ - ✅ Tag creation and pushing to GitHub
36
+ - ✅ Release workflow trigger
37
+
38
+ ### Step 3: Monitor Release Process
39
+ 1. Check that GitHub Actions workflow starts successfully
40
+ 2. Monitor workflow completion at: https://github.com/basicmachines-co/basic-memory/actions
41
+ 3. Verify PyPI publication
42
+ 4. Test installation: `uv tool install basic-memory`
43
+
44
+ ### Step 4: Post-Release Validation
45
+ 1. Verify GitHub release is created automatically
46
+ 2. Check PyPI publication
47
+ 3. Validate release assets
48
+ 4. Update any post-release documentation
49
+
50
+ ## Pre-conditions Check
51
+ Before starting, verify:
52
+ - [ ] All beta testing is complete
53
+ - [ ] Critical bugs are fixed
54
+ - [ ] Breaking changes are documented
55
+ - [ ] CHANGELOG.md is updated (if needed)
56
+ - [ ] Version number follows semantic versioning
57
+
58
+ ## Error Handling
59
+ - If `just release` fails, examine the error output for specific issues
60
+ - If quality checks fail, fix issues and retry
61
+ - If changelog entry missing, update CHANGELOG.md and commit before retrying
62
+ - If GitHub Actions fail, check workflow logs for debugging
63
+
64
+ ## Success Output
65
+ ```
66
+ 🎉 Stable Release v0.13.2 Created Successfully!
67
+
68
+ 🏷️ Tag: v0.13.2
69
+ 📋 GitHub Release: https://github.com/basicmachines-co/basic-memory/releases/tag/v0.13.2
70
+ 📦 PyPI: https://pypi.org/project/basic-memory/0.13.2/
71
+ 🚀 GitHub Actions: Completed
72
+
73
+ Install with:
74
+ uv tool install basic-memory
75
+
76
+ Users can now upgrade:
77
+ uv tool upgrade basic-memory
78
+ ```
79
+
80
+ ## Context
81
+ - This creates production releases used by end users
82
+ - Must pass all quality gates before proceeding
83
+ - Uses the automated justfile target for consistency
84
+ - Version is automatically updated in `__init__.py`
85
+ - Triggers automated GitHub release with changelog
86
+ - Leverages uv-dynamic-versioning for package version management
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: basic-memory
3
- Version: 0.13.1
3
+ Version: 0.13.3
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
@@ -0,0 +1,182 @@
1
+ # Basic Memory - Modern Command Runner
2
+
3
+ # Install dependencies
4
+ install:
5
+ pip install -e ".[dev]"
6
+
7
+ # Run unit tests in parallel
8
+ test-unit:
9
+ uv run pytest -p pytest_mock -v -n auto
10
+
11
+ # Run integration tests in parallel
12
+ test-int:
13
+ uv run pytest -p pytest_mock -v --no-cov -n auto test-int
14
+
15
+ # Run all tests
16
+ test: test-unit test-int
17
+
18
+ # Lint and fix code
19
+ lint:
20
+ ruff check . --fix
21
+
22
+ # Type check code
23
+ type-check:
24
+ uv run pyright
25
+
26
+ # Clean build artifacts and cache files
27
+ clean:
28
+ find . -type f -name '*.pyc' -delete
29
+ find . -type d -name '__pycache__' -exec rm -r {} +
30
+ rm -rf installer/build/ installer/dist/ dist/
31
+ rm -f rw.*.dmg .coverage.*
32
+
33
+ # Format code with ruff
34
+ format:
35
+ uv run ruff format .
36
+
37
+ # Run MCP inspector tool
38
+ run-inspector:
39
+ npx @modelcontextprotocol/inspector
40
+
41
+ # Build macOS installer
42
+ installer-mac:
43
+ cd installer && chmod +x make_icons.sh && ./make_icons.sh
44
+ cd installer && uv run python setup.py bdist_mac
45
+
46
+ # Build Windows installer
47
+ installer-win:
48
+ cd installer && uv run python setup.py bdist_win32
49
+
50
+ # Update all dependencies to latest versions
51
+ update-deps:
52
+ uv sync --upgrade
53
+
54
+ # Run all code quality checks and tests
55
+ check: lint format type-check test
56
+
57
+ # Generate Alembic migration with descriptive message
58
+ migration message:
59
+ cd src/basic_memory/alembic && alembic revision --autogenerate -m "{{message}}"
60
+
61
+ # Create a stable release (e.g., just release v0.13.2)
62
+ release version:
63
+ #!/usr/bin/env bash
64
+ set -euo pipefail
65
+
66
+ # Validate version format
67
+ if [[ ! "{{version}}" =~ ^v[0-9]+\.[0-9]+\.[0-9]+$ ]]; then
68
+ echo "❌ Invalid version format. Use: v0.13.2"
69
+ exit 1
70
+ fi
71
+
72
+ # Extract version number without 'v' prefix
73
+ VERSION_NUM=$(echo "{{version}}" | sed 's/^v//')
74
+
75
+ echo "🚀 Creating stable release {{version}}"
76
+
77
+ # Pre-flight checks
78
+ echo "📋 Running pre-flight checks..."
79
+ if [[ -n $(git status --porcelain) ]]; then
80
+ echo "❌ Uncommitted changes found. Please commit or stash them first."
81
+ exit 1
82
+ fi
83
+
84
+ if [[ $(git branch --show-current) != "main" ]]; then
85
+ echo "❌ Not on main branch. Switch to main first."
86
+ exit 1
87
+ fi
88
+
89
+ # Check if tag already exists
90
+ if git tag -l "{{version}}" | grep -q "{{version}}"; then
91
+ echo "❌ Tag {{version}} already exists"
92
+ exit 1
93
+ fi
94
+
95
+ # Run quality checks
96
+ echo "🔍 Running quality checks..."
97
+ just check
98
+
99
+ # Update version in __init__.py
100
+ echo "📝 Updating version in __init__.py..."
101
+ sed -i.bak "s/__version__ = \".*\"/__version__ = \"$VERSION_NUM\"/" src/basic_memory/__init__.py
102
+ rm -f src/basic_memory/__init__.py.bak
103
+
104
+ # Commit version update
105
+ git add src/basic_memory/__init__.py
106
+ git commit -m "chore: update version to $VERSION_NUM for {{version}} release"
107
+
108
+ # Create and push tag
109
+ echo "🏷️ Creating tag {{version}}..."
110
+ git tag "{{version}}"
111
+
112
+ echo "📤 Pushing to GitHub..."
113
+ git push origin main
114
+ git push origin "{{version}}"
115
+
116
+ echo "✅ Release {{version}} created successfully!"
117
+ echo "📦 GitHub Actions will build and publish to PyPI"
118
+ echo "🔗 Monitor at: https://github.com/basicmachines-co/basic-memory/actions"
119
+
120
+ # Create a beta release (e.g., just beta v0.13.2b1)
121
+ beta version:
122
+ #!/usr/bin/env bash
123
+ set -euo pipefail
124
+
125
+ # Validate version format (allow beta/rc suffixes)
126
+ if [[ ! "{{version}}" =~ ^v[0-9]+\.[0-9]+\.[0-9]+(b[0-9]+|rc[0-9]+)$ ]]; then
127
+ echo "❌ Invalid beta version format. Use: v0.13.2b1 or v0.13.2rc1"
128
+ exit 1
129
+ fi
130
+
131
+ # Extract version number without 'v' prefix
132
+ VERSION_NUM=$(echo "{{version}}" | sed 's/^v//')
133
+
134
+ echo "🧪 Creating beta release {{version}}"
135
+
136
+ # Pre-flight checks
137
+ echo "📋 Running pre-flight checks..."
138
+ if [[ -n $(git status --porcelain) ]]; then
139
+ echo "❌ Uncommitted changes found. Please commit or stash them first."
140
+ exit 1
141
+ fi
142
+
143
+ if [[ $(git branch --show-current) != "main" ]]; then
144
+ echo "❌ Not on main branch. Switch to main first."
145
+ exit 1
146
+ fi
147
+
148
+ # Check if tag already exists
149
+ if git tag -l "{{version}}" | grep -q "{{version}}"; then
150
+ echo "❌ Tag {{version}} already exists"
151
+ exit 1
152
+ fi
153
+
154
+ # Run quality checks
155
+ echo "🔍 Running quality checks..."
156
+ just check
157
+
158
+ # Update version in __init__.py
159
+ echo "📝 Updating version in __init__.py..."
160
+ sed -i.bak "s/__version__ = \".*\"/__version__ = \"$VERSION_NUM\"/" src/basic_memory/__init__.py
161
+ rm -f src/basic_memory/__init__.py.bak
162
+
163
+ # Commit version update
164
+ git add src/basic_memory/__init__.py
165
+ git commit -m "chore: update version to $VERSION_NUM for {{version}} beta release"
166
+
167
+ # Create and push tag
168
+ echo "🏷️ Creating tag {{version}}..."
169
+ git tag "{{version}}"
170
+
171
+ echo "📤 Pushing to GitHub..."
172
+ git push origin main
173
+ git push origin "{{version}}"
174
+
175
+ echo "✅ Beta release {{version}} created successfully!"
176
+ echo "📦 GitHub Actions will build and publish to PyPI as pre-release"
177
+ echo "🔗 Monitor at: https://github.com/basicmachines-co/basic-memory/actions"
178
+ echo "📥 Install with: uv tool install basic-memory --pre"
179
+
180
+ # List all available recipes
181
+ default:
182
+ @just --list
@@ -1,4 +1,7 @@
1
1
  """basic-memory - Local-first knowledge management combining Zettelkasten with knowledge graphs"""
2
2
 
3
+ # Package version - updated by release automation
4
+ __version__ = "0.13.3"
5
+
3
6
  # API version for FastAPI - independent of package version
4
- __version__ = "v0"
7
+ __api_version__ = "v0"
@@ -9,7 +9,6 @@ from rich.console import Console
9
9
  from rich.table import Table
10
10
 
11
11
  from basic_memory.cli.app import app
12
- from basic_memory.config import config
13
12
  from basic_memory.mcp.project_session import session
14
13
  from basic_memory.mcp.resources.project_info import project_info
15
14
  import json
@@ -24,6 +23,7 @@ from basic_memory.mcp.tools.utils import call_post
24
23
  from basic_memory.schemas.project_info import ProjectStatusResponse
25
24
  from basic_memory.mcp.tools.utils import call_delete
26
25
  from basic_memory.mcp.tools.utils import call_put
26
+ from basic_memory.utils import generate_permalink
27
27
 
28
28
  console = Console()
29
29
 
@@ -44,11 +44,8 @@ def format_path(path: str) -> str:
44
44
  def list_projects() -> None:
45
45
  """List all configured projects."""
46
46
  # Use API to list projects
47
-
48
- project_url = config.project_url
49
-
50
47
  try:
51
- response = asyncio.run(call_get(client, f"{project_url}/project/projects"))
48
+ response = asyncio.run(call_get(client, "/projects/projects"))
52
49
  result = ProjectList.model_validate(response.json())
53
50
 
54
51
  table = Table(title="Basic Memory Projects")
@@ -65,7 +62,6 @@ def list_projects() -> None:
65
62
  console.print(table)
66
63
  except Exception as e:
67
64
  console.print(f"[red]Error listing projects: {str(e)}[/red]")
68
- console.print("[yellow]Note: Make sure the Basic Memory server is running.[/yellow]")
69
65
  raise typer.Exit(1)
70
66
 
71
67
 
@@ -80,16 +76,14 @@ def add_project(
80
76
  resolved_path = os.path.abspath(os.path.expanduser(path))
81
77
 
82
78
  try:
83
- project_url = config.project_url
84
79
  data = {"name": name, "path": resolved_path, "set_default": set_default}
85
80
 
86
- response = asyncio.run(call_post(client, f"{project_url}/project/projects", json=data))
81
+ response = asyncio.run(call_post(client, "/projects/projects", json=data))
87
82
  result = ProjectStatusResponse.model_validate(response.json())
88
83
 
89
84
  console.print(f"[green]{result.message}[/green]")
90
85
  except Exception as e:
91
86
  console.print(f"[red]Error adding project: {str(e)}[/red]")
92
- console.print("[yellow]Note: Make sure the Basic Memory server is running.[/yellow]")
93
87
  raise typer.Exit(1)
94
88
 
95
89
  # Display usage hint
@@ -105,15 +99,13 @@ def remove_project(
105
99
  ) -> None:
106
100
  """Remove a project from configuration."""
107
101
  try:
108
- project_url = config.project_url
109
-
110
- response = asyncio.run(call_delete(client, f"{project_url}/project/projects/{name}"))
102
+ project_name = generate_permalink(name)
103
+ response = asyncio.run(call_delete(client, f"/projects/{project_name}"))
111
104
  result = ProjectStatusResponse.model_validate(response.json())
112
105
 
113
106
  console.print(f"[green]{result.message}[/green]")
114
107
  except Exception as e:
115
108
  console.print(f"[red]Error removing project: {str(e)}[/red]")
116
- console.print("[yellow]Note: Make sure the Basic Memory server is running.[/yellow]")
117
109
  raise typer.Exit(1)
118
110
 
119
111
  # Show this message regardless of method used
@@ -126,20 +118,16 @@ def set_default_project(
126
118
  ) -> None:
127
119
  """Set the default project and activate it for the current session."""
128
120
  try:
129
- project_url = config.project_url
121
+ project_name = generate_permalink(name)
130
122
 
131
- response = asyncio.run(call_put(client, f"{project_url}/project/projects/{name}/default"))
123
+ response = asyncio.run(call_put(client, f"projects/{project_name}/default"))
132
124
  result = ProjectStatusResponse.model_validate(response.json())
133
125
 
134
126
  console.print(f"[green]{result.message}[/green]")
135
127
  except Exception as e:
136
128
  console.print(f"[red]Error setting default project: {str(e)}[/red]")
137
- console.print("[yellow]Note: Make sure the Basic Memory server is running.[/yellow]")
138
129
  raise typer.Exit(1)
139
130
 
140
- # Always activate it for the current session
141
- os.environ["BASIC_MEMORY_PROJECT"] = name
142
-
143
131
  # Reload configuration to apply the change
144
132
  from importlib import reload
145
133
  from basic_memory import config as config_module
@@ -149,21 +137,18 @@ def set_default_project(
149
137
  console.print("[green]Project activated for current session[/green]")
150
138
 
151
139
 
152
- @project_app.command("sync")
140
+ @project_app.command("sync-config")
153
141
  def synchronize_projects() -> None:
154
- """Synchronize projects between configuration file and database."""
142
+ """Synchronize project config between configuration file and database."""
155
143
  # Call the API to synchronize projects
156
144
 
157
- project_url = config.project_url
158
-
159
145
  try:
160
- response = asyncio.run(call_post(client, f"{project_url}/project/sync"))
146
+ response = asyncio.run(call_post(client, "/projects/sync"))
161
147
  result = ProjectStatusResponse.model_validate(response.json())
162
148
 
163
149
  console.print(f"[green]{result.message}[/green]")
164
150
  except Exception as e: # pragma: no cover
165
151
  console.print(f"[red]Error synchronizing projects: {str(e)}[/red]")
166
- console.print("[yellow]Note: Make sure the Basic Memory server is running.[/yellow]")
167
152
  raise typer.Exit(1)
168
153
 
169
154
 
@@ -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")
264
279
 
265
280
 
266
281
  # Create config manager
@@ -9,13 +9,13 @@ 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
16
15
  from basic_memory.mcp.tools.utils import call_get, call_put, call_post, call_delete
17
16
  from basic_memory.schemas import ProjectInfoResponse
18
17
  from basic_memory.schemas.project_info import ProjectList, ProjectStatusResponse, ProjectInfoRequest
18
+ from basic_memory.utils import generate_permalink
19
19
 
20
20
 
21
21
  @mcp.tool()
@@ -77,33 +77,45 @@ async def switch_project(project_name: str, ctx: Context | None = None) -> str:
77
77
  if ctx: # pragma: no cover
78
78
  await ctx.info(f"Switching to project: {project_name}")
79
79
 
80
+ project_permalink = generate_permalink(project_name)
80
81
  current_project = session.get_current_project()
81
82
  try:
82
83
  # Validate project exists by getting project list
83
84
  response = await call_get(client, "/projects/projects")
84
85
  project_list = ProjectList.model_validate(response.json())
85
86
 
86
- # Check if project exists
87
- project_exists = any(p.name == project_name for p in project_list.projects)
88
- 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:
89
100
  available_projects = [p.name for p in project_list.projects]
90
101
  return f"Error: Project '{project_name}' not found. Available projects: {', '.join(available_projects)}"
91
102
 
92
- # Switch to the project
93
- session.set_current_project(project_name)
103
+ # Switch to the project using the canonical name from database
104
+ canonical_name = target_project.name
105
+ session.set_current_project(canonical_name)
94
106
  current_project = session.get_current_project()
95
- project_config = get_project_config(current_project)
96
107
 
97
108
  # Get project info to show summary
98
109
  try:
110
+ current_project_permalink = generate_permalink(canonical_name)
99
111
  response = await call_get(
100
112
  client,
101
- f"{project_config.project_url}/project/info",
102
- params={"project_name": project_name},
113
+ f"/{current_project_permalink}/project/info",
114
+ params={"project_name": canonical_name},
103
115
  )
104
116
  project_info = ProjectInfoResponse.model_validate(response.json())
105
117
 
106
- result = f"✓ Switched to {project_name} project\n\n"
118
+ result = f"✓ Switched to {canonical_name} project\n\n"
107
119
  result += "Project Summary:\n"
108
120
  result += f"• {project_info.statistics.total_entities} entities\n"
109
121
  result += f"• {project_info.statistics.total_observations} observations\n"
@@ -111,11 +123,11 @@ async def switch_project(project_name: str, ctx: Context | None = None) -> str:
111
123
 
112
124
  except Exception as e:
113
125
  # If we can't get project info, still confirm the switch
114
- logger.warning(f"Could not get project info for {project_name}: {e}")
115
- 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"
116
128
  result += "Project summary unavailable.\n"
117
129
 
118
- return add_project_metadata(result, project_name)
130
+ return add_project_metadata(result, canonical_name)
119
131
 
120
132
  except Exception as e:
121
133
  logger.error(f"Error switching to project {project_name}: {e}")
@@ -163,13 +175,13 @@ async def get_current_project(ctx: Context | None = None) -> str:
163
175
  await ctx.info("Getting current project information")
164
176
 
165
177
  current_project = session.get_current_project()
166
- project_config = get_project_config(current_project)
167
178
  result = f"Current project: {current_project}\n\n"
168
179
 
169
- # get project stats
180
+ # get project stats (use permalink in URL path)
181
+ current_project_permalink = generate_permalink(current_project)
170
182
  response = await call_get(
171
183
  client,
172
- f"{project_config.project_url}/project/info",
184
+ f"/{current_project_permalink}/project/info",
173
185
  params={"project_name": current_project},
174
186
  )
175
187
  project_info = ProjectInfoResponse.model_validate(response.json())