basic-memory 0.12.1__tar.gz → 0.12.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.

Potentially problematic release.


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

Files changed (225) hide show
  1. {basic_memory-0.12.1 → basic_memory-0.12.2}/CHANGELOG.md +11 -0
  2. {basic_memory-0.12.1 → basic_memory-0.12.2}/PKG-INFO +1 -1
  3. {basic_memory-0.12.1 → basic_memory-0.12.2}/installer/installer.py +1 -1
  4. {basic_memory-0.12.1 → basic_memory-0.12.2}/pyproject.toml +1 -1
  5. {basic_memory-0.12.1 → basic_memory-0.12.2}/src/basic_memory/__init__.py +1 -1
  6. {basic_memory-0.12.1 → basic_memory-0.12.2}/src/basic_memory/cli/commands/import_memory_json.py +1 -1
  7. {basic_memory-0.12.1 → basic_memory-0.12.2}/src/basic_memory/markdown/entity_parser.py +1 -1
  8. {basic_memory-0.12.1 → basic_memory-0.12.2}/src/basic_memory/sync/sync_service.py +3 -5
  9. {basic_memory-0.12.1 → basic_memory-0.12.2}/tests/api/test_resource_router.py +3 -3
  10. {basic_memory-0.12.1 → basic_memory-0.12.2}/tests/cli/test_import_chatgpt.py +8 -7
  11. {basic_memory-0.12.1 → basic_memory-0.12.2}/tests/cli/test_import_claude_conversations.py +5 -4
  12. {basic_memory-0.12.1 → basic_memory-0.12.2}/tests/cli/test_import_claude_projects.py +5 -4
  13. {basic_memory-0.12.1 → basic_memory-0.12.2}/tests/cli/test_import_memory_json.py +4 -3
  14. {basic_memory-0.12.1 → basic_memory-0.12.2}/tests/markdown/test_markdown_processor.py +5 -5
  15. {basic_memory-0.12.1 → basic_memory-0.12.2}/tests/mcp/test_tool_canvas.py +4 -4
  16. {basic_memory-0.12.1 → basic_memory-0.12.2}/tests/sync/test_tmp_files.py +2 -2
  17. {basic_memory-0.12.1 → basic_memory-0.12.2}/tests/sync/test_watch_service.py +1 -1
  18. {basic_memory-0.12.1 → basic_memory-0.12.2}/tests/utils/test_file_utils.py +10 -10
  19. {basic_memory-0.12.1 → basic_memory-0.12.2}/uv.lock +1 -1
  20. {basic_memory-0.12.1 → basic_memory-0.12.2}/.github/ISSUE_TEMPLATE/bug_report.md +0 -0
  21. {basic_memory-0.12.1 → basic_memory-0.12.2}/.github/ISSUE_TEMPLATE/config.yml +0 -0
  22. {basic_memory-0.12.1 → basic_memory-0.12.2}/.github/ISSUE_TEMPLATE/documentation.md +0 -0
  23. {basic_memory-0.12.1 → basic_memory-0.12.2}/.github/ISSUE_TEMPLATE/feature_request.md +0 -0
  24. {basic_memory-0.12.1 → basic_memory-0.12.2}/.github/dependabot.yml +0 -0
  25. {basic_memory-0.12.1 → basic_memory-0.12.2}/.github/workflows/claude-code-actions.yml +0 -0
  26. {basic_memory-0.12.1 → basic_memory-0.12.2}/.github/workflows/pr-title.yml +0 -0
  27. {basic_memory-0.12.1 → basic_memory-0.12.2}/.github/workflows/release.yml +0 -0
  28. {basic_memory-0.12.1 → basic_memory-0.12.2}/.github/workflows/test.yml +0 -0
  29. {basic_memory-0.12.1 → basic_memory-0.12.2}/.gitignore +0 -0
  30. {basic_memory-0.12.1 → basic_memory-0.12.2}/.python-version +0 -0
  31. {basic_memory-0.12.1 → basic_memory-0.12.2}/CITATION.cff +0 -0
  32. {basic_memory-0.12.1 → basic_memory-0.12.2}/CLA.md +0 -0
  33. {basic_memory-0.12.1 → basic_memory-0.12.2}/CLAUDE.md +0 -0
  34. {basic_memory-0.12.1 → basic_memory-0.12.2}/CODE_OF_CONDUCT.md +0 -0
  35. {basic_memory-0.12.1 → basic_memory-0.12.2}/CONTRIBUTING.md +0 -0
  36. {basic_memory-0.12.1 → basic_memory-0.12.2}/Dockerfile +0 -0
  37. {basic_memory-0.12.1 → basic_memory-0.12.2}/LICENSE +0 -0
  38. {basic_memory-0.12.1 → basic_memory-0.12.2}/Makefile +0 -0
  39. {basic_memory-0.12.1 → basic_memory-0.12.2}/README.md +0 -0
  40. {basic_memory-0.12.1 → basic_memory-0.12.2}/SECURITY.md +0 -0
  41. {basic_memory-0.12.1 → basic_memory-0.12.2}/basic-memory.md +0 -0
  42. {basic_memory-0.12.1 → basic_memory-0.12.2}/docs/AI Assistant Guide.md +0 -0
  43. {basic_memory-0.12.1 → basic_memory-0.12.2}/docs/CLI Reference.md +0 -0
  44. {basic_memory-0.12.1 → basic_memory-0.12.2}/docs/Canvas.md +0 -0
  45. {basic_memory-0.12.1 → basic_memory-0.12.2}/docs/Getting Started with Basic Memory.md +0 -0
  46. {basic_memory-0.12.1 → basic_memory-0.12.2}/docs/Knowledge Format.md +0 -0
  47. {basic_memory-0.12.1 → basic_memory-0.12.2}/docs/Obsidian Integration.md +0 -0
  48. {basic_memory-0.12.1 → basic_memory-0.12.2}/docs/Technical Information.md +0 -0
  49. {basic_memory-0.12.1 → basic_memory-0.12.2}/docs/User Guide.md +0 -0
  50. {basic_memory-0.12.1 → basic_memory-0.12.2}/docs/Welcome to Basic memory.md +0 -0
  51. {basic_memory-0.12.1 → basic_memory-0.12.2}/docs/attachments/Canvas.png +0 -0
  52. {basic_memory-0.12.1 → basic_memory-0.12.2}/docs/attachments/Claude-Obsidian-Demo.mp4 +0 -0
  53. {basic_memory-0.12.1 → basic_memory-0.12.2}/docs/attachments/Prompt.png +0 -0
  54. {basic_memory-0.12.1 → basic_memory-0.12.2}/docs/attachments/disk-ai-logo-400x400.png +0 -0
  55. {basic_memory-0.12.1 → basic_memory-0.12.2}/docs/attachments/disk-ai-logo.png +0 -0
  56. {basic_memory-0.12.1 → basic_memory-0.12.2}/docs/attachments/prompt 1.png +0 -0
  57. {basic_memory-0.12.1 → basic_memory-0.12.2}/docs/attachments/prompt2.png +0 -0
  58. {basic_memory-0.12.1 → basic_memory-0.12.2}/docs/attachments/prompt3.png +0 -0
  59. {basic_memory-0.12.1 → basic_memory-0.12.2}/docs/attachments/prompt4.png +0 -0
  60. {basic_memory-0.12.1 → basic_memory-0.12.2}/docs/publish.js +0 -0
  61. {basic_memory-0.12.1 → basic_memory-0.12.2}/examples/Coffee Notes/Brewing Equipment.md +0 -0
  62. {basic_memory-0.12.1 → basic_memory-0.12.2}/examples/Coffee Notes/Coffee Bean Origins.md +0 -0
  63. {basic_memory-0.12.1 → basic_memory-0.12.2}/examples/Coffee Notes/Coffee Brewing Methods.md +0 -0
  64. {basic_memory-0.12.1 → basic_memory-0.12.2}/examples/Coffee Notes/Coffee Flavor Map.md +0 -0
  65. {basic_memory-0.12.1 → basic_memory-0.12.2}/examples/Coffee Notes/Coffee Knowledge Base.md +0 -0
  66. {basic_memory-0.12.1 → basic_memory-0.12.2}/examples/Coffee Notes/Flavor Extraction.md +0 -0
  67. {basic_memory-0.12.1 → basic_memory-0.12.2}/examples/Coffee Notes/Perfect Pour Over Coffee Method.canvas +0 -0
  68. {basic_memory-0.12.1 → basic_memory-0.12.2}/examples/Coffee Notes/Tasting Notes.md +0 -0
  69. {basic_memory-0.12.1 → basic_memory-0.12.2}/installer/Basic.icns +0 -0
  70. {basic_memory-0.12.1 → basic_memory-0.12.2}/installer/README.md +0 -0
  71. {basic_memory-0.12.1 → basic_memory-0.12.2}/installer/icon.svg +0 -0
  72. {basic_memory-0.12.1 → basic_memory-0.12.2}/installer/make_icons.sh +0 -0
  73. {basic_memory-0.12.1 → basic_memory-0.12.2}/installer/setup.py +0 -0
  74. {basic_memory-0.12.1 → basic_memory-0.12.2}/llms-install.md +0 -0
  75. {basic_memory-0.12.1 → basic_memory-0.12.2}/memory.json +0 -0
  76. {basic_memory-0.12.1 → basic_memory-0.12.2}/scripts/install.sh +0 -0
  77. {basic_memory-0.12.1 → basic_memory-0.12.2}/smithery.yaml +0 -0
  78. {basic_memory-0.12.1 → basic_memory-0.12.2}/src/basic_memory/alembic/alembic.ini +0 -0
  79. {basic_memory-0.12.1 → basic_memory-0.12.2}/src/basic_memory/alembic/env.py +0 -0
  80. {basic_memory-0.12.1 → basic_memory-0.12.2}/src/basic_memory/alembic/migrations.py +0 -0
  81. {basic_memory-0.12.1 → basic_memory-0.12.2}/src/basic_memory/alembic/script.py.mako +0 -0
  82. {basic_memory-0.12.1 → basic_memory-0.12.2}/src/basic_memory/alembic/versions/3dae7c7b1564_initial_schema.py +0 -0
  83. {basic_memory-0.12.1 → basic_memory-0.12.2}/src/basic_memory/alembic/versions/502b60eaa905_remove_required_from_entity_permalink.py +0 -0
  84. {basic_memory-0.12.1 → basic_memory-0.12.2}/src/basic_memory/alembic/versions/b3c3938bacdb_relation_to_name_unique_index.py +0 -0
  85. {basic_memory-0.12.1 → basic_memory-0.12.2}/src/basic_memory/alembic/versions/cc7172b46608_update_search_index_schema.py +0 -0
  86. {basic_memory-0.12.1 → basic_memory-0.12.2}/src/basic_memory/api/__init__.py +0 -0
  87. {basic_memory-0.12.1 → basic_memory-0.12.2}/src/basic_memory/api/app.py +0 -0
  88. {basic_memory-0.12.1 → basic_memory-0.12.2}/src/basic_memory/api/routers/__init__.py +0 -0
  89. {basic_memory-0.12.1 → basic_memory-0.12.2}/src/basic_memory/api/routers/knowledge_router.py +0 -0
  90. {basic_memory-0.12.1 → basic_memory-0.12.2}/src/basic_memory/api/routers/memory_router.py +0 -0
  91. {basic_memory-0.12.1 → basic_memory-0.12.2}/src/basic_memory/api/routers/project_info_router.py +0 -0
  92. {basic_memory-0.12.1 → basic_memory-0.12.2}/src/basic_memory/api/routers/resource_router.py +0 -0
  93. {basic_memory-0.12.1 → basic_memory-0.12.2}/src/basic_memory/api/routers/search_router.py +0 -0
  94. {basic_memory-0.12.1 → basic_memory-0.12.2}/src/basic_memory/cli/__init__.py +0 -0
  95. {basic_memory-0.12.1 → basic_memory-0.12.2}/src/basic_memory/cli/app.py +0 -0
  96. {basic_memory-0.12.1 → basic_memory-0.12.2}/src/basic_memory/cli/commands/__init__.py +0 -0
  97. {basic_memory-0.12.1 → basic_memory-0.12.2}/src/basic_memory/cli/commands/db.py +0 -0
  98. {basic_memory-0.12.1 → basic_memory-0.12.2}/src/basic_memory/cli/commands/import_chatgpt.py +0 -0
  99. {basic_memory-0.12.1 → basic_memory-0.12.2}/src/basic_memory/cli/commands/import_claude_conversations.py +0 -0
  100. {basic_memory-0.12.1 → basic_memory-0.12.2}/src/basic_memory/cli/commands/import_claude_projects.py +0 -0
  101. {basic_memory-0.12.1 → basic_memory-0.12.2}/src/basic_memory/cli/commands/mcp.py +0 -0
  102. {basic_memory-0.12.1 → basic_memory-0.12.2}/src/basic_memory/cli/commands/project.py +0 -0
  103. {basic_memory-0.12.1 → basic_memory-0.12.2}/src/basic_memory/cli/commands/status.py +0 -0
  104. {basic_memory-0.12.1 → basic_memory-0.12.2}/src/basic_memory/cli/commands/sync.py +0 -0
  105. {basic_memory-0.12.1 → basic_memory-0.12.2}/src/basic_memory/cli/commands/tool.py +0 -0
  106. {basic_memory-0.12.1 → basic_memory-0.12.2}/src/basic_memory/cli/main.py +0 -0
  107. {basic_memory-0.12.1 → basic_memory-0.12.2}/src/basic_memory/config.py +0 -0
  108. {basic_memory-0.12.1 → basic_memory-0.12.2}/src/basic_memory/db.py +0 -0
  109. {basic_memory-0.12.1 → basic_memory-0.12.2}/src/basic_memory/deps.py +0 -0
  110. {basic_memory-0.12.1 → basic_memory-0.12.2}/src/basic_memory/file_utils.py +0 -0
  111. {basic_memory-0.12.1 → basic_memory-0.12.2}/src/basic_memory/markdown/__init__.py +0 -0
  112. {basic_memory-0.12.1 → basic_memory-0.12.2}/src/basic_memory/markdown/markdown_processor.py +0 -0
  113. {basic_memory-0.12.1 → basic_memory-0.12.2}/src/basic_memory/markdown/plugins.py +0 -0
  114. {basic_memory-0.12.1 → basic_memory-0.12.2}/src/basic_memory/markdown/schemas.py +0 -0
  115. {basic_memory-0.12.1 → basic_memory-0.12.2}/src/basic_memory/markdown/utils.py +0 -0
  116. {basic_memory-0.12.1 → basic_memory-0.12.2}/src/basic_memory/mcp/__init__.py +0 -0
  117. {basic_memory-0.12.1 → basic_memory-0.12.2}/src/basic_memory/mcp/async_client.py +0 -0
  118. {basic_memory-0.12.1 → basic_memory-0.12.2}/src/basic_memory/mcp/main.py +0 -0
  119. {basic_memory-0.12.1 → basic_memory-0.12.2}/src/basic_memory/mcp/prompts/__init__.py +0 -0
  120. {basic_memory-0.12.1 → basic_memory-0.12.2}/src/basic_memory/mcp/prompts/ai_assistant_guide.py +0 -0
  121. {basic_memory-0.12.1 → basic_memory-0.12.2}/src/basic_memory/mcp/prompts/continue_conversation.py +0 -0
  122. {basic_memory-0.12.1 → basic_memory-0.12.2}/src/basic_memory/mcp/prompts/recent_activity.py +0 -0
  123. {basic_memory-0.12.1 → basic_memory-0.12.2}/src/basic_memory/mcp/prompts/search.py +0 -0
  124. {basic_memory-0.12.1 → basic_memory-0.12.2}/src/basic_memory/mcp/prompts/utils.py +0 -0
  125. {basic_memory-0.12.1 → basic_memory-0.12.2}/src/basic_memory/mcp/resources/ai_assistant_guide.md +0 -0
  126. {basic_memory-0.12.1 → basic_memory-0.12.2}/src/basic_memory/mcp/server.py +0 -0
  127. {basic_memory-0.12.1 → basic_memory-0.12.2}/src/basic_memory/mcp/tools/__init__.py +0 -0
  128. {basic_memory-0.12.1 → basic_memory-0.12.2}/src/basic_memory/mcp/tools/build_context.py +0 -0
  129. {basic_memory-0.12.1 → basic_memory-0.12.2}/src/basic_memory/mcp/tools/canvas.py +0 -0
  130. {basic_memory-0.12.1 → basic_memory-0.12.2}/src/basic_memory/mcp/tools/delete_note.py +0 -0
  131. {basic_memory-0.12.1 → basic_memory-0.12.2}/src/basic_memory/mcp/tools/project_info.py +0 -0
  132. {basic_memory-0.12.1 → basic_memory-0.12.2}/src/basic_memory/mcp/tools/read_content.py +0 -0
  133. {basic_memory-0.12.1 → basic_memory-0.12.2}/src/basic_memory/mcp/tools/read_note.py +0 -0
  134. {basic_memory-0.12.1 → basic_memory-0.12.2}/src/basic_memory/mcp/tools/recent_activity.py +0 -0
  135. {basic_memory-0.12.1 → basic_memory-0.12.2}/src/basic_memory/mcp/tools/search.py +0 -0
  136. {basic_memory-0.12.1 → basic_memory-0.12.2}/src/basic_memory/mcp/tools/utils.py +0 -0
  137. {basic_memory-0.12.1 → basic_memory-0.12.2}/src/basic_memory/mcp/tools/write_note.py +0 -0
  138. {basic_memory-0.12.1 → basic_memory-0.12.2}/src/basic_memory/models/__init__.py +0 -0
  139. {basic_memory-0.12.1 → basic_memory-0.12.2}/src/basic_memory/models/base.py +0 -0
  140. {basic_memory-0.12.1 → basic_memory-0.12.2}/src/basic_memory/models/knowledge.py +0 -0
  141. {basic_memory-0.12.1 → basic_memory-0.12.2}/src/basic_memory/models/search.py +0 -0
  142. {basic_memory-0.12.1 → basic_memory-0.12.2}/src/basic_memory/repository/__init__.py +0 -0
  143. {basic_memory-0.12.1 → basic_memory-0.12.2}/src/basic_memory/repository/entity_repository.py +0 -0
  144. {basic_memory-0.12.1 → basic_memory-0.12.2}/src/basic_memory/repository/observation_repository.py +0 -0
  145. {basic_memory-0.12.1 → basic_memory-0.12.2}/src/basic_memory/repository/project_info_repository.py +0 -0
  146. {basic_memory-0.12.1 → basic_memory-0.12.2}/src/basic_memory/repository/relation_repository.py +0 -0
  147. {basic_memory-0.12.1 → basic_memory-0.12.2}/src/basic_memory/repository/repository.py +0 -0
  148. {basic_memory-0.12.1 → basic_memory-0.12.2}/src/basic_memory/repository/search_repository.py +0 -0
  149. {basic_memory-0.12.1 → basic_memory-0.12.2}/src/basic_memory/schemas/__init__.py +0 -0
  150. {basic_memory-0.12.1 → basic_memory-0.12.2}/src/basic_memory/schemas/base.py +0 -0
  151. {basic_memory-0.12.1 → basic_memory-0.12.2}/src/basic_memory/schemas/delete.py +0 -0
  152. {basic_memory-0.12.1 → basic_memory-0.12.2}/src/basic_memory/schemas/memory.py +0 -0
  153. {basic_memory-0.12.1 → basic_memory-0.12.2}/src/basic_memory/schemas/project_info.py +0 -0
  154. {basic_memory-0.12.1 → basic_memory-0.12.2}/src/basic_memory/schemas/request.py +0 -0
  155. {basic_memory-0.12.1 → basic_memory-0.12.2}/src/basic_memory/schemas/response.py +0 -0
  156. {basic_memory-0.12.1 → basic_memory-0.12.2}/src/basic_memory/schemas/search.py +0 -0
  157. {basic_memory-0.12.1 → basic_memory-0.12.2}/src/basic_memory/services/__init__.py +0 -0
  158. {basic_memory-0.12.1 → basic_memory-0.12.2}/src/basic_memory/services/context_service.py +0 -0
  159. {basic_memory-0.12.1 → basic_memory-0.12.2}/src/basic_memory/services/entity_service.py +0 -0
  160. {basic_memory-0.12.1 → basic_memory-0.12.2}/src/basic_memory/services/exceptions.py +0 -0
  161. {basic_memory-0.12.1 → basic_memory-0.12.2}/src/basic_memory/services/file_service.py +0 -0
  162. {basic_memory-0.12.1 → basic_memory-0.12.2}/src/basic_memory/services/initialization.py +0 -0
  163. {basic_memory-0.12.1 → basic_memory-0.12.2}/src/basic_memory/services/link_resolver.py +0 -0
  164. {basic_memory-0.12.1 → basic_memory-0.12.2}/src/basic_memory/services/search_service.py +0 -0
  165. {basic_memory-0.12.1 → basic_memory-0.12.2}/src/basic_memory/services/service.py +0 -0
  166. {basic_memory-0.12.1 → basic_memory-0.12.2}/src/basic_memory/sync/__init__.py +0 -0
  167. {basic_memory-0.12.1 → basic_memory-0.12.2}/src/basic_memory/sync/watch_service.py +0 -0
  168. {basic_memory-0.12.1 → basic_memory-0.12.2}/src/basic_memory/utils.py +0 -0
  169. {basic_memory-0.12.1 → basic_memory-0.12.2}/static/ai_assistant_guide.md +0 -0
  170. {basic_memory-0.12.1 → basic_memory-0.12.2}/static/json_canvas_spec_1_0.md +0 -0
  171. {basic_memory-0.12.1 → basic_memory-0.12.2}/tests/Non-MarkdownFileSupport.pdf +0 -0
  172. {basic_memory-0.12.1 → basic_memory-0.12.2}/tests/Screenshot.png +0 -0
  173. {basic_memory-0.12.1 → basic_memory-0.12.2}/tests/__init__.py +0 -0
  174. {basic_memory-0.12.1 → basic_memory-0.12.2}/tests/api/conftest.py +0 -0
  175. {basic_memory-0.12.1 → basic_memory-0.12.2}/tests/api/test_knowledge_router.py +0 -0
  176. {basic_memory-0.12.1 → basic_memory-0.12.2}/tests/api/test_memory_router.py +0 -0
  177. {basic_memory-0.12.1 → basic_memory-0.12.2}/tests/api/test_project_info_router.py +0 -0
  178. {basic_memory-0.12.1 → basic_memory-0.12.2}/tests/api/test_search_router.py +0 -0
  179. {basic_memory-0.12.1 → basic_memory-0.12.2}/tests/cli/conftest.py +0 -0
  180. {basic_memory-0.12.1 → basic_memory-0.12.2}/tests/cli/test_cli_tools.py +0 -0
  181. {basic_memory-0.12.1 → basic_memory-0.12.2}/tests/cli/test_project_commands.py +0 -0
  182. {basic_memory-0.12.1 → basic_memory-0.12.2}/tests/cli/test_project_info.py +0 -0
  183. {basic_memory-0.12.1 → basic_memory-0.12.2}/tests/cli/test_status.py +0 -0
  184. {basic_memory-0.12.1 → basic_memory-0.12.2}/tests/cli/test_sync.py +0 -0
  185. {basic_memory-0.12.1 → basic_memory-0.12.2}/tests/cli/test_version.py +0 -0
  186. {basic_memory-0.12.1 → basic_memory-0.12.2}/tests/conftest.py +0 -0
  187. {basic_memory-0.12.1 → basic_memory-0.12.2}/tests/edit_file_test.py +0 -0
  188. {basic_memory-0.12.1 → basic_memory-0.12.2}/tests/markdown/__init__.py +0 -0
  189. {basic_memory-0.12.1 → basic_memory-0.12.2}/tests/markdown/test_entity_parser.py +0 -0
  190. {basic_memory-0.12.1 → basic_memory-0.12.2}/tests/markdown/test_markdown_plugins.py +0 -0
  191. {basic_memory-0.12.1 → basic_memory-0.12.2}/tests/markdown/test_observation_edge_cases.py +0 -0
  192. {basic_memory-0.12.1 → basic_memory-0.12.2}/tests/markdown/test_parser_edge_cases.py +0 -0
  193. {basic_memory-0.12.1 → basic_memory-0.12.2}/tests/markdown/test_relation_edge_cases.py +0 -0
  194. {basic_memory-0.12.1 → basic_memory-0.12.2}/tests/markdown/test_task_detection.py +0 -0
  195. {basic_memory-0.12.1 → basic_memory-0.12.2}/tests/mcp/conftest.py +0 -0
  196. {basic_memory-0.12.1 → basic_memory-0.12.2}/tests/mcp/test_prompts.py +0 -0
  197. {basic_memory-0.12.1 → basic_memory-0.12.2}/tests/mcp/test_resources.py +0 -0
  198. {basic_memory-0.12.1 → basic_memory-0.12.2}/tests/mcp/test_tool_memory.py +0 -0
  199. {basic_memory-0.12.1 → basic_memory-0.12.2}/tests/mcp/test_tool_project_info.py +0 -0
  200. {basic_memory-0.12.1 → basic_memory-0.12.2}/tests/mcp/test_tool_read_note.py +0 -0
  201. {basic_memory-0.12.1 → basic_memory-0.12.2}/tests/mcp/test_tool_resource.py +0 -0
  202. {basic_memory-0.12.1 → basic_memory-0.12.2}/tests/mcp/test_tool_search.py +0 -0
  203. {basic_memory-0.12.1 → basic_memory-0.12.2}/tests/mcp/test_tool_utils.py +0 -0
  204. {basic_memory-0.12.1 → basic_memory-0.12.2}/tests/mcp/test_tool_write_note.py +0 -0
  205. {basic_memory-0.12.1 → basic_memory-0.12.2}/tests/repository/test_entity_repository.py +0 -0
  206. {basic_memory-0.12.1 → basic_memory-0.12.2}/tests/repository/test_observation_repository.py +0 -0
  207. {basic_memory-0.12.1 → basic_memory-0.12.2}/tests/repository/test_relation_repository.py +0 -0
  208. {basic_memory-0.12.1 → basic_memory-0.12.2}/tests/repository/test_repository.py +0 -0
  209. {basic_memory-0.12.1 → basic_memory-0.12.2}/tests/schemas/test_memory_url.py +0 -0
  210. {basic_memory-0.12.1 → basic_memory-0.12.2}/tests/schemas/test_schemas.py +0 -0
  211. {basic_memory-0.12.1 → basic_memory-0.12.2}/tests/schemas/test_search.py +0 -0
  212. {basic_memory-0.12.1 → basic_memory-0.12.2}/tests/services/test_context_service.py +0 -0
  213. {basic_memory-0.12.1 → basic_memory-0.12.2}/tests/services/test_entity_service.py +0 -0
  214. {basic_memory-0.12.1 → basic_memory-0.12.2}/tests/services/test_file_service.py +0 -0
  215. {basic_memory-0.12.1 → basic_memory-0.12.2}/tests/services/test_initialization.py +0 -0
  216. {basic_memory-0.12.1 → basic_memory-0.12.2}/tests/services/test_link_resolver.py +0 -0
  217. {basic_memory-0.12.1 → basic_memory-0.12.2}/tests/services/test_search_service.py +0 -0
  218. {basic_memory-0.12.1 → basic_memory-0.12.2}/tests/sync/test_sync_service.py +0 -0
  219. {basic_memory-0.12.1 → basic_memory-0.12.2}/tests/sync/test_sync_wikilink_issue.py +0 -0
  220. {basic_memory-0.12.1 → basic_memory-0.12.2}/tests/sync/test_watch_service_edge_cases.py +0 -0
  221. {basic_memory-0.12.1 → basic_memory-0.12.2}/tests/test_basic_memory.py +0 -0
  222. {basic_memory-0.12.1 → basic_memory-0.12.2}/tests/test_config.py +0 -0
  223. {basic_memory-0.12.1 → basic_memory-0.12.2}/tests/utils/test_parse_tags.py +0 -0
  224. {basic_memory-0.12.1 → basic_memory-0.12.2}/tests/utils/test_permalink_formatting.py +0 -0
  225. {basic_memory-0.12.1 → basic_memory-0.12.2}/tests/utils/test_utf8_handling.py +0 -0
