basic-memory 0.17.4__tar.gz → 0.17.6__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.
Files changed (431) hide show
  1. {basic_memory-0.17.4 → basic_memory-0.17.6}/.github/workflows/test.yml +3 -3
  2. basic_memory-0.17.6/.python-version +1 -0
  3. {basic_memory-0.17.4 → basic_memory-0.17.6}/CHANGELOG.md +24 -0
  4. {basic_memory-0.17.4 → basic_memory-0.17.6}/Dockerfile +10 -4
  5. {basic_memory-0.17.4 → basic_memory-0.17.6}/PKG-INFO +5 -2
  6. {basic_memory-0.17.4 → basic_memory-0.17.6}/justfile +10 -0
  7. {basic_memory-0.17.4 → basic_memory-0.17.6}/pyproject.toml +7 -6
  8. {basic_memory-0.17.4 → basic_memory-0.17.6}/src/basic_memory/__init__.py +1 -1
  9. {basic_memory-0.17.4 → basic_memory-0.17.6}/src/basic_memory/alembic/env.py +12 -8
  10. {basic_memory-0.17.4 → basic_memory-0.17.6}/src/basic_memory/alembic/versions/6830751f5fb6_merge_multiple_heads.py +3 -3
  11. {basic_memory-0.17.4 → basic_memory-0.17.6}/src/basic_memory/api/v2/routers/knowledge_router.py +1 -3
  12. {basic_memory-0.17.4 → basic_memory-0.17.6}/src/basic_memory/api/v2/routers/project_router.py +1 -3
  13. {basic_memory-0.17.4 → basic_memory-0.17.6}/src/basic_memory/cli/app.py +0 -6
  14. {basic_memory-0.17.4 → basic_memory-0.17.6}/src/basic_memory/cli/commands/cloud/core_commands.py +5 -7
  15. {basic_memory-0.17.4 → basic_memory-0.17.6}/src/basic_memory/cli/commands/cloud/rclone_commands.py +1 -0
  16. {basic_memory-0.17.4 → basic_memory-0.17.6}/src/basic_memory/cli/commands/cloud/upload_command.py +2 -2
  17. {basic_memory-0.17.4 → basic_memory-0.17.6}/src/basic_memory/cli/commands/command_utils.py +6 -2
  18. {basic_memory-0.17.4 → basic_memory-0.17.6}/src/basic_memory/cli/commands/db.py +5 -3
  19. {basic_memory-0.17.4 → basic_memory-0.17.6}/src/basic_memory/cli/commands/format.py +2 -2
  20. {basic_memory-0.17.4 → basic_memory-0.17.6}/src/basic_memory/cli/commands/import_chatgpt.py +3 -3
  21. {basic_memory-0.17.4 → basic_memory-0.17.6}/src/basic_memory/cli/commands/import_claude_conversations.py +3 -3
  22. {basic_memory-0.17.4 → basic_memory-0.17.6}/src/basic_memory/cli/commands/import_claude_projects.py +3 -3
  23. {basic_memory-0.17.4 → basic_memory-0.17.6}/src/basic_memory/cli/commands/import_memory_json.py +3 -3
  24. {basic_memory-0.17.4 → basic_memory-0.17.6}/src/basic_memory/cli/commands/project.py +19 -20
  25. {basic_memory-0.17.4 → basic_memory-0.17.6}/src/basic_memory/cli/commands/tool.py +7 -7
  26. {basic_memory-0.17.4 → basic_memory-0.17.6}/src/basic_memory/deps/projects.py +1 -3
  27. {basic_memory-0.17.4 → basic_memory-0.17.6}/src/basic_memory/deps/repositories.py +6 -2
  28. {basic_memory-0.17.4 → basic_memory-0.17.6}/src/basic_memory/deps/services.py +6 -2
  29. {basic_memory-0.17.4 → basic_memory-0.17.6}/src/basic_memory/mcp/container.py +1 -3
  30. {basic_memory-0.17.4 → basic_memory-0.17.6}/src/basic_memory/mcp/server.py +3 -3
  31. {basic_memory-0.17.4 → basic_memory-0.17.6}/src/basic_memory/mcp/tools/canvas.py +3 -1
  32. {basic_memory-0.17.4 → basic_memory-0.17.6}/src/basic_memory/mcp/tools/read_content.py +3 -1
  33. {basic_memory-0.17.4 → basic_memory-0.17.6}/src/basic_memory/mcp/tools/recent_activity.py +14 -4
  34. {basic_memory-0.17.4 → basic_memory-0.17.6}/src/basic_memory/mcp/tools/utils.py +6 -2
  35. {basic_memory-0.17.4 → basic_memory-0.17.6}/src/basic_memory/mcp/tools/write_note.py +3 -1
  36. {basic_memory-0.17.4 → basic_memory-0.17.6}/src/basic_memory/models/knowledge.py +1 -3
  37. {basic_memory-0.17.4 → basic_memory-0.17.6}/src/basic_memory/models/project.py +1 -3
  38. {basic_memory-0.17.4 → basic_memory-0.17.6}/src/basic_memory/repository/entity_repository.py +1 -3
  39. {basic_memory-0.17.4 → basic_memory-0.17.6}/src/basic_memory/repository/relation_repository.py +3 -3
  40. {basic_memory-0.17.4 → basic_memory-0.17.6}/src/basic_memory/repository/repository.py +4 -3
  41. {basic_memory-0.17.4 → basic_memory-0.17.6}/src/basic_memory/runtime.py +1 -1
  42. {basic_memory-0.17.4 → basic_memory-0.17.6}/src/basic_memory/services/context_service.py +3 -1
  43. {basic_memory-0.17.4 → basic_memory-0.17.6}/src/basic_memory/sync/coordinator.py +1 -1
  44. {basic_memory-0.17.4 → basic_memory-0.17.6}/src/basic_memory/sync/sync_service.py +3 -1
  45. {basic_memory-0.17.4 → basic_memory-0.17.6}/src/basic_memory/telemetry.py +87 -16
  46. {basic_memory-0.17.4 → basic_memory-0.17.6}/test-int/mcp/test_lifespan_shutdown_sync_task_cancellation_integration.py +3 -1
  47. {basic_memory-0.17.4 → basic_memory-0.17.6}/tests/api/test_directory_router.py +0 -1
  48. {basic_memory-0.17.4 → basic_memory-0.17.6}/tests/api/test_management_router.py +0 -2
  49. {basic_memory-0.17.4 → basic_memory-0.17.6}/tests/api/test_project_router.py +4 -2
  50. {basic_memory-0.17.4 → basic_memory-0.17.6}/tests/api/test_relation_background_resolution.py +2 -0
  51. {basic_memory-0.17.4 → basic_memory-0.17.6}/tests/api/v2/test_knowledge_router.py +3 -1
  52. {basic_memory-0.17.4 → basic_memory-0.17.6}/tests/api/v2/test_project_router.py +7 -3
  53. {basic_memory-0.17.4 → basic_memory-0.17.6}/tests/cli/cloud/test_cloud_api_client_and_utils.py +9 -5
  54. {basic_memory-0.17.4 → basic_memory-0.17.6}/tests/cli/cloud/test_rclone_config_and_bmignore_filters.py +0 -2
  55. {basic_memory-0.17.4 → basic_memory-0.17.6}/tests/cli/cloud/test_upload_path.py +3 -3
  56. {basic_memory-0.17.4 → basic_memory-0.17.6}/tests/cli/test_auth_cli_auth.py +9 -4
  57. {basic_memory-0.17.4 → basic_memory-0.17.6}/tests/cli/test_cli_tool_exit.py +3 -1
  58. basic_memory-0.17.6/tests/cli/test_cli_tools.py +38 -0
  59. {basic_memory-0.17.4 → basic_memory-0.17.6}/tests/cli/test_cloud_authentication.py +0 -2
  60. {basic_memory-0.17.4 → basic_memory-0.17.6}/tests/mcp/clients/test_clients.py +0 -1
  61. {basic_memory-0.17.4 → basic_memory-0.17.6}/tests/mcp/test_async_client_modes.py +0 -2
  62. {basic_memory-0.17.4 → basic_memory-0.17.6}/tests/mcp/test_project_context.py +0 -2
  63. {basic_memory-0.17.4 → basic_memory-0.17.6}/tests/mcp/test_recent_activity_prompt_modes.py +16 -6
  64. {basic_memory-0.17.4 → basic_memory-0.17.6}/tests/mcp/test_server_lifespan_branches.py +0 -3
  65. {basic_memory-0.17.4 → basic_memory-0.17.6}/tests/mcp/test_tool_move_note.py +0 -2
  66. {basic_memory-0.17.4 → basic_memory-0.17.6}/tests/mcp/test_tool_project_management.py +0 -2
  67. {basic_memory-0.17.4 → basic_memory-0.17.6}/tests/mcp/test_tool_read_content.py +0 -2
  68. {basic_memory-0.17.4 → basic_memory-0.17.6}/tests/mcp/test_tool_recent_activity.py +1 -2
  69. {basic_memory-0.17.4 → basic_memory-0.17.6}/tests/repository/test_postgres_search_repository.py +9 -5
  70. {basic_memory-0.17.4 → basic_memory-0.17.6}/tests/schemas/test_relation_response_reference_resolution.py +0 -3
  71. {basic_memory-0.17.4 → basic_memory-0.17.6}/tests/services/test_initialization.py +12 -6
  72. {basic_memory-0.17.4 → basic_memory-0.17.6}/tests/services/test_initialization_cloud_mode_branches.py +5 -3
  73. {basic_memory-0.17.4 → basic_memory-0.17.6}/tests/services/test_project_service_operations.py +0 -2
  74. {basic_memory-0.17.4 → basic_memory-0.17.6}/tests/sync/test_watch_service_atomic_adds.py +0 -2
  75. {basic_memory-0.17.4 → basic_memory-0.17.6}/tests/sync/test_watch_service_reload.py +0 -2
  76. {basic_memory-0.17.4 → basic_memory-0.17.6}/tests/test_rclone_commands.py +56 -19
  77. {basic_memory-0.17.4 → basic_memory-0.17.6}/tests/test_runtime.py +0 -1
  78. {basic_memory-0.17.4 → basic_memory-0.17.6}/tests/test_telemetry.py +45 -23
  79. basic_memory-0.17.6/uv.lock +2704 -0
  80. basic_memory-0.17.4/.python-version +0 -1
  81. basic_memory-0.17.4/specs/SPEC-1 Specification-Driven Development Process.md +0 -156
  82. basic_memory-0.17.4/specs/SPEC-10 Unified Deployment Workflow and Event Tracking.md +0 -569
  83. basic_memory-0.17.4/specs/SPEC-11 Basic Memory API Performance Optimization.md +0 -186
  84. basic_memory-0.17.4/specs/SPEC-12 OpenTelemetry Observability.md +0 -182
  85. basic_memory-0.17.4/specs/SPEC-13 CLI Authentication with Subscription Validation.md +0 -917
  86. basic_memory-0.17.4/specs/SPEC-14 Cloud Git Versioning & GitHub Backup.md +0 -210
  87. basic_memory-0.17.4/specs/SPEC-14- Cloud Git Versioning & GitHub Backup.md +0 -210
  88. basic_memory-0.17.4/specs/SPEC-15 Configuration Persistence via Tigris for Cloud Tenants.md +0 -273
  89. basic_memory-0.17.4/specs/SPEC-16 MCP Cloud Service Consolidation.md +0 -800
  90. basic_memory-0.17.4/specs/SPEC-17 Semantic Search with ChromaDB.md +0 -1439
  91. basic_memory-0.17.4/specs/SPEC-18 AI Memory Management Tool.md +0 -528
  92. basic_memory-0.17.4/specs/SPEC-19 Sync Performance and Memory Optimization.md +0 -1046
  93. basic_memory-0.17.4/specs/SPEC-2 Slash Commands Reference.md +0 -120
  94. basic_memory-0.17.4/specs/SPEC-20 Simplified Project-Scoped Rclone Sync.md +0 -1216
  95. basic_memory-0.17.4/specs/SPEC-3 Agent Definitions.md +0 -108
  96. basic_memory-0.17.4/specs/SPEC-4 Notes Web UI Component Architecture.md +0 -311
  97. basic_memory-0.17.4/specs/SPEC-5 CLI Cloud Upload via WebDAV.md +0 -201
  98. basic_memory-0.17.4/specs/SPEC-6 Explicit Project Parameter Architecture.md +0 -497
  99. basic_memory-0.17.4/specs/SPEC-7 POC to spike Tigris Turso for local access to cloud data.md +0 -324
  100. basic_memory-0.17.4/specs/SPEC-8 TigrisFS Integration.md +0 -886
  101. basic_memory-0.17.4/specs/SPEC-9 Multi-Project Bidirectional Sync Architecture.md +0 -1114
  102. basic_memory-0.17.4/specs/SPEC-9 Signed Header Tenant Information.md +0 -196
  103. basic_memory-0.17.4/specs/SPEC-9-1 Follow-Ups- Conflict, Sync, and Observability.md +0 -390
  104. basic_memory-0.17.4/tests/cli/test_cli_tools.py +0 -500
  105. basic_memory-0.17.4/uv.lock +0 -2363
  106. {basic_memory-0.17.4 → basic_memory-0.17.6}/.claude/commands/release/beta.md +0 -0
  107. {basic_memory-0.17.4 → basic_memory-0.17.6}/.claude/commands/release/changelog.md +0 -0
  108. {basic_memory-0.17.4 → basic_memory-0.17.6}/.claude/commands/release/release-check.md +0 -0
  109. {basic_memory-0.17.4 → basic_memory-0.17.6}/.claude/commands/release/release.md +0 -0
  110. {basic_memory-0.17.4 → basic_memory-0.17.6}/.claude/commands/spec.md +0 -0
  111. {basic_memory-0.17.4 → basic_memory-0.17.6}/.claude/commands/test-live.md +0 -0
  112. {basic_memory-0.17.4 → basic_memory-0.17.6}/.claude/settings.json +0 -0
  113. {basic_memory-0.17.4 → basic_memory-0.17.6}/.dockerignore +0 -0
  114. {basic_memory-0.17.4 → basic_memory-0.17.6}/.env.example +0 -0
  115. {basic_memory-0.17.4 → basic_memory-0.17.6}/.github/ISSUE_TEMPLATE/bug_report.md +0 -0
  116. {basic_memory-0.17.4 → basic_memory-0.17.6}/.github/ISSUE_TEMPLATE/config.yml +0 -0
  117. {basic_memory-0.17.4 → basic_memory-0.17.6}/.github/ISSUE_TEMPLATE/documentation.md +0 -0
  118. {basic_memory-0.17.4 → basic_memory-0.17.6}/.github/ISSUE_TEMPLATE/feature_request.md +0 -0
  119. {basic_memory-0.17.4 → basic_memory-0.17.6}/.github/dependabot.yml +0 -0
  120. {basic_memory-0.17.4 → basic_memory-0.17.6}/.github/workflows/claude-code-review.yml +0 -0
  121. {basic_memory-0.17.4 → basic_memory-0.17.6}/.github/workflows/claude-issue-triage.yml +0 -0
  122. {basic_memory-0.17.4 → basic_memory-0.17.6}/.github/workflows/claude.yml +0 -0
  123. {basic_memory-0.17.4 → basic_memory-0.17.6}/.github/workflows/dev-release.yml +0 -0
  124. {basic_memory-0.17.4 → basic_memory-0.17.6}/.github/workflows/docker.yml +0 -0
  125. {basic_memory-0.17.4 → basic_memory-0.17.6}/.github/workflows/pr-title.yml +0 -0
  126. {basic_memory-0.17.4 → basic_memory-0.17.6}/.github/workflows/release.yml +0 -0
  127. {basic_memory-0.17.4 → basic_memory-0.17.6}/.gitignore +0 -0
  128. {basic_memory-0.17.4 → basic_memory-0.17.6}/CITATION.cff +0 -0
  129. {basic_memory-0.17.4 → basic_memory-0.17.6}/CLA.md +0 -0
  130. {basic_memory-0.17.4 → basic_memory-0.17.6}/CLAUDE.md +0 -0
  131. {basic_memory-0.17.4 → basic_memory-0.17.6}/CODE_OF_CONDUCT.md +0 -0
  132. {basic_memory-0.17.4 → basic_memory-0.17.6}/CONTRIBUTING.md +0 -0
  133. {basic_memory-0.17.4 → basic_memory-0.17.6}/LICENSE +0 -0
  134. {basic_memory-0.17.4 → basic_memory-0.17.6}/README.md +0 -0
  135. {basic_memory-0.17.4 → basic_memory-0.17.6}/SECURITY.md +0 -0
  136. {basic_memory-0.17.4 → basic_memory-0.17.6}/docker-compose-postgres.yml +0 -0
  137. {basic_memory-0.17.4 → basic_memory-0.17.6}/docker-compose.yml +0 -0
  138. {basic_memory-0.17.4 → basic_memory-0.17.6}/docs/ARCHITECTURE.md +0 -0
  139. {basic_memory-0.17.4 → basic_memory-0.17.6}/docs/Docker.md +0 -0
  140. {basic_memory-0.17.4 → basic_memory-0.17.6}/docs/ai-assistant-guide-extended.md +0 -0
  141. {basic_memory-0.17.4 → basic_memory-0.17.6}/docs/character-handling.md +0 -0
  142. {basic_memory-0.17.4 → basic_memory-0.17.6}/docs/cloud-cli.md +0 -0
  143. {basic_memory-0.17.4 → basic_memory-0.17.6}/docs/testing-coverage.md +0 -0
  144. {basic_memory-0.17.4 → basic_memory-0.17.6}/llms-install.md +0 -0
  145. {basic_memory-0.17.4 → basic_memory-0.17.6}/smithery.yaml +0 -0
  146. {basic_memory-0.17.4 → basic_memory-0.17.6}/src/basic_memory/alembic/alembic.ini +0 -0
  147. {basic_memory-0.17.4 → basic_memory-0.17.6}/src/basic_memory/alembic/migrations.py +0 -0
  148. {basic_memory-0.17.4 → basic_memory-0.17.6}/src/basic_memory/alembic/script.py.mako +0 -0
  149. {basic_memory-0.17.4 → basic_memory-0.17.6}/src/basic_memory/alembic/versions/314f1ea54dc4_add_postgres_full_text_search_support_.py +0 -0
  150. {basic_memory-0.17.4 → basic_memory-0.17.6}/src/basic_memory/alembic/versions/3dae7c7b1564_initial_schema.py +0 -0
  151. {basic_memory-0.17.4 → basic_memory-0.17.6}/src/basic_memory/alembic/versions/502b60eaa905_remove_required_from_entity_permalink.py +0 -0
  152. {basic_memory-0.17.4 → basic_memory-0.17.6}/src/basic_memory/alembic/versions/5fe1ab1ccebe_add_projects_table.py +0 -0
  153. {basic_memory-0.17.4 → basic_memory-0.17.6}/src/basic_memory/alembic/versions/647e7a75e2cd_project_constraint_fix.py +0 -0
  154. {basic_memory-0.17.4 → basic_memory-0.17.6}/src/basic_memory/alembic/versions/9d9c1cb7d8f5_add_mtime_and_size_columns_to_entity_.py +0 -0
  155. {basic_memory-0.17.4 → basic_memory-0.17.6}/src/basic_memory/alembic/versions/a1b2c3d4e5f6_fix_project_foreign_keys.py +0 -0
  156. {basic_memory-0.17.4 → basic_memory-0.17.6}/src/basic_memory/alembic/versions/a2b3c4d5e6f7_add_search_index_entity_cascade.py +0 -0
  157. {basic_memory-0.17.4 → basic_memory-0.17.6}/src/basic_memory/alembic/versions/b3c3938bacdb_relation_to_name_unique_index.py +0 -0
  158. {basic_memory-0.17.4 → basic_memory-0.17.6}/src/basic_memory/alembic/versions/cc7172b46608_update_search_index_schema.py +0 -0
  159. {basic_memory-0.17.4 → basic_memory-0.17.6}/src/basic_memory/alembic/versions/e7e1f4367280_add_scan_watermark_tracking_to_project.py +0 -0
  160. {basic_memory-0.17.4 → basic_memory-0.17.6}/src/basic_memory/alembic/versions/f8a9b2c3d4e5_add_pg_trgm_for_fuzzy_link_resolution.py +0 -0
  161. {basic_memory-0.17.4 → basic_memory-0.17.6}/src/basic_memory/alembic/versions/g9a0b3c4d5e6_add_external_id_to_project_and_entity.py +0 -0
  162. {basic_memory-0.17.4 → basic_memory-0.17.6}/src/basic_memory/api/__init__.py +0 -0
  163. {basic_memory-0.17.4 → basic_memory-0.17.6}/src/basic_memory/api/app.py +0 -0
  164. {basic_memory-0.17.4 → basic_memory-0.17.6}/src/basic_memory/api/container.py +0 -0
  165. {basic_memory-0.17.4 → basic_memory-0.17.6}/src/basic_memory/api/routers/__init__.py +0 -0
  166. {basic_memory-0.17.4 → basic_memory-0.17.6}/src/basic_memory/api/routers/directory_router.py +0 -0
  167. {basic_memory-0.17.4 → basic_memory-0.17.6}/src/basic_memory/api/routers/importer_router.py +0 -0
  168. {basic_memory-0.17.4 → basic_memory-0.17.6}/src/basic_memory/api/routers/knowledge_router.py +0 -0
  169. {basic_memory-0.17.4 → basic_memory-0.17.6}/src/basic_memory/api/routers/management_router.py +0 -0
  170. {basic_memory-0.17.4 → basic_memory-0.17.6}/src/basic_memory/api/routers/memory_router.py +0 -0
  171. {basic_memory-0.17.4 → basic_memory-0.17.6}/src/basic_memory/api/routers/project_router.py +0 -0
  172. {basic_memory-0.17.4 → basic_memory-0.17.6}/src/basic_memory/api/routers/prompt_router.py +0 -0
  173. {basic_memory-0.17.4 → basic_memory-0.17.6}/src/basic_memory/api/routers/resource_router.py +0 -0
  174. {basic_memory-0.17.4 → basic_memory-0.17.6}/src/basic_memory/api/routers/search_router.py +0 -0
  175. {basic_memory-0.17.4 → basic_memory-0.17.6}/src/basic_memory/api/routers/utils.py +0 -0
  176. {basic_memory-0.17.4 → basic_memory-0.17.6}/src/basic_memory/api/template_loader.py +0 -0
  177. {basic_memory-0.17.4 → basic_memory-0.17.6}/src/basic_memory/api/v2/__init__.py +0 -0
  178. {basic_memory-0.17.4 → basic_memory-0.17.6}/src/basic_memory/api/v2/routers/__init__.py +0 -0
  179. {basic_memory-0.17.4 → basic_memory-0.17.6}/src/basic_memory/api/v2/routers/directory_router.py +0 -0
  180. {basic_memory-0.17.4 → basic_memory-0.17.6}/src/basic_memory/api/v2/routers/importer_router.py +0 -0
  181. {basic_memory-0.17.4 → basic_memory-0.17.6}/src/basic_memory/api/v2/routers/memory_router.py +0 -0
  182. {basic_memory-0.17.4 → basic_memory-0.17.6}/src/basic_memory/api/v2/routers/prompt_router.py +0 -0
  183. {basic_memory-0.17.4 → basic_memory-0.17.6}/src/basic_memory/api/v2/routers/resource_router.py +0 -0
  184. {basic_memory-0.17.4 → basic_memory-0.17.6}/src/basic_memory/api/v2/routers/search_router.py +0 -0
  185. {basic_memory-0.17.4 → basic_memory-0.17.6}/src/basic_memory/cli/__init__.py +0 -0
  186. {basic_memory-0.17.4 → basic_memory-0.17.6}/src/basic_memory/cli/auth.py +0 -0
  187. {basic_memory-0.17.4 → basic_memory-0.17.6}/src/basic_memory/cli/commands/__init__.py +0 -0
  188. {basic_memory-0.17.4 → basic_memory-0.17.6}/src/basic_memory/cli/commands/cloud/__init__.py +0 -0
  189. {basic_memory-0.17.4 → basic_memory-0.17.6}/src/basic_memory/cli/commands/cloud/api_client.py +0 -0
  190. {basic_memory-0.17.4 → basic_memory-0.17.6}/src/basic_memory/cli/commands/cloud/bisync_commands.py +0 -0
  191. {basic_memory-0.17.4 → basic_memory-0.17.6}/src/basic_memory/cli/commands/cloud/cloud_utils.py +0 -0
  192. {basic_memory-0.17.4 → basic_memory-0.17.6}/src/basic_memory/cli/commands/cloud/rclone_config.py +0 -0
  193. {basic_memory-0.17.4 → basic_memory-0.17.6}/src/basic_memory/cli/commands/cloud/rclone_installer.py +0 -0
  194. {basic_memory-0.17.4 → basic_memory-0.17.6}/src/basic_memory/cli/commands/cloud/upload.py +0 -0
  195. {basic_memory-0.17.4 → basic_memory-0.17.6}/src/basic_memory/cli/commands/mcp.py +0 -0
  196. {basic_memory-0.17.4 → basic_memory-0.17.6}/src/basic_memory/cli/commands/status.py +0 -0
  197. {basic_memory-0.17.4 → basic_memory-0.17.6}/src/basic_memory/cli/commands/telemetry.py +0 -0
  198. {basic_memory-0.17.4 → basic_memory-0.17.6}/src/basic_memory/cli/container.py +0 -0
  199. {basic_memory-0.17.4 → basic_memory-0.17.6}/src/basic_memory/cli/main.py +0 -0
  200. {basic_memory-0.17.4 → basic_memory-0.17.6}/src/basic_memory/config.py +0 -0
  201. {basic_memory-0.17.4 → basic_memory-0.17.6}/src/basic_memory/db.py +0 -0
  202. {basic_memory-0.17.4 → basic_memory-0.17.6}/src/basic_memory/deps/__init__.py +0 -0
  203. {basic_memory-0.17.4 → basic_memory-0.17.6}/src/basic_memory/deps/config.py +0 -0
  204. {basic_memory-0.17.4 → basic_memory-0.17.6}/src/basic_memory/deps/db.py +0 -0
  205. {basic_memory-0.17.4 → basic_memory-0.17.6}/src/basic_memory/deps/importers.py +0 -0
  206. {basic_memory-0.17.4 → basic_memory-0.17.6}/src/basic_memory/deps.py +0 -0
  207. {basic_memory-0.17.4 → basic_memory-0.17.6}/src/basic_memory/file_utils.py +0 -0
  208. {basic_memory-0.17.4 → basic_memory-0.17.6}/src/basic_memory/ignore_utils.py +0 -0
  209. {basic_memory-0.17.4 → basic_memory-0.17.6}/src/basic_memory/importers/__init__.py +0 -0
  210. {basic_memory-0.17.4 → basic_memory-0.17.6}/src/basic_memory/importers/base.py +0 -0
  211. {basic_memory-0.17.4 → basic_memory-0.17.6}/src/basic_memory/importers/chatgpt_importer.py +0 -0
  212. {basic_memory-0.17.4 → basic_memory-0.17.6}/src/basic_memory/importers/claude_conversations_importer.py +0 -0
  213. {basic_memory-0.17.4 → basic_memory-0.17.6}/src/basic_memory/importers/claude_projects_importer.py +0 -0
  214. {basic_memory-0.17.4 → basic_memory-0.17.6}/src/basic_memory/importers/memory_json_importer.py +0 -0
  215. {basic_memory-0.17.4 → basic_memory-0.17.6}/src/basic_memory/importers/utils.py +0 -0
  216. {basic_memory-0.17.4 → basic_memory-0.17.6}/src/basic_memory/markdown/__init__.py +0 -0
  217. {basic_memory-0.17.4 → basic_memory-0.17.6}/src/basic_memory/markdown/entity_parser.py +0 -0
  218. {basic_memory-0.17.4 → basic_memory-0.17.6}/src/basic_memory/markdown/markdown_processor.py +0 -0
  219. {basic_memory-0.17.4 → basic_memory-0.17.6}/src/basic_memory/markdown/plugins.py +0 -0
  220. {basic_memory-0.17.4 → basic_memory-0.17.6}/src/basic_memory/markdown/schemas.py +0 -0
  221. {basic_memory-0.17.4 → basic_memory-0.17.6}/src/basic_memory/markdown/utils.py +0 -0
  222. {basic_memory-0.17.4 → basic_memory-0.17.6}/src/basic_memory/mcp/__init__.py +0 -0
  223. {basic_memory-0.17.4 → basic_memory-0.17.6}/src/basic_memory/mcp/async_client.py +0 -0
  224. {basic_memory-0.17.4 → basic_memory-0.17.6}/src/basic_memory/mcp/clients/__init__.py +0 -0
  225. {basic_memory-0.17.4 → basic_memory-0.17.6}/src/basic_memory/mcp/clients/directory.py +0 -0
  226. {basic_memory-0.17.4 → basic_memory-0.17.6}/src/basic_memory/mcp/clients/knowledge.py +0 -0
  227. {basic_memory-0.17.4 → basic_memory-0.17.6}/src/basic_memory/mcp/clients/memory.py +0 -0
  228. {basic_memory-0.17.4 → basic_memory-0.17.6}/src/basic_memory/mcp/clients/project.py +0 -0
  229. {basic_memory-0.17.4 → basic_memory-0.17.6}/src/basic_memory/mcp/clients/resource.py +0 -0
  230. {basic_memory-0.17.4 → basic_memory-0.17.6}/src/basic_memory/mcp/clients/search.py +0 -0
  231. {basic_memory-0.17.4 → basic_memory-0.17.6}/src/basic_memory/mcp/project_context.py +0 -0
  232. {basic_memory-0.17.4 → basic_memory-0.17.6}/src/basic_memory/mcp/prompts/__init__.py +0 -0
  233. {basic_memory-0.17.4 → basic_memory-0.17.6}/src/basic_memory/mcp/prompts/ai_assistant_guide.py +0 -0
  234. {basic_memory-0.17.4 → basic_memory-0.17.6}/src/basic_memory/mcp/prompts/continue_conversation.py +0 -0
  235. {basic_memory-0.17.4 → basic_memory-0.17.6}/src/basic_memory/mcp/prompts/recent_activity.py +0 -0
  236. {basic_memory-0.17.4 → basic_memory-0.17.6}/src/basic_memory/mcp/prompts/search.py +0 -0
  237. {basic_memory-0.17.4 → basic_memory-0.17.6}/src/basic_memory/mcp/prompts/utils.py +0 -0
  238. {basic_memory-0.17.4 → basic_memory-0.17.6}/src/basic_memory/mcp/resources/ai_assistant_guide.md +0 -0
  239. {basic_memory-0.17.4 → basic_memory-0.17.6}/src/basic_memory/mcp/resources/project_info.py +0 -0
  240. {basic_memory-0.17.4 → basic_memory-0.17.6}/src/basic_memory/mcp/tools/__init__.py +0 -0
  241. {basic_memory-0.17.4 → basic_memory-0.17.6}/src/basic_memory/mcp/tools/build_context.py +0 -0
  242. {basic_memory-0.17.4 → basic_memory-0.17.6}/src/basic_memory/mcp/tools/chatgpt_tools.py +0 -0
  243. {basic_memory-0.17.4 → basic_memory-0.17.6}/src/basic_memory/mcp/tools/delete_note.py +0 -0
  244. {basic_memory-0.17.4 → basic_memory-0.17.6}/src/basic_memory/mcp/tools/edit_note.py +0 -0
  245. {basic_memory-0.17.4 → basic_memory-0.17.6}/src/basic_memory/mcp/tools/list_directory.py +0 -0
  246. {basic_memory-0.17.4 → basic_memory-0.17.6}/src/basic_memory/mcp/tools/move_note.py +0 -0
  247. {basic_memory-0.17.4 → basic_memory-0.17.6}/src/basic_memory/mcp/tools/project_management.py +0 -0
  248. {basic_memory-0.17.4 → basic_memory-0.17.6}/src/basic_memory/mcp/tools/read_note.py +0 -0
  249. {basic_memory-0.17.4 → basic_memory-0.17.6}/src/basic_memory/mcp/tools/search.py +0 -0
  250. {basic_memory-0.17.4 → basic_memory-0.17.6}/src/basic_memory/mcp/tools/view_note.py +0 -0
  251. {basic_memory-0.17.4 → basic_memory-0.17.6}/src/basic_memory/models/__init__.py +0 -0
  252. {basic_memory-0.17.4 → basic_memory-0.17.6}/src/basic_memory/models/base.py +0 -0
  253. {basic_memory-0.17.4 → basic_memory-0.17.6}/src/basic_memory/models/search.py +0 -0
  254. {basic_memory-0.17.4 → basic_memory-0.17.6}/src/basic_memory/project_resolver.py +0 -0
  255. {basic_memory-0.17.4 → basic_memory-0.17.6}/src/basic_memory/repository/__init__.py +0 -0
  256. {basic_memory-0.17.4 → basic_memory-0.17.6}/src/basic_memory/repository/observation_repository.py +0 -0
  257. {basic_memory-0.17.4 → basic_memory-0.17.6}/src/basic_memory/repository/postgres_search_repository.py +0 -0
  258. {basic_memory-0.17.4 → basic_memory-0.17.6}/src/basic_memory/repository/project_info_repository.py +0 -0
  259. {basic_memory-0.17.4 → basic_memory-0.17.6}/src/basic_memory/repository/project_repository.py +0 -0
  260. {basic_memory-0.17.4 → basic_memory-0.17.6}/src/basic_memory/repository/search_index_row.py +0 -0
  261. {basic_memory-0.17.4 → basic_memory-0.17.6}/src/basic_memory/repository/search_repository.py +0 -0
  262. {basic_memory-0.17.4 → basic_memory-0.17.6}/src/basic_memory/repository/search_repository_base.py +0 -0
  263. {basic_memory-0.17.4 → basic_memory-0.17.6}/src/basic_memory/repository/sqlite_search_repository.py +0 -0
  264. {basic_memory-0.17.4 → basic_memory-0.17.6}/src/basic_memory/schemas/__init__.py +0 -0
  265. {basic_memory-0.17.4 → basic_memory-0.17.6}/src/basic_memory/schemas/base.py +0 -0
  266. {basic_memory-0.17.4 → basic_memory-0.17.6}/src/basic_memory/schemas/cloud.py +0 -0
  267. {basic_memory-0.17.4 → basic_memory-0.17.6}/src/basic_memory/schemas/delete.py +0 -0
  268. {basic_memory-0.17.4 → basic_memory-0.17.6}/src/basic_memory/schemas/directory.py +0 -0
  269. {basic_memory-0.17.4 → basic_memory-0.17.6}/src/basic_memory/schemas/importer.py +0 -0
  270. {basic_memory-0.17.4 → basic_memory-0.17.6}/src/basic_memory/schemas/memory.py +0 -0
  271. {basic_memory-0.17.4 → basic_memory-0.17.6}/src/basic_memory/schemas/project_info.py +0 -0
  272. {basic_memory-0.17.4 → basic_memory-0.17.6}/src/basic_memory/schemas/prompt.py +0 -0
  273. {basic_memory-0.17.4 → basic_memory-0.17.6}/src/basic_memory/schemas/request.py +0 -0
  274. {basic_memory-0.17.4 → basic_memory-0.17.6}/src/basic_memory/schemas/response.py +0 -0
  275. {basic_memory-0.17.4 → basic_memory-0.17.6}/src/basic_memory/schemas/search.py +0 -0
  276. {basic_memory-0.17.4 → basic_memory-0.17.6}/src/basic_memory/schemas/sync_report.py +0 -0
  277. {basic_memory-0.17.4 → basic_memory-0.17.6}/src/basic_memory/schemas/v2/__init__.py +0 -0
  278. {basic_memory-0.17.4 → basic_memory-0.17.6}/src/basic_memory/schemas/v2/entity.py +0 -0
  279. {basic_memory-0.17.4 → basic_memory-0.17.6}/src/basic_memory/schemas/v2/resource.py +0 -0
  280. {basic_memory-0.17.4 → basic_memory-0.17.6}/src/basic_memory/services/__init__.py +0 -0
  281. {basic_memory-0.17.4 → basic_memory-0.17.6}/src/basic_memory/services/directory_service.py +0 -0
  282. {basic_memory-0.17.4 → basic_memory-0.17.6}/src/basic_memory/services/entity_service.py +0 -0
  283. {basic_memory-0.17.4 → basic_memory-0.17.6}/src/basic_memory/services/exceptions.py +0 -0
  284. {basic_memory-0.17.4 → basic_memory-0.17.6}/src/basic_memory/services/file_service.py +0 -0
  285. {basic_memory-0.17.4 → basic_memory-0.17.6}/src/basic_memory/services/initialization.py +0 -0
  286. {basic_memory-0.17.4 → basic_memory-0.17.6}/src/basic_memory/services/link_resolver.py +0 -0
  287. {basic_memory-0.17.4 → basic_memory-0.17.6}/src/basic_memory/services/project_service.py +0 -0
  288. {basic_memory-0.17.4 → basic_memory-0.17.6}/src/basic_memory/services/search_service.py +0 -0
  289. {basic_memory-0.17.4 → basic_memory-0.17.6}/src/basic_memory/services/service.py +0 -0
  290. {basic_memory-0.17.4 → basic_memory-0.17.6}/src/basic_memory/sync/__init__.py +0 -0
  291. {basic_memory-0.17.4 → basic_memory-0.17.6}/src/basic_memory/sync/background_sync.py +0 -0
  292. {basic_memory-0.17.4 → basic_memory-0.17.6}/src/basic_memory/sync/watch_service.py +0 -0
  293. {basic_memory-0.17.4 → basic_memory-0.17.6}/src/basic_memory/templates/prompts/continue_conversation.hbs +0 -0
  294. {basic_memory-0.17.4 → basic_memory-0.17.6}/src/basic_memory/templates/prompts/search.hbs +0 -0
  295. {basic_memory-0.17.4 → basic_memory-0.17.6}/src/basic_memory/utils.py +0 -0
  296. {basic_memory-0.17.4 → basic_memory-0.17.6}/test-int/BENCHMARKS.md +0 -0
  297. {basic_memory-0.17.4 → basic_memory-0.17.6}/test-int/cli/test_project_commands_integration.py +0 -0
  298. {basic_memory-0.17.4 → basic_memory-0.17.6}/test-int/cli/test_version_integration.py +0 -0
  299. {basic_memory-0.17.4 → basic_memory-0.17.6}/test-int/conftest.py +0 -0
  300. {basic_memory-0.17.4 → basic_memory-0.17.6}/test-int/mcp/test_build_context_underscore.py +0 -0
  301. {basic_memory-0.17.4 → basic_memory-0.17.6}/test-int/mcp/test_build_context_validation.py +0 -0
  302. {basic_memory-0.17.4 → basic_memory-0.17.6}/test-int/mcp/test_chatgpt_tools_integration.py +0 -0
  303. {basic_memory-0.17.4 → basic_memory-0.17.6}/test-int/mcp/test_default_project_mode_integration.py +0 -0
  304. {basic_memory-0.17.4 → basic_memory-0.17.6}/test-int/mcp/test_delete_note_integration.py +0 -0
  305. {basic_memory-0.17.4 → basic_memory-0.17.6}/test-int/mcp/test_edit_note_integration.py +0 -0
  306. {basic_memory-0.17.4 → basic_memory-0.17.6}/test-int/mcp/test_list_directory_integration.py +0 -0
  307. {basic_memory-0.17.4 → basic_memory-0.17.6}/test-int/mcp/test_move_note_integration.py +0 -0
  308. {basic_memory-0.17.4 → basic_memory-0.17.6}/test-int/mcp/test_project_management_integration.py +0 -0
  309. {basic_memory-0.17.4 → basic_memory-0.17.6}/test-int/mcp/test_project_state_sync_integration.py +0 -0
  310. {basic_memory-0.17.4 → basic_memory-0.17.6}/test-int/mcp/test_read_content_integration.py +0 -0
  311. {basic_memory-0.17.4 → basic_memory-0.17.6}/test-int/mcp/test_read_note_integration.py +0 -0
  312. {basic_memory-0.17.4 → basic_memory-0.17.6}/test-int/mcp/test_search_integration.py +0 -0
  313. {basic_memory-0.17.4 → basic_memory-0.17.6}/test-int/mcp/test_single_project_mcp_integration.py +0 -0
  314. {basic_memory-0.17.4 → basic_memory-0.17.6}/test-int/mcp/test_write_note_integration.py +0 -0
  315. {basic_memory-0.17.4 → basic_memory-0.17.6}/test-int/test_db_wal_mode.py +0 -0
  316. {basic_memory-0.17.4 → basic_memory-0.17.6}/test-int/test_disable_permalinks_integration.py +0 -0
  317. {basic_memory-0.17.4 → basic_memory-0.17.6}/tests/Non-MarkdownFileSupport.pdf +0 -0
  318. {basic_memory-0.17.4 → basic_memory-0.17.6}/tests/README.md +0 -0
  319. {basic_memory-0.17.4 → basic_memory-0.17.6}/tests/Screenshot.png +0 -0
  320. {basic_memory-0.17.4 → basic_memory-0.17.6}/tests/__init__.py +0 -0
  321. {basic_memory-0.17.4 → basic_memory-0.17.6}/tests/api/conftest.py +0 -0
  322. {basic_memory-0.17.4 → basic_memory-0.17.6}/tests/api/test_api_container.py +0 -0
  323. {basic_memory-0.17.4 → basic_memory-0.17.6}/tests/api/test_async_client.py +0 -0
  324. {basic_memory-0.17.4 → basic_memory-0.17.6}/tests/api/test_continue_conversation_template.py +0 -0
  325. {basic_memory-0.17.4 → basic_memory-0.17.6}/tests/api/test_importer_router.py +0 -0
  326. {basic_memory-0.17.4 → basic_memory-0.17.6}/tests/api/test_knowledge_router.py +0 -0
  327. {basic_memory-0.17.4 → basic_memory-0.17.6}/tests/api/test_memory_router.py +0 -0
  328. {basic_memory-0.17.4 → basic_memory-0.17.6}/tests/api/test_project_router_operations.py +0 -0
  329. {basic_memory-0.17.4 → basic_memory-0.17.6}/tests/api/test_prompt_router.py +0 -0
  330. {basic_memory-0.17.4 → basic_memory-0.17.6}/tests/api/test_resource_router.py +0 -0
  331. {basic_memory-0.17.4 → basic_memory-0.17.6}/tests/api/test_search_router.py +0 -0
  332. {basic_memory-0.17.4 → basic_memory-0.17.6}/tests/api/test_search_template.py +0 -0
  333. {basic_memory-0.17.4 → basic_memory-0.17.6}/tests/api/test_template_loader.py +0 -0
  334. {basic_memory-0.17.4 → basic_memory-0.17.6}/tests/api/test_template_loader_helpers.py +0 -0
  335. {basic_memory-0.17.4 → basic_memory-0.17.6}/tests/api/v2/__init__.py +0 -0
  336. {basic_memory-0.17.4 → basic_memory-0.17.6}/tests/api/v2/conftest.py +0 -0
  337. {basic_memory-0.17.4 → basic_memory-0.17.6}/tests/api/v2/test_directory_router.py +0 -0
  338. {basic_memory-0.17.4 → basic_memory-0.17.6}/tests/api/v2/test_importer_router.py +0 -0
  339. {basic_memory-0.17.4 → basic_memory-0.17.6}/tests/api/v2/test_memory_router.py +0 -0
  340. {basic_memory-0.17.4 → basic_memory-0.17.6}/tests/api/v2/test_prompt_router.py +0 -0
  341. {basic_memory-0.17.4 → basic_memory-0.17.6}/tests/api/v2/test_resource_router.py +0 -0
  342. {basic_memory-0.17.4 → basic_memory-0.17.6}/tests/api/v2/test_search_router.py +0 -0
  343. {basic_memory-0.17.4 → basic_memory-0.17.6}/tests/cli/conftest.py +0 -0
  344. {basic_memory-0.17.4 → basic_memory-0.17.6}/tests/cli/test_cli_container.py +0 -0
  345. {basic_memory-0.17.4 → basic_memory-0.17.6}/tests/cli/test_cli_exit.py +0 -0
  346. {basic_memory-0.17.4 → basic_memory-0.17.6}/tests/cli/test_ignore_utils.py +0 -0
  347. {basic_memory-0.17.4 → basic_memory-0.17.6}/tests/cli/test_import_chatgpt.py +0 -0
  348. {basic_memory-0.17.4 → basic_memory-0.17.6}/tests/cli/test_import_claude_conversations.py +0 -0
  349. {basic_memory-0.17.4 → basic_memory-0.17.6}/tests/cli/test_import_claude_projects.py +0 -0
  350. {basic_memory-0.17.4 → basic_memory-0.17.6}/tests/cli/test_import_memory_json.py +0 -0
  351. {basic_memory-0.17.4 → basic_memory-0.17.6}/tests/cli/test_project_add_with_local_path.py +0 -0
  352. {basic_memory-0.17.4 → basic_memory-0.17.6}/tests/cli/test_upload.py +0 -0
  353. {basic_memory-0.17.4 → basic_memory-0.17.6}/tests/conftest.py +0 -0
  354. {basic_memory-0.17.4 → basic_memory-0.17.6}/tests/db/test_issue_254_foreign_key_constraints.py +0 -0
  355. {basic_memory-0.17.4 → basic_memory-0.17.6}/tests/importers/test_conversation_indexing.py +0 -0
  356. {basic_memory-0.17.4 → basic_memory-0.17.6}/tests/importers/test_importer_base.py +0 -0
  357. {basic_memory-0.17.4 → basic_memory-0.17.6}/tests/importers/test_importer_utils.py +0 -0
  358. {basic_memory-0.17.4 → basic_memory-0.17.6}/tests/markdown/__init__.py +0 -0
  359. {basic_memory-0.17.4 → basic_memory-0.17.6}/tests/markdown/test_date_frontmatter_parsing.py +0 -0
  360. {basic_memory-0.17.4 → basic_memory-0.17.6}/tests/markdown/test_entity_parser.py +0 -0
  361. {basic_memory-0.17.4 → basic_memory-0.17.6}/tests/markdown/test_entity_parser_error_handling.py +0 -0
  362. {basic_memory-0.17.4 → basic_memory-0.17.6}/tests/markdown/test_markdown_plugins.py +0 -0
  363. {basic_memory-0.17.4 → basic_memory-0.17.6}/tests/markdown/test_markdown_processor.py +0 -0
  364. {basic_memory-0.17.4 → basic_memory-0.17.6}/tests/markdown/test_observation_edge_cases.py +0 -0
  365. {basic_memory-0.17.4 → basic_memory-0.17.6}/tests/markdown/test_parser_edge_cases.py +0 -0
  366. {basic_memory-0.17.4 → basic_memory-0.17.6}/tests/markdown/test_relation_edge_cases.py +0 -0
  367. {basic_memory-0.17.4 → basic_memory-0.17.6}/tests/markdown/test_task_detection.py +0 -0
  368. {basic_memory-0.17.4 → basic_memory-0.17.6}/tests/mcp/clients/__init__.py +0 -0
  369. {basic_memory-0.17.4 → basic_memory-0.17.6}/tests/mcp/conftest.py +0 -0
  370. {basic_memory-0.17.4 → basic_memory-0.17.6}/tests/mcp/test_mcp_container.py +0 -0
  371. {basic_memory-0.17.4 → basic_memory-0.17.6}/tests/mcp/test_obsidian_yaml_formatting.py +0 -0
  372. {basic_memory-0.17.4 → basic_memory-0.17.6}/tests/mcp/test_permalink_collision_file_overwrite.py +0 -0
  373. {basic_memory-0.17.4 → basic_memory-0.17.6}/tests/mcp/test_prompts.py +0 -0
  374. {basic_memory-0.17.4 → basic_memory-0.17.6}/tests/mcp/test_resources.py +0 -0
  375. {basic_memory-0.17.4 → basic_memory-0.17.6}/tests/mcp/test_tool_build_context.py +0 -0
  376. {basic_memory-0.17.4 → basic_memory-0.17.6}/tests/mcp/test_tool_canvas.py +0 -0
  377. {basic_memory-0.17.4 → basic_memory-0.17.6}/tests/mcp/test_tool_delete_note.py +0 -0
  378. {basic_memory-0.17.4 → basic_memory-0.17.6}/tests/mcp/test_tool_edit_note.py +0 -0
  379. {basic_memory-0.17.4 → basic_memory-0.17.6}/tests/mcp/test_tool_list_directory.py +0 -0
  380. {basic_memory-0.17.4 → basic_memory-0.17.6}/tests/mcp/test_tool_read_note.py +0 -0
  381. {basic_memory-0.17.4 → basic_memory-0.17.6}/tests/mcp/test_tool_resource.py +0 -0
  382. {basic_memory-0.17.4 → basic_memory-0.17.6}/tests/mcp/test_tool_search.py +0 -0
  383. {basic_memory-0.17.4 → basic_memory-0.17.6}/tests/mcp/test_tool_utils.py +0 -0
  384. {basic_memory-0.17.4 → basic_memory-0.17.6}/tests/mcp/test_tool_view_note.py +0 -0
  385. {basic_memory-0.17.4 → basic_memory-0.17.6}/tests/mcp/test_tool_write_note.py +0 -0
  386. {basic_memory-0.17.4 → basic_memory-0.17.6}/tests/mcp/test_tool_write_note_kebab_filenames.py +0 -0
  387. {basic_memory-0.17.4 → basic_memory-0.17.6}/tests/mcp/tools/test_chatgpt_tools.py +0 -0
  388. {basic_memory-0.17.4 → basic_memory-0.17.6}/tests/repository/test_entity_repository.py +0 -0
  389. {basic_memory-0.17.4 → basic_memory-0.17.6}/tests/repository/test_entity_repository_upsert.py +0 -0
  390. {basic_memory-0.17.4 → basic_memory-0.17.6}/tests/repository/test_entity_upsert_issue_187.py +0 -0
  391. {basic_memory-0.17.4 → basic_memory-0.17.6}/tests/repository/test_observation_repository.py +0 -0
  392. {basic_memory-0.17.4 → basic_memory-0.17.6}/tests/repository/test_project_info_repository.py +0 -0
  393. {basic_memory-0.17.4 → basic_memory-0.17.6}/tests/repository/test_project_repository.py +0 -0
  394. {basic_memory-0.17.4 → basic_memory-0.17.6}/tests/repository/test_relation_repository.py +0 -0
  395. {basic_memory-0.17.4 → basic_memory-0.17.6}/tests/repository/test_repository.py +0 -0
  396. {basic_memory-0.17.4 → basic_memory-0.17.6}/tests/repository/test_search_repository.py +0 -0
  397. {basic_memory-0.17.4 → basic_memory-0.17.6}/tests/repository/test_search_repository_edit_bug_fix.py +0 -0
  398. {basic_memory-0.17.4 → basic_memory-0.17.6}/tests/schemas/test_base_timeframe_minimum.py +0 -0
  399. {basic_memory-0.17.4 → basic_memory-0.17.6}/tests/schemas/test_memory_serialization.py +0 -0
  400. {basic_memory-0.17.4 → basic_memory-0.17.6}/tests/schemas/test_memory_url.py +0 -0
  401. {basic_memory-0.17.4 → basic_memory-0.17.6}/tests/schemas/test_memory_url_validation.py +0 -0
  402. {basic_memory-0.17.4 → basic_memory-0.17.6}/tests/schemas/test_schemas.py +0 -0
  403. {basic_memory-0.17.4 → basic_memory-0.17.6}/tests/schemas/test_search.py +0 -0
  404. {basic_memory-0.17.4 → basic_memory-0.17.6}/tests/services/test_context_service.py +0 -0
  405. {basic_memory-0.17.4 → basic_memory-0.17.6}/tests/services/test_directory_service.py +0 -0
  406. {basic_memory-0.17.4 → basic_memory-0.17.6}/tests/services/test_entity_service.py +0 -0
  407. {basic_memory-0.17.4 → basic_memory-0.17.6}/tests/services/test_entity_service_disable_permalinks.py +0 -0
  408. {basic_memory-0.17.4 → basic_memory-0.17.6}/tests/services/test_file_service.py +0 -0
  409. {basic_memory-0.17.4 → basic_memory-0.17.6}/tests/services/test_link_resolver.py +0 -0
  410. {basic_memory-0.17.4 → basic_memory-0.17.6}/tests/services/test_project_removal_bug.py +0 -0
  411. {basic_memory-0.17.4 → basic_memory-0.17.6}/tests/services/test_project_service.py +0 -0
  412. {basic_memory-0.17.4 → basic_memory-0.17.6}/tests/services/test_search_service.py +0 -0
  413. {basic_memory-0.17.4 → basic_memory-0.17.6}/tests/sync/test_character_conflicts.py +0 -0
  414. {basic_memory-0.17.4 → basic_memory-0.17.6}/tests/sync/test_coordinator.py +0 -0
  415. {basic_memory-0.17.4 → basic_memory-0.17.6}/tests/sync/test_sync_service.py +0 -0
  416. {basic_memory-0.17.4 → basic_memory-0.17.6}/tests/sync/test_sync_service_incremental.py +0 -0
  417. {basic_memory-0.17.4 → basic_memory-0.17.6}/tests/sync/test_sync_wikilink_issue.py +0 -0
  418. {basic_memory-0.17.4 → basic_memory-0.17.6}/tests/sync/test_tmp_files.py +0 -0
  419. {basic_memory-0.17.4 → basic_memory-0.17.6}/tests/sync/test_watch_service.py +0 -0
  420. {basic_memory-0.17.4 → basic_memory-0.17.6}/tests/sync/test_watch_service_edge_cases.py +0 -0
  421. {basic_memory-0.17.4 → basic_memory-0.17.6}/tests/test_config.py +0 -0
  422. {basic_memory-0.17.4 → basic_memory-0.17.6}/tests/test_deps.py +0 -0
  423. {basic_memory-0.17.4 → basic_memory-0.17.6}/tests/test_production_cascade_delete.py +0 -0
  424. {basic_memory-0.17.4 → basic_memory-0.17.6}/tests/test_project_resolver.py +0 -0
  425. {basic_memory-0.17.4 → basic_memory-0.17.6}/tests/utils/test_file_utils.py +0 -0
  426. {basic_memory-0.17.4 → basic_memory-0.17.6}/tests/utils/test_frontmatter_obsidian_compatible.py +0 -0
  427. {basic_memory-0.17.4 → basic_memory-0.17.6}/tests/utils/test_parse_tags.py +0 -0
  428. {basic_memory-0.17.4 → basic_memory-0.17.6}/tests/utils/test_permalink_formatting.py +0 -0
  429. {basic_memory-0.17.4 → basic_memory-0.17.6}/tests/utils/test_timezone_utils.py +0 -0
  430. {basic_memory-0.17.4 → basic_memory-0.17.6}/tests/utils/test_utf8_handling.py +0 -0
  431. {basic_memory-0.17.4 → basic_memory-0.17.6}/tests/utils/test_validate_project_path.py +0 -0
@@ -19,7 +19,7 @@ jobs:
19
19
  fail-fast: false
20
20
  matrix:
21
21
  os: [ubuntu-latest, windows-latest]
22
- python-version: [ "3.12", "3.13" ]
22
+ python-version: [ "3.12", "3.13", "3.14" ]
23
23
  runs-on: ${{ matrix.os }}
24
24
 
25
25
  steps:
@@ -75,7 +75,7 @@ jobs:
75
75
  strategy:
76
76
  fail-fast: false
77
77
  matrix:
78
- python-version: [ "3.12", "3.13" ]
78
+ python-version: [ "3.12", "3.13", "3.14" ]
79
79
  runs-on: ubuntu-latest
80
80
 
81
81
  # Note: No services section needed - testcontainers handles Postgres in Docker
@@ -164,4 +164,4 @@ jobs:
164
164
  uses: actions/upload-artifact@v4
165
165
  with:
166
166
  name: htmlcov
167
- path: htmlcov/
167
+ path: htmlcov/
@@ -0,0 +1 @@
1
+ 3.14
@@ -1,5 +1,29 @@
1
1
  # CHANGELOG
2
2
 
3
+ ## v0.17.6 (2026-01-17)
4
+
5
+ ### Bug Fixes
6
+
7
+ - **#510**: Fix Docker container Python symlink broken at runtime
8
+ ([`1799c94`](https://github.com/basicmachines-co/basic-memory/commit/1799c94))
9
+
10
+ ### Internal
11
+
12
+ - Remove logfire config and specs docs, reduce lifespan and sync logging to debug level
13
+ ([`d1d433d`](https://github.com/basicmachines-co/basic-memory/commit/d1d433d),
14
+ [`803f3ef`](https://github.com/basicmachines-co/basic-memory/commit/803f3ef))
15
+
16
+ ## v0.17.5 (2026-01-11)
17
+
18
+ ### Bug Fixes
19
+
20
+ - **#505**: Prevent CLI commands from hanging on exit (Python 3.14 compatibility)
21
+ ([`863e0a4`](https://github.com/basicmachines-co/basic-memory/commit/863e0a4))
22
+ - Skip `nest_asyncio` on Python 3.14+ where it causes event loop issues
23
+ - Simplify CLI test infrastructure for cross-version compatibility
24
+ - Update pyright to 1.1.408 for Python 3.14 support
25
+ - Fix SQLAlchemy rowcount typing for Python 3.14
26
+
3
27
  ## v0.17.4 (2026-01-05)
4
28
 
5
29
  ### Bug Fixes
@@ -8,8 +8,13 @@ ARG GID=1000
8
8
  COPY --from=ghcr.io/astral-sh/uv:latest /uv /uvx /bin/
9
9
 
10
10
  # Set environment variables
11
+ # UV_PYTHON_INSTALL_DIR ensures Python is installed to a persistent location
12
+ # that survives in the final image (not in /root/.local which gets lost)
13
+ # UV_PYTHON_PREFERENCE=only-managed tells uv to use its managed Python version
11
14
  ENV PYTHONUNBUFFERED=1 \
12
- PYTHONDONTWRITEBYTECODE=1
15
+ PYTHONDONTWRITEBYTECODE=1 \
16
+ UV_PYTHON_INSTALL_DIR=/python \
17
+ UV_PYTHON_PREFERENCE=only-managed
13
18
 
14
19
  # Create a group and user with the provided UID/GID
15
20
  # Check if the GID already exists, if not create appgroup
@@ -19,9 +24,10 @@ RUN (getent group ${GID} || groupadd --gid ${GID} appgroup) && \
19
24
  # Copy the project into the image
20
25
  ADD . /app
21
26
 
22
- # Sync the project into a new environment, asserting the lockfile is up to date
27
+ # Install Python 3.13 explicitly and sync the project
23
28
  WORKDIR /app
24
- RUN uv sync --locked
29
+ RUN uv python install 3.13
30
+ RUN uv sync --locked --python 3.13
25
31
 
26
32
  # Create necessary directories and set ownership
27
33
  RUN mkdir -p /app/data/basic-memory /app/.basic-memory && \
@@ -43,4 +49,4 @@ HEALTHCHECK --interval=30s --timeout=10s --start-period=5s --retries=3 \
43
49
  CMD basic-memory --version || exit 1
44
50
 
45
51
  # Use the basic-memory entrypoint to run the MCP server with default SSE transport
46
- CMD ["basic-memory", "mcp", "--transport", "sse", "--host", "0.0.0.0", "--port", "8000"]
52
+ CMD ["basic-memory", "mcp", "--transport", "sse", "--host", "0.0.0.0", "--port", "8000"]
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: basic-memory
3
- Version: 0.17.4
3
+ Version: 0.17.6
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
@@ -12,11 +12,13 @@ Requires-Python: >=3.12
12
12
  Requires-Dist: aiofiles>=24.1.0
13
13
  Requires-Dist: aiosqlite>=0.20.0
14
14
  Requires-Dist: alembic>=1.14.1
15
+ Requires-Dist: anyio>=4.10.0
15
16
  Requires-Dist: asyncpg>=0.30.0
16
17
  Requires-Dist: dateparser>=1.2.0
17
18
  Requires-Dist: fastapi[standard]>=0.115.8
18
19
  Requires-Dist: fastmcp==2.12.3
19
20
  Requires-Dist: greenlet>=3.1.1
21
+ Requires-Dist: httpx>=0.28.0
20
22
  Requires-Dist: loguru>=0.7.3
21
23
  Requires-Dist: markdown-it-py>=3.0.0
22
24
  Requires-Dist: mcp>=1.23.1
@@ -29,7 +31,7 @@ Requires-Dist: pillow>=11.1.0
29
31
  Requires-Dist: psycopg==3.3.1
30
32
  Requires-Dist: pybars3>=0.9.7
31
33
  Requires-Dist: pydantic-settings>=2.6.1
32
- Requires-Dist: pydantic[email,timezone]>=2.10.3
34
+ Requires-Dist: pydantic[email,timezone]>=2.12.0
33
35
  Requires-Dist: pyjwt>=2.10.1
34
36
  Requires-Dist: pyright>=1.1.390
35
37
  Requires-Dist: pytest-aio>=1.9.0
@@ -38,6 +40,7 @@ Requires-Dist: python-dotenv>=1.1.0
38
40
  Requires-Dist: python-frontmatter>=1.1.0
39
41
  Requires-Dist: pyyaml>=6.0.1
40
42
  Requires-Dist: rich>=13.9.4
43
+ Requires-Dist: sniffio>=1.3.1
41
44
  Requires-Dist: sqlalchemy>=2.0.0
42
45
  Requires-Dist: typer>=0.9.0
43
46
  Requires-Dist: unidecode>=1.3.8
@@ -220,6 +220,11 @@ release version:
220
220
  echo "✅ Release {{version}} created successfully!"
221
221
  echo "📦 GitHub Actions will build and publish to PyPI"
222
222
  echo "🔗 Monitor at: https://github.com/basicmachines-co/basic-memory/actions"
223
+ echo ""
224
+ echo "📝 REMINDER: Update documentation sites after release is published:"
225
+ echo " 1. docs.basicmemory.com - Add release notes to src/pages/latest-releases.mdx"
226
+ echo " 2. basicmachines.co - Update version in src/components/sections/hero.tsx"
227
+ echo " See: .claude/commands/release/release.md for detailed instructions"
223
228
 
224
229
  # Create a beta release (e.g., just beta v0.13.2b1)
225
230
  beta version:
@@ -281,6 +286,11 @@ beta version:
281
286
  echo "📦 GitHub Actions will build and publish to PyPI as pre-release"
282
287
  echo "🔗 Monitor at: https://github.com/basicmachines-co/basic-memory/actions"
283
288
  echo "📥 Install with: uv tool install basic-memory --pre"
289
+ echo ""
290
+ echo "📝 REMINDER: For stable releases, update documentation sites:"
291
+ echo " 1. docs.basicmemory.com - Add release notes to src/pages/latest-releases.mdx"
292
+ echo " 2. basicmachines.co - Update version in src/components/sections/hero.tsx"
293
+ echo " See: .claude/commands/release/release.md for detailed instructions"
284
294
 
285
295
  # List all available recipes
286
296
  default:
@@ -14,7 +14,7 @@ dependencies = [
14
14
  "typer>=0.9.0",
15
15
  "aiosqlite>=0.20.0",
16
16
  "greenlet>=3.1.1",
17
- "pydantic[email,timezone]>=2.10.3",
17
+ "pydantic[email,timezone]>=2.12.0",
18
18
  "mcp>=1.23.1",
19
19
  "pydantic-settings>=2.6.1",
20
20
  "loguru>=0.7.3",
@@ -29,7 +29,7 @@ dependencies = [
29
29
  "alembic>=1.14.1",
30
30
  "pillow>=11.1.0",
31
31
  "pybars3>=0.9.7",
32
- "fastmcp==2.12.3", # Pinned - 2.14.x breaks MCP tools visibility (issue #463)
32
+ "fastmcp==2.12.3", # Pinned - 2.14.x breaks MCP tools visibility (issue #463)
33
33
  "pyjwt>=2.10.1",
34
34
  "python-dotenv>=1.1.0",
35
35
  "pytest-aio>=1.9.0",
@@ -41,7 +41,10 @@ dependencies = [
41
41
  "mdformat>=0.7.22",
42
42
  "mdformat-gfm>=0.3.7",
43
43
  "mdformat-frontmatter>=2.0.8",
44
- "openpanel>=0.0.1", # Anonymous usage telemetry (Homebrew-style opt-out)
44
+ "openpanel>=0.0.1", # Anonymous usage telemetry (Homebrew-style opt-out)
45
+ "sniffio>=1.3.1",
46
+ "anyio>=4.10.0",
47
+ "httpx>=0.28.0",
45
48
  ]
46
49
 
47
50
 
@@ -88,6 +91,7 @@ dev = [
88
91
  "freezegun>=1.5.5",
89
92
  "testcontainers[postgres]>=4.0.0",
90
93
  "psycopg>=3.2.0",
94
+ "pyright>=1.1.408",
91
95
  ]
92
96
 
93
97
  [tool.hatch.version]
@@ -142,6 +146,3 @@ omit = [
142
146
  "*/telemetry.py", # External analytics; tested lightly, excluded from strict coverage target
143
147
  "*/services/migration_service.py", # Complex migration scenarios
144
148
  ]
145
-
146
- [tool.logfire]
147
- ignore_no_config = true
@@ -1,7 +1,7 @@
1
1
  """basic-memory - Local-first knowledge management combining Zettelkasten with knowledge graphs"""
2
2
 
3
3
  # Package version - updated by release automation
4
- __version__ = "0.17.4"
4
+ __version__ = "0.17.6"
5
5
 
6
6
  # API version for FastAPI - independent of package version
7
7
  __api_version__ = "v0"
@@ -5,14 +5,18 @@ import os
5
5
  from logging.config import fileConfig
6
6
 
7
7
  # Allow nested event loops (needed for pytest-asyncio and other async contexts)
8
- # Note: nest_asyncio doesn't work with uvloop, so we handle that case separately
9
- try:
10
- import nest_asyncio
11
-
12
- nest_asyncio.apply()
13
- except (ImportError, ValueError):
14
- # nest_asyncio not available or can't patch this loop type (e.g., uvloop)
15
- pass
8
+ # Note: nest_asyncio doesn't work with uvloop or Python 3.14+, so we handle those cases separately
9
+ import sys
10
+
11
+ if sys.version_info < (3, 14):
12
+ try:
13
+ import nest_asyncio
14
+
15
+ nest_asyncio.apply()
16
+ except (ImportError, ValueError):
17
+ # nest_asyncio not available or can't patch this loop type (e.g., uvloop)
18
+ pass
19
+ # For Python 3.14+, we rely on the thread-based fallback in run_migrations_online()
16
20
 
17
21
  from sqlalchemy import engine_from_config, pool
18
22
  from sqlalchemy.ext.asyncio import AsyncEngine, create_async_engine
@@ -5,13 +5,13 @@ Revises: a2b3c4d5e6f7, g9a0b3c4d5e6
5
5
  Create Date: 2025-12-29 12:46:46.476268
6
6
 
7
7
  """
8
- from typing import Sequence, Union
9
8
 
9
+ from typing import Sequence, Union
10
10
 
11
11
 
12
12
  # revision identifiers, used by Alembic.
13
- revision: str = '6830751f5fb6'
14
- down_revision: Union[str, Sequence[str], None] = ('a2b3c4d5e6f7', 'g9a0b3c4d5e6')
13
+ revision: str = "6830751f5fb6"
14
+ down_revision: Union[str, Sequence[str], None] = ("a2b3c4d5e6f7", "g9a0b3c4d5e6")
15
15
  branch_labels: Union[str, Sequence[str], None] = None
16
16
  depends_on: Union[str, Sequence[str], None] = None
17
17
 
@@ -414,9 +414,7 @@ async def move_entity(
414
414
 
415
415
  result = EntityResponseV2.model_validate(moved_entity)
416
416
 
417
- logger.info(
418
- f"API v2 response: moved external_id={entity_id} to '{data.destination_path}'"
419
- )
417
+ logger.info(f"API v2 response: moved external_id={entity_id} to '{data.destination_path}'")
420
418
 
421
419
  return result
422
420
 
@@ -264,9 +264,7 @@ async def delete_project_by_id(
264
264
  # Use is_default from database, not ConfigManager (which doesn't work in cloud mode)
265
265
  if old_project.is_default:
266
266
  available_projects = await project_service.list_projects()
267
- other_projects = [
268
- p.name for p in available_projects if p.external_id != project_id
269
- ]
267
+ other_projects = [p.name for p in available_projects if p.external_id != project_id]
270
268
  detail = f"Cannot delete default project '{old_project.name}'. "
271
269
  if other_projects:
272
270
  detail += ( # pragma: no cover
@@ -1,9 +1,3 @@
1
- # Suppress Logfire "not configured" warning - we only use Logfire in cloud/server contexts
2
- import os
3
-
4
- os.environ.setdefault("LOGFIRE_IGNORE_NO_CONFIG", "1")
5
-
6
- # Remove loguru's default handler IMMEDIATELY, before any other imports.
7
1
  # This prevents DEBUG logs from appearing on stdout during module-level
8
2
  # initialization (e.g., template_loader.TemplateLoader() logs at DEBUG level).
9
3
  from loguru import logger
@@ -1,11 +1,10 @@
1
1
  """Core cloud commands for Basic Memory CLI."""
2
2
 
3
- import asyncio
4
-
5
3
  import typer
6
4
  from rich.console import Console
7
5
 
8
6
  from basic_memory.cli.app import cloud_app
7
+ from basic_memory.cli.commands.command_utils import run_with_cleanup
9
8
  from basic_memory.cli.auth import CLIAuth
10
9
  from basic_memory.config import ConfigManager
11
10
  from basic_memory.cli.commands.cloud.api_client import (
@@ -64,7 +63,7 @@ def login():
64
63
  )
65
64
  raise typer.Exit(1)
66
65
 
67
- asyncio.run(_login())
66
+ run_with_cleanup(_login())
68
67
 
69
68
 
70
69
  @cloud_app.command()
@@ -110,7 +109,7 @@ def status() -> None:
110
109
  console.print("\n[blue]Checking cloud instance health...[/blue]")
111
110
 
112
111
  # Make API request to check health
113
- response = asyncio.run(
112
+ response = run_with_cleanup(
114
113
  make_api_request(method="GET", url=f"{host_url}/proxy/health", headers=headers)
115
114
  )
116
115
 
@@ -140,7 +139,6 @@ def status() -> None:
140
139
  def setup() -> None:
141
140
  """Set up cloud sync by installing rclone and configuring credentials.
142
141
 
143
- SPEC-20: Simplified to project-scoped workflow.
144
142
  After setup, use project commands for syncing:
145
143
  bm project add <name> <path> --local-path ~/projects/<name>
146
144
  bm project bisync --name <name> --resync # First time
@@ -156,12 +154,12 @@ def setup() -> None:
156
154
 
157
155
  # Step 2: Get tenant info
158
156
  console.print("\n[blue]Step 2: Getting tenant information...[/blue]")
159
- tenant_info = asyncio.run(get_mount_info())
157
+ tenant_info = run_with_cleanup(get_mount_info())
160
158
  console.print(f"[green]Found tenant: {tenant_info.tenant_id}[/green]")
161
159
 
162
160
  # Step 3: Generate credentials
163
161
  console.print("\n[blue]Step 3: Generating sync credentials...[/blue]")
164
- creds = asyncio.run(generate_mount_credentials(tenant_info.tenant_id))
162
+ creds = run_with_cleanup(generate_mount_credentials(tenant_info.tenant_id))
165
163
  console.print("[green]Generated secure credentials[/green]")
166
164
 
167
165
  # Step 4: Configure rclone remote
@@ -27,6 +27,7 @@ console = Console()
27
27
  # Minimum rclone version for --create-empty-src-dirs support
28
28
  MIN_RCLONE_VERSION_EMPTY_DIRS = (1, 64, 0)
29
29
 
30
+
30
31
  class RunResult(Protocol):
31
32
  returncode: int
32
33
  stdout: str
@@ -1,12 +1,12 @@
1
1
  """Upload CLI commands for basic-memory projects."""
2
2
 
3
- import asyncio
4
3
  from pathlib import Path
5
4
 
6
5
  import typer
7
6
  from rich.console import Console
8
7
 
9
8
  from basic_memory.cli.app import cloud_app
9
+ from basic_memory.cli.commands.command_utils import run_with_cleanup
10
10
  from basic_memory.cli.commands.cloud.cloud_utils import (
11
11
  create_cloud_project,
12
12
  project_exists,
@@ -121,4 +121,4 @@ def upload(
121
121
  console.print(f"[yellow]Warning: Sync failed: {e}[/yellow]")
122
122
  console.print("[dim]Files uploaded but may not be indexed yet[/dim]")
123
123
 
124
- asyncio.run(_upload())
124
+ run_with_cleanup(_upload())
@@ -14,6 +14,7 @@ from basic_memory.mcp.async_client import get_client
14
14
  from basic_memory.mcp.tools.utils import call_post, call_get
15
15
  from basic_memory.mcp.project_context import get_active_project
16
16
  from basic_memory.schemas import ProjectInfoResponse
17
+ from basic_memory.telemetry import shutdown_telemetry
17
18
 
18
19
  console = Console()
19
20
 
@@ -23,8 +24,8 @@ T = TypeVar("T")
23
24
  def run_with_cleanup(coro: Coroutine[Any, Any, T]) -> T:
24
25
  """Run an async coroutine with proper database cleanup.
25
26
 
26
- This helper ensures database connections are cleaned up before the event
27
- loop closes, preventing process hangs in CLI commands.
27
+ This helper ensures database connections and telemetry threads are cleaned up
28
+ before the event loop closes, preventing process hangs in CLI commands.
28
29
 
29
30
  Args:
30
31
  coro: The coroutine to run
@@ -38,6 +39,9 @@ def run_with_cleanup(coro: Coroutine[Any, Any, T]) -> T:
38
39
  return await coro
39
40
  finally:
40
41
  await db.shutdown_db()
42
+ # Shutdown telemetry to stop the OpenPanel background thread
43
+ # This prevents hangs on Python 3.14+ during thread shutdown
44
+ shutdown_telemetry()
41
45
 
42
46
  return asyncio.run(_with_cleanup())
43
47
 
@@ -1,6 +1,5 @@
1
1
  """Database management commands."""
2
2
 
3
- import asyncio
4
3
  from pathlib import Path
5
4
 
6
5
  import typer
@@ -10,6 +9,7 @@ from sqlalchemy.exc import OperationalError
10
9
 
11
10
  from basic_memory import db
12
11
  from basic_memory.cli.app import app
12
+ from basic_memory.cli.commands.command_utils import run_with_cleanup
13
13
  from basic_memory.config import ConfigManager
14
14
  from basic_memory.repository import ProjectRepository
15
15
  from basic_memory.services.initialization import reconcile_projects_with_config
@@ -81,7 +81,7 @@ def reset(
81
81
 
82
82
  # Create a new empty database (preserves project configuration)
83
83
  try:
84
- asyncio.run(db.run_migrations(app_config))
84
+ run_with_cleanup(db.run_migrations(app_config))
85
85
  except OperationalError as e:
86
86
  if "disk I/O error" in str(e) or "database is locked" in str(e):
87
87
  console.print(
@@ -99,5 +99,7 @@ def reset(
99
99
  console.print("[yellow]No projects configured. Skipping reindex.[/yellow]")
100
100
  else:
101
101
  console.print(f"Rebuilding search index for {len(projects)} project(s)...")
102
- asyncio.run(_reindex_projects(app_config))
102
+ # Note: _reindex_projects has its own cleanup, but run_with_cleanup
103
+ # ensures db.shutdown_db() is called even if _reindex_projects changes
104
+ run_with_cleanup(_reindex_projects(app_config))
103
105
  console.print("[green]Reindex complete[/green]")
@@ -1,6 +1,5 @@
1
1
  """Format command for basic-memory CLI."""
2
2
 
3
- import asyncio
4
3
  from pathlib import Path
5
4
  from typing import Annotated, Optional
6
5
 
@@ -10,6 +9,7 @@ from rich.console import Console
10
9
  from rich.progress import Progress, SpinnerColumn, TextColumn
11
10
 
12
11
  from basic_memory.cli.app import app
12
+ from basic_memory.cli.commands.command_utils import run_with_cleanup
13
13
  from basic_memory.config import ConfigManager, get_project_config
14
14
  from basic_memory.file_utils import format_file
15
15
 
@@ -189,7 +189,7 @@ def format(
189
189
  basic-memory format notes/ # Format all files in directory
190
190
  """
191
191
  try:
192
- asyncio.run(run_format(path, project))
192
+ run_with_cleanup(run_format(path, project))
193
193
  except Exception as e:
194
194
  if not isinstance(e, typer.Exit):
195
195
  logger.error(f"Error formatting files: {e}")
@@ -1,12 +1,12 @@
1
1
  """Import command for ChatGPT conversations."""
2
2
 
3
- import asyncio
4
3
  import json
5
4
  from pathlib import Path
6
5
  from typing import Annotated, Tuple
7
6
 
8
7
  import typer
9
8
  from basic_memory.cli.app import import_app
9
+ from basic_memory.cli.commands.command_utils import run_with_cleanup
10
10
  from basic_memory.config import ConfigManager, get_project_config
11
11
  from basic_memory.importers import ChatGPTImporter
12
12
  from basic_memory.markdown import EntityParser, MarkdownProcessor
@@ -53,7 +53,7 @@ def import_chatgpt(
53
53
  raise typer.Exit(1)
54
54
 
55
55
  # Get importer dependencies
56
- markdown_processor, file_service = asyncio.run(get_importer_dependencies())
56
+ markdown_processor, file_service = run_with_cleanup(get_importer_dependencies())
57
57
  config = get_project_config()
58
58
  # Process the file
59
59
  base_path = config.home / folder
@@ -63,7 +63,7 @@ def import_chatgpt(
63
63
  importer = ChatGPTImporter(config.home, markdown_processor, file_service)
64
64
  with conversations_json.open("r", encoding="utf-8") as file:
65
65
  json_data = json.load(file)
66
- result = asyncio.run(importer.import_data(json_data, folder))
66
+ result = run_with_cleanup(importer.import_data(json_data, folder))
67
67
 
68
68
  if not result.success: # pragma: no cover
69
69
  typer.echo(f"Error during import: {result.error_message}", err=True)
@@ -1,12 +1,12 @@
1
1
  """Import command for basic-memory CLI to import chat data from conversations2.json format."""
2
2
 
3
- import asyncio
4
3
  import json
5
4
  from pathlib import Path
6
5
  from typing import Annotated, Tuple
7
6
 
8
7
  import typer
9
8
  from basic_memory.cli.app import claude_app
9
+ from basic_memory.cli.commands.command_utils import run_with_cleanup
10
10
  from basic_memory.config import ConfigManager, get_project_config
11
11
  from basic_memory.importers.claude_conversations_importer import ClaudeConversationsImporter
12
12
  from basic_memory.markdown import EntityParser, MarkdownProcessor
@@ -54,7 +54,7 @@ def import_claude(
54
54
  raise typer.Exit(1)
55
55
 
56
56
  # Get importer dependencies
57
- markdown_processor, file_service = asyncio.run(get_importer_dependencies())
57
+ markdown_processor, file_service = run_with_cleanup(get_importer_dependencies())
58
58
 
59
59
  # Create the importer
60
60
  importer = ClaudeConversationsImporter(config.home, markdown_processor, file_service)
@@ -66,7 +66,7 @@ def import_claude(
66
66
  # Run the import
67
67
  with conversations_json.open("r", encoding="utf-8") as file:
68
68
  json_data = json.load(file)
69
- result = asyncio.run(importer.import_data(json_data, folder))
69
+ result = run_with_cleanup(importer.import_data(json_data, folder))
70
70
 
71
71
  if not result.success: # pragma: no cover
72
72
  typer.echo(f"Error during import: {result.error_message}", err=True)
@@ -1,12 +1,12 @@
1
1
  """Import command for basic-memory CLI to import project data from Claude.ai."""
2
2
 
3
- import asyncio
4
3
  import json
5
4
  from pathlib import Path
6
5
  from typing import Annotated, Tuple
7
6
 
8
7
  import typer
9
8
  from basic_memory.cli.app import claude_app
9
+ from basic_memory.cli.commands.command_utils import run_with_cleanup
10
10
  from basic_memory.config import ConfigManager, get_project_config
11
11
  from basic_memory.importers.claude_projects_importer import ClaudeProjectsImporter
12
12
  from basic_memory.markdown import EntityParser, MarkdownProcessor
@@ -53,7 +53,7 @@ def import_projects(
53
53
  raise typer.Exit(1)
54
54
 
55
55
  # Get importer dependencies
56
- markdown_processor, file_service = asyncio.run(get_importer_dependencies())
56
+ markdown_processor, file_service = run_with_cleanup(get_importer_dependencies())
57
57
 
58
58
  # Create the importer
59
59
  importer = ClaudeProjectsImporter(config.home, markdown_processor, file_service)
@@ -65,7 +65,7 @@ def import_projects(
65
65
  # Run the import
66
66
  with projects_json.open("r", encoding="utf-8") as file:
67
67
  json_data = json.load(file)
68
- result = asyncio.run(importer.import_data(json_data, base_folder))
68
+ result = run_with_cleanup(importer.import_data(json_data, base_folder))
69
69
 
70
70
  if not result.success: # pragma: no cover
71
71
  typer.echo(f"Error during import: {result.error_message}", err=True)
@@ -1,12 +1,12 @@
1
1
  """Import command for basic-memory CLI to import from JSON memory format."""
2
2
 
3
- import asyncio
4
3
  import json
5
4
  from pathlib import Path
6
5
  from typing import Annotated, Tuple
7
6
 
8
7
  import typer
9
8
  from basic_memory.cli.app import import_app
9
+ from basic_memory.cli.commands.command_utils import run_with_cleanup
10
10
  from basic_memory.config import ConfigManager, get_project_config
11
11
  from basic_memory.importers.memory_json_importer import MemoryJsonImporter
12
12
  from basic_memory.markdown import EntityParser, MarkdownProcessor
@@ -52,7 +52,7 @@ def memory_json(
52
52
  config = get_project_config()
53
53
  try:
54
54
  # Get importer dependencies
55
- markdown_processor, file_service = asyncio.run(get_importer_dependencies())
55
+ markdown_processor, file_service = run_with_cleanup(get_importer_dependencies())
56
56
 
57
57
  # Create the importer
58
58
  importer = MemoryJsonImporter(config.home, markdown_processor, file_service)
@@ -67,7 +67,7 @@ def memory_json(
67
67
  for line in file:
68
68
  json_data = json.loads(line)
69
69
  file_data.append(json_data)
70
- result = asyncio.run(importer.import_data(file_data, destination_folder))
70
+ result = run_with_cleanup(importer.import_data(file_data, destination_folder))
71
71
 
72
72
  if not result.success: # pragma: no cover
73
73
  typer.echo(f"Error during import: {result.error_message}", err=True)