basic-memory 0.7.0__py3-none-any.whl → 0.17.4__py3-none-any.whl

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 (195) hide show
  1. basic_memory/__init__.py +5 -1
  2. basic_memory/alembic/alembic.ini +119 -0
  3. basic_memory/alembic/env.py +130 -20
  4. basic_memory/alembic/migrations.py +4 -9
  5. basic_memory/alembic/versions/314f1ea54dc4_add_postgres_full_text_search_support_.py +131 -0
  6. basic_memory/alembic/versions/502b60eaa905_remove_required_from_entity_permalink.py +51 -0
  7. basic_memory/alembic/versions/5fe1ab1ccebe_add_projects_table.py +120 -0
  8. basic_memory/alembic/versions/647e7a75e2cd_project_constraint_fix.py +112 -0
  9. basic_memory/alembic/versions/6830751f5fb6_merge_multiple_heads.py +24 -0
  10. basic_memory/alembic/versions/9d9c1cb7d8f5_add_mtime_and_size_columns_to_entity_.py +49 -0
  11. basic_memory/alembic/versions/a1b2c3d4e5f6_fix_project_foreign_keys.py +49 -0
  12. basic_memory/alembic/versions/a2b3c4d5e6f7_add_search_index_entity_cascade.py +56 -0
  13. basic_memory/alembic/versions/b3c3938bacdb_relation_to_name_unique_index.py +44 -0
  14. basic_memory/alembic/versions/cc7172b46608_update_search_index_schema.py +113 -0
  15. basic_memory/alembic/versions/e7e1f4367280_add_scan_watermark_tracking_to_project.py +37 -0
  16. basic_memory/alembic/versions/f8a9b2c3d4e5_add_pg_trgm_for_fuzzy_link_resolution.py +239 -0
  17. basic_memory/alembic/versions/g9a0b3c4d5e6_add_external_id_to_project_and_entity.py +173 -0
  18. basic_memory/api/app.py +87 -20
  19. basic_memory/api/container.py +133 -0
  20. basic_memory/api/routers/__init__.py +4 -1
  21. basic_memory/api/routers/directory_router.py +84 -0
  22. basic_memory/api/routers/importer_router.py +152 -0
  23. basic_memory/api/routers/knowledge_router.py +180 -23
  24. basic_memory/api/routers/management_router.py +80 -0
  25. basic_memory/api/routers/memory_router.py +9 -64
  26. basic_memory/api/routers/project_router.py +460 -0
  27. basic_memory/api/routers/prompt_router.py +260 -0
  28. basic_memory/api/routers/resource_router.py +136 -11
  29. basic_memory/api/routers/search_router.py +5 -5
  30. basic_memory/api/routers/utils.py +169 -0
  31. basic_memory/api/template_loader.py +292 -0
  32. basic_memory/api/v2/__init__.py +35 -0
  33. basic_memory/api/v2/routers/__init__.py +21 -0
  34. basic_memory/api/v2/routers/directory_router.py +93 -0
  35. basic_memory/api/v2/routers/importer_router.py +181 -0
  36. basic_memory/api/v2/routers/knowledge_router.py +427 -0
  37. basic_memory/api/v2/routers/memory_router.py +130 -0
  38. basic_memory/api/v2/routers/project_router.py +359 -0
  39. basic_memory/api/v2/routers/prompt_router.py +269 -0
  40. basic_memory/api/v2/routers/resource_router.py +286 -0
  41. basic_memory/api/v2/routers/search_router.py +73 -0
  42. basic_memory/cli/app.py +80 -10
  43. basic_memory/cli/auth.py +300 -0
  44. basic_memory/cli/commands/__init__.py +15 -2
  45. basic_memory/cli/commands/cloud/__init__.py +6 -0
  46. basic_memory/cli/commands/cloud/api_client.py +127 -0
  47. basic_memory/cli/commands/cloud/bisync_commands.py +110 -0
  48. basic_memory/cli/commands/cloud/cloud_utils.py +108 -0
  49. basic_memory/cli/commands/cloud/core_commands.py +195 -0
  50. basic_memory/cli/commands/cloud/rclone_commands.py +397 -0
  51. basic_memory/cli/commands/cloud/rclone_config.py +110 -0
  52. basic_memory/cli/commands/cloud/rclone_installer.py +263 -0
  53. basic_memory/cli/commands/cloud/upload.py +240 -0
  54. basic_memory/cli/commands/cloud/upload_command.py +124 -0
  55. basic_memory/cli/commands/command_utils.py +99 -0
  56. basic_memory/cli/commands/db.py +87 -12
  57. basic_memory/cli/commands/format.py +198 -0
  58. basic_memory/cli/commands/import_chatgpt.py +47 -223
  59. basic_memory/cli/commands/import_claude_conversations.py +48 -171
  60. basic_memory/cli/commands/import_claude_projects.py +53 -160
  61. basic_memory/cli/commands/import_memory_json.py +55 -111
  62. basic_memory/cli/commands/mcp.py +67 -11
  63. basic_memory/cli/commands/project.py +889 -0
  64. basic_memory/cli/commands/status.py +52 -34
  65. basic_memory/cli/commands/telemetry.py +81 -0
  66. basic_memory/cli/commands/tool.py +341 -0
  67. basic_memory/cli/container.py +84 -0
  68. basic_memory/cli/main.py +14 -6
  69. basic_memory/config.py +580 -26
  70. basic_memory/db.py +285 -28
  71. basic_memory/deps/__init__.py +293 -0
  72. basic_memory/deps/config.py +26 -0
  73. basic_memory/deps/db.py +56 -0
  74. basic_memory/deps/importers.py +200 -0
  75. basic_memory/deps/projects.py +238 -0
  76. basic_memory/deps/repositories.py +179 -0
  77. basic_memory/deps/services.py +480 -0
  78. basic_memory/deps.py +16 -185
  79. basic_memory/file_utils.py +318 -54
  80. basic_memory/ignore_utils.py +297 -0
  81. basic_memory/importers/__init__.py +27 -0
  82. basic_memory/importers/base.py +100 -0
  83. basic_memory/importers/chatgpt_importer.py +245 -0
  84. basic_memory/importers/claude_conversations_importer.py +192 -0
  85. basic_memory/importers/claude_projects_importer.py +184 -0
  86. basic_memory/importers/memory_json_importer.py +128 -0
  87. basic_memory/importers/utils.py +61 -0
  88. basic_memory/markdown/entity_parser.py +182 -23
  89. basic_memory/markdown/markdown_processor.py +70 -7
  90. basic_memory/markdown/plugins.py +43 -23
  91. basic_memory/markdown/schemas.py +1 -1
  92. basic_memory/markdown/utils.py +38 -14
  93. basic_memory/mcp/async_client.py +135 -4
  94. basic_memory/mcp/clients/__init__.py +28 -0
  95. basic_memory/mcp/clients/directory.py +70 -0
  96. basic_memory/mcp/clients/knowledge.py +176 -0
  97. basic_memory/mcp/clients/memory.py +120 -0
  98. basic_memory/mcp/clients/project.py +89 -0
  99. basic_memory/mcp/clients/resource.py +71 -0
  100. basic_memory/mcp/clients/search.py +65 -0
  101. basic_memory/mcp/container.py +110 -0
  102. basic_memory/mcp/project_context.py +155 -0
  103. basic_memory/mcp/prompts/__init__.py +19 -0
  104. basic_memory/mcp/prompts/ai_assistant_guide.py +70 -0
  105. basic_memory/mcp/prompts/continue_conversation.py +62 -0
  106. basic_memory/mcp/prompts/recent_activity.py +188 -0
  107. basic_memory/mcp/prompts/search.py +57 -0
  108. basic_memory/mcp/prompts/utils.py +162 -0
  109. basic_memory/mcp/resources/ai_assistant_guide.md +283 -0
  110. basic_memory/mcp/resources/project_info.py +71 -0
  111. basic_memory/mcp/server.py +61 -9
  112. basic_memory/mcp/tools/__init__.py +33 -21
  113. basic_memory/mcp/tools/build_context.py +120 -0
  114. basic_memory/mcp/tools/canvas.py +152 -0
  115. basic_memory/mcp/tools/chatgpt_tools.py +190 -0
  116. basic_memory/mcp/tools/delete_note.py +249 -0
  117. basic_memory/mcp/tools/edit_note.py +325 -0
  118. basic_memory/mcp/tools/list_directory.py +157 -0
  119. basic_memory/mcp/tools/move_note.py +549 -0
  120. basic_memory/mcp/tools/project_management.py +204 -0
  121. basic_memory/mcp/tools/read_content.py +281 -0
  122. basic_memory/mcp/tools/read_note.py +265 -0
  123. basic_memory/mcp/tools/recent_activity.py +528 -0
  124. basic_memory/mcp/tools/search.py +377 -24
  125. basic_memory/mcp/tools/utils.py +402 -16
  126. basic_memory/mcp/tools/view_note.py +78 -0
  127. basic_memory/mcp/tools/write_note.py +230 -0
  128. basic_memory/models/__init__.py +3 -2
  129. basic_memory/models/knowledge.py +82 -17
  130. basic_memory/models/project.py +93 -0
  131. basic_memory/models/search.py +68 -8
  132. basic_memory/project_resolver.py +222 -0
  133. basic_memory/repository/__init__.py +2 -0
  134. basic_memory/repository/entity_repository.py +437 -8
  135. basic_memory/repository/observation_repository.py +36 -3
  136. basic_memory/repository/postgres_search_repository.py +451 -0
  137. basic_memory/repository/project_info_repository.py +10 -0
  138. basic_memory/repository/project_repository.py +140 -0
  139. basic_memory/repository/relation_repository.py +79 -4
  140. basic_memory/repository/repository.py +148 -29
  141. basic_memory/repository/search_index_row.py +95 -0
  142. basic_memory/repository/search_repository.py +79 -268
  143. basic_memory/repository/search_repository_base.py +241 -0
  144. basic_memory/repository/sqlite_search_repository.py +437 -0
  145. basic_memory/runtime.py +61 -0
  146. basic_memory/schemas/__init__.py +22 -9
  147. basic_memory/schemas/base.py +131 -12
  148. basic_memory/schemas/cloud.py +50 -0
  149. basic_memory/schemas/directory.py +31 -0
  150. basic_memory/schemas/importer.py +35 -0
  151. basic_memory/schemas/memory.py +194 -25
  152. basic_memory/schemas/project_info.py +213 -0
  153. basic_memory/schemas/prompt.py +90 -0
  154. basic_memory/schemas/request.py +56 -2
  155. basic_memory/schemas/response.py +85 -28
  156. basic_memory/schemas/search.py +36 -35
  157. basic_memory/schemas/sync_report.py +72 -0
  158. basic_memory/schemas/v2/__init__.py +27 -0
  159. basic_memory/schemas/v2/entity.py +133 -0
  160. basic_memory/schemas/v2/resource.py +47 -0
  161. basic_memory/services/__init__.py +2 -1
  162. basic_memory/services/context_service.py +451 -138
  163. basic_memory/services/directory_service.py +310 -0
  164. basic_memory/services/entity_service.py +636 -71
  165. basic_memory/services/exceptions.py +21 -0
  166. basic_memory/services/file_service.py +402 -33
  167. basic_memory/services/initialization.py +216 -0
  168. basic_memory/services/link_resolver.py +50 -56
  169. basic_memory/services/project_service.py +888 -0
  170. basic_memory/services/search_service.py +232 -37
  171. basic_memory/sync/__init__.py +4 -2
  172. basic_memory/sync/background_sync.py +26 -0
  173. basic_memory/sync/coordinator.py +160 -0
  174. basic_memory/sync/sync_service.py +1200 -109
  175. basic_memory/sync/watch_service.py +432 -135
  176. basic_memory/telemetry.py +249 -0
  177. basic_memory/templates/prompts/continue_conversation.hbs +110 -0
  178. basic_memory/templates/prompts/search.hbs +101 -0
  179. basic_memory/utils.py +407 -54
  180. basic_memory-0.17.4.dist-info/METADATA +617 -0
  181. basic_memory-0.17.4.dist-info/RECORD +193 -0
  182. {basic_memory-0.7.0.dist-info → basic_memory-0.17.4.dist-info}/WHEEL +1 -1
  183. {basic_memory-0.7.0.dist-info → basic_memory-0.17.4.dist-info}/entry_points.txt +1 -0
  184. basic_memory/alembic/README +0 -1
  185. basic_memory/cli/commands/sync.py +0 -206
  186. basic_memory/cli/commands/tools.py +0 -157
  187. basic_memory/mcp/tools/knowledge.py +0 -68
  188. basic_memory/mcp/tools/memory.py +0 -170
  189. basic_memory/mcp/tools/notes.py +0 -202
  190. basic_memory/schemas/discovery.py +0 -28
  191. basic_memory/sync/file_change_scanner.py +0 -158
  192. basic_memory/sync/utils.py +0 -31
  193. basic_memory-0.7.0.dist-info/METADATA +0 -378
  194. basic_memory-0.7.0.dist-info/RECORD +0 -82
  195. {basic_memory-0.7.0.dist-info → basic_memory-0.17.4.dist-info}/licenses/LICENSE +0 -0
@@ -0,0 +1,193 @@
1
+ basic_memory/__init__.py,sha256=55IxjGVPeNkok9zorXtokzrcp9xuZvceZg3jyJGMFAk,256
2
+ basic_memory/config.py,sha256=c7RgGVADQ2CKWMygUtgYFzaHVt8S5G-owzkgfLIrMuI,22882
3
+ basic_memory/db.py,sha256=8pYSA7_RzXr83rzh_SIm5XHIihc_UDgqJDgKJcv7Qiw,15926
4
+ basic_memory/deps.py,sha256=fbn9z1A6sDwSNx4RuSmXYpBysTKqNDv2XL0UqNS6LaI,680
5
+ basic_memory/file_utils.py,sha256=EJzuL3rHNcZhszebDbbMKrCZhyPCLxoJSTSapmL2vFQ,13908
6
+ basic_memory/ignore_utils.py,sha256=82KS-7bkKH70lr9ebDeoTuJ0b39sX0WDNxeOkqfrrUc,7865
7
+ basic_memory/project_resolver.py,sha256=4spoIJBd20PEAGi0AliB7BXTpqxieoMOQ8N6bkcULOo,7892
8
+ basic_memory/runtime.py,sha256=Zfk0-xVPWWdJFklx6fNDv9HmpT3_3pY3jxGmyl2goFY,1786
9
+ basic_memory/telemetry.py,sha256=rcpXrrQIU8WKIA9Kj-MoR7fr5NfnfuuJy4YhhaCI7OA,7346
10
+ basic_memory/utils.py,sha256=jr1ft-XqtE8PGznULSyas5ZNGTE7BJ9Cls040ezVJeM,16823
11
+ basic_memory/alembic/alembic.ini,sha256=IEZsnF8CbbZnkwBr67LzKKNobHuzTaQNUvM8Psop5xc,3733
12
+ basic_memory/alembic/env.py,sha256=JIa6un7jKBzo7yD13NtTZg253AQ98Sa1b4Y4-ildRj8,6800
13
+ basic_memory/alembic/migrations.py,sha256=lriHPXDdBLSNXEW3QTpU0SJKuVd1V-8NrVkpN3qfsUQ,718
14
+ basic_memory/alembic/script.py.mako,sha256=MEqL-2qATlST9TAOeYgscMn1uy6HUS9NFvDgl93dMj8,635
15
+ basic_memory/alembic/versions/314f1ea54dc4_add_postgres_full_text_search_support_.py,sha256=n5Cm7iW-POJtIFCgWufRpTwDiewTMp-Wuwcxk5xT6ZE,5276
16
+ basic_memory/alembic/versions/3dae7c7b1564_initial_schema.py,sha256=lTbWlAnd1es7xU99DoJgfaRe1_Kte8TL98riqeKGV80,4363
17
+ basic_memory/alembic/versions/502b60eaa905_remove_required_from_entity_permalink.py,sha256=k6xYTmYPM9Ros-7CA7BwZBKYwoK_gmVdC-2n8FAjdoE,1840
18
+ basic_memory/alembic/versions/5fe1ab1ccebe_add_projects_table.py,sha256=xTSVvB-caYl_CdVfzhj-eqdQEOxQ12NIHOc8dBSqCMQ,4779
19
+ basic_memory/alembic/versions/647e7a75e2cd_project_constraint_fix.py,sha256=oFtjzJd37HUMezuCUonK-yRc867_9L5zxd4CnLhFIi4,4655
20
+ basic_memory/alembic/versions/6830751f5fb6_merge_multiple_heads.py,sha256=Eosn3aWG8jLlVBoBfi2oA-QmcrcIsH-c4eVWtLctxTc,499
21
+ basic_memory/alembic/versions/9d9c1cb7d8f5_add_mtime_and_size_columns_to_entity_.py,sha256=DYlXlRYO3Ms6x9GbrFGWgj1QEzsdKHx-4AA4lSVM7y0,1587
22
+ basic_memory/alembic/versions/a1b2c3d4e5f6_fix_project_foreign_keys.py,sha256=i42eQyO08RWf4exnH1q1PKw_EJFsHAG-T4pdLTMSpiA,1818
23
+ basic_memory/alembic/versions/a2b3c4d5e6f7_add_search_index_entity_cascade.py,sha256=Oh_J5Jw85J3LvknfizFP7_1SoelZM_A7IjBau8lRpfk,1671
24
+ basic_memory/alembic/versions/b3c3938bacdb_relation_to_name_unique_index.py,sha256=RsGymQzfRXV1LSNKiyi0lMilTxW1NgwS9jR67ye2apI,1428
25
+ basic_memory/alembic/versions/cc7172b46608_update_search_index_schema.py,sha256=ZJm9nSbCJUNJxdbZNMx0JUwSYKttP8hJqMEuxVE4rsM,4124
26
+ basic_memory/alembic/versions/e7e1f4367280_add_scan_watermark_tracking_to_project.py,sha256=hQaX7qf0ZYYz3zoEDp_DOHy-RteYjajlAdD2GNXvYt0,1114
27
+ basic_memory/alembic/versions/f8a9b2c3d4e5_add_pg_trgm_for_fuzzy_link_resolution.py,sha256=6dHMYwsFlKqPlG4HUrKm56MyRBu2dvvuw8xY4UzVDro,9417
28
+ basic_memory/alembic/versions/g9a0b3c4d5e6_add_external_id_to_project_and_entity.py,sha256=SOmnmHsv_eV1co3P_GFF0_CyTBVDR6HZ3P2Xt_eUP3E,6695
29
+ basic_memory/api/__init__.py,sha256=wCpj-21j1D0KzKl9Ql6unLBVFY0K1uGp_FeSZRKtqpk,72
30
+ basic_memory/api/app.py,sha256=2UlLbnOZcyEmQq5S9PZ7vq6jEmF1kAmi2Aq-13gZpVc,4290
31
+ basic_memory/api/container.py,sha256=OctctAOuqqaNT9ByyY_6Ka94Co0ay1FplhUUQRky6G8,4210
32
+ basic_memory/api/template_loader.py,sha256=exbTeXyJRgyLFmSjNeroxjT7X2DWFm2X5qUVa3drbYM,8607
33
+ basic_memory/api/routers/__init__.py,sha256=REO5CKQ96o5vtGWACcsIxIpWybIUSeKXc83RWbWc8BQ,398
34
+ basic_memory/api/routers/directory_router.py,sha256=eKl9P6uYZnmA4J58ZPydbLkDPtiYH_84LcVFclkL364,2832
35
+ basic_memory/api/routers/importer_router.py,sha256=xFUCorkPWo8AF0ya0UrcLmXNf8CjPZdAqddQIH8PO-o,4513
36
+ basic_memory/api/routers/knowledge_router.py,sha256=WoIcKSo1yl1zOuhi9XNAawrtGL0nOXauKWa1sZldDdw,10753
37
+ basic_memory/api/routers/management_router.py,sha256=zbzilNzsYUbFbE2uFXRM33cDn9IbI-73y8C1-b-19O4,2730
38
+ basic_memory/api/routers/memory_router.py,sha256=a9Cnx3XgwSkO-2ABFzI3wM3PoMGxuyfJFFp7NfFZapc,3003
39
+ basic_memory/api/routers/project_router.py,sha256=IkFYsy4q5kJIue4jiZrZF_hJGsAeUBfrV0FNZHi14qs,17004
40
+ basic_memory/api/routers/prompt_router.py,sha256=4wxq6-NREgVJM8N9C0YsN1AAUDD8nkTCOzWyzSqTSFw,9948
41
+ basic_memory/api/routers/resource_router.py,sha256=m1olee0Rvsv86qYYmPLfIDK8tGaVWzk-XjDhn3wLHkI,9509
42
+ basic_memory/api/routers/search_router.py,sha256=GD62jlCQTiL_VNsdibi-b1f6H40KCWo9SX2Cl7YH4QU,1226
43
+ basic_memory/api/routers/utils.py,sha256=hpGLULvohK12G8f6RePjtL02NEiu0xuNFJNBPIMvsdY,6843
44
+ basic_memory/api/v2/__init__.py,sha256=7Q7bFdq3D55hjzpMVMGOfSWCfYcOejGdvSp7y0hires,850
45
+ basic_memory/api/v2/routers/__init__.py,sha256=GlaI2T99TKXha151DVU48GcdIe_nOQcBIX2JXMrYpTM,863
46
+ basic_memory/api/v2/routers/directory_router.py,sha256=Lhz_8M3Iy9B58co_PvI6ZkkVdYaw8npZq06tjoyhODA,3266
47
+ basic_memory/api/v2/routers/importer_router.py,sha256=tJuD1nyREuDqpaeAkIBW0zuNhY8YZetHgMBxeYhIado,5912
48
+ basic_memory/api/v2/routers/knowledge_router.py,sha256=BmkcEIZn08wQBOXY_VnuIIwBCavYKiE_VgZCwIOcnMU,14403
49
+ basic_memory/api/v2/routers/memory_router.py,sha256=iDqmEPG-KKTVQMCS-PH2u4s4CCzPDdBU795irty8CeU,4866
50
+ basic_memory/api/v2/routers/project_router.py,sha256=JzhLqzwBheOLzkoozqt06hY5Snu1EV8chSSQBuF3F5I,13271
51
+ basic_memory/api/v2/routers/prompt_router.py,sha256=_PRBH4oTB41FdoEzivSbZEwIdeCQ6idBZzNqZ4nw0cY,10486
52
+ basic_memory/api/v2/routers/resource_router.py,sha256=QyG3fz1yqRS4yuPI73L9I35g0IxQ8qa5FZ-gphNb6cY,11275
53
+ basic_memory/api/v2/routers/search_router.py,sha256=Kl2MY3CKlajt9T7jRXZ5mi9obpwVO5ok0goFQ3EZ3z4,2562
54
+ basic_memory/cli/__init__.py,sha256=arcKLAWRDhPD7x5t80MlviZeYzwHZ0GZigyy3NKVoGk,33
55
+ basic_memory/cli/app.py,sha256=vyIpfr-uQLCY9bIA3ZEJrgFHFgRH_YqpPkw07vc1YzU,2976
56
+ basic_memory/cli/auth.py,sha256=AucC3aDubkqhXZ_gSitm19Gzoz2paFOmp3MIOdVRCKo,11448
57
+ basic_memory/cli/container.py,sha256=5On9FlnUhlOO9k1b2FKsMsZRrS8p7RjOejHSF7o-IBM,2352
58
+ basic_memory/cli/main.py,sha256=B5U7OzW7HF7NcwFUIzJZErJDt7yzBTPTCC5IvcEIx2Y,682
59
+ basic_memory/cli/commands/__init__.py,sha256=g6Hyl8lqPytwLT1o7QOtRUJTla5_D4FxmMvVpurE7iU,425
60
+ basic_memory/cli/commands/command_utils.py,sha256=FFA_JBjIPB5bW5RevePJq5kFP1RSlTA9bOm9AE4wX3c,3311
61
+ basic_memory/cli/commands/db.py,sha256=BNPbx6gwctYUG3VkbhAel3faYOhHAz_48XhsF5M8K18,4219
62
+ basic_memory/cli/commands/format.py,sha256=pywqgO1U-WHR1gg56m-KFMQojYIsMJ5OlawtKStSiiA,6650
63
+ basic_memory/cli/commands/import_chatgpt.py,sha256=X01TUQvlX6e84vcNZ3WH-Hqy3lEvhfkzzFAUWFCFdvo,3233
64
+ basic_memory/cli/commands/import_claude_conversations.py,sha256=7L5bJ7G_Oaovuye0-ReoB8J3yPcL7H1jGO90qAoCUAY,3323
65
+ basic_memory/cli/commands/import_claude_projects.py,sha256=mQYYr51YMKQZF4Q1iWQj9XRZdo88soO-uTc8f-grBQ8,3268
66
+ basic_memory/cli/commands/import_memory_json.py,sha256=ELif785gzrmsHsafdRZTEG8RkXAonR6Ll7ExihjXHH4,3244
67
+ basic_memory/cli/commands/mcp.py,sha256=uoAtkg7kFYk6yVpi39R_ZeBW8dXuWche31mHROb7IEA,2904
68
+ basic_memory/cli/commands/project.py,sha256=MXyzWxdZIO8ilABatHYdA4KNVXvFzEV-4dOHyHOpohU,34596
69
+ basic_memory/cli/commands/status.py,sha256=ByT7NdupMwKW1dJaDSssgkzCpi17ljEY8OZIoQ7bAhQ,6654
70
+ basic_memory/cli/commands/telemetry.py,sha256=I5gKaAPsyU7wZOjrdQmEj1HCDlD9U7ZYF031fVCyLkw,2388
71
+ basic_memory/cli/commands/tool.py,sha256=8bsbYfaYEfAEvLfciQx1fZ0vssgbahMvrbmWzYg9188,11971
72
+ basic_memory/cli/commands/cloud/__init__.py,sha256=WYDh_GRqKMqhQI21maV2RD1QsDdkgzvRrV9XWa0MJf4,353
73
+ basic_memory/cli/commands/cloud/api_client.py,sha256=eNCARB-F9WNi-zftgAdFT4kdbXvpY3c5lLMCmSXGt1g,4876
74
+ basic_memory/cli/commands/cloud/bisync_commands.py,sha256=5ARgesF8-ODGbghvEjIHuTXI6HxoURPpx5VtNotE5xQ,3916
75
+ basic_memory/cli/commands/cloud/cloud_utils.py,sha256=2D9IkfPZC6z4lpsdibBNDFYI77c_2QV4iI8EIxRy38c,3242
76
+ basic_memory/cli/commands/cloud/core_commands.py,sha256=rkCiK1zz2j_xdvk-_oDw_mvuA9cHol5maFpIWHapE6Q,7371
77
+ basic_memory/cli/commands/cloud/rclone_commands.py,sha256=actXulg5qInIlsjzryNHHXV1zweV6e0se2hyIGtiGo4,11674
78
+ basic_memory/cli/commands/cloud/rclone_config.py,sha256=b-1RZB1zMY_IDyT1uhVm39Cee3flfp5nbJs7Lm7QkcM,3272
79
+ basic_memory/cli/commands/cloud/rclone_installer.py,sha256=xqyIhiq-4PMYxTdKO9o09OTN62IhX0nplM-Td4UwxuU,9886
80
+ basic_memory/cli/commands/cloud/upload.py,sha256=BUHemmjxXJfyhd9stvwS8TxblvkIHoNbXQKlOBYICzg,8738
81
+ basic_memory/cli/commands/cloud/upload_command.py,sha256=Mdzm5U2m_5DqOyJ9DNeO-xrDn1e5dIm4Ep-zfXcUlDs,4183
82
+ basic_memory/deps/__init__.py,sha256=Jt78_kI_A3XtfanlGc9s4BXzDnVtPipw4lmthci1P48,8574
83
+ basic_memory/deps/config.py,sha256=LpMW-64kpm4brZQiQ6UyNK4xNtktC04Egm54a6c9KTk,806
84
+ basic_memory/deps/db.py,sha256=aqGxP0Ort6PKUjslrngkK5CFXCKrDxPtKbB34ThxUDo,1773
85
+ basic_memory/deps/importers.py,sha256=XMK6S-gPy0FaIMeBU4UXwduV_RMFr8p_wxe7cPTV3Lg,6514
86
+ basic_memory/deps/projects.py,sha256=g0Bb7TuqNNi2UJD35TOj-H0W7fYpy9YifwJXwPfae4s,7318
87
+ basic_memory/deps/repositories.py,sha256=y8-xUbI3VQw7o75b1nazmfx7oH_87KYQqM5RfBHwlck,5729
88
+ basic_memory/deps/services.py,sha256=l1Sb9IpRUPDw--aNCAmX3dp2UwOyyQ575PZSQl7CngQ,15323
89
+ basic_memory/importers/__init__.py,sha256=BTcBW97P3thcsWa5w9tQsvOu8ynHDgw2-8tPgkCZoh8,795
90
+ basic_memory/importers/base.py,sha256=fqGrGP7dgHFmKyjXJRfHqPBUutw_YihgvrhQMxh_Cqo,3477
91
+ basic_memory/importers/chatgpt_importer.py,sha256=mM8niTx08FxyMJSaXnwKyDutdpptfzdoVwJTHznxYew,8145
92
+ basic_memory/importers/claude_conversations_importer.py,sha256=Rf_zRfqTwvOSm8zdhjnn2JTRUV4eDL9r_VaJtEE4NkE,6525
93
+ basic_memory/importers/claude_projects_importer.py,sha256=xRxJgAMMTej2q1bWyoSLMk8qOLdmuv3t8s1GJae6Z2Q,6796
94
+ basic_memory/importers/memory_json_importer.py,sha256=61uk8A3QVSumOUBviuH97PMuPbGKqZqDNwZ8_iBNRLE,5479
95
+ basic_memory/importers/utils.py,sha256=nTrxEkLL3gsUQVDKahVnYTr-p4CVRQIJnV2naF8Jlnc,1915
96
+ basic_memory/markdown/__init__.py,sha256=DdzioCWtDnKaq05BHYLgL_78FawEHLpLXnp-kPSVfIc,501
97
+ basic_memory/markdown/entity_parser.py,sha256=Ij8uKKrIpFylHBSw_4mVPLUow3mNmGDhJRDuR7S55oY,9535
98
+ basic_memory/markdown/markdown_processor.py,sha256=YK8KF8NY0N9nQM3I_8Pcxybf5SPOPnIL5kzmFBFBlx0,7429
99
+ basic_memory/markdown/plugins.py,sha256=r9IZh5EJwa2tgSvYVm6PltcbepRMGANlZc7UDWreSBI,7613
100
+ basic_memory/markdown/schemas.py,sha256=eyxYCr1hVyWmImcle0asE5It_DD6ARkqaBZYu1KK5n4,1896
101
+ basic_memory/markdown/utils.py,sha256=aNaeG0Qb74gac9fIuPg6GGH-VTjTap4WlyOIP49cUAs,3742
102
+ basic_memory/mcp/__init__.py,sha256=dsDOhKqjYeIbCULbHIxfcItTbqudEuEg1Np86eq0GEQ,35
103
+ basic_memory/mcp/async_client.py,sha256=8xcVEKWzbRJ5vy5AH86Vumu8ZDkHTI8NgCKzIfH52iQ,5270
104
+ basic_memory/mcp/container.py,sha256=S4u3utsGLr3vHVuQ5zZP2HMCPzlFpDX68h-5-uMfdeA,3341
105
+ basic_memory/mcp/project_context.py,sha256=yD_UtAdSKlc1u1rCtk84WvnQE1-EevCJPevroaU3WDE,5999
106
+ basic_memory/mcp/server.py,sha256=J-awXNkGsJFbnGInbzASyCoNFiiRpHPy-8NMldmMt_U,2151
107
+ basic_memory/mcp/clients/__init__.py,sha256=YFHUJFnCSfm1gvxtuMaa2NxCjfi97_6Pr5LuY2jQLrc,953
108
+ basic_memory/mcp/clients/directory.py,sha256=FVBG0zLL0-PiNkAI6D_y-UPVnR1FnyICQBhIA11w-K8,1978
109
+ basic_memory/mcp/clients/knowledge.py,sha256=lArEEJUAFim7ngAU0rd5u2rLl1DrslQLxc-I3yL6j-4,5455
110
+ basic_memory/mcp/clients/memory.py,sha256=YmrJY_14cnSNxg7JPp33xMQjH2knqLf9cisG6tnNxjI,3530
111
+ basic_memory/mcp/clients/project.py,sha256=_mPBAVUtELxYnEHL07tNPNcMaPWrUuUffTpaLQhagik,2571
112
+ basic_memory/mcp/clients/resource.py,sha256=iP8ZbEG0YSoBVPKzzeklA0TMC8c5QwuSF0TQL2qMsRI,2135
113
+ basic_memory/mcp/clients/search.py,sha256=QnY943gy1DhXBrE-gGqCrfM6Mm8SNEFw-uoXl_7xHIQ,1908
114
+ basic_memory/mcp/prompts/__init__.py,sha256=-Bl9Dgj2TD9PULjzggPqXuvPEjWCRy7S9Yg03h2-U7A,615
115
+ basic_memory/mcp/prompts/ai_assistant_guide.py,sha256=e_p5mFFR5DrYgxtImN8he2RcF3t_ihbzJVO0fRqx8IA,2598
116
+ basic_memory/mcp/prompts/continue_conversation.py,sha256=L-f_hKIBWnILzmYuQii948EdXyDSYh1qWVQAbJQU3l8,2097
117
+ basic_memory/mcp/prompts/recent_activity.py,sha256=esu423j_kyr9e-TM-_FFcoomqohU0nJLuD6Fiozy1Bs,6506
118
+ basic_memory/mcp/prompts/search.py,sha256=QCX8fOI-BBxHSzPBvvVq6jZPklPO1jHG0560LVkks98,1775
119
+ basic_memory/mcp/prompts/utils.py,sha256=jFF7PmuE6TznsF8v0lMuHm_ID48aSQKJHj8roOMX9Sg,5793
120
+ basic_memory/mcp/resources/ai_assistant_guide.md,sha256=u3vjEgCQvVTbOqEGx6lnu-KJDBDgx22SimCy4h0KxFg,7286
121
+ basic_memory/mcp/resources/project_info.py,sha256=68Z00eE4bxBK6PB3uf4abQXaMIcBPIONuHfF3VsEtLA,2553
122
+ basic_memory/mcp/tools/__init__.py,sha256=NjY89Ap0-ApZHNKmRLOWxwrMGcNhjHp5B-FYeWcNvAs,1513
123
+ basic_memory/mcp/tools/build_context.py,sha256=ESwWMNCSXtqMkthzDckmcHvVaSuAIbsxpHZWxg3RZ48,4733
124
+ basic_memory/mcp/tools/canvas.py,sha256=Ee-Q-22I_VjCPUQeGik7Anx6g4YoLyAmaE0ugBsEO1s,5729
125
+ basic_memory/mcp/tools/chatgpt_tools.py,sha256=_YwrMqqcszvRe-xg38PHMzLWGLGJibvCNntAV1gREfo,7019
126
+ basic_memory/mcp/tools/delete_note.py,sha256=rn6Q8JE5MeWVz0_KfXJB8Fm2-yxubqkKxL3BUKJ3Z_k,10232
127
+ basic_memory/mcp/tools/edit_note.py,sha256=1QkSis7USwz7WXFdAwnaJP_OfaEj_0Mcz5riOKc6OrI,15683
128
+ basic_memory/mcp/tools/list_directory.py,sha256=5FlVXR7WLwAQg5LgxCXW_bg_o9n5xfaCXXQfTVXaTdc,5863
129
+ basic_memory/mcp/tools/move_note.py,sha256=5vshdyAmgoXnnRSuxqvmducKmvu0aCtxWwDTSZkF27c,21851
130
+ basic_memory/mcp/tools/project_management.py,sha256=MRZFaMjUQ6toUMcpnCcTXdYnHaOApoEm8bQF9QaHXSw,8202
131
+ basic_memory/mcp/tools/read_content.py,sha256=j9uBIb6fcM5VVYskLviA47j3KfDvDs_miPmDmDbK-NU,10496
132
+ basic_memory/mcp/tools/read_note.py,sha256=WbfECgyG-Rd3Wv9rggpBPI3jnsdJqU3sf5UX0DFVq-Q,9971
133
+ basic_memory/mcp/tools/recent_activity.py,sha256=WtGUnIS4wLteo-7IcOfyvDrl9BYUqZ5tTlHmTYyJha8,21071
134
+ basic_memory/mcp/tools/search.py,sha256=vvliypUf-PH5jOWpUa6eACkarjEBy4lcwfdZ-h1TDUc,17182
135
+ basic_memory/mcp/tools/utils.py,sha256=3-5Y0EBU3bPbBfvXqzisVZOIaZt6lJ4EGxWmApODHuo,19304
136
+ basic_memory/mcp/tools/view_note.py,sha256=3Icz9RlTybbt5Acn5DwbZQxvCr8V4UlegH_7NMnpe4s,2523
137
+ basic_memory/mcp/tools/write_note.py,sha256=Q0KVxz2ttjrTR9JR_VNmXCu5TI5-Kf7ohx34pkzOm4M,9717
138
+ basic_memory/models/__init__.py,sha256=j0C4dtFi-FOEaQKR8dQWEG-dJtdQ15NBTiJg4nbIXNU,333
139
+ basic_memory/models/base.py,sha256=4hAXJ8CE1RnjKhb23lPd-QM7G_FXIdTowMJ9bRixspU,225
140
+ basic_memory/models/knowledge.py,sha256=hYH7zSyWFZFjncjd70A26PJB44piGUKkKZ1P0lkn9as,8862
141
+ basic_memory/models/project.py,sha256=9QZz8VVush3flf_CCibBmZ8n_WEq6xpMrrjH8bmHxvg,3408
142
+ basic_memory/models/search.py,sha256=OsZFTQlo5UUJnOxfW8KE9HxflxQTVTqE473AncNsCXQ,3527
143
+ basic_memory/repository/__init__.py,sha256=MWK-o8QikqzOpe5SyPbKQ2ioB5BWA0Upz65tgg-E0DU,327
144
+ basic_memory/repository/entity_repository.py,sha256=dlUOI_yjH7IB5T03NqfqNi4UmFkhSJqi4bGyQICXNxE,21879
145
+ basic_memory/repository/observation_repository.py,sha256=hNuDBnT02YXRGHQJ240P8MgU6n6Y9MS2Ci7hyhpgAiw,2944
146
+ basic_memory/repository/postgres_search_repository.py,sha256=YAong5g2ASPgFO9svckMNg1X0A5fzAp3GFg8PNKlnOI,18880
147
+ basic_memory/repository/project_info_repository.py,sha256=8XLVAYKkBWQ6GbKj1iqA9OK0FGPHdTlOs7ZtfeUf9t8,338
148
+ basic_memory/repository/project_repository.py,sha256=CKyiL6Uum-kqjwKuJYAZmP26CzzVmPupuE3AjzHBolQ,4943
149
+ basic_memory/repository/relation_repository.py,sha256=CVRa80rQ0QmMgEiQ56ni17iuXaQwM8SeFvawuh0Tbtc,5991
150
+ basic_memory/repository/repository.py,sha256=7sJZoZVXRuvlSDLjOVBrqQaWTbKHvHLGHRB5ZDWjCiQ,15639
151
+ basic_memory/repository/search_index_row.py,sha256=37Kz0-LXxuP8u2kEG3Y5aa5SVrDsqI1RT1xaFyYlgXU,3046
152
+ basic_memory/repository/search_repository.py,sha256=1TfgWVt68_EtF0w-f3s5DeySlmdA9u5uX6kNa9c3jMc,3449
153
+ basic_memory/repository/search_repository_base.py,sha256=28X4ybAXhbxAzH_seb9hd7XGZQwluzYb07_INNR0Gd8,9619
154
+ basic_memory/repository/sqlite_search_repository.py,sha256=lQqvnqJXvRigK4cTpQ4Imwn2LE-rTaoSA1bhkakHdeo,16424
155
+ basic_memory/schemas/__init__.py,sha256=6bZUVwc-Bvd6yKdNigUslYS3jFYgIQ9eqT-eujtEXY4,1785
156
+ basic_memory/schemas/base.py,sha256=xyBLxmPQkxAF9hkmBi9bppHAaW2TWM9LPkNiVBkdJmw,10797
157
+ basic_memory/schemas/cloud.py,sha256=4cxS5-Lo0teASdP5q9N6dYlR5TdCpO2_5h2zdB84nu8,1847
158
+ basic_memory/schemas/delete.py,sha256=UAR2JK99WMj3gP-yoGWlHD3eZEkvlTSRf8QoYIE-Wfw,1180
159
+ basic_memory/schemas/directory.py,sha256=BEPGSkWldW6y35WmZ_TyN7pR2hVqytY2rr96wEbNHks,982
160
+ basic_memory/schemas/importer.py,sha256=rDPfQjyjKyjOe26pwp1UH4eDqGwMKfeNs1Fjv5PxOc0,693
161
+ basic_memory/schemas/memory.py,sha256=Ek6l-3jq6tYCp3jKrerlEQrlWzyiI3VtMcgeq-VScZM,9403
162
+ basic_memory/schemas/project_info.py,sha256=Q54mUHCgDLTnh7l0VpJcIKYFHxvimz1N3vtUONW-XzU,6926
163
+ basic_memory/schemas/prompt.py,sha256=SpIVfZprQT8E5uP40j3CpBc2nHKflwOo3iZD7BFPIHE,3648
164
+ basic_memory/schemas/request.py,sha256=Mv5EvrLZlFIiPr8dOjo_4QXvkseYhQI7cd_X2zDsxQM,3760
165
+ basic_memory/schemas/response.py,sha256=t_wT7YozRzVK7CEHCDdqBryiAjUQA0oSG6B8oRsOB4s,9253
166
+ basic_memory/schemas/search.py,sha256=IUjfaLBe6qtQSvUnOAruRZomxNX-xY4AE3Ja6prlbn4,3931
167
+ basic_memory/schemas/sync_report.py,sha256=XHOhcTwMyJX3vO2lESU-H1IN9iVAFe6LH5IZZSOOueo,2605
168
+ basic_memory/schemas/v2/__init__.py,sha256=hnPse-NZOwNjThIVZc63lHdaA0eZJ0B7JVI4rxZaYzA,655
169
+ basic_memory/schemas/v2/entity.py,sha256=BVk4A4QzAmCogWQoKN9UnXbUQwlygQ-vx2_2e3HM6KI,4855
170
+ basic_memory/schemas/v2/resource.py,sha256=rkX0qjM7OjtF0dEUAiGDY-WSlebFIjfHup2Oae4O0wY,1613
171
+ basic_memory/services/__init__.py,sha256=XGt8WX3fX_0K9L37Msy8HF8nlMZYIG3uQ6mUX6_iJtg,259
172
+ basic_memory/services/context_service.py,sha256=gyfgqMfvWahcV4ePgg-zwJdcoiLDlUt8mBHauO8UwCA,22207
173
+ basic_memory/services/directory_service.py,sha256=Ecc0XCl2S8F7i8jYKmjncN_tlNaSrQQR-AdzST0m1Vo,11966
174
+ basic_memory/services/entity_service.py,sha256=3PCGaESTzFahzOHZ3y69osDXUcCank33yQK6Vx4U9PE,37245
175
+ basic_memory/services/exceptions.py,sha256=PWrdv9_oKHW-7LfGy930nSfmaquZoRbIuRmdE6_7oNw,819
176
+ basic_memory/services/file_service.py,sha256=xAaNzhmRovOcl5K5Po1mng1hnatHbqsSlXdv9wUXI0g,20868
177
+ basic_memory/services/initialization.py,sha256=dO9O1KvhxEfu475HmDMni2qdAwxNPkg4pJdZAigIA8k,8079
178
+ basic_memory/services/link_resolver.py,sha256=lgOs3PfyqvIu1_pfbzK7j4IonDcqiZKm0zdFgdgv95M,4595
179
+ basic_memory/services/project_service.py,sha256=IeVPIV55gry1srI2oGF89_5Ofho2NeEgfFe5eXCgPto,36517
180
+ basic_memory/services/search_service.py,sha256=jPN1c-0RNpoFDGGlxIwVziC_AVB8jRIwBJRgSlW1HnU,16029
181
+ basic_memory/services/service.py,sha256=V-d_8gOV07zGIQDpL-Ksqs3ZN9l3qf3HZOK1f_YNTag,336
182
+ basic_memory/sync/__init__.py,sha256=UrzOvib6A-MFpmXu9kkKXvHdcEHRuErNvwVlX-rwZNw,242
183
+ basic_memory/sync/background_sync.py,sha256=VJr2SukRKLdsbfB-9Re4LehcpK15a-RLXAFB-sAdRRM,726
184
+ basic_memory/sync/coordinator.py,sha256=kDWFyRLBS4MI0TRUFoxaCCfir1429Iwld4OLL_bqYyo,4978
185
+ basic_memory/sync/sync_service.py,sha256=KZ9GDKRPaUjJ9xIaHEufCCmVnT40mrssueT9gEWKOSQ,54129
186
+ basic_memory/sync/watch_service.py,sha256=pNMN6DpRs1N1eego6PMA5iw7gKQuJ07tSgNEv4mCVLo,21300
187
+ basic_memory/templates/prompts/continue_conversation.hbs,sha256=trrDHSXA5S0JCbInMoUJL04xvCGRB_ku1RHNQHtl6ZI,3076
188
+ basic_memory/templates/prompts/search.hbs,sha256=H1cCIsHKp4VC1GrH2KeUB8pGe5vXFPqb2VPotypmeCA,3098
189
+ basic_memory-0.17.4.dist-info/METADATA,sha256=4XpKgcL1gzY1Qcjhi_E0S0puyRvAXGF76eILjiVQyvQ,20347
190
+ basic_memory-0.17.4.dist-info/WHEEL,sha256=WLgqFyCfm_KASv4WHyYy0P3pM_m7J5L9k2skdKLirC8,87
191
+ basic_memory-0.17.4.dist-info/entry_points.txt,sha256=wvE2mRF6-Pg4weIYcfQ-86NOLZD4WJg7F7TIsRVFLb8,90
192
+ basic_memory-0.17.4.dist-info/licenses/LICENSE,sha256=hIahDEOTzuHCU5J2nd07LWwkLW7Hko4UFO__ffsvB-8,34523
193
+ basic_memory-0.17.4.dist-info/RECORD,,
@@ -1,4 +1,4 @@
1
1
  Wheel-Version: 1.0