@@ -1,6 +1,17 @@
1
1
  # CHANGELOG
2
2
 
3
3
 
4
+ ## v0.12.2 (2025-04-08)
5
+
6
+ ### Bug Fixes
7
+
8
+ - Utf8 for all file reads/write/open instead of default platform encoding
9
+ ([#91](https://github.com/basicmachines-co/basic-memory/pull/91),
10
+ [`2934176`](https://github.com/basicmachines-co/basic-memory/commit/29341763318408ea8f1e954a41046c4185f836c6))
11
+
12
+ Signed-off-by: phernandez <paul@basicmachines.co>
13
+
14
+
4
15
  ## v0.12.1 (2025-04-07)
5
16
 
6
17
  ### Bug Fixes
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: basic-memory
3
- Version: 0.12.1
3
+ Version: 0.12.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
@@ -44,7 +44,7 @@ def update_claude_config():
44
44
 
45
45
  # Load existing config or create new
46
46
  if config_path.exists():
47
- config = json.loads(config_path.read_text())
47
+ config = json.loads(config_path.read_text(encoding="utf-8"))
48
48
  else:
49
49
  config = {"mcpServers": {}}
50
50
 
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "basic-memory"
3
- version = "0.12.1"
3
+ version = "0.12.2"
4
4
  description = "Local-first knowledge management combining Zettelkasten with knowledge graphs"
5
5
  readme = "README.md"
6
6
  requires-python = ">=3.12.1"
@@ -1,3 +1,3 @@
1
1
  """basic-memory - Local-first knowledge management combining Zettelkasten with knowledge graphs"""
2
2
 
3
- __version__ = "0.12.1"
3
+ __version__ = "0.12.2"
@@ -38,7 +38,7 @@ async def process_memory_json(
38
38
  read_task = progress.add_task("Reading memory.json...", total=None)
39
39
 
40
40
  # First pass - collect entities and relations
41
- with open(json_path) as f:
41
+ with open(json_path, encoding="utf-8") as f:
42
42
  lines = f.readlines()
43
43
  progress.update(read_task, total=len(lines))
44
44
 
@@ -104,7 +104,7 @@ class EntityParser:
104
104
  absolute_path = self.base_path / path
105
105
 
106
106
  # Parse frontmatter and content using python-frontmatter
107
- file_content = absolute_path.read_text()
107
+ file_content = absolute_path.read_text(encoding="utf-8")
108
108
  return await self.parse_file_content(absolute_path, file_content)
109
109
 
110
110
  async def parse_file_content(self, absolute_path, file_content):
@@ -1,9 +1,8 @@
1
1
  """Service for syncing files between filesystem and database."""
2
2
 
3
3
  import os
4
-
5
- from dataclasses import dataclass
6
- from dataclasses import field
4
+ import time
5
+ from dataclasses import dataclass, field
7
6
  from datetime import datetime
8
7
  from pathlib import Path
9
8
  from typing import Dict, Optional, Set, Tuple
@@ -18,7 +17,6 @@ from basic_memory.models import Entity
18
17
  from basic_memory.repository import EntityRepository, RelationRepository
19
18
  from basic_memory.services import EntityService, FileService
20
19
  from basic_memory.services.search_service import SearchService
21
- import time
22
20
 
23
21
 
24
22
  @dataclass
@@ -237,7 +235,7 @@ class SyncService:
237
235
  logger.debug(f"Parsing markdown file, path: {path}, new: {new}")
238
236
 
239
237
  file_path = self.entity_parser.base_path / path
240
- file_content = file_path.read_text()
238
+ file_content = file_path.read_text(encoding="utf-8")
241
239
  file_contains_frontmatter = has_frontmatter(file_content)
242
240
 
243
241
  # entity markdown will always contain front matter, so it can be used up create/update the entity
@@ -2,9 +2,9 @@
2
2
 
3
3
  import json
4
4
  from datetime import datetime, timezone
5
+ from pathlib import Path
5
6
 
6
7
  import pytest
7
- from pathlib import Path
8
8
 
9
9
  from basic_memory.schemas import EntityResponse
10
10
 
@@ -346,7 +346,7 @@ async def test_put_resource_new_file(client, test_config, entity_repository, sea
346
346
  assert full_path.exists()
347
347
 
348
348
  # Verify file content
349
- file_content = full_path.read_text()
349
+ file_content = full_path.read_text(encoding="utf-8")
350
350
  assert json.loads(file_content) == canvas_data
351
351
 
352
352
  # Verify entity was created in DB
@@ -420,7 +420,7 @@ async def test_put_resource_update_existing(client, test_config, entity_reposito
420
420
  assert response.status_code == 200
421
421
 
422
422
  # Verify file was updated
423
- updated_content = full_path.read_text()
423
+ updated_content = full_path.read_text(encoding="utf-8")
424
424
  assert json.loads(updated_content) == updated_data
425
425
 
426
426
  # Verify entity was updated
@@ -1,10 +1,11 @@
1
1
  """Tests for import_chatgpt command."""
2
2
 
3
3
  import json
4
+
4
5
  import pytest
5
6
  from typer.testing import CliRunner
6
7
 
7
- from basic_memory.cli.app import import_app, app
8
+ from basic_memory.cli.app import app, import_app
8
9
  from basic_memory.cli.commands import import_chatgpt
9
10
  from basic_memory.config import config
10
11
  from basic_memory.markdown import EntityParser, MarkdownProcessor
@@ -144,7 +145,7 @@ def sample_conversation_with_hidden():
144
145
  def sample_chatgpt_json(tmp_path, sample_conversation):
145
146
  """Create a sample ChatGPT JSON file."""
146
147
  json_file = tmp_path / "conversations.json"
147
- with open(json_file, "w") as f:
148
+ with open(json_file, "w", encoding="utf-8") as f:
148
149
  json.dump([sample_conversation], f)
149
150
  return json_file
150
151
 
@@ -167,7 +168,7 @@ async def test_process_chatgpt_json(tmp_path, sample_chatgpt_json):
167
168
  assert conv_path.exists()
168
169
 
169
170
  # Check content formatting
170
- content = conv_path.read_text()
171
+ content = conv_path.read_text(encoding="utf-8")
171
172
  assert "# Test Conversation" in content
172
173
  assert "### User" in content
173
174
  assert "Hello, this is a test message" in content
@@ -183,14 +184,14 @@ async def test_process_code_blocks(tmp_path, sample_conversation_with_code):
183
184
 
184
185
  # Create test file
185
186
  json_file = tmp_path / "code_test.json"
186
- with open(json_file, "w") as f:
187
+ with open(json_file, "w", encoding="utf-8") as f:
187
188
  json.dump([sample_conversation_with_code], f)
188
189
 
189
190
  await import_chatgpt.process_chatgpt_json(json_file, tmp_path, processor)
190
191
 
191
192
  # Check content
192
193
  conv_path = tmp_path / "20250111-code-test.md"
193
- content = conv_path.read_text()
194
+ content = conv_path.read_text(encoding="utf-8")
194
195
  assert "```python" in content
195
196
  assert "def hello():" in content
196
197
  assert "```" in content
@@ -204,7 +205,7 @@ async def test_hidden_messages(tmp_path, sample_conversation_with_hidden):
204
205
 
205
206
  # Create test file
206
207
  json_file = tmp_path / "hidden_test.json"
207
- with open(json_file, "w") as f:
208
+ with open(json_file, "w", encoding="utf-8") as f:
208
209
  json.dump([sample_conversation_with_hidden], f)
209
210
 
210
211
  results = await import_chatgpt.process_chatgpt_json(json_file, tmp_path, processor)
@@ -214,7 +215,7 @@ async def test_hidden_messages(tmp_path, sample_conversation_with_hidden):
214
215
 
215
216
  # Check content
216
217
  conv_path = tmp_path / "20250111-hidden-test.md"
217
- content = conv_path.read_text()
218
+ content = conv_path.read_text(encoding="utf-8")
218
219
  assert "Visible message" in content
219
220
  assert "Hidden message" not in content
220
221
 
@@ -1,6 +1,7 @@
1
1
  """Tests for import_claude command (chat conversations)."""
2
2
 
3
3
  import json
4
+
4
5
  import pytest
5
6
  from typer.testing import CliRunner
6
7
 
@@ -44,7 +45,7 @@ def sample_conversation():
44
45
  def sample_conversations_json(tmp_path, sample_conversation):
45
46
  """Create a sample conversations.json file."""
46
47
  json_file = tmp_path / "conversations.json"
47
- with open(json_file, "w") as f:
48
+ with open(json_file, "w", encoding="utf-8") as f:
48
49
  json.dump([sample_conversation], f)
49
50
  return json_file
50
51
 
@@ -65,7 +66,7 @@ async def test_process_chat_json(tmp_path, sample_conversations_json):
65
66
  # Check conversation file
66
67
  conv_path = tmp_path / "20250105-test-conversation.md"
67
68
  assert conv_path.exists()
68
- content = conv_path.read_text()
69
+ content = conv_path.read_text(encoding="utf-8")
69
70
 
70
71
  # Check content formatting
71
72
  assert "### Human" in content
@@ -156,7 +157,7 @@ def test_import_conversation_with_attachments(tmp_path):
156
157
  }
157
158
 
158
159
  json_file = tmp_path / "with_attachments.json"
159
- with open(json_file, "w") as f:
160
+ with open(json_file, "w", encoding="utf-8") as f:
160
161
  json.dump([conversation], f)
161
162
 
162
163
  # Set up environment
@@ -168,7 +169,7 @@ def test_import_conversation_with_attachments(tmp_path):
168
169
 
169
170
  # Check attachment formatting
170
171
  conv_path = tmp_path / "conversations/20250105-test-with-attachments.md"
171
- content = conv_path.read_text()
172
+ content = conv_path.read_text(encoding="utf-8")
172
173
  assert "**Attachment: test.txt**" in content
173
174
  assert "```" in content
174
175
  assert "Test file content" in content
@@ -1,6 +1,7 @@
1
1
  """Tests for import_claude_projects command."""
2
2
 
3
3
  import json
4
+
4
5
  import pytest
5
6
  from typer.testing import CliRunner
6
7
 
@@ -43,7 +44,7 @@ def sample_project():
43
44
  def sample_projects_json(tmp_path, sample_project):
44
45
  """Create a sample projects.json file."""
45
46
  json_file = tmp_path / "projects.json"
46
- with open(json_file, "w") as f:
47
+ with open(json_file, "w", encoding="utf-8") as f:
47
48
  json.dump([sample_project], f)
48
49
  return json_file
49
50
 
@@ -70,14 +71,14 @@ async def test_process_projects_json(tmp_path, sample_projects_json):
70
71
  # Check document files
71
72
  doc1 = project_dir / "docs/test-document.md"
72
73
  assert doc1.exists()
73
- content1 = doc1.read_text()
74
+ content1 = doc1.read_text(encoding="utf-8")
74
75
  assert "# Test Document" in content1
75
76
  assert "This is test content" in content1
76
77
 
77
78
  # Check prompt template
78
79
  prompt = project_dir / "prompt-template.md"
79
80
  assert prompt.exists()
80
- prompt_content = prompt.read_text()
81
+ prompt_content = prompt.read_text(encoding="utf-8")
81
82
  assert "# Test Prompt" in prompt_content
82
83
  assert "This is a test prompt" in prompt_content
83
84
 
@@ -160,7 +161,7 @@ def test_import_project_without_prompt(tmp_path):
160
161
  }
161
162
 
162
163
  json_file = tmp_path / "no_prompt.json"
163
- with open(json_file, "w") as f:
164
+ with open(json_file, "w", encoding="utf-8") as f:
164
165
  json.dump([project], f)
165
166
 
166
167
  # Set up environment
@@ -1,6 +1,7 @@
1
1
  """Tests for import_memory_json command."""
2
2
 
3
3
  import json
4
+
4
5
  import pytest
5
6
  from typer.testing import CliRunner
6
7
 
@@ -35,7 +36,7 @@ def sample_entities():
35
36
  def sample_json_file(tmp_path, sample_entities):
36
37
  """Create a sample memory.json file."""
37
38
  json_file = tmp_path / "memory.json"
38
- with open(json_file, "w") as f:
39
+ with open(json_file, "w", encoding="utf-8") as f:
39
40
  for entity in sample_entities:
40
41
  f.write(json.dumps(entity) + "\n")
41
42
  return json_file
@@ -55,7 +56,7 @@ async def test_process_memory_json(tmp_path, sample_json_file):
55
56
  # Check file was created
56
57
  entity_file = tmp_path / "test/test_entity.md"
57
58
  assert entity_file.exists()
58
- content = entity_file.read_text()
59
+ content = entity_file.read_text(encoding="utf-8")
59
60
  assert "Test observation 1" in content
60
61
  assert "Test observation 2" in content
61
62
  assert "test_relation [[related_entity]]" in content
@@ -120,7 +121,7 @@ def test_import_json_command_handle_old_format(tmp_path):
120
121
  ]
121
122
 
122
123
  json_file = tmp_path / "old_format.json"
123
- with open(json_file, "w") as f:
124
+ with open(json_file, "w", encoding="utf-8") as f:
124
125
  for item in old_format:
125
126
  f.write(json.dumps(item) + "\n")
126
127
 
@@ -8,10 +8,10 @@ from pathlib import Path
8
8
 
9
9
  import pytest
10
10
 
11
- from basic_memory.markdown.markdown_processor import MarkdownProcessor, DirtyFileError
11
+ from basic_memory.markdown.markdown_processor import DirtyFileError, MarkdownProcessor
12
12
  from basic_memory.markdown.schemas import (
13
- EntityMarkdown,
14
13
  EntityFrontmatter,
14
+ EntityMarkdown,
15
15
  Observation,
16
16
  Relation,
17
17
  )
@@ -41,7 +41,7 @@ async def test_write_new_minimal_file(markdown_processor: MarkdownProcessor, tmp
41
41
  await markdown_processor.write_file(path, markdown)
42
42
 
43
43
  # Read back and verify
44
- content = path.read_text()
44
+ content = path.read_text(encoding="utf-8")
45
45
  assert "---" in content # Has frontmatter
46
46
  assert "type: note" in content
47
47
  assert "permalink: test" in content
@@ -90,7 +90,7 @@ async def test_write_new_file_with_content(markdown_processor: MarkdownProcessor
90
90
  await markdown_processor.write_file(path, markdown)
91
91
 
92
92
  # Read back and verify
93
- content = path.read_text()
93
+ content = path.read_text(encoding="utf-8")
94
94
 
95
95
  # Check content preserved exactly
96
96
  assert "# Custom Title" in content
@@ -169,7 +169,7 @@ async def test_dirty_file_detection(markdown_processor: MarkdownProcessor, tmp_p
169
169
  checksum = await markdown_processor.write_file(path, initial)
170
170
 
171
171
  # Modify file directly
172
- path.write_text(path.read_text() + "\nModified!")
172
+ path.write_text(path.read_text(encoding="utf-8") + "\nModified!")
173
173
 
174
174
  # Try to update with old checksum
175
175
  update = EntityMarkdown(
@@ -46,7 +46,7 @@ async def test_create_canvas(app, test_config):
46
46
  assert file_path.exists()
47
47
 
48
48
  # Verify content is correct
49
- content = json.loads(file_path.read_text())
49
+ content = json.loads(file_path.read_text(encoding="utf-8"))
50
50
  assert content["nodes"] == nodes
51
51
  assert content["edges"] == edges
52
52
 
@@ -81,7 +81,7 @@ async def test_create_canvas_with_extension(app, test_config):
81
81
  assert file_path.exists()
82
82
 
83
83
  # Verify content
84
- content = json.loads(file_path.read_text())
84
+ content = json.loads(file_path.read_text(encoding="utf-8"))
85
85
  assert content["nodes"] == nodes
86
86
 
87
87
 
@@ -134,7 +134,7 @@ async def test_update_existing_canvas(app, test_config):
134
134
  assert "Updated: visualizations/update-test.canvas" in result
135
135
 
136
136
  # Verify content was updated
137
- content = json.loads(file_path.read_text())
137
+ content = json.loads(file_path.read_text(encoding="utf-8"))
138
138
  assert content["nodes"] == updated_nodes
139
139
  assert content["edges"] == updated_edges
140
140
 
@@ -252,7 +252,7 @@ async def test_create_canvas_complex_content(app, test_config):
252
252
  assert file_path.exists()
253
253
 
254
254
  # Verify content is correct with all complex structures
255
- content = json.loads(file_path.read_text())
255
+ content = json.loads(file_path.read_text(encoding="utf-8"))
256
256
  assert len(content["nodes"]) == 4
257
257
  assert len(content["edges"]) == 2
258
258
 
@@ -144,14 +144,14 @@ async def test_rapid_atomic_writes(watch_service, test_config):
144
144
  await asyncio.sleep(0.1)
145
145
 
146
146
  # Read content to verify
147
- content1 = final_path.read_text()
147
+ content1 = final_path.read_text(encoding="utf-8")
148
148
  assert content1 == "First version"
149
149
 
150
150
  # Simulate the second atomic write
151
151
  tmp2_path.rename(final_path)
152
152
 
153
153
  # Verify content was updated
154
- content2 = final_path.read_text()
154
+ content2 = final_path.read_text(encoding="utf-8")
155
155
  assert content2 == "Second version"
156
156
 
157
157
  # Create a batch of changes that might arrive in mixed order
@@ -63,7 +63,7 @@ async def test_write_status(watch_service):
63
63
  await watch_service.write_status()
64
64
 
65
65
  assert watch_service.status_path.exists()
66
- data = json.loads(watch_service.status_path.read_text())
66
+ data = json.loads(watch_service.status_path.read_text(encoding="utf-8"))
67
67
  assert not data["running"]
68
68
  assert data["error_count"] == 0
69
69
 
@@ -5,16 +5,16 @@ from pathlib import Path
5
5
  import pytest
6
6
 
7
7
  from basic_memory.file_utils import (
8
+ FileError,
9
+ FileWriteError,
10
+ ParseError,
8
11
  compute_checksum,
9
12
  ensure_directory,
10
- write_file_atomic,
11
- parse_frontmatter,
12
13
  has_frontmatter,
14
+ parse_frontmatter,
13
15
  remove_frontmatter,
14
- FileError,
15
- FileWriteError,
16
- ParseError,
17
16
  update_frontmatter,
17
+ write_file_atomic,
18
18
  )
19
19
 
20
20
 
@@ -52,7 +52,7 @@ async def test_write_file_atomic(tmp_path: Path):
52
52
 
53
53
  await write_file_atomic(test_file, content)
54
54
  assert test_file.exists()
55
- assert test_file.read_text() == content
55
+ assert test_file.read_text(encoding="utf-8") == content
56
56
 
57
57
  # Temp file should be cleaned up
58
58
  assert not test_file.with_suffix(".tmp").exists()
@@ -185,7 +185,7 @@ async def test_update_frontmatter(tmp_path: Path):
185
185
  checksum = await update_frontmatter(test_file, updates)
186
186
 
187
187
  # Verify content
188
- updated = test_file.read_text()
188
+ updated = test_file.read_text(encoding="utf-8")
189
189
  assert "title: Test" in updated
190
190
  assert "type: note" in updated
191
191
  assert "Test Content" in updated
@@ -204,13 +204,13 @@ async def test_update_frontmatter(tmp_path: Path):
204
204
  assert new_checksum != checksum
205
205
 
206
206
  # Verify content
207
- updated = test_file.read_text()
207
+ updated = test_file.read_text(encoding="utf-8")
208
208
  fm = parse_frontmatter(updated)
209
209
  assert fm == {"title": "Test", "type": "doc", "tags": ["test"]}
210
210
  assert "Test Content" in updated
211
211
 
212
212
  # Test 3: Update with empty dict shouldn't change anything
213
- checksum_before = await compute_checksum(test_file.read_text())
213
+ checksum_before = await compute_checksum(test_file.read_text(encoding="utf-8"))
214
214
  new_checksum = await update_frontmatter(test_file, {})
215
215
  assert new_checksum == checksum_before
216
216
 
@@ -229,7 +229,7 @@ More content here"""
229
229
  test_file.write_text(content)
230
230
  await update_frontmatter(test_file, {"title": "Test"})
231
231
 
232
- updated = test_file.read_text()
232
+ updated = test_file.read_text(encoding="utf-8")
233
233
  assert remove_frontmatter(updated).strip() == content
234
234
 
235
235
 
@@ -71,7 +71,7 @@ wheels = [
71
71
 
72
72
  [[package]]
73
73
  name = "basic-memory"
74
- version = "0.12.0"
74
+ version = "0.12.1"
75
75
  source = { editable = "." }
76
76
  dependencies = [
77
77
  { name = "aiosqlite" },
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes