basic-memory 0.19.0__tar.gz → 0.19.2__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 (637) hide show
  1. {basic_memory-0.19.0 → basic_memory-0.19.2}/CHANGELOG.md +29 -0
  2. {basic_memory-0.19.0 → basic_memory-0.19.2}/PKG-INFO +13 -1
  3. {basic_memory-0.19.0 → basic_memory-0.19.2}/README.md +12 -0
  4. {basic_memory-0.19.0 → basic_memory-0.19.2}/server.json +2 -2
  5. {basic_memory-0.19.0 → basic_memory-0.19.2}/src/basic_memory/__init__.py +1 -1
  6. {basic_memory-0.19.0 → basic_memory-0.19.2}/src/basic_memory/api/v2/routers/knowledge_router.py +48 -0
  7. {basic_memory-0.19.0 → basic_memory-0.19.2}/src/basic_memory/mcp/tools/canvas.py +5 -3
  8. {basic_memory-0.19.0 → basic_memory-0.19.2}/src/basic_memory/mcp/tools/delete_note.py +1 -1
  9. {basic_memory-0.19.0 → basic_memory-0.19.2}/src/basic_memory/mcp/tools/edit_note.py +19 -5
  10. {basic_memory-0.19.0 → basic_memory-0.19.2}/src/basic_memory/mcp/tools/move_note.py +21 -2
  11. {basic_memory-0.19.0 → basic_memory-0.19.2}/src/basic_memory/mcp/tools/search.py +12 -2
  12. {basic_memory-0.19.0 → basic_memory-0.19.2}/src/basic_memory/mcp/tools/write_note.py +4 -3
  13. {basic_memory-0.19.0 → basic_memory-0.19.2}/src/basic_memory/repository/search_repository_base.py +24 -9
  14. {basic_memory-0.19.0 → basic_memory-0.19.2}/src/basic_memory/schemas/base.py +5 -3
  15. {basic_memory-0.19.0 → basic_memory-0.19.2}/src/basic_memory/schemas/request.py +18 -3
  16. {basic_memory-0.19.0 → basic_memory-0.19.2}/src/basic_memory/schemas/v2/__init__.py +8 -0
  17. basic_memory-0.19.2/src/basic_memory/schemas/v2/graph.py +31 -0
  18. {basic_memory-0.19.0 → basic_memory-0.19.2}/src/basic_memory/services/entity_service.py +75 -0
  19. {basic_memory-0.19.0 → basic_memory-0.19.2}/src/basic_memory/services/project_service.py +70 -44
  20. {basic_memory-0.19.0 → basic_memory-0.19.2}/src/basic_memory/utils.py +63 -3
  21. {basic_memory-0.19.0 → basic_memory-0.19.2}/test-int/cli/test_cli_tool_edit_note_integration.py +1 -1
  22. {basic_memory-0.19.0 → basic_memory-0.19.2}/test-int/mcp/test_delete_note_integration.py +30 -5
  23. {basic_memory-0.19.0 → basic_memory-0.19.2}/test-int/mcp/test_edit_note_integration.py +78 -0
  24. {basic_memory-0.19.0 → basic_memory-0.19.2}/test-int/mcp/test_move_note_integration.py +53 -0
  25. basic_memory-0.19.2/test-int/mcp/test_string_params_integration.py +167 -0
  26. {basic_memory-0.19.0 → basic_memory-0.19.2}/tests/mcp/test_tool_delete_note.py +27 -3
  27. {basic_memory-0.19.0 → basic_memory-0.19.2}/tests/mcp/test_tool_edit_note.py +160 -1
  28. {basic_memory-0.19.0 → basic_memory-0.19.2}/tests/mcp/test_tool_move_note.py +25 -0
  29. {basic_memory-0.19.0 → basic_memory-0.19.2}/tests/repository/test_semantic_search_base.py +23 -0
  30. {basic_memory-0.19.0 → basic_memory-0.19.2}/tests/schemas/test_schemas.py +43 -3
  31. {basic_memory-0.19.0 → basic_memory-0.19.2}/tests/services/test_entity_service.py +261 -0
  32. {basic_memory-0.19.0 → basic_memory-0.19.2}/tests/services/test_project_service_embedding_status.py +41 -0
  33. basic_memory-0.19.2/tests/test_coerce.py +58 -0
  34. basic_memory-0.19.2/tests/utils/test_setup_logging.py +162 -0
  35. {basic_memory-0.19.0 → basic_memory-0.19.2}/uv.lock +9 -3
  36. {basic_memory-0.19.0 → basic_memory-0.19.2}/.claude/commands/release/beta.md +0 -0
  37. {basic_memory-0.19.0 → basic_memory-0.19.2}/.claude/commands/release/changelog.md +0 -0
  38. {basic_memory-0.19.0 → basic_memory-0.19.2}/.claude/commands/release/release-check.md +0 -0
  39. {basic_memory-0.19.0 → basic_memory-0.19.2}/.claude/commands/release/release.md +0 -0
  40. {basic_memory-0.19.0 → basic_memory-0.19.2}/.claude/commands/spec.md +0 -0
  41. {basic_memory-0.19.0 → basic_memory-0.19.2}/.claude/commands/test-live.md +0 -0
  42. {basic_memory-0.19.0 → basic_memory-0.19.2}/.claude/settings.json +0 -0
  43. {basic_memory-0.19.0 → basic_memory-0.19.2}/.dockerignore +0 -0
  44. {basic_memory-0.19.0 → basic_memory-0.19.2}/.env.example +0 -0
  45. {basic_memory-0.19.0 → basic_memory-0.19.2}/.github/ISSUE_TEMPLATE/bug_report.md +0 -0
  46. {basic_memory-0.19.0 → basic_memory-0.19.2}/.github/ISSUE_TEMPLATE/config.yml +0 -0
  47. {basic_memory-0.19.0 → basic_memory-0.19.2}/.github/ISSUE_TEMPLATE/documentation.md +0 -0
  48. {basic_memory-0.19.0 → basic_memory-0.19.2}/.github/ISSUE_TEMPLATE/feature_request.md +0 -0
  49. {basic_memory-0.19.0 → basic_memory-0.19.2}/.github/dependabot.yml +0 -0
  50. {basic_memory-0.19.0 → basic_memory-0.19.2}/.github/workflows/claude-code-review.yml +0 -0
  51. {basic_memory-0.19.0 → basic_memory-0.19.2}/.github/workflows/claude-issue-triage.yml +0 -0
  52. {basic_memory-0.19.0 → basic_memory-0.19.2}/.github/workflows/claude.yml +0 -0
  53. {basic_memory-0.19.0 → basic_memory-0.19.2}/.github/workflows/dev-release.yml +0 -0
  54. {basic_memory-0.19.0 → basic_memory-0.19.2}/.github/workflows/docker.yml +0 -0
  55. {basic_memory-0.19.0 → basic_memory-0.19.2}/.github/workflows/pr-title.yml +0 -0
  56. {basic_memory-0.19.0 → basic_memory-0.19.2}/.github/workflows/release.yml +0 -0
  57. {basic_memory-0.19.0 → basic_memory-0.19.2}/.github/workflows/test.yml +0 -0
  58. {basic_memory-0.19.0 → basic_memory-0.19.2}/.gitignore +0 -0
  59. {basic_memory-0.19.0 → basic_memory-0.19.2}/.python-version +0 -0
  60. {basic_memory-0.19.0 → basic_memory-0.19.2}/AGENTS.md +0 -0
  61. {basic_memory-0.19.0 → basic_memory-0.19.2}/CITATION.cff +0 -0
  62. {basic_memory-0.19.0 → basic_memory-0.19.2}/CLA.md +0 -0
  63. {basic_memory-0.19.0 → basic_memory-0.19.2}/CLAUDE.md +0 -0
  64. {basic_memory-0.19.0 → basic_memory-0.19.2}/CODE_OF_CONDUCT.md +0 -0
  65. {basic_memory-0.19.0 → basic_memory-0.19.2}/CONTRIBUTING.md +0 -0
  66. {basic_memory-0.19.0 → basic_memory-0.19.2}/Dockerfile +0 -0
  67. {basic_memory-0.19.0 → basic_memory-0.19.2}/LICENSE +0 -0
  68. {basic_memory-0.19.0 → basic_memory-0.19.2}/NOTE-FORMAT.md +0 -0
  69. {basic_memory-0.19.0 → basic_memory-0.19.2}/SECURITY.md +0 -0
  70. {basic_memory-0.19.0 → basic_memory-0.19.2}/docker-compose-postgres.yml +0 -0
  71. {basic_memory-0.19.0 → basic_memory-0.19.2}/docker-compose.yml +0 -0
  72. {basic_memory-0.19.0 → basic_memory-0.19.2}/docs/ARCHITECTURE.md +0 -0
  73. {basic_memory-0.19.0 → basic_memory-0.19.2}/docs/Docker.md +0 -0
  74. {basic_memory-0.19.0 → basic_memory-0.19.2}/docs/NOTE-FORMAT.md +0 -0
  75. {basic_memory-0.19.0 → basic_memory-0.19.2}/docs/SPEC-PER-PROJECT-ROUTING.md +0 -0
  76. {basic_memory-0.19.0 → basic_memory-0.19.2}/docs/ai-assistant-guide-extended.md +0 -0
  77. {basic_memory-0.19.0 → basic_memory-0.19.2}/docs/character-handling.md +0 -0
  78. {basic_memory-0.19.0 → basic_memory-0.19.2}/docs/cloud-cli.md +0 -0
  79. {basic_memory-0.19.0 → basic_memory-0.19.2}/docs/cloud-semantic-search-value.md +0 -0
  80. {basic_memory-0.19.0 → basic_memory-0.19.2}/docs/mcp-ui-bakeoff-instructions.md +0 -0
  81. {basic_memory-0.19.0 → basic_memory-0.19.2}/docs/metadata-search.md +0 -0
  82. {basic_memory-0.19.0 → basic_memory-0.19.2}/docs/post-v0.18.0-test-plan.md +0 -0
  83. {basic_memory-0.19.0 → basic_memory-0.19.2}/docs/releases/v0.19.0.md +0 -0
  84. {basic_memory-0.19.0 → basic_memory-0.19.2}/docs/semantic-search-test-log.md +0 -0
  85. {basic_memory-0.19.0 → basic_memory-0.19.2}/docs/semantic-search.md +0 -0
  86. {basic_memory-0.19.0 → basic_memory-0.19.2}/docs/specs/SPEC-LOCAL-PLUS-PUBLISH.md +0 -0
  87. {basic_memory-0.19.0 → basic_memory-0.19.2}/docs/specs/SPEC-SCHEMA-IMPL.md +0 -0
  88. {basic_memory-0.19.0 → basic_memory-0.19.2}/docs/specs/SPEC-SCHEMA.md +0 -0
  89. {basic_memory-0.19.0 → basic_memory-0.19.2}/docs/testing-coverage.md +0 -0
  90. {basic_memory-0.19.0 → basic_memory-0.19.2}/justfile +0 -0
  91. {basic_memory-0.19.0 → basic_memory-0.19.2}/llms-install.md +0 -0
  92. {basic_memory-0.19.0 → basic_memory-0.19.2}/pyproject.toml +0 -0
  93. {basic_memory-0.19.0 → basic_memory-0.19.2}/smithery.yaml +0 -0
  94. {basic_memory-0.19.0 → basic_memory-0.19.2}/src/basic_memory/alembic/alembic.ini +0 -0
  95. {basic_memory-0.19.0 → basic_memory-0.19.2}/src/basic_memory/alembic/env.py +0 -0
  96. {basic_memory-0.19.0 → basic_memory-0.19.2}/src/basic_memory/alembic/migrations.py +0 -0
  97. {basic_memory-0.19.0 → basic_memory-0.19.2}/src/basic_memory/alembic/script.py.mako +0 -0
  98. {basic_memory-0.19.0 → basic_memory-0.19.2}/src/basic_memory/alembic/versions/314f1ea54dc4_add_postgres_full_text_search_support_.py +0 -0
  99. {basic_memory-0.19.0 → basic_memory-0.19.2}/src/basic_memory/alembic/versions/3dae7c7b1564_initial_schema.py +0 -0
  100. {basic_memory-0.19.0 → basic_memory-0.19.2}/src/basic_memory/alembic/versions/502b60eaa905_remove_required_from_entity_permalink.py +0 -0
  101. {basic_memory-0.19.0 → basic_memory-0.19.2}/src/basic_memory/alembic/versions/5fe1ab1ccebe_add_projects_table.py +0 -0
  102. {basic_memory-0.19.0 → basic_memory-0.19.2}/src/basic_memory/alembic/versions/647e7a75e2cd_project_constraint_fix.py +0 -0
  103. {basic_memory-0.19.0 → basic_memory-0.19.2}/src/basic_memory/alembic/versions/6830751f5fb6_merge_multiple_heads.py +0 -0
  104. {basic_memory-0.19.0 → basic_memory-0.19.2}/src/basic_memory/alembic/versions/9d9c1cb7d8f5_add_mtime_and_size_columns_to_entity_.py +0 -0
  105. {basic_memory-0.19.0 → basic_memory-0.19.2}/src/basic_memory/alembic/versions/a1b2c3d4e5f6_fix_project_foreign_keys.py +0 -0
  106. {basic_memory-0.19.0 → basic_memory-0.19.2}/src/basic_memory/alembic/versions/a2b3c4d5e6f7_add_search_index_entity_cascade.py +0 -0
  107. {basic_memory-0.19.0 → basic_memory-0.19.2}/src/basic_memory/alembic/versions/b3c3938bacdb_relation_to_name_unique_index.py +0 -0
  108. {basic_memory-0.19.0 → basic_memory-0.19.2}/src/basic_memory/alembic/versions/cc7172b46608_update_search_index_schema.py +0 -0
  109. {basic_memory-0.19.0 → basic_memory-0.19.2}/src/basic_memory/alembic/versions/d7e8f9a0b1c2_add_structured_metadata_indexes.py +0 -0
  110. {basic_memory-0.19.0 → basic_memory-0.19.2}/src/basic_memory/alembic/versions/e7e1f4367280_add_scan_watermark_tracking_to_project.py +0 -0
  111. {basic_memory-0.19.0 → basic_memory-0.19.2}/src/basic_memory/alembic/versions/f8a9b2c3d4e5_add_pg_trgm_for_fuzzy_link_resolution.py +0 -0
  112. {basic_memory-0.19.0 → basic_memory-0.19.2}/src/basic_memory/alembic/versions/g9a0b3c4d5e6_add_external_id_to_project_and_entity.py +0 -0
  113. {basic_memory-0.19.0 → basic_memory-0.19.2}/src/basic_memory/alembic/versions/h1b2c3d4e5f6_add_postgres_vector_search_tables.py +0 -0
  114. {basic_memory-0.19.0 → basic_memory-0.19.2}/src/basic_memory/alembic/versions/i2c3d4e5f6g7_auto_backfill_semantic_embeddings.py +0 -0
  115. {basic_memory-0.19.0 → basic_memory-0.19.2}/src/basic_memory/alembic/versions/j3d4e5f6g7h8_rename_entity_type_to_note_type.py +0 -0
  116. {basic_memory-0.19.0 → basic_memory-0.19.2}/src/basic_memory/alembic/versions/k4e5f6g7h8i9_add_created_by_and_last_updated_by_to_entity.py +0 -0
  117. {basic_memory-0.19.0 → basic_memory-0.19.2}/src/basic_memory/api/__init__.py +0 -0
  118. {basic_memory-0.19.0 → basic_memory-0.19.2}/src/basic_memory/api/app.py +0 -0
  119. {basic_memory-0.19.0 → basic_memory-0.19.2}/src/basic_memory/api/container.py +0 -0
  120. {basic_memory-0.19.0 → basic_memory-0.19.2}/src/basic_memory/api/template_loader.py +0 -0
  121. {basic_memory-0.19.0 → basic_memory-0.19.2}/src/basic_memory/api/v2/__init__.py +0 -0
  122. {basic_memory-0.19.0 → basic_memory-0.19.2}/src/basic_memory/api/v2/routers/__init__.py +0 -0
  123. {basic_memory-0.19.0 → basic_memory-0.19.2}/src/basic_memory/api/v2/routers/directory_router.py +0 -0
  124. {basic_memory-0.19.0 → basic_memory-0.19.2}/src/basic_memory/api/v2/routers/importer_router.py +0 -0
  125. {basic_memory-0.19.0 → basic_memory-0.19.2}/src/basic_memory/api/v2/routers/memory_router.py +0 -0
  126. {basic_memory-0.19.0 → basic_memory-0.19.2}/src/basic_memory/api/v2/routers/project_router.py +0 -0
  127. {basic_memory-0.19.0 → basic_memory-0.19.2}/src/basic_memory/api/v2/routers/prompt_router.py +0 -0
  128. {basic_memory-0.19.0 → basic_memory-0.19.2}/src/basic_memory/api/v2/routers/resource_router.py +0 -0
  129. {basic_memory-0.19.0 → basic_memory-0.19.2}/src/basic_memory/api/v2/routers/schema_router.py +0 -0
  130. {basic_memory-0.19.0 → basic_memory-0.19.2}/src/basic_memory/api/v2/routers/search_router.py +0 -0
  131. {basic_memory-0.19.0 → basic_memory-0.19.2}/src/basic_memory/api/v2/utils.py +0 -0
  132. {basic_memory-0.19.0 → basic_memory-0.19.2}/src/basic_memory/cli/__init__.py +0 -0
  133. {basic_memory-0.19.0 → basic_memory-0.19.2}/src/basic_memory/cli/analytics.py +0 -0
  134. {basic_memory-0.19.0 → basic_memory-0.19.2}/src/basic_memory/cli/app.py +0 -0
  135. {basic_memory-0.19.0 → basic_memory-0.19.2}/src/basic_memory/cli/auth.py +0 -0
  136. {basic_memory-0.19.0 → basic_memory-0.19.2}/src/basic_memory/cli/commands/__init__.py +0 -0
  137. {basic_memory-0.19.0 → basic_memory-0.19.2}/src/basic_memory/cli/commands/cloud/__init__.py +0 -0
  138. {basic_memory-0.19.0 → basic_memory-0.19.2}/src/basic_memory/cli/commands/cloud/api_client.py +0 -0
  139. {basic_memory-0.19.0 → basic_memory-0.19.2}/src/basic_memory/cli/commands/cloud/bisync_commands.py +0 -0
  140. {basic_memory-0.19.0 → basic_memory-0.19.2}/src/basic_memory/cli/commands/cloud/cloud_utils.py +0 -0
  141. {basic_memory-0.19.0 → basic_memory-0.19.2}/src/basic_memory/cli/commands/cloud/core_commands.py +0 -0
  142. {basic_memory-0.19.0 → basic_memory-0.19.2}/src/basic_memory/cli/commands/cloud/project_sync.py +0 -0
  143. {basic_memory-0.19.0 → basic_memory-0.19.2}/src/basic_memory/cli/commands/cloud/rclone_commands.py +0 -0
  144. {basic_memory-0.19.0 → basic_memory-0.19.2}/src/basic_memory/cli/commands/cloud/rclone_config.py +0 -0
  145. {basic_memory-0.19.0 → basic_memory-0.19.2}/src/basic_memory/cli/commands/cloud/rclone_installer.py +0 -0
  146. {basic_memory-0.19.0 → basic_memory-0.19.2}/src/basic_memory/cli/commands/cloud/restore.py +0 -0
  147. {basic_memory-0.19.0 → basic_memory-0.19.2}/src/basic_memory/cli/commands/cloud/schemas.py +0 -0
  148. {basic_memory-0.19.0 → basic_memory-0.19.2}/src/basic_memory/cli/commands/cloud/snapshot.py +0 -0
  149. {basic_memory-0.19.0 → basic_memory-0.19.2}/src/basic_memory/cli/commands/cloud/upload.py +0 -0
  150. {basic_memory-0.19.0 → basic_memory-0.19.2}/src/basic_memory/cli/commands/cloud/upload_command.py +0 -0
  151. {basic_memory-0.19.0 → basic_memory-0.19.2}/src/basic_memory/cli/commands/cloud/workspace.py +0 -0
  152. {basic_memory-0.19.0 → basic_memory-0.19.2}/src/basic_memory/cli/commands/command_utils.py +0 -0
  153. {basic_memory-0.19.0 → basic_memory-0.19.2}/src/basic_memory/cli/commands/db.py +0 -0
  154. {basic_memory-0.19.0 → basic_memory-0.19.2}/src/basic_memory/cli/commands/doctor.py +0 -0
  155. {basic_memory-0.19.0 → basic_memory-0.19.2}/src/basic_memory/cli/commands/format.py +0 -0
  156. {basic_memory-0.19.0 → basic_memory-0.19.2}/src/basic_memory/cli/commands/import_chatgpt.py +0 -0
  157. {basic_memory-0.19.0 → basic_memory-0.19.2}/src/basic_memory/cli/commands/import_claude_conversations.py +0 -0
  158. {basic_memory-0.19.0 → basic_memory-0.19.2}/src/basic_memory/cli/commands/import_claude_projects.py +0 -0
  159. {basic_memory-0.19.0 → basic_memory-0.19.2}/src/basic_memory/cli/commands/import_memory_json.py +0 -0
  160. {basic_memory-0.19.0 → basic_memory-0.19.2}/src/basic_memory/cli/commands/mcp.py +0 -0
  161. {basic_memory-0.19.0 → basic_memory-0.19.2}/src/basic_memory/cli/commands/project.py +0 -0
  162. {basic_memory-0.19.0 → basic_memory-0.19.2}/src/basic_memory/cli/commands/routing.py +0 -0
  163. {basic_memory-0.19.0 → basic_memory-0.19.2}/src/basic_memory/cli/commands/schema.py +0 -0
  164. {basic_memory-0.19.0 → basic_memory-0.19.2}/src/basic_memory/cli/commands/status.py +0 -0
  165. {basic_memory-0.19.0 → basic_memory-0.19.2}/src/basic_memory/cli/commands/tool.py +0 -0
  166. {basic_memory-0.19.0 → basic_memory-0.19.2}/src/basic_memory/cli/container.py +0 -0
  167. {basic_memory-0.19.0 → basic_memory-0.19.2}/src/basic_memory/cli/main.py +0 -0
  168. {basic_memory-0.19.0 → basic_memory-0.19.2}/src/basic_memory/cli/promo.py +0 -0
  169. {basic_memory-0.19.0 → basic_memory-0.19.2}/src/basic_memory/config.py +0 -0
  170. {basic_memory-0.19.0 → basic_memory-0.19.2}/src/basic_memory/db.py +0 -0
  171. {basic_memory-0.19.0 → basic_memory-0.19.2}/src/basic_memory/deps/__init__.py +0 -0
  172. {basic_memory-0.19.0 → basic_memory-0.19.2}/src/basic_memory/deps/config.py +0 -0
  173. {basic_memory-0.19.0 → basic_memory-0.19.2}/src/basic_memory/deps/db.py +0 -0
  174. {basic_memory-0.19.0 → basic_memory-0.19.2}/src/basic_memory/deps/importers.py +0 -0
  175. {basic_memory-0.19.0 → basic_memory-0.19.2}/src/basic_memory/deps/projects.py +0 -0
  176. {basic_memory-0.19.0 → basic_memory-0.19.2}/src/basic_memory/deps/repositories.py +0 -0
  177. {basic_memory-0.19.0 → basic_memory-0.19.2}/src/basic_memory/deps/services.py +0 -0
  178. {basic_memory-0.19.0 → basic_memory-0.19.2}/src/basic_memory/deps.py +0 -0
  179. {basic_memory-0.19.0 → basic_memory-0.19.2}/src/basic_memory/file_utils.py +0 -0
  180. {basic_memory-0.19.0 → basic_memory-0.19.2}/src/basic_memory/ignore_utils.py +0 -0
  181. {basic_memory-0.19.0 → basic_memory-0.19.2}/src/basic_memory/importers/__init__.py +0 -0
  182. {basic_memory-0.19.0 → basic_memory-0.19.2}/src/basic_memory/importers/base.py +0 -0
  183. {basic_memory-0.19.0 → basic_memory-0.19.2}/src/basic_memory/importers/chatgpt_importer.py +0 -0
  184. {basic_memory-0.19.0 → basic_memory-0.19.2}/src/basic_memory/importers/claude_conversations_importer.py +0 -0
  185. {basic_memory-0.19.0 → basic_memory-0.19.2}/src/basic_memory/importers/claude_projects_importer.py +0 -0
  186. {basic_memory-0.19.0 → basic_memory-0.19.2}/src/basic_memory/importers/memory_json_importer.py +0 -0
  187. {basic_memory-0.19.0 → basic_memory-0.19.2}/src/basic_memory/importers/utils.py +0 -0
  188. {basic_memory-0.19.0 → basic_memory-0.19.2}/src/basic_memory/markdown/__init__.py +0 -0
  189. {basic_memory-0.19.0 → basic_memory-0.19.2}/src/basic_memory/markdown/entity_parser.py +0 -0
  190. {basic_memory-0.19.0 → basic_memory-0.19.2}/src/basic_memory/markdown/markdown_processor.py +0 -0
  191. {basic_memory-0.19.0 → basic_memory-0.19.2}/src/basic_memory/markdown/plugins.py +0 -0
  192. {basic_memory-0.19.0 → basic_memory-0.19.2}/src/basic_memory/markdown/schemas.py +0 -0
  193. {basic_memory-0.19.0 → basic_memory-0.19.2}/src/basic_memory/markdown/utils.py +0 -0
  194. {basic_memory-0.19.0 → basic_memory-0.19.2}/src/basic_memory/mcp/__init__.py +0 -0
  195. {basic_memory-0.19.0 → basic_memory-0.19.2}/src/basic_memory/mcp/async_client.py +0 -0
  196. {basic_memory-0.19.0 → basic_memory-0.19.2}/src/basic_memory/mcp/clients/__init__.py +0 -0
  197. {basic_memory-0.19.0 → basic_memory-0.19.2}/src/basic_memory/mcp/clients/directory.py +0 -0
  198. {basic_memory-0.19.0 → basic_memory-0.19.2}/src/basic_memory/mcp/clients/knowledge.py +0 -0
  199. {basic_memory-0.19.0 → basic_memory-0.19.2}/src/basic_memory/mcp/clients/memory.py +0 -0
  200. {basic_memory-0.19.0 → basic_memory-0.19.2}/src/basic_memory/mcp/clients/project.py +0 -0
  201. {basic_memory-0.19.0 → basic_memory-0.19.2}/src/basic_memory/mcp/clients/resource.py +0 -0
  202. {basic_memory-0.19.0 → basic_memory-0.19.2}/src/basic_memory/mcp/clients/schema.py +0 -0
  203. {basic_memory-0.19.0 → basic_memory-0.19.2}/src/basic_memory/mcp/clients/search.py +0 -0
  204. {basic_memory-0.19.0 → basic_memory-0.19.2}/src/basic_memory/mcp/container.py +0 -0
  205. {basic_memory-0.19.0 → basic_memory-0.19.2}/src/basic_memory/mcp/formatting.py +0 -0
  206. {basic_memory-0.19.0 → basic_memory-0.19.2}/src/basic_memory/mcp/project_context.py +0 -0
  207. {basic_memory-0.19.0 → basic_memory-0.19.2}/src/basic_memory/mcp/prompts/__init__.py +0 -0
  208. {basic_memory-0.19.0 → basic_memory-0.19.2}/src/basic_memory/mcp/prompts/ai_assistant_guide.py +0 -0
  209. {basic_memory-0.19.0 → basic_memory-0.19.2}/src/basic_memory/mcp/prompts/continue_conversation.py +0 -0
  210. {basic_memory-0.19.0 → basic_memory-0.19.2}/src/basic_memory/mcp/prompts/recent_activity.py +0 -0
  211. {basic_memory-0.19.0 → basic_memory-0.19.2}/src/basic_memory/mcp/prompts/search.py +0 -0
  212. {basic_memory-0.19.0 → basic_memory-0.19.2}/src/basic_memory/mcp/prompts/utils.py +0 -0
  213. {basic_memory-0.19.0 → basic_memory-0.19.2}/src/basic_memory/mcp/resources/__init__.py +0 -0
  214. {basic_memory-0.19.0 → basic_memory-0.19.2}/src/basic_memory/mcp/resources/ai_assistant_guide.md +0 -0
  215. {basic_memory-0.19.0 → basic_memory-0.19.2}/src/basic_memory/mcp/resources/cloud_info.md +0 -0
  216. {basic_memory-0.19.0 → basic_memory-0.19.2}/src/basic_memory/mcp/resources/project_info.py +0 -0
  217. {basic_memory-0.19.0 → basic_memory-0.19.2}/src/basic_memory/mcp/resources/release_notes.md +0 -0
  218. {basic_memory-0.19.0 → basic_memory-0.19.2}/src/basic_memory/mcp/resources/ui.py +0 -0
  219. {basic_memory-0.19.0 → basic_memory-0.19.2}/src/basic_memory/mcp/server.py +0 -0
  220. {basic_memory-0.19.0 → basic_memory-0.19.2}/src/basic_memory/mcp/tools/__init__.py +0 -0
  221. {basic_memory-0.19.0 → basic_memory-0.19.2}/src/basic_memory/mcp/tools/build_context.py +0 -0
  222. {basic_memory-0.19.0 → basic_memory-0.19.2}/src/basic_memory/mcp/tools/chatgpt_tools.py +0 -0
  223. {basic_memory-0.19.0 → basic_memory-0.19.2}/src/basic_memory/mcp/tools/cloud_info.py +0 -0
  224. {basic_memory-0.19.0 → basic_memory-0.19.2}/src/basic_memory/mcp/tools/list_directory.py +0 -0
  225. {basic_memory-0.19.0 → basic_memory-0.19.2}/src/basic_memory/mcp/tools/project_management.py +0 -0
  226. {basic_memory-0.19.0 → basic_memory-0.19.2}/src/basic_memory/mcp/tools/read_content.py +0 -0
  227. {basic_memory-0.19.0 → basic_memory-0.19.2}/src/basic_memory/mcp/tools/read_note.py +0 -0
  228. {basic_memory-0.19.0 → basic_memory-0.19.2}/src/basic_memory/mcp/tools/recent_activity.py +0 -0
  229. {basic_memory-0.19.0 → basic_memory-0.19.2}/src/basic_memory/mcp/tools/release_notes.py +0 -0
  230. {basic_memory-0.19.0 → basic_memory-0.19.2}/src/basic_memory/mcp/tools/schema.py +0 -0
  231. {basic_memory-0.19.0 → basic_memory-0.19.2}/src/basic_memory/mcp/tools/ui_sdk.py +0 -0
  232. {basic_memory-0.19.0 → basic_memory-0.19.2}/src/basic_memory/mcp/tools/utils.py +0 -0
  233. {basic_memory-0.19.0 → basic_memory-0.19.2}/src/basic_memory/mcp/tools/view_note.py +0 -0
  234. {basic_memory-0.19.0 → basic_memory-0.19.2}/src/basic_memory/mcp/tools/workspaces.py +0 -0
  235. {basic_memory-0.19.0 → basic_memory-0.19.2}/src/basic_memory/mcp/ui/__init__.py +0 -0
  236. {basic_memory-0.19.0 → basic_memory-0.19.2}/src/basic_memory/mcp/ui/html/note-preview-mcp-ui.html +0 -0
  237. {basic_memory-0.19.0 → basic_memory-0.19.2}/src/basic_memory/mcp/ui/html/note-preview-tool-ui.html +0 -0
  238. {basic_memory-0.19.0 → basic_memory-0.19.2}/src/basic_memory/mcp/ui/html/note-preview-vanilla.html +0 -0
  239. {basic_memory-0.19.0 → basic_memory-0.19.2}/src/basic_memory/mcp/ui/html/search-results-mcp-ui.html +0 -0
  240. {basic_memory-0.19.0 → basic_memory-0.19.2}/src/basic_memory/mcp/ui/html/search-results-tool-ui.html +0 -0
  241. {basic_memory-0.19.0 → basic_memory-0.19.2}/src/basic_memory/mcp/ui/html/search-results-vanilla.html +0 -0
  242. {basic_memory-0.19.0 → basic_memory-0.19.2}/src/basic_memory/mcp/ui/sdk.py +0 -0
  243. {basic_memory-0.19.0 → basic_memory-0.19.2}/src/basic_memory/mcp/ui/templates.py +0 -0
  244. {basic_memory-0.19.0 → basic_memory-0.19.2}/src/basic_memory/models/__init__.py +0 -0
  245. {basic_memory-0.19.0 → basic_memory-0.19.2}/src/basic_memory/models/base.py +0 -0
  246. {basic_memory-0.19.0 → basic_memory-0.19.2}/src/basic_memory/models/knowledge.py +0 -0
  247. {basic_memory-0.19.0 → basic_memory-0.19.2}/src/basic_memory/models/project.py +0 -0
  248. {basic_memory-0.19.0 → basic_memory-0.19.2}/src/basic_memory/models/search.py +0 -0
  249. {basic_memory-0.19.0 → basic_memory-0.19.2}/src/basic_memory/project_resolver.py +0 -0
  250. {basic_memory-0.19.0 → basic_memory-0.19.2}/src/basic_memory/repository/__init__.py +0 -0
  251. {basic_memory-0.19.0 → basic_memory-0.19.2}/src/basic_memory/repository/embedding_provider.py +0 -0
  252. {basic_memory-0.19.0 → basic_memory-0.19.2}/src/basic_memory/repository/embedding_provider_factory.py +0 -0
  253. {basic_memory-0.19.0 → basic_memory-0.19.2}/src/basic_memory/repository/entity_repository.py +0 -0
  254. {basic_memory-0.19.0 → basic_memory-0.19.2}/src/basic_memory/repository/fastembed_provider.py +0 -0
  255. {basic_memory-0.19.0 → basic_memory-0.19.2}/src/basic_memory/repository/metadata_filters.py +0 -0
  256. {basic_memory-0.19.0 → basic_memory-0.19.2}/src/basic_memory/repository/observation_repository.py +0 -0
  257. {basic_memory-0.19.0 → basic_memory-0.19.2}/src/basic_memory/repository/openai_provider.py +0 -0
  258. {basic_memory-0.19.0 → basic_memory-0.19.2}/src/basic_memory/repository/postgres_search_repository.py +0 -0
  259. {basic_memory-0.19.0 → basic_memory-0.19.2}/src/basic_memory/repository/project_info_repository.py +0 -0
  260. {basic_memory-0.19.0 → basic_memory-0.19.2}/src/basic_memory/repository/project_repository.py +0 -0
  261. {basic_memory-0.19.0 → basic_memory-0.19.2}/src/basic_memory/repository/relation_repository.py +0 -0
  262. {basic_memory-0.19.0 → basic_memory-0.19.2}/src/basic_memory/repository/repository.py +0 -0
  263. {basic_memory-0.19.0 → basic_memory-0.19.2}/src/basic_memory/repository/search_index_row.py +0 -0
  264. {basic_memory-0.19.0 → basic_memory-0.19.2}/src/basic_memory/repository/search_repository.py +0 -0
  265. {basic_memory-0.19.0 → basic_memory-0.19.2}/src/basic_memory/repository/semantic_errors.py +0 -0
  266. {basic_memory-0.19.0 → basic_memory-0.19.2}/src/basic_memory/repository/sqlite_search_repository.py +0 -0
  267. {basic_memory-0.19.0 → basic_memory-0.19.2}/src/basic_memory/runtime.py +0 -0
  268. {basic_memory-0.19.0 → basic_memory-0.19.2}/src/basic_memory/schema/__init__.py +0 -0
  269. {basic_memory-0.19.0 → basic_memory-0.19.2}/src/basic_memory/schema/diff.py +0 -0
  270. {basic_memory-0.19.0 → basic_memory-0.19.2}/src/basic_memory/schema/inference.py +0 -0
  271. {basic_memory-0.19.0 → basic_memory-0.19.2}/src/basic_memory/schema/parser.py +0 -0
  272. {basic_memory-0.19.0 → basic_memory-0.19.2}/src/basic_memory/schema/resolver.py +0 -0
  273. {basic_memory-0.19.0 → basic_memory-0.19.2}/src/basic_memory/schema/validator.py +0 -0
  274. {basic_memory-0.19.0 → basic_memory-0.19.2}/src/basic_memory/schemas/__init__.py +0 -0
  275. {basic_memory-0.19.0 → basic_memory-0.19.2}/src/basic_memory/schemas/cloud.py +0 -0
  276. {basic_memory-0.19.0 → basic_memory-0.19.2}/src/basic_memory/schemas/delete.py +0 -0
  277. {basic_memory-0.19.0 → basic_memory-0.19.2}/src/basic_memory/schemas/directory.py +0 -0
  278. {basic_memory-0.19.0 → basic_memory-0.19.2}/src/basic_memory/schemas/importer.py +0 -0
  279. {basic_memory-0.19.0 → basic_memory-0.19.2}/src/basic_memory/schemas/memory.py +0 -0
  280. {basic_memory-0.19.0 → basic_memory-0.19.2}/src/basic_memory/schemas/project_info.py +0 -0
  281. {basic_memory-0.19.0 → basic_memory-0.19.2}/src/basic_memory/schemas/prompt.py +0 -0
  282. {basic_memory-0.19.0 → basic_memory-0.19.2}/src/basic_memory/schemas/response.py +0 -0
  283. {basic_memory-0.19.0 → basic_memory-0.19.2}/src/basic_memory/schemas/schema.py +0 -0
  284. {basic_memory-0.19.0 → basic_memory-0.19.2}/src/basic_memory/schemas/search.py +0 -0
  285. {basic_memory-0.19.0 → basic_memory-0.19.2}/src/basic_memory/schemas/sync_report.py +0 -0
  286. {basic_memory-0.19.0 → basic_memory-0.19.2}/src/basic_memory/schemas/v2/entity.py +0 -0
  287. {basic_memory-0.19.0 → basic_memory-0.19.2}/src/basic_memory/schemas/v2/resource.py +0 -0
  288. {basic_memory-0.19.0 → basic_memory-0.19.2}/src/basic_memory/services/__init__.py +0 -0
  289. {basic_memory-0.19.0 → basic_memory-0.19.2}/src/basic_memory/services/context_service.py +0 -0
  290. {basic_memory-0.19.0 → basic_memory-0.19.2}/src/basic_memory/services/directory_service.py +0 -0
  291. {basic_memory-0.19.0 → basic_memory-0.19.2}/src/basic_memory/services/exceptions.py +0 -0
  292. {basic_memory-0.19.0 → basic_memory-0.19.2}/src/basic_memory/services/file_service.py +0 -0
  293. {basic_memory-0.19.0 → basic_memory-0.19.2}/src/basic_memory/services/initialization.py +0 -0
  294. {basic_memory-0.19.0 → basic_memory-0.19.2}/src/basic_memory/services/link_resolver.py +0 -0
  295. {basic_memory-0.19.0 → basic_memory-0.19.2}/src/basic_memory/services/search_service.py +0 -0
  296. {basic_memory-0.19.0 → basic_memory-0.19.2}/src/basic_memory/services/service.py +0 -0
  297. {basic_memory-0.19.0 → basic_memory-0.19.2}/src/basic_memory/sync/__init__.py +0 -0
  298. {basic_memory-0.19.0 → basic_memory-0.19.2}/src/basic_memory/sync/background_sync.py +0 -0
  299. {basic_memory-0.19.0 → basic_memory-0.19.2}/src/basic_memory/sync/coordinator.py +0 -0
  300. {basic_memory-0.19.0 → basic_memory-0.19.2}/src/basic_memory/sync/sync_service.py +0 -0
  301. {basic_memory-0.19.0 → basic_memory-0.19.2}/src/basic_memory/sync/watch_service.py +0 -0
  302. {basic_memory-0.19.0 → basic_memory-0.19.2}/src/basic_memory/templates/prompts/continue_conversation.hbs +0 -0
  303. {basic_memory-0.19.0 → basic_memory-0.19.2}/src/basic_memory/templates/prompts/search.hbs +0 -0
  304. {basic_memory-0.19.0 → basic_memory-0.19.2}/test-int/BENCHMARKS.md +0 -0
  305. {basic_memory-0.19.0 → basic_memory-0.19.2}/test-int/cli/test_cli_tool_json_failure_integration.py +0 -0
  306. {basic_memory-0.19.0 → basic_memory-0.19.2}/test-int/cli/test_cli_tool_json_integration.py +0 -0
  307. {basic_memory-0.19.0 → basic_memory-0.19.2}/test-int/cli/test_project_commands_integration.py +0 -0
  308. {basic_memory-0.19.0 → basic_memory-0.19.2}/test-int/cli/test_routing_integration.py +0 -0
  309. {basic_memory-0.19.0 → basic_memory-0.19.2}/test-int/cli/test_search_notes_meta_integration.py +0 -0
  310. {basic_memory-0.19.0 → basic_memory-0.19.2}/test-int/cli/test_version_integration.py +0 -0
  311. {basic_memory-0.19.0 → basic_memory-0.19.2}/test-int/compare_search_benchmarks.py +0 -0
  312. {basic_memory-0.19.0 → basic_memory-0.19.2}/test-int/conftest.py +0 -0
  313. {basic_memory-0.19.0 → basic_memory-0.19.2}/test-int/fixtures/schema/drift/people/drift-person-01.md +0 -0
  314. {basic_memory-0.19.0 → basic_memory-0.19.2}/test-int/fixtures/schema/drift/people/drift-person-02.md +0 -0
  315. {basic_memory-0.19.0 → basic_memory-0.19.2}/test-int/fixtures/schema/drift/people/drift-person-03.md +0 -0
  316. {basic_memory-0.19.0 → basic_memory-0.19.2}/test-int/fixtures/schema/drift/people/drift-person-04.md +0 -0
  317. {basic_memory-0.19.0 → basic_memory-0.19.2}/test-int/fixtures/schema/drift/people/drift-person-05.md +0 -0
  318. {basic_memory-0.19.0 → basic_memory-0.19.2}/test-int/fixtures/schema/drift/people/drift-person-06.md +0 -0
  319. {basic_memory-0.19.0 → basic_memory-0.19.2}/test-int/fixtures/schema/drift/people/drift-person-07.md +0 -0
  320. {basic_memory-0.19.0 → basic_memory-0.19.2}/test-int/fixtures/schema/drift/people/drift-person-08.md +0 -0
  321. {basic_memory-0.19.0 → basic_memory-0.19.2}/test-int/fixtures/schema/drift/people/drift-person-09.md +0 -0
  322. {basic_memory-0.19.0 → basic_memory-0.19.2}/test-int/fixtures/schema/drift/people/drift-person-10.md +0 -0
  323. {basic_memory-0.19.0 → basic_memory-0.19.2}/test-int/fixtures/schema/drift/people/drift-person-11.md +0 -0
  324. {basic_memory-0.19.0 → basic_memory-0.19.2}/test-int/fixtures/schema/drift/people/drift-person-12.md +0 -0
  325. {basic_memory-0.19.0 → basic_memory-0.19.2}/test-int/fixtures/schema/drift/people/drift-person-13.md +0 -0
  326. {basic_memory-0.19.0 → basic_memory-0.19.2}/test-int/fixtures/schema/drift/people/drift-person-14.md +0 -0
  327. {basic_memory-0.19.0 → basic_memory-0.19.2}/test-int/fixtures/schema/drift/people/drift-person-15.md +0 -0
  328. {basic_memory-0.19.0 → basic_memory-0.19.2}/test-int/fixtures/schema/drift/people/drift-person-16.md +0 -0
  329. {basic_memory-0.19.0 → basic_memory-0.19.2}/test-int/fixtures/schema/drift/people/drift-person-17.md +0 -0
  330. {basic_memory-0.19.0 → basic_memory-0.19.2}/test-int/fixtures/schema/drift/people/drift-person-18.md +0 -0
  331. {basic_memory-0.19.0 → basic_memory-0.19.2}/test-int/fixtures/schema/drift/people/drift-person-19.md +0 -0
  332. {basic_memory-0.19.0 → basic_memory-0.19.2}/test-int/fixtures/schema/drift/people/drift-person-20.md +0 -0
  333. {basic_memory-0.19.0 → basic_memory-0.19.2}/test-int/fixtures/schema/drift/schema/Person.md +0 -0
  334. {basic_memory-0.19.0 → basic_memory-0.19.2}/test-int/fixtures/schema/edge-cases/array-single.md +0 -0
  335. {basic_memory-0.19.0 → basic_memory-0.19.2}/test-int/fixtures/schema/edge-cases/empty-note.md +0 -0
  336. {basic_memory-0.19.0 → basic_memory-0.19.2}/test-int/fixtures/schema/edge-cases/explicit-overrides-type.md +0 -0
  337. {basic_memory-0.19.0 → basic_memory-0.19.2}/test-int/fixtures/schema/edge-cases/inline-and-type.md +0 -0
  338. {basic_memory-0.19.0 → basic_memory-0.19.2}/test-int/fixtures/schema/edge-cases/no-frontmatter.md +0 -0
  339. {basic_memory-0.19.0 → basic_memory-0.19.2}/test-int/fixtures/schema/edge-cases/relation-only.md +0 -0
  340. {basic_memory-0.19.0 → basic_memory-0.19.2}/test-int/fixtures/schema/edge-cases/type-no-schema.md +0 -0
  341. {basic_memory-0.19.0 → basic_memory-0.19.2}/test-int/fixtures/schema/edge-cases/unicode-fields.md +0 -0
  342. {basic_memory-0.19.0 → basic_memory-0.19.2}/test-int/fixtures/schema/inference/people/ada-lovelace.md +0 -0
  343. {basic_memory-0.19.0 → basic_memory-0.19.2}/test-int/fixtures/schema/inference/people/alan-turing.md +0 -0
  344. {basic_memory-0.19.0 → basic_memory-0.19.2}/test-int/fixtures/schema/inference/people/anders-hejlsberg.md +0 -0
  345. {basic_memory-0.19.0 → basic_memory-0.19.2}/test-int/fixtures/schema/inference/people/andrej-karpathy.md +0 -0
  346. {basic_memory-0.19.0 → basic_memory-0.19.2}/test-int/fixtures/schema/inference/people/barbara-liskov.md +0 -0
  347. {basic_memory-0.19.0 → basic_memory-0.19.2}/test-int/fixtures/schema/inference/people/bjarne-stroustrup.md +0 -0
  348. {basic_memory-0.19.0 → basic_memory-0.19.2}/test-int/fixtures/schema/inference/people/brendan-eich.md +0 -0
  349. {basic_memory-0.19.0 → basic_memory-0.19.2}/test-int/fixtures/schema/inference/people/claude-shannon.md +0 -0
  350. {basic_memory-0.19.0 → basic_memory-0.19.2}/test-int/fixtures/schema/inference/people/dennis-ritchie.md +0 -0
  351. {basic_memory-0.19.0 → basic_memory-0.19.2}/test-int/fixtures/schema/inference/people/dijkstra.md +0 -0
  352. {basic_memory-0.19.0 → basic_memory-0.19.2}/test-int/fixtures/schema/inference/people/donald-knuth.md +0 -0
  353. {basic_memory-0.19.0 → basic_memory-0.19.2}/test-int/fixtures/schema/inference/people/fei-fei-li.md +0 -0
  354. {basic_memory-0.19.0 → basic_memory-0.19.2}/test-int/fixtures/schema/inference/people/geoffrey-hinton.md +0 -0
  355. {basic_memory-0.19.0 → basic_memory-0.19.2}/test-int/fixtures/schema/inference/people/grace-hopper.md +0 -0
  356. {basic_memory-0.19.0 → basic_memory-0.19.2}/test-int/fixtures/schema/inference/people/guido-van-rossum.md +0 -0
  357. {basic_memory-0.19.0 → basic_memory-0.19.2}/test-int/fixtures/schema/inference/people/james-gosling.md +0 -0
  358. {basic_memory-0.19.0 → basic_memory-0.19.2}/test-int/fixtures/schema/inference/people/john-carmack.md +0 -0
  359. {basic_memory-0.19.0 → basic_memory-0.19.2}/test-int/fixtures/schema/inference/people/ken-thompson.md +0 -0
  360. {basic_memory-0.19.0 → basic_memory-0.19.2}/test-int/fixtures/schema/inference/people/larry-page.md +0 -0
  361. {basic_memory-0.19.0 → basic_memory-0.19.2}/test-int/fixtures/schema/inference/people/leslie-lamport.md +0 -0
  362. {basic_memory-0.19.0 → basic_memory-0.19.2}/test-int/fixtures/schema/inference/people/linus-torvalds.md +0 -0
  363. {basic_memory-0.19.0 → basic_memory-0.19.2}/test-int/fixtures/schema/inference/people/margaret-hamilton.md +0 -0
  364. {basic_memory-0.19.0 → basic_memory-0.19.2}/test-int/fixtures/schema/inference/people/rasmus-lerdorf.md +0 -0
  365. {basic_memory-0.19.0 → basic_memory-0.19.2}/test-int/fixtures/schema/inference/people/richard-stallman.md +0 -0
  366. {basic_memory-0.19.0 → basic_memory-0.19.2}/test-int/fixtures/schema/inference/people/rob-pike.md +0 -0
  367. {basic_memory-0.19.0 → basic_memory-0.19.2}/test-int/fixtures/schema/inference/people/satoshi-nakamoto.md +0 -0
  368. {basic_memory-0.19.0 → basic_memory-0.19.2}/test-int/fixtures/schema/inference/people/tim-berners-lee.md +0 -0
  369. {basic_memory-0.19.0 → basic_memory-0.19.2}/test-int/fixtures/schema/inference/people/vint-cerf.md +0 -0
  370. {basic_memory-0.19.0 → basic_memory-0.19.2}/test-int/fixtures/schema/inference/people/yann-lecun.md +0 -0
  371. {basic_memory-0.19.0 → basic_memory-0.19.2}/test-int/fixtures/schema/inference/people/yukihiro-matsumoto.md +0 -0
  372. {basic_memory-0.19.0 → basic_memory-0.19.2}/test-int/fixtures/schema/schemas/Book.md +0 -0
  373. {basic_memory-0.19.0 → basic_memory-0.19.2}/test-int/fixtures/schema/schemas/Meeting.md +0 -0
  374. {basic_memory-0.19.0 → basic_memory-0.19.2}/test-int/fixtures/schema/schemas/Person.md +0 -0
  375. {basic_memory-0.19.0 → basic_memory-0.19.2}/test-int/fixtures/schema/schemas/SoftwareProject.md +0 -0
  376. {basic_memory-0.19.0 → basic_memory-0.19.2}/test-int/fixtures/schema/schemas/StrictSchema.md +0 -0
  377. {basic_memory-0.19.0 → basic_memory-0.19.2}/test-int/fixtures/schema/valid/basic-memory.md +0 -0
  378. {basic_memory-0.19.0 → basic_memory-0.19.2}/test-int/fixtures/schema/valid/explicit-ref-note.md +0 -0
  379. {basic_memory-0.19.0 → basic_memory-0.19.2}/test-int/fixtures/schema/valid/no-schema-note.md +0 -0
  380. {basic_memory-0.19.0 → basic_memory-0.19.2}/test-int/fixtures/schema/valid/paul-graham.md +0 -0
  381. {basic_memory-0.19.0 → basic_memory-0.19.2}/test-int/fixtures/schema/valid/rich-hickey.md +0 -0
  382. {basic_memory-0.19.0 → basic_memory-0.19.2}/test-int/fixtures/schema/valid/standup-2024-01-15.md +0 -0
  383. {basic_memory-0.19.0 → basic_memory-0.19.2}/test-int/fixtures/schema/warnings/extra-observations.md +0 -0
  384. {basic_memory-0.19.0 → basic_memory-0.19.2}/test-int/fixtures/schema/warnings/missing-multiple.md +0 -0
  385. {basic_memory-0.19.0 → basic_memory-0.19.2}/test-int/fixtures/schema/warnings/missing-required.md +0 -0
  386. {basic_memory-0.19.0 → basic_memory-0.19.2}/test-int/fixtures/schema/warnings/wrong-enum-value.md +0 -0
  387. {basic_memory-0.19.0 → basic_memory-0.19.2}/test-int/mcp/test_build_context_underscore.py +0 -0
  388. {basic_memory-0.19.0 → basic_memory-0.19.2}/test-int/mcp/test_build_context_validation.py +0 -0
  389. {basic_memory-0.19.0 → basic_memory-0.19.2}/test-int/mcp/test_chatgpt_tools_integration.py +0 -0
  390. {basic_memory-0.19.0 → basic_memory-0.19.2}/test-int/mcp/test_default_project_mode_integration.py +0 -0
  391. {basic_memory-0.19.0 → basic_memory-0.19.2}/test-int/mcp/test_delete_directory_integration.py +0 -0
  392. {basic_memory-0.19.0 → basic_memory-0.19.2}/test-int/mcp/test_lifespan_shutdown_sync_task_cancellation_integration.py +0 -0
  393. {basic_memory-0.19.0 → basic_memory-0.19.2}/test-int/mcp/test_list_directory_integration.py +0 -0
  394. {basic_memory-0.19.0 → basic_memory-0.19.2}/test-int/mcp/test_move_directory_integration.py +0 -0
  395. {basic_memory-0.19.0 → basic_memory-0.19.2}/test-int/mcp/test_output_format_json_integration.py +0 -0
  396. {basic_memory-0.19.0 → basic_memory-0.19.2}/test-int/mcp/test_pagination_integration.py +0 -0
  397. {basic_memory-0.19.0 → basic_memory-0.19.2}/test-int/mcp/test_permalink_collision_integration.py +0 -0
  398. {basic_memory-0.19.0 → basic_memory-0.19.2}/test-int/mcp/test_project_management_integration.py +0 -0
  399. {basic_memory-0.19.0 → basic_memory-0.19.2}/test-int/mcp/test_project_state_sync_integration.py +0 -0
  400. {basic_memory-0.19.0 → basic_memory-0.19.2}/test-int/mcp/test_read_content_integration.py +0 -0
  401. {basic_memory-0.19.0 → basic_memory-0.19.2}/test-int/mcp/test_read_note_integration.py +0 -0
  402. {basic_memory-0.19.0 → basic_memory-0.19.2}/test-int/mcp/test_search_integration.py +0 -0
  403. {basic_memory-0.19.0 → basic_memory-0.19.2}/test-int/mcp/test_single_project_mcp_integration.py +0 -0
  404. {basic_memory-0.19.0 → basic_memory-0.19.2}/test-int/mcp/test_smoke_integration.py +0 -0
  405. {basic_memory-0.19.0 → basic_memory-0.19.2}/test-int/mcp/test_ui_sdk_integration.py +0 -0
  406. {basic_memory-0.19.0 → basic_memory-0.19.2}/test-int/mcp/test_write_note_integration.py +0 -0
  407. {basic_memory-0.19.0 → basic_memory-0.19.2}/test-int/semantic/__init__.py +0 -0
  408. {basic_memory-0.19.0 → basic_memory-0.19.2}/test-int/semantic/conftest.py +0 -0
  409. {basic_memory-0.19.0 → basic_memory-0.19.2}/test-int/semantic/corpus.py +0 -0
  410. {basic_memory-0.19.0 → basic_memory-0.19.2}/test-int/semantic/metrics.py +0 -0
  411. {basic_memory-0.19.0 → basic_memory-0.19.2}/test-int/semantic/report.py +0 -0
  412. {basic_memory-0.19.0 → basic_memory-0.19.2}/test-int/semantic/test_multiterm_semantic_queries.py +0 -0
  413. {basic_memory-0.19.0 → basic_memory-0.19.2}/test-int/semantic/test_search_diagnostics.py +0 -0
  414. {basic_memory-0.19.0 → basic_memory-0.19.2}/test-int/semantic/test_semantic_coverage.py +0 -0
  415. {basic_memory-0.19.0 → basic_memory-0.19.2}/test-int/semantic/test_semantic_quality.py +0 -0
  416. {basic_memory-0.19.0 → basic_memory-0.19.2}/test-int/test_db_wal_mode.py +0 -0
  417. {basic_memory-0.19.0 → basic_memory-0.19.2}/test-int/test_disable_permalinks_integration.py +0 -0
  418. {basic_memory-0.19.0 → basic_memory-0.19.2}/test-int/test_schema/__init__.py +0 -0
  419. {basic_memory-0.19.0 → basic_memory-0.19.2}/test-int/test_schema/conftest.py +0 -0
  420. {basic_memory-0.19.0 → basic_memory-0.19.2}/test-int/test_schema/helpers.py +0 -0
  421. {basic_memory-0.19.0 → basic_memory-0.19.2}/test-int/test_schema/test_diff_integration.py +0 -0
  422. {basic_memory-0.19.0 → basic_memory-0.19.2}/test-int/test_schema/test_inference_integration.py +0 -0
  423. {basic_memory-0.19.0 → basic_memory-0.19.2}/test-int/test_schema/test_parser_integration.py +0 -0
  424. {basic_memory-0.19.0 → basic_memory-0.19.2}/test-int/test_schema/test_validator_integration.py +0 -0
  425. {basic_memory-0.19.0 → basic_memory-0.19.2}/test-int/test_search_performance_benchmark.py +0 -0
  426. {basic_memory-0.19.0 → basic_memory-0.19.2}/tests/Non-MarkdownFileSupport.pdf +0 -0
  427. {basic_memory-0.19.0 → basic_memory-0.19.2}/tests/README.md +0 -0
  428. {basic_memory-0.19.0 → basic_memory-0.19.2}/tests/Screenshot.png +0 -0
  429. {basic_memory-0.19.0 → basic_memory-0.19.2}/tests/__init__.py +0 -0
  430. {basic_memory-0.19.0 → basic_memory-0.19.2}/tests/api/v2/__init__.py +0 -0
  431. {basic_memory-0.19.0 → basic_memory-0.19.2}/tests/api/v2/conftest.py +0 -0
  432. {basic_memory-0.19.0 → basic_memory-0.19.2}/tests/api/v2/test_directory_router.py +0 -0
  433. {basic_memory-0.19.0 → basic_memory-0.19.2}/tests/api/v2/test_importer_router.py +0 -0
  434. {basic_memory-0.19.0 → basic_memory-0.19.2}/tests/api/v2/test_knowledge_router.py +0 -0
  435. {basic_memory-0.19.0 → basic_memory-0.19.2}/tests/api/v2/test_memory_router.py +0 -0
  436. {basic_memory-0.19.0 → basic_memory-0.19.2}/tests/api/v2/test_project_router.py +0 -0
  437. {basic_memory-0.19.0 → basic_memory-0.19.2}/tests/api/v2/test_prompt_router.py +0 -0
  438. {basic_memory-0.19.0 → basic_memory-0.19.2}/tests/api/v2/test_resource_router.py +0 -0
  439. {basic_memory-0.19.0 → basic_memory-0.19.2}/tests/api/v2/test_schema_router.py +0 -0
  440. {basic_memory-0.19.0 → basic_memory-0.19.2}/tests/api/v2/test_search_router.py +0 -0
  441. {basic_memory-0.19.0 → basic_memory-0.19.2}/tests/cli/cloud/test_cloud_api_client_and_utils.py +0 -0
  442. {basic_memory-0.19.0 → basic_memory-0.19.2}/tests/cli/cloud/test_rclone_config_and_bmignore_filters.py +0 -0
  443. {basic_memory-0.19.0 → basic_memory-0.19.2}/tests/cli/cloud/test_upload_command_routing.py +0 -0
  444. {basic_memory-0.19.0 → basic_memory-0.19.2}/tests/cli/cloud/test_upload_path.py +0 -0
  445. {basic_memory-0.19.0 → basic_memory-0.19.2}/tests/cli/conftest.py +0 -0
  446. {basic_memory-0.19.0 → basic_memory-0.19.2}/tests/cli/test_analytics.py +0 -0
  447. {basic_memory-0.19.0 → basic_memory-0.19.2}/tests/cli/test_auth_cli_auth.py +0 -0
  448. {basic_memory-0.19.0 → basic_memory-0.19.2}/tests/cli/test_cli_container.py +0 -0
  449. {basic_memory-0.19.0 → basic_memory-0.19.2}/tests/cli/test_cli_exit.py +0 -0
  450. {basic_memory-0.19.0 → basic_memory-0.19.2}/tests/cli/test_cli_schema.py +0 -0
  451. {basic_memory-0.19.0 → basic_memory-0.19.2}/tests/cli/test_cli_tool_exit.py +0 -0
  452. {basic_memory-0.19.0 → basic_memory-0.19.2}/tests/cli/test_cli_tool_json_output.py +0 -0
  453. {basic_memory-0.19.0 → basic_memory-0.19.2}/tests/cli/test_cli_tools.py +0 -0
  454. {basic_memory-0.19.0 → basic_memory-0.19.2}/tests/cli/test_cloud_authentication.py +0 -0
  455. {basic_memory-0.19.0 → basic_memory-0.19.2}/tests/cli/test_cloud_promo.py +0 -0
  456. {basic_memory-0.19.0 → basic_memory-0.19.2}/tests/cli/test_cloud_status.py +0 -0
  457. {basic_memory-0.19.0 → basic_memory-0.19.2}/tests/cli/test_db_reset_exit.py +0 -0
  458. {basic_memory-0.19.0 → basic_memory-0.19.2}/tests/cli/test_ignore_utils.py +0 -0
  459. {basic_memory-0.19.0 → basic_memory-0.19.2}/tests/cli/test_import_chatgpt.py +0 -0
  460. {basic_memory-0.19.0 → basic_memory-0.19.2}/tests/cli/test_import_claude_conversations.py +0 -0
  461. {basic_memory-0.19.0 → basic_memory-0.19.2}/tests/cli/test_import_claude_projects.py +0 -0
  462. {basic_memory-0.19.0 → basic_memory-0.19.2}/tests/cli/test_import_memory_json.py +0 -0
  463. {basic_memory-0.19.0 → basic_memory-0.19.2}/tests/cli/test_json_output.py +0 -0
  464. {basic_memory-0.19.0 → basic_memory-0.19.2}/tests/cli/test_project_add_with_local_path.py +0 -0
  465. {basic_memory-0.19.0 → basic_memory-0.19.2}/tests/cli/test_project_info_errors.py +0 -0
  466. {basic_memory-0.19.0 → basic_memory-0.19.2}/tests/cli/test_project_list_and_ls.py +0 -0
  467. {basic_memory-0.19.0 → basic_memory-0.19.2}/tests/cli/test_project_set_cloud_local.py +0 -0
  468. {basic_memory-0.19.0 → basic_memory-0.19.2}/tests/cli/test_restore_commands.py +0 -0
  469. {basic_memory-0.19.0 → basic_memory-0.19.2}/tests/cli/test_routing.py +0 -0
  470. {basic_memory-0.19.0 → basic_memory-0.19.2}/tests/cli/test_snapshot_commands.py +0 -0
  471. {basic_memory-0.19.0 → basic_memory-0.19.2}/tests/cli/test_upload.py +0 -0
  472. {basic_memory-0.19.0 → basic_memory-0.19.2}/tests/cli/test_workspace_commands.py +0 -0
  473. {basic_memory-0.19.0 → basic_memory-0.19.2}/tests/conftest.py +0 -0
  474. {basic_memory-0.19.0 → basic_memory-0.19.2}/tests/db/test_issue_254_foreign_key_constraints.py +0 -0
  475. {basic_memory-0.19.0 → basic_memory-0.19.2}/tests/importers/test_conversation_indexing.py +0 -0
  476. {basic_memory-0.19.0 → basic_memory-0.19.2}/tests/importers/test_importer_base.py +0 -0
  477. {basic_memory-0.19.0 → basic_memory-0.19.2}/tests/importers/test_importer_utils.py +0 -0
  478. {basic_memory-0.19.0 → basic_memory-0.19.2}/tests/markdown/__init__.py +0 -0
  479. {basic_memory-0.19.0 → basic_memory-0.19.2}/tests/markdown/test_date_frontmatter_parsing.py +0 -0
  480. {basic_memory-0.19.0 → basic_memory-0.19.2}/tests/markdown/test_entity_parser.py +0 -0
  481. {basic_memory-0.19.0 → basic_memory-0.19.2}/tests/markdown/test_entity_parser_error_handling.py +0 -0
  482. {basic_memory-0.19.0 → basic_memory-0.19.2}/tests/markdown/test_markdown_plugins.py +0 -0
  483. {basic_memory-0.19.0 → basic_memory-0.19.2}/tests/markdown/test_markdown_processor.py +0 -0
  484. {basic_memory-0.19.0 → basic_memory-0.19.2}/tests/markdown/test_markdown_utils.py +0 -0
  485. {basic_memory-0.19.0 → basic_memory-0.19.2}/tests/markdown/test_observation_edge_cases.py +0 -0
  486. {basic_memory-0.19.0 → basic_memory-0.19.2}/tests/markdown/test_parser_edge_cases.py +0 -0
  487. {basic_memory-0.19.0 → basic_memory-0.19.2}/tests/markdown/test_relation_edge_cases.py +0 -0
  488. {basic_memory-0.19.0 → basic_memory-0.19.2}/tests/markdown/test_task_detection.py +0 -0
  489. {basic_memory-0.19.0 → basic_memory-0.19.2}/tests/mcp/clients/__init__.py +0 -0
  490. {basic_memory-0.19.0 → basic_memory-0.19.2}/tests/mcp/clients/test_clients.py +0 -0
  491. {basic_memory-0.19.0 → basic_memory-0.19.2}/tests/mcp/conftest.py +0 -0
  492. {basic_memory-0.19.0 → basic_memory-0.19.2}/tests/mcp/test_async_client_force_local.py +0 -0
  493. {basic_memory-0.19.0 → basic_memory-0.19.2}/tests/mcp/test_async_client_modes.py +0 -0
  494. {basic_memory-0.19.0 → basic_memory-0.19.2}/tests/mcp/test_client_schema.py +0 -0
  495. {basic_memory-0.19.0 → basic_memory-0.19.2}/tests/mcp/test_mcp_container.py +0 -0
  496. {basic_memory-0.19.0 → basic_memory-0.19.2}/tests/mcp/test_obsidian_yaml_formatting.py +0 -0
  497. {basic_memory-0.19.0 → basic_memory-0.19.2}/tests/mcp/test_permalink_collision_file_overwrite.py +0 -0
  498. {basic_memory-0.19.0 → basic_memory-0.19.2}/tests/mcp/test_project_context.py +0 -0
  499. {basic_memory-0.19.0 → basic_memory-0.19.2}/tests/mcp/test_prompt_tool_delegation.py +0 -0
  500. {basic_memory-0.19.0 → basic_memory-0.19.2}/tests/mcp/test_prompts.py +0 -0
  501. {basic_memory-0.19.0 → basic_memory-0.19.2}/tests/mcp/test_recent_activity_prompt_modes.py +0 -0
  502. {basic_memory-0.19.0 → basic_memory-0.19.2}/tests/mcp/test_resources.py +0 -0
  503. {basic_memory-0.19.0 → basic_memory-0.19.2}/tests/mcp/test_server_lifespan_branches.py +0 -0
  504. {basic_memory-0.19.0 → basic_memory-0.19.2}/tests/mcp/test_tool_build_context.py +0 -0
  505. {basic_memory-0.19.0 → basic_memory-0.19.2}/tests/mcp/test_tool_canvas.py +0 -0
  506. {basic_memory-0.19.0 → basic_memory-0.19.2}/tests/mcp/test_tool_cloud_discovery.py +0 -0
  507. {basic_memory-0.19.0 → basic_memory-0.19.2}/tests/mcp/test_tool_contracts.py +0 -0
  508. {basic_memory-0.19.0 → basic_memory-0.19.2}/tests/mcp/test_tool_json_output_modes.py +0 -0
  509. {basic_memory-0.19.0 → basic_memory-0.19.2}/tests/mcp/test_tool_list_directory.py +0 -0
  510. {basic_memory-0.19.0 → basic_memory-0.19.2}/tests/mcp/test_tool_project_management.py +0 -0
  511. {basic_memory-0.19.0 → basic_memory-0.19.2}/tests/mcp/test_tool_read_content.py +0 -0
  512. {basic_memory-0.19.0 → basic_memory-0.19.2}/tests/mcp/test_tool_read_note.py +0 -0
  513. {basic_memory-0.19.0 → basic_memory-0.19.2}/tests/mcp/test_tool_recent_activity.py +0 -0
  514. {basic_memory-0.19.0 → basic_memory-0.19.2}/tests/mcp/test_tool_resource.py +0 -0
  515. {basic_memory-0.19.0 → basic_memory-0.19.2}/tests/mcp/test_tool_schema.py +0 -0
  516. {basic_memory-0.19.0 → basic_memory-0.19.2}/tests/mcp/test_tool_search.py +0 -0
  517. {basic_memory-0.19.0 → basic_memory-0.19.2}/tests/mcp/test_tool_utils.py +0 -0
  518. {basic_memory-0.19.0 → basic_memory-0.19.2}/tests/mcp/test_tool_utils_cloud_auth.py +0 -0
  519. {basic_memory-0.19.0 → basic_memory-0.19.2}/tests/mcp/test_tool_view_note.py +0 -0
  520. {basic_memory-0.19.0 → basic_memory-0.19.2}/tests/mcp/test_tool_workspace_management.py +0 -0
  521. {basic_memory-0.19.0 → basic_memory-0.19.2}/tests/mcp/test_tool_write_note.py +0 -0
  522. {basic_memory-0.19.0 → basic_memory-0.19.2}/tests/mcp/test_tool_write_note_kebab_filenames.py +0 -0
  523. {basic_memory-0.19.0 → basic_memory-0.19.2}/tests/mcp/test_tool_write_note_metadata.py +0 -0
  524. {basic_memory-0.19.0 → basic_memory-0.19.2}/tests/mcp/test_ui_resources.py +0 -0
  525. {basic_memory-0.19.0 → basic_memory-0.19.2}/tests/mcp/test_ui_sdk.py +0 -0
  526. {basic_memory-0.19.0 → basic_memory-0.19.2}/tests/mcp/test_ui_templates.py +0 -0
  527. {basic_memory-0.19.0 → basic_memory-0.19.2}/tests/mcp/tools/test_chatgpt_tools.py +0 -0
  528. {basic_memory-0.19.0 → basic_memory-0.19.2}/tests/repository/test_distance_to_similarity.py +0 -0
  529. {basic_memory-0.19.0 → basic_memory-0.19.2}/tests/repository/test_entity_repository.py +0 -0
  530. {basic_memory-0.19.0 → basic_memory-0.19.2}/tests/repository/test_entity_repository_upsert.py +0 -0
  531. {basic_memory-0.19.0 → basic_memory-0.19.2}/tests/repository/test_entity_upsert_issue_187.py +0 -0
  532. {basic_memory-0.19.0 → basic_memory-0.19.2}/tests/repository/test_fastembed_provider.py +0 -0
  533. {basic_memory-0.19.0 → basic_memory-0.19.2}/tests/repository/test_hybrid_fusion.py +0 -0
  534. {basic_memory-0.19.0 → basic_memory-0.19.2}/tests/repository/test_metadata_filters.py +0 -0
  535. {basic_memory-0.19.0 → basic_memory-0.19.2}/tests/repository/test_metadata_filters_edge_cases.py +0 -0
  536. {basic_memory-0.19.0 → basic_memory-0.19.2}/tests/repository/test_observation_repository.py +0 -0
  537. {basic_memory-0.19.0 → basic_memory-0.19.2}/tests/repository/test_openai_provider.py +0 -0
  538. {basic_memory-0.19.0 → basic_memory-0.19.2}/tests/repository/test_postgres_search_repository.py +0 -0
  539. {basic_memory-0.19.0 → basic_memory-0.19.2}/tests/repository/test_postgres_search_repository_unit.py +0 -0
  540. {basic_memory-0.19.0 → basic_memory-0.19.2}/tests/repository/test_project_info_repository.py +0 -0
  541. {basic_memory-0.19.0 → basic_memory-0.19.2}/tests/repository/test_project_repository.py +0 -0
  542. {basic_memory-0.19.0 → basic_memory-0.19.2}/tests/repository/test_relation_repository.py +0 -0
  543. {basic_memory-0.19.0 → basic_memory-0.19.2}/tests/repository/test_repository.py +0 -0
  544. {basic_memory-0.19.0 → basic_memory-0.19.2}/tests/repository/test_search_index_row.py +0 -0
  545. {basic_memory-0.19.0 → basic_memory-0.19.2}/tests/repository/test_search_repository.py +0 -0
  546. {basic_memory-0.19.0 → basic_memory-0.19.2}/tests/repository/test_search_repository_edit_bug_fix.py +0 -0
  547. {basic_memory-0.19.0 → basic_memory-0.19.2}/tests/repository/test_search_text_with_metadata_filters.py +0 -0
  548. {basic_memory-0.19.0 → basic_memory-0.19.2}/tests/repository/test_sqlite_vector_search_repository.py +0 -0
  549. {basic_memory-0.19.0 → basic_memory-0.19.2}/tests/repository/test_vector_pagination.py +0 -0
  550. {basic_memory-0.19.0 → basic_memory-0.19.2}/tests/repository/test_vector_threshold.py +0 -0
  551. {basic_memory-0.19.0 → basic_memory-0.19.2}/tests/schema/__init__.py +0 -0
  552. {basic_memory-0.19.0 → basic_memory-0.19.2}/tests/schema/test_diff.py +0 -0
  553. {basic_memory-0.19.0 → basic_memory-0.19.2}/tests/schema/test_inference.py +0 -0
  554. {basic_memory-0.19.0 → basic_memory-0.19.2}/tests/schema/test_parser.py +0 -0
  555. {basic_memory-0.19.0 → basic_memory-0.19.2}/tests/schema/test_resolver.py +0 -0
  556. {basic_memory-0.19.0 → basic_memory-0.19.2}/tests/schema/test_validator.py +0 -0
  557. {basic_memory-0.19.0 → basic_memory-0.19.2}/tests/schemas/test_base_timeframe_minimum.py +0 -0
  558. {basic_memory-0.19.0 → basic_memory-0.19.2}/tests/schemas/test_memory_serialization.py +0 -0
  559. {basic_memory-0.19.0 → basic_memory-0.19.2}/tests/schemas/test_memory_url.py +0 -0
  560. {basic_memory-0.19.0 → basic_memory-0.19.2}/tests/schemas/test_memory_url_validation.py +0 -0
  561. {basic_memory-0.19.0 → basic_memory-0.19.2}/tests/schemas/test_relation_response_reference_resolution.py +0 -0
  562. {basic_memory-0.19.0 → basic_memory-0.19.2}/tests/schemas/test_search.py +0 -0
  563. {basic_memory-0.19.0 → basic_memory-0.19.2}/tests/services/test_context_service.py +0 -0
  564. {basic_memory-0.19.0 → basic_memory-0.19.2}/tests/services/test_directory_service.py +0 -0
  565. {basic_memory-0.19.0 → basic_memory-0.19.2}/tests/services/test_entity_service_disable_permalinks.py +0 -0
  566. {basic_memory-0.19.0 → basic_memory-0.19.2}/tests/services/test_file_service.py +0 -0
  567. {basic_memory-0.19.0 → basic_memory-0.19.2}/tests/services/test_initialization.py +0 -0
  568. {basic_memory-0.19.0 → basic_memory-0.19.2}/tests/services/test_initialization_cloud_mode_branches.py +0 -0
  569. {basic_memory-0.19.0 → basic_memory-0.19.2}/tests/services/test_link_resolver.py +0 -0
  570. {basic_memory-0.19.0 → basic_memory-0.19.2}/tests/services/test_project_removal_bug.py +0 -0
  571. {basic_memory-0.19.0 → basic_memory-0.19.2}/tests/services/test_project_service.py +0 -0
  572. {basic_memory-0.19.0 → basic_memory-0.19.2}/tests/services/test_project_service_cloud_info.py +0 -0
  573. {basic_memory-0.19.0 → basic_memory-0.19.2}/tests/services/test_project_service_operations.py +0 -0
  574. {basic_memory-0.19.0 → basic_memory-0.19.2}/tests/services/test_search_service.py +0 -0
  575. {basic_memory-0.19.0 → basic_memory-0.19.2}/tests/services/test_semantic_search.py +0 -0
  576. {basic_memory-0.19.0 → basic_memory-0.19.2}/tests/services/test_task_scheduler_semantic.py +0 -0
  577. {basic_memory-0.19.0 → basic_memory-0.19.2}/tests/sync/test_character_conflicts.py +0 -0
  578. {basic_memory-0.19.0 → basic_memory-0.19.2}/tests/sync/test_coordinator.py +0 -0
  579. {basic_memory-0.19.0 → basic_memory-0.19.2}/tests/sync/test_sync_service.py +0 -0
  580. {basic_memory-0.19.0 → basic_memory-0.19.2}/tests/sync/test_sync_service_incremental.py +0 -0
  581. {basic_memory-0.19.0 → basic_memory-0.19.2}/tests/sync/test_sync_wikilink_issue.py +0 -0
  582. {basic_memory-0.19.0 → basic_memory-0.19.2}/tests/sync/test_tmp_files.py +0 -0
  583. {basic_memory-0.19.0 → basic_memory-0.19.2}/tests/sync/test_watch_service.py +0 -0
  584. {basic_memory-0.19.0 → basic_memory-0.19.2}/tests/sync/test_watch_service_atomic_adds.py +0 -0
  585. {basic_memory-0.19.0 → basic_memory-0.19.2}/tests/sync/test_watch_service_edge_cases.py +0 -0
  586. {basic_memory-0.19.0 → basic_memory-0.19.2}/tests/sync/test_watch_service_reload.py +0 -0
  587. {basic_memory-0.19.0 → basic_memory-0.19.2}/tests/sync/test_watch_service_stress.py +0 -0
  588. {basic_memory-0.19.0 → basic_memory-0.19.2}/tests/test_config.py +0 -0
  589. {basic_memory-0.19.0 → basic_memory-0.19.2}/tests/test_deps.py +0 -0
  590. {basic_memory-0.19.0 → basic_memory-0.19.2}/tests/test_production_cascade_delete.py +0 -0
  591. {basic_memory-0.19.0 → basic_memory-0.19.2}/tests/test_project_resolver.py +0 -0
  592. {basic_memory-0.19.0 → basic_memory-0.19.2}/tests/test_rclone_commands.py +0 -0
  593. {basic_memory-0.19.0 → basic_memory-0.19.2}/tests/test_runtime.py +0 -0
  594. {basic_memory-0.19.0 → basic_memory-0.19.2}/tests/utils/test_file_utils.py +0 -0
  595. {basic_memory-0.19.0 → basic_memory-0.19.2}/tests/utils/test_frontmatter_obsidian_compatible.py +0 -0
  596. {basic_memory-0.19.0 → basic_memory-0.19.2}/tests/utils/test_parse_tags.py +0 -0
  597. {basic_memory-0.19.0 → basic_memory-0.19.2}/tests/utils/test_permalink_formatting.py +0 -0
  598. {basic_memory-0.19.0 → basic_memory-0.19.2}/tests/utils/test_timezone_utils.py +0 -0
  599. {basic_memory-0.19.0 → basic_memory-0.19.2}/tests/utils/test_utf8_handling.py +0 -0
  600. {basic_memory-0.19.0 → basic_memory-0.19.2}/tests/utils/test_validate_project_path.py +0 -0
  601. {basic_memory-0.19.0 → basic_memory-0.19.2}/ui/tool-ui-react/.gitignore +0 -0
  602. {basic_memory-0.19.0 → basic_memory-0.19.2}/ui/tool-ui-react/build.mjs +0 -0
  603. {basic_memory-0.19.0 → basic_memory-0.19.2}/ui/tool-ui-react/package-lock.json +0 -0
  604. {basic_memory-0.19.0 → basic_memory-0.19.2}/ui/tool-ui-react/package.json +0 -0
  605. {basic_memory-0.19.0 → basic_memory-0.19.2}/ui/tool-ui-react/src/components/tool-ui/data-table/_adapter.tsx +0 -0
  606. {basic_memory-0.19.0 → basic_memory-0.19.2}/ui/tool-ui-react/src/components/tool-ui/data-table/data-table.tsx +0 -0
  607. {basic_memory-0.19.0 → basic_memory-0.19.2}/ui/tool-ui-react/src/components/tool-ui/data-table/error-boundary.tsx +0 -0
  608. {basic_memory-0.19.0 → basic_memory-0.19.2}/ui/tool-ui-react/src/components/tool-ui/data-table/formatters.tsx +0 -0
  609. {basic_memory-0.19.0 → basic_memory-0.19.2}/ui/tool-ui-react/src/components/tool-ui/data-table/index.tsx +0 -0
  610. {basic_memory-0.19.0 → basic_memory-0.19.2}/ui/tool-ui-react/src/components/tool-ui/data-table/schema.ts +0 -0
  611. {basic_memory-0.19.0 → basic_memory-0.19.2}/ui/tool-ui-react/src/components/tool-ui/data-table/types.ts +0 -0
  612. {basic_memory-0.19.0 → basic_memory-0.19.2}/ui/tool-ui-react/src/components/tool-ui/data-table/utilities.ts +0 -0
  613. {basic_memory-0.19.0 → basic_memory-0.19.2}/ui/tool-ui-react/src/components/tool-ui/shared/_adapter.tsx +0 -0
  614. {basic_memory-0.19.0 → basic_memory-0.19.2}/ui/tool-ui-react/src/components/tool-ui/shared/action-buttons.tsx +0 -0
  615. {basic_memory-0.19.0 → basic_memory-0.19.2}/ui/tool-ui-react/src/components/tool-ui/shared/actions-config.ts +0 -0
  616. {basic_memory-0.19.0 → basic_memory-0.19.2}/ui/tool-ui-react/src/components/tool-ui/shared/error-boundary.tsx +0 -0
  617. {basic_memory-0.19.0 → basic_memory-0.19.2}/ui/tool-ui-react/src/components/tool-ui/shared/index.ts +0 -0
  618. {basic_memory-0.19.0 → basic_memory-0.19.2}/ui/tool-ui-react/src/components/tool-ui/shared/media/aspect-ratio.ts +0 -0
  619. {basic_memory-0.19.0 → basic_memory-0.19.2}/ui/tool-ui-react/src/components/tool-ui/shared/media/format-utils.ts +0 -0
  620. {basic_memory-0.19.0 → basic_memory-0.19.2}/ui/tool-ui-react/src/components/tool-ui/shared/media/index.ts +0 -0
  621. {basic_memory-0.19.0 → basic_memory-0.19.2}/ui/tool-ui-react/src/components/tool-ui/shared/media/overlay-gradient.ts +0 -0
  622. {basic_memory-0.19.0 → basic_memory-0.19.2}/ui/tool-ui-react/src/components/tool-ui/shared/media/sanitize-href.ts +0 -0
  623. {basic_memory-0.19.0 → basic_memory-0.19.2}/ui/tool-ui-react/src/components/tool-ui/shared/parse.ts +0 -0
  624. {basic_memory-0.19.0 → basic_memory-0.19.2}/ui/tool-ui-react/src/components/tool-ui/shared/schema.ts +0 -0
  625. {basic_memory-0.19.0 → basic_memory-0.19.2}/ui/tool-ui-react/src/components/tool-ui/shared/use-action-buttons.tsx +0 -0
  626. {basic_memory-0.19.0 → basic_memory-0.19.2}/ui/tool-ui-react/src/components/tool-ui/shared/use-copy-to-clipboard.ts +0 -0
  627. {basic_memory-0.19.0 → basic_memory-0.19.2}/ui/tool-ui-react/src/components/tool-ui/shared/utils.ts +0 -0
  628. {basic_memory-0.19.0 → basic_memory-0.19.2}/ui/tool-ui-react/src/components/ui/accordion.tsx +0 -0
  629. {basic_memory-0.19.0 → basic_memory-0.19.2}/ui/tool-ui-react/src/components/ui/badge.tsx +0 -0
  630. {basic_memory-0.19.0 → basic_memory-0.19.2}/ui/tool-ui-react/src/components/ui/button.tsx +0 -0
  631. {basic_memory-0.19.0 → basic_memory-0.19.2}/ui/tool-ui-react/src/components/ui/dropdown-menu.tsx +0 -0
  632. {basic_memory-0.19.0 → basic_memory-0.19.2}/ui/tool-ui-react/src/components/ui/table.tsx +0 -0
  633. {basic_memory-0.19.0 → basic_memory-0.19.2}/ui/tool-ui-react/src/components/ui/tooltip.tsx +0 -0
  634. {basic_memory-0.19.0 → basic_memory-0.19.2}/ui/tool-ui-react/src/note-preview.tsx +0 -0
  635. {basic_memory-0.19.0 → basic_memory-0.19.2}/ui/tool-ui-react/src/search-results.tsx +0 -0
  636. {basic_memory-0.19.0 → basic_memory-0.19.2}/ui/tool-ui-react/src/styles.css +0 -0
  637. {basic_memory-0.19.0 → basic_memory-0.19.2}/ui/tool-ui-react/tailwind.config.js +0 -0
@@ -2,6 +2,35 @@
2
2
 
3
3
  ## Unreleased
4
4
 
5
+ ## v0.19.2 (2026-03-09)
6
+
7
+ ### Bug Fixes
8
+
9
+ - **#657**: Coerce string params to list/dict in MCP tools
10
+ - MCP clients that serialize `list`/`dict` arguments as JSON strings no longer fail Pydantic validation
11
+ - Adds `BeforeValidator` coercion to `search_notes` (`entity_types`, `note_types`, `tags`, `metadata_filters`), `write_note` (`metadata`), and `canvas` (`nodes`, `edges`)
12
+ - **#655**: Handle SQLite and Windows semantic search regressions
13
+ - Fix embedding status query for non-semantic SQLite databases
14
+ - Windows-safe log file rotation with per-process log filenames
15
+ - Robust `setup_logging` that handles all environments cleanly
16
+
17
+ ## v0.19.1 (2026-03-08)
18
+
19
+ ### Bug Fixes
20
+
21
+ - **#649**: Enforce strict entity resolution in destructive MCP tools (`edit_note`, `move_note`, `delete_note`)
22
+ - Prevents fuzzy-match fallback from silently editing/moving/deleting the wrong note
23
+ - DST-related timeframe validation fix (round instead of truncate days)
24
+
25
+ ### Features
26
+
27
+ - **#648**: Add `insert_before_section` and `insert_after_section` edit operations
28
+ - Add `GET /knowledge/graph` endpoint for full graph visualization
29
+
30
+ ### Dependencies
31
+
32
+ - Bump authlib from 1.6.6 to 1.6.7
33
+
5
34
  ## v0.19.0 (2026-03-07)
6
35
 
7
36
  ### Highlights
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: basic-memory
3
- Version: 0.19.0
3
+ Version: 0.19.2
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
@@ -74,6 +74,18 @@ Basic Memory lets you build persistent knowledge through natural conversations w
74
74
  Claude, while keeping everything in simple Markdown files on your computer. It uses the Model Context Protocol (MCP) to
75
75
  enable any compatible LLM to read and write to your local knowledge base.
76
76
 
77
+ ## What's New in v0.19.0
78
+
79
+ - **Semantic Vector Search** — find notes by meaning, not just keywords. Combines full-text and vector similarity for hybrid search with FastEmbed embeddings.
80
+ - **Schema System** — infer, validate, and diff the structure of your knowledge base with `schema_infer`, `schema_validate`, and `schema_diff` tools.
81
+ - **Per-Project Cloud Routing** — route individual projects through the cloud while others stay local, using API key authentication (`basic-memory project set-cloud`).
82
+ - **FastMCP 3.0** — upgraded to FastMCP 3.0 with tool annotations for better client integration.
83
+ - **CLI Overhaul** — JSON output mode (`--json`) for scripting, workspace-aware commands, and an htop-inspired project dashboard.
84
+ - **Smarter Editing** — `edit_note` append/prepend auto-creates notes if they don't exist; `write_note` has an overwrite guard to prevent accidental data loss.
85
+ - **Richer Search Results** — matched chunk text returned in search results for better context.
86
+
87
+ See the full [CHANGELOG](CHANGELOG.md) for details.
88
+
77
89
  - Website: [basicmemory.com](https://basicmemory.com?utm_source=github&utm_medium=referral&utm_campaign=readme)
78
90
  - Documentation: [docs.basicmemory.com](https://docs.basicmemory.com?utm_source=github&utm_medium=referral&utm_campaign=readme)
79
91
  - Community: [Discord](https://discord.gg/tyvKNccgqN?utm_source=github&utm_medium=referral&utm_campaign=readme)
@@ -23,6 +23,18 @@ Basic Memory lets you build persistent knowledge through natural conversations w
23
23
  Claude, while keeping everything in simple Markdown files on your computer. It uses the Model Context Protocol (MCP) to
24
24
  enable any compatible LLM to read and write to your local knowledge base.
25
25
 
26
+ ## What's New in v0.19.0
27
+
28
+ - **Semantic Vector Search** — find notes by meaning, not just keywords. Combines full-text and vector similarity for hybrid search with FastEmbed embeddings.
29
+ - **Schema System** — infer, validate, and diff the structure of your knowledge base with `schema_infer`, `schema_validate`, and `schema_diff` tools.
30
+ - **Per-Project Cloud Routing** — route individual projects through the cloud while others stay local, using API key authentication (`basic-memory project set-cloud`).
31
+ - **FastMCP 3.0** — upgraded to FastMCP 3.0 with tool annotations for better client integration.
32
+ - **CLI Overhaul** — JSON output mode (`--json`) for scripting, workspace-aware commands, and an htop-inspired project dashboard.
33
+ - **Smarter Editing** — `edit_note` append/prepend auto-creates notes if they don't exist; `write_note` has an overwrite guard to prevent accidental data loss.
34
+ - **Richer Search Results** — matched chunk text returned in search results for better context.
35
+
36
+ See the full [CHANGELOG](CHANGELOG.md) for details.
37
+
26
38
  - Website: [basicmemory.com](https://basicmemory.com?utm_source=github&utm_medium=referral&utm_campaign=readme)
27
39
  - Documentation: [docs.basicmemory.com](https://docs.basicmemory.com?utm_source=github&utm_medium=referral&utm_campaign=readme)
28
40
  - Community: [Discord](https://discord.gg/tyvKNccgqN?utm_source=github&utm_medium=referral&utm_campaign=readme)
@@ -6,12 +6,12 @@
6
6
  "url": "https://github.com/basicmachines-co/basic-memory.git",
7
7
  "source": "github"
8
8
  },
9
- "version": "0.19.0",
9
+ "version": "0.19.2",
10
10
  "packages": [
11
11
  {
12
12
  "registryType": "pypi",
13
13
  "identifier": "basic-memory",
14
- "version": "0.19.0",
14
+ "version": "0.19.2",
15
15
  "runtimeHint": "uvx",
16
16
  "runtimeArguments": [
17
17
  {"type": "positional", "value": "basic-memory"},
@@ -1,7 +1,7 @@
1
1
  """basic-memory - Local-first knowledge management combining Zettelkasten with knowledge graphs"""
2
2
 
3
3
  # Package version - updated by release automation
4
- __version__ = "0.19.0"
4
+ __version__ = "0.19.2"
5
5
 
6
6
  # API version for FastAPI - independent of package version
7
7
  __api_version__ = "v0"
@@ -20,6 +20,7 @@ from basic_memory.deps import (
20
20
  ProjectConfigV2ExternalDep,
21
21
  AppConfigDep,
22
22
  EntityRepositoryV2ExternalDep,
23
+ RelationRepositoryV2ExternalDep,
23
24
  ProjectExternalIdPathDep,
24
25
  TaskSchedulerDep,
25
26
  FileServiceV2ExternalDep,
@@ -31,6 +32,9 @@ from basic_memory.schemas.v2 import (
31
32
  EntityResolveRequest,
32
33
  EntityResolveResponse,
33
34
  EntityResponseV2,
35
+ GraphEdge,
36
+ GraphNode,
37
+ GraphResponse,
34
38
  MoveEntityRequestV2,
35
39
  MoveDirectoryRequestV2,
36
40
  DeleteDirectoryRequestV2,
@@ -56,6 +60,50 @@ def _schedule_vector_sync_if_enabled(
56
60
  )
57
61
 
58
62
 
63
+ ## Graph endpoint
64
+
65
+
66
+ @router.get("/graph", response_model=GraphResponse)
67
+ async def get_graph(
68
+ project_id: ProjectExternalIdPathDep,
69
+ entity_repository: EntityRepositoryV2ExternalDep,
70
+ relation_repository: RelationRepositoryV2ExternalDep,
71
+ ) -> GraphResponse:
72
+ """Return all entities and resolved relations for knowledge graph visualization.
73
+
74
+ Returns a flat node/edge structure optimized for rendering with graph libraries.
75
+ Only includes resolved relations (where to_id is not null).
76
+ """
77
+ logger.info("API v2 request: get_graph")
78
+
79
+ # Fetch all entities for this project
80
+ entities = await entity_repository.find_all(use_load_options=False)
81
+ nodes = [
82
+ GraphNode(
83
+ external_id=entity.external_id,
84
+ title=entity.title,
85
+ note_type=entity.note_type,
86
+ file_path=entity.file_path,
87
+ )
88
+ for entity in entities
89
+ ]
90
+
91
+ # Fetch all resolved relations (to_id is not null) with eager-loaded entities
92
+ relations = await relation_repository.find_all()
93
+ edges = [
94
+ GraphEdge(
95
+ from_id=relation.from_entity.external_id,
96
+ to_id=relation.to_entity.external_id,
97
+ relation_type=relation.relation_type,
98
+ )
99
+ for relation in relations
100
+ if relation.to_entity is not None
101
+ ]
102
+
103
+ logger.info(f"API v2 response: graph with {len(nodes)} nodes and {len(edges)} edges")
104
+ return GraphResponse(nodes=nodes, edges=edges)
105
+
106
+
59
107
  ## Resolution endpoint
60
108
 
61
109
 
@@ -4,12 +4,14 @@ This tool creates Obsidian canvas files (.canvas) using the JSON Canvas 1.0 spec
4
4
  """
5
5
 
6
6
  import json
7
- from typing import Dict, List, Any, Optional
7
+ from typing import Annotated, Dict, List, Any, Optional
8
8
 
9
9
  from loguru import logger
10
10
  from fastmcp import Context
11
+ from pydantic import BeforeValidator
11
12
 
12
13
  from basic_memory.mcp.project_context import get_project_client
14
+ from basic_memory.utils import coerce_list
13
15
  from basic_memory.mcp.server import mcp
14
16
  from basic_memory.mcp.tools.utils import call_put, call_post, resolve_entity_id
15
17
 
@@ -19,8 +21,8 @@ from basic_memory.mcp.tools.utils import call_put, call_post, resolve_entity_id
19
21
  annotations={"destructiveHint": False, "idempotentHint": True, "openWorldHint": False},
20
22
  )
21
23
  async def canvas(
22
- nodes: List[Dict[str, Any]],
23
- edges: List[Dict[str, Any]],
24
+ nodes: Annotated[List[Dict[str, Any]], BeforeValidator(coerce_list)],
25
+ edges: Annotated[List[Dict[str, Any]], BeforeValidator(coerce_list)],
24
26
  title: str,
25
27
  directory: str,
26
28
  project: Optional[str] = None,
@@ -318,7 +318,7 @@ delete_note("path/to/file.md")
318
318
  note_file_path = None
319
319
  try:
320
320
  # Resolve identifier to entity ID
321
- entity_id = await knowledge_client.resolve_entity(identifier)
321
+ entity_id = await knowledge_client.resolve_entity(identifier, strict=True)
322
322
  if output_format == "json":
323
323
  entity = await knowledge_client.get_entity(entity_id)
324
324
  note_title = entity.title
@@ -158,7 +158,7 @@ Error editing note '{identifier}': {error_message}
158
158
 
159
159
 
160
160
  @mcp.tool(
161
- description="Edit an existing markdown note using various operations like append, prepend, find_replace, or replace_section.",
161
+ description="Edit an existing markdown note using various operations like append, prepend, find_replace, replace_section, insert_before_section, or insert_after_section.",
162
162
  annotations={"destructiveHint": False, "openWorldHint": False},
163
163
  )
164
164
  async def edit_note(
@@ -190,6 +190,8 @@ async def edit_note(
190
190
  - "prepend": Add content to the beginning of the note (creates the note if it doesn't exist)
191
191
  - "find_replace": Replace occurrences of find_text with content (note must exist)
192
192
  - "replace_section": Replace content under a specific markdown header (note must exist)
193
+ - "insert_before_section": Insert content before a section heading without consuming it (note must exist)
194
+ - "insert_after_section": Insert content after a section heading without consuming it (note must exist)
193
195
  content: The content to add or use for replacement
194
196
  project: Project name to edit in. Optional - server will resolve using hierarchy.
195
197
  If unknown, use list_memory_projects() to discover available projects.
@@ -257,7 +259,14 @@ async def edit_note(
257
259
  logger.info("MCP tool call", tool="edit_note", identifier=identifier, operation=operation)
258
260
 
259
261
  # Validate operation
260
- valid_operations = ["append", "prepend", "find_replace", "replace_section"]
262
+ valid_operations = [
263
+ "append",
264
+ "prepend",
265
+ "find_replace",
266
+ "replace_section",
267
+ "insert_before_section",
268
+ "insert_after_section",
269
+ ]
261
270
  if operation not in valid_operations:
262
271
  raise ValueError(
263
272
  f"Invalid operation '{operation}'. Must be one of: {', '.join(valid_operations)}"
@@ -266,8 +275,9 @@ async def edit_note(
266
275
  # Validate required parameters for specific operations
267
276
  if operation == "find_replace" and not find_text:
268
277
  raise ValueError("find_text parameter is required for find_replace operation")
269
- if operation == "replace_section" and not section:
270
- raise ValueError("section parameter is required for replace_section operation")
278
+ section_ops = ("replace_section", "insert_before_section", "insert_after_section")
279
+ if operation in section_ops and not section:
280
+ raise ValueError("section parameter is required for section-based operations")
271
281
 
272
282
  # Use the PATCH endpoint to edit the entity
273
283
  try:
@@ -283,7 +293,7 @@ async def edit_note(
283
293
 
284
294
  # Try to resolve the entity; for append/prepend, create it if not found
285
295
  try:
286
- entity_id = await knowledge_client.resolve_entity(identifier)
296
+ entity_id = await knowledge_client.resolve_entity(identifier, strict=True)
287
297
  except Exception as resolve_error:
288
298
  # Trigger: entity does not exist yet
289
299
  # Why: append/prepend can meaningfully create a new note from the content,
@@ -389,6 +399,10 @@ async def edit_note(
389
399
  summary.append("operation: Find and replace operation completed")
390
400
  elif operation == "replace_section":
391
401
  summary.append(f"operation: Replaced content under section '{section}'")
402
+ elif operation == "insert_before_section":
403
+ summary.append(f"operation: Inserted content before section '{section}'")
404
+ elif operation == "insert_after_section":
405
+ summary.append(f"operation: Inserted content after section '{section}'")
392
406
 
393
407
  # Count observations by category (reuse logic from write_note)
394
408
  categories = {}
@@ -6,6 +6,7 @@ from typing import Optional, Literal
6
6
 
7
7
  from loguru import logger
8
8
  from fastmcp import Context
9
+ from mcp.server.fastmcp.exceptions import ToolError
9
10
 
10
11
  from basic_memory.mcp.server import mcp
11
12
  from basic_memory.mcp.project_context import get_project_client
@@ -637,7 +638,7 @@ move_note("path/to/file.md", "{destination_path}/file.md")
637
638
  """Resolve and cache the source entity ID for the duration of this move."""
638
639
  nonlocal resolved_entity_id
639
640
  if resolved_entity_id is None:
640
- resolved_entity_id = await knowledge_client.resolve_entity(identifier)
641
+ resolved_entity_id = await knowledge_client.resolve_entity(identifier, strict=True)
641
642
  return resolved_entity_id
642
643
 
643
644
  try:
@@ -645,8 +646,26 @@ move_note("path/to/file.md", "{destination_path}/file.md")
645
646
  source_entity = await knowledge_client.get_entity(resolved_entity_id)
646
647
  if "." in source_entity.file_path:
647
648
  source_ext = source_entity.file_path.split(".")[-1]
649
+ except ToolError as e:
650
+ # Trigger: strict=True resolve_entity raised because the entity was not found.
651
+ # Why: fail fast with a formatted error instead of silently falling through
652
+ # to extension defaults and failing later with a confusing message.
653
+ # Outcome: move_note returns a user-facing not-found error immediately.
654
+ logger.error(f"Move failed for '{identifier}' to '{destination_path}': {e}")
655
+ if output_format == "json":
656
+ return {
657
+ "moved": False,
658
+ "title": None,
659
+ "permalink": None,
660
+ "file_path": None,
661
+ "source": identifier,
662
+ "destination": destination_path,
663
+ "error": str(e),
664
+ }
665
+ return _format_move_error_response(str(e), identifier, destination_path)
648
666
  except Exception as e:
649
- # If we can't fetch source metadata, continue with extension defaults.
667
+ # If we can't fetch source metadata (e.g. get_entity or file_path parsing fails),
668
+ # continue with extension defaults — the entity was at least resolved.
650
669
  logger.debug(f"Could not fetch source entity for extension check: {e}")
651
670
 
652
671
  # --- Resolve destination_folder into destination_path ---
@@ -6,8 +6,10 @@ from typing import Annotated, List, Optional, Dict, Any, Literal
6
6
 
7
7
  from loguru import logger
8
8
  from fastmcp import Context
9
+ from pydantic import BeforeValidator
9
10
 
10
11
  from basic_memory.config import ConfigManager
12
+ from basic_memory.utils import coerce_dict, coerce_list
11
13
  from basic_memory.mcp.container import get_container
12
14
  from basic_memory.mcp.project_context import (
13
15
  detect_project_from_url_prefix,
@@ -307,18 +309,26 @@ async def search_notes(
307
309
  output_format: Literal["text", "json"] = "text",
308
310
  note_types: Annotated[
309
311
  List[str] | None,
312
+ BeforeValidator(coerce_list),
310
313
  "Filter by the 'type' field in note frontmatter (e.g. 'note', 'chapter', 'person'). "
311
314
  "Case-insensitive.",
312
315
  ] = None,
313
316
  entity_types: Annotated[
314
317
  List[str] | None,
318
+ BeforeValidator(coerce_list),
315
319
  "Filter by knowledge graph item type: 'entity' (whole notes), 'observation', or "
316
320
  "'relation'. Defaults to 'entity'. Do NOT pass schema/frontmatter types like "
317
321
  "'Chapter' here — use note_types instead.",
318
322
  ] = None,
319
323
  after_date: Optional[str] = None,
320
- metadata_filters: Optional[Dict[str, Any]] = None,
321
- tags: Optional[List[str]] = None,
324
+ metadata_filters: Annotated[
325
+ Dict[str, Any] | None,
326
+ BeforeValidator(coerce_dict),
327
+ ] = None,
328
+ tags: Annotated[
329
+ List[str] | None,
330
+ BeforeValidator(coerce_list),
331
+ ] = None,
322
332
  status: Optional[str] = None,
323
333
  min_similarity: Optional[float] = None,
324
334
  context: Context | None = None,
@@ -1,16 +1,17 @@
1
1
  """Write note tool for Basic Memory MCP server."""
2
2
 
3
3
  import textwrap
4
- from typing import List, Union, Optional, Literal
4
+ from typing import Annotated, List, Union, Optional, Literal
5
5
 
6
6
  from loguru import logger
7
+ from pydantic import BeforeValidator
7
8
 
8
9
  from basic_memory.config import ConfigManager
9
10
  from basic_memory.mcp.project_context import get_project_client, add_project_metadata
10
11
  from basic_memory.mcp.server import mcp
11
12
  from fastmcp import Context
12
13
  from basic_memory.schemas.base import Entity
13
- from basic_memory.utils import parse_tags, validate_project_path
14
+ from basic_memory.utils import coerce_dict, parse_tags, validate_project_path
14
15
 
15
16
  # Define TagType as a Union that can accept either a string or a list of strings or None
16
17
  TagType = Union[List[str], str, None]
@@ -28,7 +29,7 @@ async def write_note(
28
29
  workspace: Optional[str] = None,
29
30
  tags: list[str] | str | None = None,
30
31
  note_type: str = "note",
31
- metadata: dict | None = None,
32
+ metadata: Annotated[dict | None, BeforeValidator(coerce_dict)] = None,
32
33
  overwrite: bool | None = None,
33
34
  output_format: Literal["text", "json"] = "text",
34
35
  context: Context | None = None,
@@ -451,21 +451,36 @@ class SearchRepositoryBase(ABC):
451
451
  return "\n\n".join(part for part in row_parts if part)
452
452
 
453
453
  def _build_chunk_records(self, rows) -> list[dict[str, str]]:
454
- records: list[dict[str, str]] = []
454
+ records_by_key: dict[str, dict[str, str]] = {}
455
+ duplicate_chunk_keys = 0
455
456
  for row in rows:
456
457
  source_text = self._compose_row_source_text(row)
457
458
  chunks = self._split_text_into_chunks(source_text)
458
459
  for chunk_index, chunk_text in enumerate(chunks):
459
460
  chunk_key = f"{row.type}:{row.id}:{chunk_index}"
460
461
  source_hash = hashlib.sha256(chunk_text.encode("utf-8")).hexdigest()
461
- records.append(
462
- {
463
- "chunk_key": chunk_key,
464
- "chunk_text": chunk_text,
465
- "source_hash": source_hash,
466
- }
467
- )
468
- return records
462
+ # Trigger: SQLite FTS5 can accumulate duplicate logical rows for the
463
+ # same search_index id because it does not enforce relational uniqueness.
464
+ # Why: duplicate chunk keys would schedule duplicate writes for the same
465
+ # chunk row and eventually trip UNIQUE(rowid) in search_vector_embeddings.
466
+ # Outcome: collapse chunk work to one deterministic record per chunk key.
467
+ if chunk_key in records_by_key:
468
+ duplicate_chunk_keys += 1
469
+ records_by_key[chunk_key] = {
470
+ "chunk_key": chunk_key,
471
+ "chunk_text": chunk_text,
472
+ "source_hash": source_hash,
473
+ }
474
+
475
+ if duplicate_chunk_keys:
476
+ logger.warning(
477
+ "Collapsed duplicate vector chunk keys before embedding sync: "
478
+ "project_id={project_id} duplicate_chunk_keys={duplicate_chunk_keys}",
479
+ project_id=self.project_id,
480
+ duplicate_chunk_keys=duplicate_chunk_keys,
481
+ )
482
+
483
+ return list(records_by_key.values())
469
484
 
470
485
  # --- Text splitting ---
471
486
 
@@ -140,10 +140,12 @@ def validate_timeframe(timeframe: str) -> str:
140
140
  if parsed > now:
141
141
  raise ValueError("Timeframe cannot be in the future") # pragma: no cover
142
142
 
143
- # Could format the duration back to our standard format
144
- days = (now - parsed).days
143
+ # Round to nearest day to handle DST transitions where an hour shift
144
+ # can cause e.g. "7d" to compute as 6 days + 23 hours
145
+ total_seconds = (now - parsed).total_seconds()
146
+ days = round(total_seconds / 86400)
145
147
 
146
- # Could enforce reasonable limits
148
+ # Enforce reasonable limits
147
149
  if days > 365:
148
150
  raise ValueError("Timeframe should be <= 1 year")
149
151
 
@@ -65,7 +65,14 @@ class EditEntityRequest(BaseModel):
65
65
  Supports various operation types for different editing scenarios.
66
66
  """
67
67
 
68
- operation: Literal["append", "prepend", "find_replace", "replace_section"]
68
+ operation: Literal[
69
+ "append",
70
+ "prepend",
71
+ "find_replace",
72
+ "replace_section",
73
+ "insert_before_section",
74
+ "insert_after_section",
75
+ ]
69
76
  content: str
70
77
  section: Optional[str] = None
71
78
  find_text: Optional[str] = None
@@ -75,8 +82,16 @@ class EditEntityRequest(BaseModel):
75
82
  @classmethod
76
83
  def validate_section_for_replace_section(cls, v, info):
77
84
  """Ensure section is provided for replace_section operation."""
78
- if info.data.get("operation") == "replace_section" and not v:
79
- raise ValueError("section parameter is required for replace_section operation")
85
+ if (
86
+ info.data.get("operation")
87
+ in (
88
+ "replace_section",
89
+ "insert_before_section",
90
+ "insert_after_section",
91
+ )
92
+ and not v
93
+ ):
94
+ raise ValueError("section parameter is required for section-based operations")
80
95
  return v
81
96
 
82
97
  @field_validator("find_text")
@@ -10,6 +10,11 @@ from basic_memory.schemas.v2.entity import (
10
10
  ProjectResolveRequest,
11
11
  ProjectResolveResponse,
12
12
  )
13
+ from basic_memory.schemas.v2.graph import (
14
+ GraphEdge,
15
+ GraphNode,
16
+ GraphResponse,
17
+ )
13
18
  from basic_memory.schemas.v2.resource import (
14
19
  CreateResourceRequest,
15
20
  UpdateResourceRequest,
@@ -25,6 +30,9 @@ __all__ = [
25
30
  "DeleteDirectoryRequestV2",
26
31
  "ProjectResolveRequest",
27
32
  "ProjectResolveResponse",
33
+ "GraphEdge",
34
+ "GraphNode",
35
+ "GraphResponse",
28
36
  "CreateResourceRequest",
29
37
  "UpdateResourceRequest",
30
38
  "ResourceResponse",
@@ -0,0 +1,31 @@
1
+ """Graph visualization schemas for the knowledge graph endpoint."""
2
+
3
+ from typing import Optional
4
+
5
+ from pydantic import BaseModel, Field
6
+
7
+
8
+ class GraphNode(BaseModel):
9
+ """A node in the knowledge graph visualization."""
10
+
11
+ external_id: str = Field(..., description="Entity external ID (UUID)")
12
+ title: str = Field(..., description="Entity title")
13
+ note_type: Optional[str] = Field(None, description="Note type (e.g., note, spec, task)")
14
+ file_path: str = Field(..., description="Relative file path")
15
+
16
+
17
+ class GraphEdge(BaseModel):
18
+ """An edge in the knowledge graph visualization."""
19
+
20
+ from_id: str = Field(..., description="External ID of source entity")
21
+ to_id: str = Field(..., description="External ID of target entity")
22
+ relation_type: str = Field(..., description="Type of relation")
23
+
24
+
25
+ class GraphResponse(BaseModel):
26
+ """Complete knowledge graph for visualization."""
27
+
28
+ nodes: list[GraphNode] = Field(default_factory=list, description="All entities as nodes")
29
+ edges: list[GraphEdge] = Field(
30
+ default_factory=list, description="All resolved relations as edges"
31
+ )
@@ -888,6 +888,14 @@ class EntityService(BaseService[EntityModel]):
888
888
  raise ValueError("section cannot be empty or whitespace only")
889
889
  return self.replace_section_content(current_content, section, content)
890
890
 
891
+ elif operation in ("insert_before_section", "insert_after_section"):
892
+ if not section:
893
+ raise ValueError("section is required for insert section operations")
894
+ if not section.strip():
895
+ raise ValueError("section cannot be empty or whitespace only")
896
+ position = "before" if operation == "insert_before_section" else "after"
897
+ return self.insert_relative_to_section(current_content, section, content, position)
898
+
891
899
  else:
892
900
  raise ValueError(f"Unsupported operation: {operation}")
893
901
 
@@ -979,6 +987,73 @@ class EntityService(BaseService[EntityModel]):
979
987
 
980
988
  return "\n".join(result_lines)
981
989
 
990
+ def insert_relative_to_section(
991
+ self,
992
+ current_content: str,
993
+ section_header: str,
994
+ new_content: str,
995
+ position: str,
996
+ ) -> str:
997
+ """Insert content before or after a section heading without consuming it.
998
+
999
+ Unlike replace_section_content, this preserves the section heading and its
1000
+ existing content. The new content is inserted immediately before or after
1001
+ the heading line.
1002
+
1003
+ Args:
1004
+ current_content: The current markdown content
1005
+ section_header: The section header to anchor on (e.g., "## Section Name")
1006
+ new_content: The content to insert
1007
+ position: "before" to insert above the heading, "after" to insert below it
1008
+
1009
+ Returns:
1010
+ The updated content with new_content inserted relative to the heading
1011
+
1012
+ Raises:
1013
+ ValueError: If the section header is not found or appears more than once
1014
+ """
1015
+ # Normalize the section header (ensure it starts with #)
1016
+ if not section_header.startswith("#"):
1017
+ section_header = "## " + section_header
1018
+
1019
+ lines = current_content.split("\n")
1020
+ matching_indices = [
1021
+ i for i, line in enumerate(lines) if line.strip() == section_header.strip()
1022
+ ]
1023
+
1024
+ if len(matching_indices) == 0:
1025
+ raise ValueError(
1026
+ f"Section '{section_header}' not found in document. "
1027
+ f"Use replace_section to create a new section."
1028
+ )
1029
+ if len(matching_indices) > 1:
1030
+ raise ValueError(
1031
+ f"Multiple sections found with header '{section_header}'. "
1032
+ f"Section insertion requires unique headers."
1033
+ )
1034
+
1035
+ idx = matching_indices[0]
1036
+
1037
+ if position == "before":
1038
+ # Insert new content before the section heading
1039
+ before = lines[:idx]
1040
+ after = lines[idx:]
1041
+ # Ensure blank line separation
1042
+ insert_lines = new_content.rstrip("\n").split("\n")
1043
+ if before and before[-1].strip() != "":
1044
+ insert_lines = [""] + insert_lines
1045
+ return "\n".join(before + insert_lines + [""] + after)
1046
+ else:
1047
+ # Insert new content after the section heading line
1048
+ before = lines[: idx + 1]
1049
+ after = lines[idx + 1 :]
1050
+ insert_lines = new_content.rstrip("\n").split("\n")
1051
+ # Ensure blank line separation so inserted text doesn't merge
1052
+ # with existing section content into a single paragraph
1053
+ if after and after[0].strip() != "":
1054
+ insert_lines = insert_lines + [""]
1055
+ return "\n".join(before + insert_lines + after)
1056
+
982
1057
  def _prepend_after_frontmatter(self, current_content: str, content: str) -> str:
983
1058
  """Prepend content after frontmatter, preserving frontmatter structure."""
984
1059