2
- Generator: hatchling 1.27.0
2
+ Generator: hatchling 1.28.0
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any
@@ -1,2 +1,3 @@
1
1
  [console_scripts]
2
2
  basic-memory = basic_memory.cli.main:app
3
+ bm = basic_memory.cli.main:app
@@ -1 +0,0 @@
1
- Generic single-database configuration.
@@ -1,206 +0,0 @@
1
- """Command module for basic-memory sync operations."""
2
-
3
- import asyncio
4
- from collections import defaultdict
5
- from dataclasses import dataclass
6
- from pathlib import Path
7
- from typing import List, Dict
8
-
9
- import typer
10
- from loguru import logger
11
- from rich.console import Console
12
- from rich.tree import Tree
13
-
14
- from basic_memory import db
15
- from basic_memory.cli.app import app
16
- from basic_memory.config import config
17
- from basic_memory.markdown import EntityParser
18
- from basic_memory.markdown.markdown_processor import MarkdownProcessor
19
- from basic_memory.repository import (
20
- EntityRepository,
21
- ObservationRepository,
22
- RelationRepository,
23
- )
24
- from basic_memory.repository.search_repository import SearchRepository
25
- from basic_memory.services import EntityService, FileService
26
- from basic_memory.services.link_resolver import LinkResolver
27
- from basic_memory.services.search_service import SearchService
28
- from basic_memory.sync import SyncService, FileChangeScanner
29
- from basic_memory.sync.utils import SyncReport
30
- from basic_memory.sync.watch_service import WatchService
31
-
32
- console = Console()
33
-
34
-
35
- @dataclass
36
- class ValidationIssue:
37
- file_path: str
38
- error: str
39
-
40
-
41
- async def get_sync_service(): # pragma: no cover
42
- """Get sync service instance with all dependencies."""
43
- _, session_maker = await db.get_or_create_db(
44
- db_path=config.database_path, db_type=db.DatabaseType.FILESYSTEM
45
- )
46
-
47
- entity_parser = EntityParser(config.home)
48
- markdown_processor = MarkdownProcessor(entity_parser)
49
- file_service = FileService(config.home, markdown_processor)
50
-
51
- # Initialize repositories
52
- entity_repository = EntityRepository(session_maker)
53
- observation_repository = ObservationRepository(session_maker)
54
- relation_repository = RelationRepository(session_maker)
55
- search_repository = SearchRepository(session_maker)
56
-
57
- # Initialize services
58
- search_service = SearchService(search_repository, entity_repository, file_service)
59
- link_resolver = LinkResolver(entity_repository, search_service)
60
-
61
- # Initialize scanner
62
- file_change_scanner = FileChangeScanner(entity_repository)
63
-
64
- # Initialize services
65
- entity_service = EntityService(
66
- entity_parser,
67
- entity_repository,
68
- observation_repository,
69
- relation_repository,
70
- file_service,
71
- link_resolver,
72
- )
73
-
74
- # Create sync service
75
- sync_service = SyncService(
76
- scanner=file_change_scanner,
77
- entity_service=entity_service,
78
- entity_parser=entity_parser,
79
- entity_repository=entity_repository,
80
- relation_repository=relation_repository,
81
- search_service=search_service,
82
- )
83
-
84
- return sync_service
85
-
86
-
87
- def group_issues_by_directory(issues: List[ValidationIssue]) -> Dict[str, List[ValidationIssue]]:
88
- """Group validation issues by directory."""
89
- grouped = defaultdict(list)
90
- for issue in issues:
91
- dir_name = Path(issue.file_path).parent.name
92
- grouped[dir_name].append(issue)
93
- return dict(grouped)
94
-
95
-
96
- def display_sync_summary(knowledge: SyncReport):
97
- """Display a one-line summary of sync changes."""
98
- total_changes = knowledge.total_changes
99
- if total_changes == 0:
100
- console.print("[green]Everything up to date[/green]")
101
- return
102
-
103
- # Format as: "Synced X files (A new, B modified, C moved, D deleted)"
104
- changes = []
105
- new_count = len(knowledge.new)
106
- mod_count = len(knowledge.modified)
107
- move_count = len(knowledge.moves)
108
- del_count = len(knowledge.deleted)
109
-
110
- if new_count:
111
- changes.append(f"[green]{new_count} new[/green]")
112
- if mod_count:
113
- changes.append(f"[yellow]{mod_count} modified[/yellow]")
114
- if move_count:
115
- changes.append(f"[blue]{move_count} moved[/blue]")
116
- if del_count:
117
- changes.append(f"[red]{del_count} deleted[/red]")
118
-
119
- console.print(f"Synced {total_changes} files ({', '.join(changes)})")
120
-
121
-
122
- def display_detailed_sync_results(knowledge: SyncReport):
123
- """Display detailed sync results with trees."""
124
- if knowledge.total_changes == 0:
125
- console.print("\n[green]Everything up to date[/green]")
126
- return
127
-
128
- console.print("\n[bold]Sync Results[/bold]")
129
-
130
- if knowledge.total_changes > 0:
131
- knowledge_tree = Tree("[bold]Knowledge Files[/bold]")
132
- if knowledge.new:
133
- created = knowledge_tree.add("[green]Created[/green]")
134
- for path in sorted(knowledge.new):
135
- checksum = knowledge.checksums.get(path, "")
136
- created.add(f"[green]{path}[/green] ({checksum[:8]})")
137
- if knowledge.modified:
138
- modified = knowledge_tree.add("[yellow]Modified[/yellow]")
139
- for path in sorted(knowledge.modified):
140
- checksum = knowledge.checksums.get(path, "")
141
- modified.add(f"[yellow]{path}[/yellow] ({checksum[:8]})")
142
- if knowledge.moves:
143
- moved = knowledge_tree.add("[blue]Moved[/blue]")
144
- for old_path, new_path in sorted(knowledge.moves.items()):
145
- checksum = knowledge.checksums.get(new_path, "")
146
- moved.add(f"[blue]{old_path}[/blue] → [blue]{new_path}[/blue] ({checksum[:8]})")
147
- if knowledge.deleted:
148
- deleted = knowledge_tree.add("[red]Deleted[/red]")
149
- for path in sorted(knowledge.deleted):
150
- deleted.add(f"[red]{path}[/red]")
151
- console.print(knowledge_tree)
152
-
153
-
154
- async def run_sync(verbose: bool = False, watch: bool = False, console_status: bool = False):
155
- """Run sync operation."""
156
-
157
- sync_service = await get_sync_service()
158
-
159
- # Start watching if requested
160
- if watch:
161
- watch_service = WatchService(
162
- sync_service=sync_service,
163
- file_service=sync_service.entity_service.file_service,
164
- config=config,
165
- )
166
- await watch_service.handle_changes(config.home)
167
- await watch_service.run(console_status=console_status) # pragma: no cover
168
- else:
169
- # one time sync
170
- knowledge_changes = await sync_service.sync(config.home)
171
- # Display results
172
- if verbose:
173
- display_detailed_sync_results(knowledge_changes)
174
- else:
175
- display_sync_summary(knowledge_changes) # pragma: no cover
176
-
177
-
178
- @app.command()
179
- def sync(
180
- verbose: bool = typer.Option(
181
- False,
182
- "--verbose",
183
- "-v",
184
- help="Show detailed sync information.",
185
- ),
186
- watch: bool = typer.Option(
187
- False,
188
- "--watch",
189
- "-w",
190
- help="Start watching for changes after sync.",
191
- ),
192
- console_status: bool = typer.Option(
193
- False, "--console-status", "-c", help="Show live console status"
194
- ),
195
- ) -> None:
196
- """Sync knowledge files with the database."""
197
- try:
198
- # Run sync
199
- asyncio.run(run_sync(verbose=verbose, watch=watch, console_status=console_status))
200
-
201
- except Exception as e: # pragma: no cover
202
- if not isinstance(e, typer.Exit):
203
- logger.exception("Sync failed")
204
- typer.echo(f"Error during sync: {e}", err=True)
205
- raise typer.Exit(1)
206
- raise
@@ -1,157 +0,0 @@
1
- """Database management commands."""
2
-
3
- import asyncio
4
- from typing import Optional, List, Annotated
5
-
6
- import typer
7
- from rich import print as rprint
8
-
9
- from basic_memory.cli.app import app
10
- from basic_memory.mcp.tools import build_context as mcp_build_context
11
- from basic_memory.mcp.tools import get_entity as mcp_get_entity
12
- from basic_memory.mcp.tools import read_note as mcp_read_note
13
- from basic_memory.mcp.tools import recent_activity as mcp_recent_activity
14
- from basic_memory.mcp.tools import search as mcp_search
15
- from basic_memory.mcp.tools import write_note as mcp_write_note
16
- from basic_memory.schemas.base import TimeFrame
17
- from basic_memory.schemas.memory import MemoryUrl
18
- from basic_memory.schemas.search import SearchQuery
19
-
20
- tool_app = typer.Typer()
21
- app.add_typer(tool_app, name="tools", help="cli versions mcp tools")
22
-
23
-
24
- @tool_app.command()
25
- def write_note(
26
- title: Annotated[str, typer.Option(help="The title of the note")],
27
- content: Annotated[str, typer.Option(help="The content of the note")],
28
- folder: Annotated[str, typer.Option(help="The folder to create the note in")],
29
- tags: Annotated[
30
- Optional[List[str]], typer.Option(help="A list of tags to apply to the note")
31
- ] = None,
32
- ):
33
- try:
34
- note = asyncio.run(mcp_write_note(title, content, folder, tags))
35
- rprint(note)
36
- except Exception as e: # pragma: no cover
37
- if not isinstance(e, typer.Exit):
38
- typer.echo(f"Error during write_note: {e}", err=True)
39
- raise typer.Exit(1)
40
- raise
41
-
42
-
43
- @tool_app.command()
44
- def read_note(identifier: str, page: int = 1, page_size: int = 10):
45
- try:
46
- note = asyncio.run(mcp_read_note(identifier, page, page_size))
47
- rprint(note)
48
- except Exception as e: # pragma: no cover
49
- if not isinstance(e, typer.Exit):
50
- typer.echo(f"Error during read_note: {e}", err=True)
51
- raise typer.Exit(1)
52
- raise
53
-
54
-
55
- @tool_app.command()
56
- def build_context(
57
- url: MemoryUrl,
58
- depth: Optional[int] = 1,
59
- timeframe: Optional[TimeFrame] = "7d",
60
- page: int = 1,
61
- page_size: int = 10,
62
- max_related: int = 10,
63
- ):
64
- try:
65
- context = asyncio.run(
66
- mcp_build_context(
67
- url=url,
68
- depth=depth,
69
- timeframe=timeframe,
70
- page=page,
71
- page_size=page_size,
72
- max_related=max_related,
73
- )
74
- )
75
- rprint(context.model_dump())
76
- except Exception as e: # pragma: no cover
77
- if not isinstance(e, typer.Exit):
78
- typer.echo(f"Error during build_context: {e}", err=True)
79
- raise typer.Exit(1)
80
- raise
81
-
82
-
83
- @tool_app.command()
84
- def recent_activity(
85
- type: Annotated[Optional[List[str]], typer.Option()] = ["entity", "observation", "relation"],
86
- depth: Optional[int] = 1,
87
- timeframe: Optional[TimeFrame] = "7d",
88
- page: int = 1,
89
- page_size: int = 10,
90
- max_related: int = 10,
91
- ):
92
- assert type is not None, "type is required"
93
- if any(t not in ["entity", "observation", "relation"] for t in type): # pragma: no cover
94
- print("type must be one of ['entity', 'observation', 'relation']")
95
- raise typer.Abort()
96
-
97
- try:
98
- context = asyncio.run(
99
- mcp_recent_activity(
100
- type=type, # pyright: ignore [reportArgumentType]
101
- depth=depth,
102
- timeframe=timeframe,
103
- page=page,
104
- page_size=page_size,
105
- max_related=max_related,
106
- )
107
- )
108
- rprint(context.model_dump())
109
- except Exception as e: # pragma: no cover
110
- if not isinstance(e, typer.Exit):
111
- typer.echo(f"Error during build_context: {e}", err=True)
112
- raise typer.Exit(1)
113
- raise
114
-
115
-
116
- @tool_app.command()
117
- def search(
118
- query: str,
119
- permalink: Annotated[bool, typer.Option("--permalink", help="Search permalink values")] = False,
120
- title: Annotated[bool, typer.Option("--title", help="Search title values")] = False,
121
- after_date: Annotated[
122
- Optional[str],
123
- typer.Option("--after_date", help="Search results after date, eg. '2d', '1 week'"),
124
- ] = None,
125
- page: int = 1,
126
- page_size: int = 10,
127
- ):
128
- if permalink and title: # pragma: no cover
129
- print("Cannot search both permalink and title")
130
- raise typer.Abort()
131
-
132
- try:
133
- search_query = SearchQuery(
134
- permalink_match=query if permalink else None,
135
- text=query if query else None,
136
- title=query if title else None,
137
- after_date=after_date,
138
- )
139
- results = asyncio.run(mcp_search(query=search_query, page=page, page_size=page_size))
140
- rprint(results.model_dump())
141
- except Exception as e: # pragma: no cover
142
- if not isinstance(e, typer.Exit):
143
- typer.echo(f"Error during search: {e}", err=True)
144
- raise typer.Exit(1)
145
- raise
146
-
147
-
148
- @tool_app.command()
149
- def get_entity(identifier: str):
150
- try:
151
- entity = asyncio.run(mcp_get_entity(identifier=identifier))
152
- rprint(entity.model_dump())
153
- except Exception as e: # pragma: no cover
154
- if not isinstance(e, typer.Exit):
155
- typer.echo(f"Error during get_entity: {e}", err=True)
156
- raise typer.Exit(1)
157
- raise
@@ -1,68 +0,0 @@
1
- """Knowledge graph management tools for Basic Memory MCP server."""
2
-
3
- import logfire
4
-
5
- from basic_memory.mcp.server import mcp
6
- from basic_memory.mcp.tools.utils import call_get, call_post
7
- from basic_memory.schemas.memory import memory_url_path
8
- from basic_memory.schemas.request import (
9
- GetEntitiesRequest,
10
- )
11
- from basic_memory.schemas.delete import (
12
- DeleteEntitiesRequest,
13
- )
14
- from basic_memory.schemas.response import EntityListResponse, EntityResponse, DeleteEntitiesResponse
15
- from basic_memory.mcp.async_client import client
16
-
17
-
18
- @mcp.tool(
19
- description="Get complete information about a specific entity including observations and relations",
20
- )
21
- async def get_entity(identifier: str) -> EntityResponse:
22
- """Get a specific entity info by its permalink.
23
-
24
- Args:
25
- identifier: Path identifier for the entity
26
- """
27
- with logfire.span("Getting entity", permalink=identifier): # pyright: ignore [reportGeneralTypeIssues]
28
- permalink = memory_url_path(identifier)
29
- url = f"/knowledge/entities/{permalink}"
30
- response = await call_get(client, url)
31
- return EntityResponse.model_validate(response.json())
32
-
33
-
34
- @mcp.tool(
35
- description="Load multiple entities by their permalinks in a single request",
36
- )
37
- async def get_entities(request: GetEntitiesRequest) -> EntityListResponse:
38
- """Load multiple entities by their permalinks.
39
-
40
- Args:
41
- request: OpenNodesRequest containing list of permalinks to load
42
-
43
- Returns:
44
- EntityListResponse containing complete details for each requested entity
45
- """
46
- with logfire.span("Getting multiple entities", permalink_count=len(request.permalinks)): # pyright: ignore [reportGeneralTypeIssues]
47
- url = "/knowledge/entities"
48
- response = await call_get(
49
- client,
50
- url,
51
- params=[
52
- ("permalink", memory_url_path(identifier)) for identifier in request.permalinks
53
- ],
54
- )
55
- return EntityListResponse.model_validate(response.json())
56
-
57
-
58
- @mcp.tool(
59
- description="Permanently delete entities and all related content (observations and relations)",
60
- )
61
- async def delete_entities(request: DeleteEntitiesRequest) -> DeleteEntitiesResponse:
62
- """Delete entities from the knowledge graph."""
63
- with logfire.span("Deleting entities", permalink_count=len(request.permalinks)): # pyright: ignore [reportGeneralTypeIssues]
64
- url = "/knowledge/entities/delete"
65
-
66
- request.permalinks = [memory_url_path(permlink) for permlink in request.permalinks]
67
- response = await call_post(client, url, json=request.model_dump())
68
- return DeleteEntitiesResponse.model_validate(response.json())