basic-memory 0.17.2__tar.gz → 0.17.4__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.
- {basic_memory-0.17.2 → basic_memory-0.17.4}/.github/workflows/claude-code-review.yml +1 -0
- {basic_memory-0.17.2 → basic_memory-0.17.4}/.github/workflows/test.yml +55 -1
- {basic_memory-0.17.2 → basic_memory-0.17.4}/CHANGELOG.md +60 -0
- {basic_memory-0.17.2 → basic_memory-0.17.4}/CLAUDE.md +26 -4
- {basic_memory-0.17.2 → basic_memory-0.17.4}/PKG-INFO +2 -2
- basic_memory-0.17.4/docs/ARCHITECTURE.md +412 -0
- basic_memory-0.17.4/docs/testing-coverage.md +30 -0
- {basic_memory-0.17.2 → basic_memory-0.17.4}/justfile +27 -12
- {basic_memory-0.17.2 → basic_memory-0.17.4}/pyproject.toml +8 -4
- {basic_memory-0.17.2 → basic_memory-0.17.4}/src/basic_memory/__init__.py +1 -1
- basic_memory-0.17.4/src/basic_memory/alembic/versions/6830751f5fb6_merge_multiple_heads.py +24 -0
- basic_memory-0.17.4/src/basic_memory/alembic/versions/g9a0b3c4d5e6_add_external_id_to_project_and_entity.py +173 -0
- {basic_memory-0.17.2 → basic_memory-0.17.4}/src/basic_memory/api/app.py +31 -43
- basic_memory-0.17.4/src/basic_memory/api/container.py +133 -0
- {basic_memory-0.17.2 → basic_memory-0.17.4}/src/basic_memory/api/routers/knowledge_router.py +4 -3
- {basic_memory-0.17.2 → basic_memory-0.17.4}/src/basic_memory/api/routers/project_router.py +17 -5
- {basic_memory-0.17.2 → basic_memory-0.17.4}/src/basic_memory/api/routers/resource_router.py +4 -4
- {basic_memory-0.17.2 → basic_memory-0.17.4}/src/basic_memory/api/v2/routers/directory_router.py +13 -13
- {basic_memory-0.17.2 → basic_memory-0.17.4}/src/basic_memory/api/v2/routers/importer_router.py +18 -19
- {basic_memory-0.17.2 → basic_memory-0.17.4}/src/basic_memory/api/v2/routers/knowledge_router.py +120 -106
- {basic_memory-0.17.2 → basic_memory-0.17.4}/src/basic_memory/api/v2/routers/memory_router.py +11 -11
- {basic_memory-0.17.2 → basic_memory-0.17.4}/src/basic_memory/api/v2/routers/project_router.py +88 -71
- {basic_memory-0.17.2 → basic_memory-0.17.4}/src/basic_memory/api/v2/routers/prompt_router.py +16 -17
- {basic_memory-0.17.2 → basic_memory-0.17.4}/src/basic_memory/api/v2/routers/resource_router.py +59 -59
- {basic_memory-0.17.2 → basic_memory-0.17.4}/src/basic_memory/api/v2/routers/search_router.py +11 -11
- {basic_memory-0.17.2 → basic_memory-0.17.4}/src/basic_memory/cli/app.py +11 -5
- {basic_memory-0.17.2 → basic_memory-0.17.4}/src/basic_memory/cli/auth.py +27 -4
- {basic_memory-0.17.2 → basic_memory-0.17.4}/src/basic_memory/cli/commands/cloud/api_client.py +20 -5
- {basic_memory-0.17.2 → basic_memory-0.17.4}/src/basic_memory/cli/commands/cloud/cloud_utils.py +13 -6
- {basic_memory-0.17.2 → basic_memory-0.17.4}/src/basic_memory/cli/commands/cloud/rclone_commands.py +47 -21
- {basic_memory-0.17.2 → basic_memory-0.17.4}/src/basic_memory/cli/commands/cloud/upload.py +10 -3
- {basic_memory-0.17.2 → basic_memory-0.17.4}/src/basic_memory/cli/commands/command_utils.py +25 -3
- basic_memory-0.17.4/src/basic_memory/cli/commands/db.py +103 -0
- {basic_memory-0.17.2 → basic_memory-0.17.4}/src/basic_memory/cli/commands/import_chatgpt.py +10 -7
- {basic_memory-0.17.2 → basic_memory-0.17.4}/src/basic_memory/cli/commands/import_claude_conversations.py +10 -7
- {basic_memory-0.17.2 → basic_memory-0.17.4}/src/basic_memory/cli/commands/import_claude_projects.py +10 -7
- {basic_memory-0.17.2 → basic_memory-0.17.4}/src/basic_memory/cli/commands/import_memory_json.py +10 -7
- {basic_memory-0.17.2 → basic_memory-0.17.4}/src/basic_memory/cli/commands/project.py +2 -2
- basic_memory-0.17.4/src/basic_memory/cli/container.py +84 -0
- {basic_memory-0.17.2 → basic_memory-0.17.4}/src/basic_memory/config.py +4 -4
- {basic_memory-0.17.2 → basic_memory-0.17.4}/src/basic_memory/db.py +31 -7
- basic_memory-0.17.4/src/basic_memory/deps/__init__.py +293 -0
- basic_memory-0.17.4/src/basic_memory/deps/config.py +26 -0
- basic_memory-0.17.4/src/basic_memory/deps/db.py +56 -0
- basic_memory-0.17.4/src/basic_memory/deps/importers.py +200 -0
- basic_memory-0.17.4/src/basic_memory/deps/projects.py +238 -0
- basic_memory-0.17.4/src/basic_memory/deps/repositories.py +179 -0
- basic_memory-0.17.4/src/basic_memory/deps/services.py +480 -0
- basic_memory-0.17.4/src/basic_memory/deps.py +16 -0
- {basic_memory-0.17.2 → basic_memory-0.17.4}/src/basic_memory/file_utils.py +4 -4
- {basic_memory-0.17.2 → basic_memory-0.17.4}/src/basic_memory/ignore_utils.py +5 -5
- basic_memory-0.17.4/src/basic_memory/importers/base.py +100 -0
- {basic_memory-0.17.2 → basic_memory-0.17.4}/src/basic_memory/importers/chatgpt_importer.py +17 -4
- {basic_memory-0.17.2 → basic_memory-0.17.4}/src/basic_memory/importers/claude_conversations_importer.py +23 -11
- {basic_memory-0.17.2 → basic_memory-0.17.4}/src/basic_memory/importers/claude_projects_importer.py +50 -14
- {basic_memory-0.17.2 → basic_memory-0.17.4}/src/basic_memory/importers/memory_json_importer.py +36 -16
- {basic_memory-0.17.2 → basic_memory-0.17.4}/src/basic_memory/markdown/markdown_processor.py +48 -4
- basic_memory-0.17.4/src/basic_memory/mcp/clients/__init__.py +28 -0
- basic_memory-0.17.4/src/basic_memory/mcp/clients/directory.py +70 -0
- basic_memory-0.17.4/src/basic_memory/mcp/clients/knowledge.py +176 -0
- basic_memory-0.17.4/src/basic_memory/mcp/clients/memory.py +120 -0
- basic_memory-0.17.4/src/basic_memory/mcp/clients/project.py +89 -0
- basic_memory-0.17.4/src/basic_memory/mcp/clients/resource.py +71 -0
- basic_memory-0.17.4/src/basic_memory/mcp/clients/search.py +65 -0
- basic_memory-0.17.4/src/basic_memory/mcp/container.py +110 -0
- {basic_memory-0.17.2 → basic_memory-0.17.4}/src/basic_memory/mcp/project_context.py +36 -34
- {basic_memory-0.17.2 → basic_memory-0.17.4}/src/basic_memory/mcp/prompts/ai_assistant_guide.py +2 -2
- {basic_memory-0.17.2 → basic_memory-0.17.4}/src/basic_memory/mcp/prompts/recent_activity.py +2 -2
- {basic_memory-0.17.2 → basic_memory-0.17.4}/src/basic_memory/mcp/prompts/utils.py +3 -3
- {basic_memory-0.17.2 → basic_memory-0.17.4}/src/basic_memory/mcp/server.py +16 -30
- {basic_memory-0.17.2 → basic_memory-0.17.4}/src/basic_memory/mcp/tools/build_context.py +12 -12
- {basic_memory-0.17.2 → basic_memory-0.17.4}/src/basic_memory/mcp/tools/canvas.py +6 -6
- {basic_memory-0.17.2 → basic_memory-0.17.4}/src/basic_memory/mcp/tools/chatgpt_tools.py +1 -1
- {basic_memory-0.17.2 → basic_memory-0.17.4}/src/basic_memory/mcp/tools/delete_note.py +18 -11
- {basic_memory-0.17.2 → basic_memory-0.17.4}/src/basic_memory/mcp/tools/edit_note.py +10 -9
- {basic_memory-0.17.2 → basic_memory-0.17.4}/src/basic_memory/mcp/tools/list_directory.py +5 -16
- {basic_memory-0.17.2 → basic_memory-0.17.4}/src/basic_memory/mcp/tools/move_note.py +29 -31
- {basic_memory-0.17.2 → basic_memory-0.17.4}/src/basic_memory/mcp/tools/project_management.py +25 -22
- {basic_memory-0.17.2 → basic_memory-0.17.4}/src/basic_memory/mcp/tools/read_content.py +2 -2
- {basic_memory-0.17.2 → basic_memory-0.17.4}/src/basic_memory/mcp/tools/read_note.py +11 -13
- {basic_memory-0.17.2 → basic_memory-0.17.4}/src/basic_memory/mcp/tools/recent_activity.py +28 -35
- {basic_memory-0.17.2 → basic_memory-0.17.4}/src/basic_memory/mcp/tools/search.py +15 -9
- {basic_memory-0.17.2 → basic_memory-0.17.4}/src/basic_memory/mcp/tools/utils.py +10 -10
- {basic_memory-0.17.2 → basic_memory-0.17.4}/src/basic_memory/mcp/tools/write_note.py +16 -16
- {basic_memory-0.17.2 → basic_memory-0.17.4}/src/basic_memory/models/knowledge.py +7 -1
- {basic_memory-0.17.2 → basic_memory-0.17.4}/src/basic_memory/models/project.py +7 -1
- {basic_memory-0.17.2 → basic_memory-0.17.4}/src/basic_memory/models/search.py +9 -0
- basic_memory-0.17.4/src/basic_memory/project_resolver.py +222 -0
- {basic_memory-0.17.2 → basic_memory-0.17.4}/src/basic_memory/repository/entity_repository.py +34 -16
- {basic_memory-0.17.2 → basic_memory-0.17.4}/src/basic_memory/repository/postgres_search_repository.py +92 -20
- {basic_memory-0.17.2 → basic_memory-0.17.4}/src/basic_memory/repository/project_repository.py +12 -0
- {basic_memory-0.17.2 → basic_memory-0.17.4}/src/basic_memory/repository/relation_repository.py +4 -4
- {basic_memory-0.17.2 → basic_memory-0.17.4}/src/basic_memory/repository/search_repository.py +11 -4
- {basic_memory-0.17.2 → basic_memory-0.17.4}/src/basic_memory/repository/search_repository_base.py +2 -2
- {basic_memory-0.17.2 → basic_memory-0.17.4}/src/basic_memory/repository/sqlite_search_repository.py +5 -7
- basic_memory-0.17.4/src/basic_memory/runtime.py +61 -0
- {basic_memory-0.17.2 → basic_memory-0.17.4}/src/basic_memory/schemas/base.py +2 -2
- {basic_memory-0.17.2 → basic_memory-0.17.4}/src/basic_memory/schemas/directory.py +2 -1
- {basic_memory-0.17.2 → basic_memory-0.17.4}/src/basic_memory/schemas/memory.py +2 -2
- {basic_memory-0.17.2 → basic_memory-0.17.4}/src/basic_memory/schemas/project_info.py +1 -0
- {basic_memory-0.17.2 → basic_memory-0.17.4}/src/basic_memory/schemas/response.py +84 -27
- {basic_memory-0.17.2 → basic_memory-0.17.4}/src/basic_memory/schemas/sync_report.py +1 -1
- {basic_memory-0.17.2 → basic_memory-0.17.4}/src/basic_memory/schemas/v2/entity.py +13 -9
- {basic_memory-0.17.2 → basic_memory-0.17.4}/src/basic_memory/schemas/v2/resource.py +2 -1
- {basic_memory-0.17.2 → basic_memory-0.17.4}/src/basic_memory/services/context_service.py +5 -5
- {basic_memory-0.17.2 → basic_memory-0.17.4}/src/basic_memory/services/directory_service.py +13 -11
- {basic_memory-0.17.2 → basic_memory-0.17.4}/src/basic_memory/services/file_service.py +12 -8
- {basic_memory-0.17.2 → basic_memory-0.17.4}/src/basic_memory/services/project_service.py +33 -25
- {basic_memory-0.17.2 → basic_memory-0.17.4}/src/basic_memory/services/search_service.py +29 -11
- basic_memory-0.17.4/src/basic_memory/sync/__init__.py +7 -0
- basic_memory-0.17.4/src/basic_memory/sync/coordinator.py +160 -0
- {basic_memory-0.17.2 → basic_memory-0.17.4}/src/basic_memory/sync/sync_service.py +9 -3
- {basic_memory-0.17.2 → basic_memory-0.17.4}/src/basic_memory/sync/watch_service.py +12 -7
- {basic_memory-0.17.2 → basic_memory-0.17.4}/src/basic_memory/utils.py +5 -5
- {basic_memory-0.17.2 → basic_memory-0.17.4}/test-int/conftest.py +2 -0
- {basic_memory-0.17.2 → basic_memory-0.17.4}/test-int/mcp/test_lifespan_shutdown_sync_task_cancellation_integration.py +22 -11
- {basic_memory-0.17.2 → basic_memory-0.17.4}/test-int/mcp/test_write_note_integration.py +1 -0
- basic_memory-0.17.4/tests/api/test_api_container.py +62 -0
- basic_memory-0.17.4/tests/api/test_async_client.py +53 -0
- {basic_memory-0.17.2 → basic_memory-0.17.4}/tests/api/test_directory_router.py +0 -199
- {basic_memory-0.17.2 → basic_memory-0.17.4}/tests/api/test_knowledge_router.py +0 -36
- basic_memory-0.17.4/tests/api/test_management_router.py +123 -0
- {basic_memory-0.17.2 → basic_memory-0.17.4}/tests/api/test_relation_background_resolution.py +19 -9
- {basic_memory-0.17.2 → basic_memory-0.17.4}/tests/api/v2/conftest.py +3 -3
- {basic_memory-0.17.2 → basic_memory-0.17.4}/tests/api/v2/test_knowledge_router.py +64 -62
- {basic_memory-0.17.2 → basic_memory-0.17.4}/tests/api/v2/test_project_router.py +55 -51
- {basic_memory-0.17.2 → basic_memory-0.17.4}/tests/api/v2/test_resource_router.py +28 -22
- basic_memory-0.17.4/tests/cli/cloud/test_cloud_api_client_and_utils.py +161 -0
- basic_memory-0.17.4/tests/cli/cloud/test_rclone_config_and_bmignore_filters.py +80 -0
- basic_memory-0.17.4/tests/cli/cloud/test_upload_path.py +73 -0
- basic_memory-0.17.4/tests/cli/test_auth_cli_auth.py +147 -0
- basic_memory-0.17.4/tests/cli/test_cli_container.py +96 -0
- {basic_memory-0.17.2 → basic_memory-0.17.4}/tests/cli/test_cli_tool_exit.py +20 -3
- {basic_memory-0.17.2 → basic_memory-0.17.4}/tests/cli/test_cli_tools.py +44 -41
- basic_memory-0.17.4/tests/cli/test_cloud_authentication.py +225 -0
- {basic_memory-0.17.2 → basic_memory-0.17.4}/tests/cli/test_import_memory_json.py +5 -3
- {basic_memory-0.17.2 → basic_memory-0.17.4}/tests/cli/test_project_add_with_local_path.py +35 -23
- {basic_memory-0.17.2 → basic_memory-0.17.4}/tests/cli/test_upload.py +84 -182
- {basic_memory-0.17.2 → basic_memory-0.17.4}/tests/conftest.py +30 -0
- {basic_memory-0.17.2 → basic_memory-0.17.4}/tests/importers/test_conversation_indexing.py +4 -2
- {basic_memory-0.17.2 → basic_memory-0.17.4}/tests/importers/test_importer_base.py +28 -43
- basic_memory-0.17.4/tests/mcp/clients/__init__.py +0 -0
- basic_memory-0.17.4/tests/mcp/clients/test_clients.py +312 -0
- basic_memory-0.17.4/tests/mcp/test_async_client_modes.py +82 -0
- basic_memory-0.17.4/tests/mcp/test_mcp_container.py +93 -0
- basic_memory-0.17.4/tests/mcp/test_project_context.py +105 -0
- basic_memory-0.17.4/tests/mcp/test_recent_activity_prompt_modes.py +101 -0
- basic_memory-0.17.4/tests/mcp/test_server_lifespan_branches.py +36 -0
- {basic_memory-0.17.2 → basic_memory-0.17.4}/tests/mcp/test_tool_move_note.py +28 -66
- basic_memory-0.17.4/tests/mcp/test_tool_project_management.py +51 -0
- basic_memory-0.17.4/tests/mcp/test_tool_read_content.py +170 -0
- {basic_memory-0.17.2 → basic_memory-0.17.4}/tests/mcp/test_tool_read_note.py +83 -25
- basic_memory-0.17.4/tests/mcp/test_tool_recent_activity.py +412 -0
- {basic_memory-0.17.2 → basic_memory-0.17.4}/tests/mcp/test_tool_search.py +56 -20
- {basic_memory-0.17.2 → basic_memory-0.17.4}/tests/mcp/test_tool_utils.py +54 -31
- {basic_memory-0.17.2 → basic_memory-0.17.4}/tests/mcp/test_tool_view_note.py +12 -57
- basic_memory-0.17.4/tests/mcp/tools/test_chatgpt_tools.py +215 -0
- basic_memory-0.17.4/tests/repository/test_postgres_search_repository.py +195 -0
- {basic_memory-0.17.2 → basic_memory-0.17.4}/tests/repository/test_search_repository.py +163 -12
- basic_memory-0.17.4/tests/schemas/test_relation_response_reference_resolution.py +42 -0
- {basic_memory-0.17.2 → basic_memory-0.17.4}/tests/schemas/test_schemas.py +43 -0
- {basic_memory-0.17.2 → basic_memory-0.17.4}/tests/services/test_entity_service.py +6 -6
- {basic_memory-0.17.2 → basic_memory-0.17.4}/tests/services/test_file_service.py +37 -19
- basic_memory-0.17.4/tests/services/test_initialization.py +120 -0
- basic_memory-0.17.4/tests/services/test_initialization_cloud_mode_branches.py +23 -0
- {basic_memory-0.17.2 → basic_memory-0.17.4}/tests/services/test_project_service.py +4 -12
- {basic_memory-0.17.2 → basic_memory-0.17.4}/tests/services/test_project_service_operations.py +0 -38
- {basic_memory-0.17.2 → basic_memory-0.17.4}/tests/services/test_search_service.py +8 -40
- basic_memory-0.17.4/tests/sync/test_coordinator.py +135 -0
- {basic_memory-0.17.2 → basic_memory-0.17.4}/tests/sync/test_sync_service.py +74 -503
- {basic_memory-0.17.2 → basic_memory-0.17.4}/tests/sync/test_watch_service.py +10 -8
- basic_memory-0.17.4/tests/sync/test_watch_service_atomic_adds.py +53 -0
- {basic_memory-0.17.2 → basic_memory-0.17.4}/tests/sync/test_watch_service_edge_cases.py +5 -15
- basic_memory-0.17.4/tests/sync/test_watch_service_reload.py +259 -0
- {basic_memory-0.17.2 → basic_memory-0.17.4}/tests/test_deps.py +26 -0
- basic_memory-0.17.4/tests/test_project_resolver.py +209 -0
- basic_memory-0.17.4/tests/test_rclone_commands.py +460 -0
- basic_memory-0.17.4/tests/test_runtime.py +53 -0
- basic_memory-0.17.4/tests/test_telemetry.py +268 -0
- {basic_memory-0.17.2 → basic_memory-0.17.4}/tests/utils/test_timezone_utils.py +6 -10
- {basic_memory-0.17.2 → basic_memory-0.17.4}/uv.lock +993 -985
- basic_memory-0.17.2/src/basic_memory/cli/commands/db.py +0 -44
- basic_memory-0.17.2/src/basic_memory/deps.py +0 -705
- basic_memory-0.17.2/src/basic_memory/importers/base.py +0 -79
- basic_memory-0.17.2/src/basic_memory/sync/__init__.py +0 -6
- basic_memory-0.17.2/tests/api/test_async_client.py +0 -56
- basic_memory-0.17.2/tests/api/test_management_router.py +0 -211
- basic_memory-0.17.2/tests/cli/test_cloud_authentication.py +0 -239
- basic_memory-0.17.2/tests/mcp/test_project_context.py +0 -144
- basic_memory-0.17.2/tests/mcp/test_tool_read_content.py +0 -495
- basic_memory-0.17.2/tests/mcp/test_tool_recent_activity.py +0 -135
- basic_memory-0.17.2/tests/mcp/tools/test_chatgpt_tools.py +0 -228
- basic_memory-0.17.2/tests/services/test_initialization.py +0 -122
- basic_memory-0.17.2/tests/sync/test_watch_service_reload.py +0 -252
- basic_memory-0.17.2/tests/test_rclone_commands.py +0 -647
- basic_memory-0.17.2/tests/test_telemetry.py +0 -276
- {basic_memory-0.17.2 → basic_memory-0.17.4}/.claude/commands/release/beta.md +0 -0
- {basic_memory-0.17.2 → basic_memory-0.17.4}/.claude/commands/release/changelog.md +0 -0
- {basic_memory-0.17.2 → basic_memory-0.17.4}/.claude/commands/release/release-check.md +0 -0
- {basic_memory-0.17.2 → basic_memory-0.17.4}/.claude/commands/release/release.md +0 -0
- {basic_memory-0.17.2 → basic_memory-0.17.4}/.claude/commands/spec.md +0 -0
- {basic_memory-0.17.2 → basic_memory-0.17.4}/.claude/commands/test-live.md +0 -0
- {basic_memory-0.17.2 → basic_memory-0.17.4}/.claude/settings.json +0 -0
- {basic_memory-0.17.2 → basic_memory-0.17.4}/.dockerignore +0 -0
- {basic_memory-0.17.2 → basic_memory-0.17.4}/.env.example +0 -0
- {basic_memory-0.17.2 → basic_memory-0.17.4}/.github/ISSUE_TEMPLATE/bug_report.md +0 -0
- {basic_memory-0.17.2 → basic_memory-0.17.4}/.github/ISSUE_TEMPLATE/config.yml +0 -0
- {basic_memory-0.17.2 → basic_memory-0.17.4}/.github/ISSUE_TEMPLATE/documentation.md +0 -0
- {basic_memory-0.17.2 → basic_memory-0.17.4}/.github/ISSUE_TEMPLATE/feature_request.md +0 -0
- {basic_memory-0.17.2 → basic_memory-0.17.4}/.github/dependabot.yml +0 -0
- {basic_memory-0.17.2 → basic_memory-0.17.4}/.github/workflows/claude-issue-triage.yml +0 -0
- {basic_memory-0.17.2 → basic_memory-0.17.4}/.github/workflows/claude.yml +0 -0
- {basic_memory-0.17.2 → basic_memory-0.17.4}/.github/workflows/dev-release.yml +0 -0
- {basic_memory-0.17.2 → basic_memory-0.17.4}/.github/workflows/docker.yml +0 -0
- {basic_memory-0.17.2 → basic_memory-0.17.4}/.github/workflows/pr-title.yml +0 -0
- {basic_memory-0.17.2 → basic_memory-0.17.4}/.github/workflows/release.yml +0 -0
- {basic_memory-0.17.2 → basic_memory-0.17.4}/.gitignore +0 -0
- {basic_memory-0.17.2 → basic_memory-0.17.4}/.python-version +0 -0
- {basic_memory-0.17.2 → basic_memory-0.17.4}/CITATION.cff +0 -0
- {basic_memory-0.17.2 → basic_memory-0.17.4}/CLA.md +0 -0
- {basic_memory-0.17.2 → basic_memory-0.17.4}/CODE_OF_CONDUCT.md +0 -0
- {basic_memory-0.17.2 → basic_memory-0.17.4}/CONTRIBUTING.md +0 -0
- {basic_memory-0.17.2 → basic_memory-0.17.4}/Dockerfile +0 -0
- {basic_memory-0.17.2 → basic_memory-0.17.4}/LICENSE +0 -0
- {basic_memory-0.17.2 → basic_memory-0.17.4}/README.md +0 -0
- {basic_memory-0.17.2 → basic_memory-0.17.4}/SECURITY.md +0 -0
- {basic_memory-0.17.2 → basic_memory-0.17.4}/docker-compose-postgres.yml +0 -0
- {basic_memory-0.17.2 → basic_memory-0.17.4}/docker-compose.yml +0 -0
- {basic_memory-0.17.2 → basic_memory-0.17.4}/docs/Docker.md +0 -0
- {basic_memory-0.17.2 → basic_memory-0.17.4}/docs/ai-assistant-guide-extended.md +0 -0
- {basic_memory-0.17.2 → basic_memory-0.17.4}/docs/character-handling.md +0 -0
- {basic_memory-0.17.2 → basic_memory-0.17.4}/docs/cloud-cli.md +0 -0
- {basic_memory-0.17.2 → basic_memory-0.17.4}/llms-install.md +0 -0
- {basic_memory-0.17.2 → basic_memory-0.17.4}/smithery.yaml +0 -0
- {basic_memory-0.17.2 → basic_memory-0.17.4}/specs/SPEC-1 Specification-Driven Development Process.md +0 -0
- {basic_memory-0.17.2 → basic_memory-0.17.4}/specs/SPEC-10 Unified Deployment Workflow and Event Tracking.md +0 -0
- {basic_memory-0.17.2 → basic_memory-0.17.4}/specs/SPEC-11 Basic Memory API Performance Optimization.md +0 -0
- {basic_memory-0.17.2 → basic_memory-0.17.4}/specs/SPEC-12 OpenTelemetry Observability.md +0 -0
- {basic_memory-0.17.2 → basic_memory-0.17.4}/specs/SPEC-13 CLI Authentication with Subscription Validation.md +0 -0
- {basic_memory-0.17.2 → basic_memory-0.17.4}/specs/SPEC-14 Cloud Git Versioning & GitHub Backup.md +0 -0
- {basic_memory-0.17.2 → basic_memory-0.17.4}/specs/SPEC-14- Cloud Git Versioning & GitHub Backup.md +0 -0
- {basic_memory-0.17.2 → basic_memory-0.17.4}/specs/SPEC-15 Configuration Persistence via Tigris for Cloud Tenants.md +0 -0
- {basic_memory-0.17.2 → basic_memory-0.17.4}/specs/SPEC-16 MCP Cloud Service Consolidation.md +0 -0
- {basic_memory-0.17.2 → basic_memory-0.17.4}/specs/SPEC-17 Semantic Search with ChromaDB.md +0 -0
- {basic_memory-0.17.2 → basic_memory-0.17.4}/specs/SPEC-18 AI Memory Management Tool.md +0 -0
- {basic_memory-0.17.2 → basic_memory-0.17.4}/specs/SPEC-19 Sync Performance and Memory Optimization.md +0 -0
- {basic_memory-0.17.2 → basic_memory-0.17.4}/specs/SPEC-2 Slash Commands Reference.md +0 -0
- {basic_memory-0.17.2 → basic_memory-0.17.4}/specs/SPEC-20 Simplified Project-Scoped Rclone Sync.md +0 -0
- {basic_memory-0.17.2 → basic_memory-0.17.4}/specs/SPEC-3 Agent Definitions.md +0 -0
- {basic_memory-0.17.2 → basic_memory-0.17.4}/specs/SPEC-4 Notes Web UI Component Architecture.md +0 -0
- {basic_memory-0.17.2 → basic_memory-0.17.4}/specs/SPEC-5 CLI Cloud Upload via WebDAV.md +0 -0
- {basic_memory-0.17.2 → basic_memory-0.17.4}/specs/SPEC-6 Explicit Project Parameter Architecture.md +0 -0
- {basic_memory-0.17.2 → basic_memory-0.17.4}/specs/SPEC-7 POC to spike Tigris Turso for local access to cloud data.md +0 -0
- {basic_memory-0.17.2 → basic_memory-0.17.4}/specs/SPEC-8 TigrisFS Integration.md +0 -0
- {basic_memory-0.17.2 → basic_memory-0.17.4}/specs/SPEC-9 Multi-Project Bidirectional Sync Architecture.md +0 -0
- {basic_memory-0.17.2 → basic_memory-0.17.4}/specs/SPEC-9 Signed Header Tenant Information.md +0 -0
- {basic_memory-0.17.2 → basic_memory-0.17.4}/specs/SPEC-9-1 Follow-Ups- Conflict, Sync, and Observability.md +0 -0
- {basic_memory-0.17.2 → basic_memory-0.17.4}/src/basic_memory/alembic/alembic.ini +0 -0
- {basic_memory-0.17.2 → basic_memory-0.17.4}/src/basic_memory/alembic/env.py +0 -0
- {basic_memory-0.17.2 → basic_memory-0.17.4}/src/basic_memory/alembic/migrations.py +0 -0
- {basic_memory-0.17.2 → basic_memory-0.17.4}/src/basic_memory/alembic/script.py.mako +0 -0
- {basic_memory-0.17.2 → basic_memory-0.17.4}/src/basic_memory/alembic/versions/314f1ea54dc4_add_postgres_full_text_search_support_.py +0 -0
- {basic_memory-0.17.2 → basic_memory-0.17.4}/src/basic_memory/alembic/versions/3dae7c7b1564_initial_schema.py +0 -0
- {basic_memory-0.17.2 → basic_memory-0.17.4}/src/basic_memory/alembic/versions/502b60eaa905_remove_required_from_entity_permalink.py +0 -0
- {basic_memory-0.17.2 → basic_memory-0.17.4}/src/basic_memory/alembic/versions/5fe1ab1ccebe_add_projects_table.py +0 -0
- {basic_memory-0.17.2 → basic_memory-0.17.4}/src/basic_memory/alembic/versions/647e7a75e2cd_project_constraint_fix.py +0 -0
- {basic_memory-0.17.2 → basic_memory-0.17.4}/src/basic_memory/alembic/versions/9d9c1cb7d8f5_add_mtime_and_size_columns_to_entity_.py +0 -0
- {basic_memory-0.17.2 → basic_memory-0.17.4}/src/basic_memory/alembic/versions/a1b2c3d4e5f6_fix_project_foreign_keys.py +0 -0
- {basic_memory-0.17.2 → basic_memory-0.17.4}/src/basic_memory/alembic/versions/a2b3c4d5e6f7_add_search_index_entity_cascade.py +0 -0
- {basic_memory-0.17.2 → basic_memory-0.17.4}/src/basic_memory/alembic/versions/b3c3938bacdb_relation_to_name_unique_index.py +0 -0
- {basic_memory-0.17.2 → basic_memory-0.17.4}/src/basic_memory/alembic/versions/cc7172b46608_update_search_index_schema.py +0 -0
- {basic_memory-0.17.2 → basic_memory-0.17.4}/src/basic_memory/alembic/versions/e7e1f4367280_add_scan_watermark_tracking_to_project.py +0 -0
- {basic_memory-0.17.2 → basic_memory-0.17.4}/src/basic_memory/alembic/versions/f8a9b2c3d4e5_add_pg_trgm_for_fuzzy_link_resolution.py +0 -0
- {basic_memory-0.17.2 → basic_memory-0.17.4}/src/basic_memory/api/__init__.py +0 -0
- {basic_memory-0.17.2 → basic_memory-0.17.4}/src/basic_memory/api/routers/__init__.py +0 -0
- {basic_memory-0.17.2 → basic_memory-0.17.4}/src/basic_memory/api/routers/directory_router.py +0 -0
- {basic_memory-0.17.2 → basic_memory-0.17.4}/src/basic_memory/api/routers/importer_router.py +0 -0
- {basic_memory-0.17.2 → basic_memory-0.17.4}/src/basic_memory/api/routers/management_router.py +0 -0
- {basic_memory-0.17.2 → basic_memory-0.17.4}/src/basic_memory/api/routers/memory_router.py +0 -0
- {basic_memory-0.17.2 → basic_memory-0.17.4}/src/basic_memory/api/routers/prompt_router.py +0 -0
- {basic_memory-0.17.2 → basic_memory-0.17.4}/src/basic_memory/api/routers/search_router.py +0 -0
- {basic_memory-0.17.2 → basic_memory-0.17.4}/src/basic_memory/api/routers/utils.py +0 -0
- {basic_memory-0.17.2 → basic_memory-0.17.4}/src/basic_memory/api/template_loader.py +0 -0
- {basic_memory-0.17.2 → basic_memory-0.17.4}/src/basic_memory/api/v2/__init__.py +0 -0
- {basic_memory-0.17.2 → basic_memory-0.17.4}/src/basic_memory/api/v2/routers/__init__.py +0 -0
- {basic_memory-0.17.2 → basic_memory-0.17.4}/src/basic_memory/cli/__init__.py +0 -0
- {basic_memory-0.17.2 → basic_memory-0.17.4}/src/basic_memory/cli/commands/__init__.py +0 -0
- {basic_memory-0.17.2 → basic_memory-0.17.4}/src/basic_memory/cli/commands/cloud/__init__.py +0 -0
- {basic_memory-0.17.2 → basic_memory-0.17.4}/src/basic_memory/cli/commands/cloud/bisync_commands.py +0 -0
- {basic_memory-0.17.2 → basic_memory-0.17.4}/src/basic_memory/cli/commands/cloud/core_commands.py +0 -0
- {basic_memory-0.17.2 → basic_memory-0.17.4}/src/basic_memory/cli/commands/cloud/rclone_config.py +0 -0
- {basic_memory-0.17.2 → basic_memory-0.17.4}/src/basic_memory/cli/commands/cloud/rclone_installer.py +0 -0
- {basic_memory-0.17.2 → basic_memory-0.17.4}/src/basic_memory/cli/commands/cloud/upload_command.py +0 -0
- {basic_memory-0.17.2 → basic_memory-0.17.4}/src/basic_memory/cli/commands/format.py +0 -0
- {basic_memory-0.17.2 → basic_memory-0.17.4}/src/basic_memory/cli/commands/mcp.py +0 -0
- {basic_memory-0.17.2 → basic_memory-0.17.4}/src/basic_memory/cli/commands/status.py +0 -0
- {basic_memory-0.17.2 → basic_memory-0.17.4}/src/basic_memory/cli/commands/telemetry.py +0 -0
- {basic_memory-0.17.2 → basic_memory-0.17.4}/src/basic_memory/cli/commands/tool.py +0 -0
- {basic_memory-0.17.2 → basic_memory-0.17.4}/src/basic_memory/cli/main.py +0 -0
- {basic_memory-0.17.2 → basic_memory-0.17.4}/src/basic_memory/importers/__init__.py +0 -0
- {basic_memory-0.17.2 → basic_memory-0.17.4}/src/basic_memory/importers/utils.py +0 -0
- {basic_memory-0.17.2 → basic_memory-0.17.4}/src/basic_memory/markdown/__init__.py +0 -0
- {basic_memory-0.17.2 → basic_memory-0.17.4}/src/basic_memory/markdown/entity_parser.py +0 -0
- {basic_memory-0.17.2 → basic_memory-0.17.4}/src/basic_memory/markdown/plugins.py +0 -0
- {basic_memory-0.17.2 → basic_memory-0.17.4}/src/basic_memory/markdown/schemas.py +0 -0
- {basic_memory-0.17.2 → basic_memory-0.17.4}/src/basic_memory/markdown/utils.py +0 -0
- {basic_memory-0.17.2 → basic_memory-0.17.4}/src/basic_memory/mcp/__init__.py +0 -0
- {basic_memory-0.17.2 → basic_memory-0.17.4}/src/basic_memory/mcp/async_client.py +0 -0
- {basic_memory-0.17.2 → basic_memory-0.17.4}/src/basic_memory/mcp/prompts/__init__.py +0 -0
- {basic_memory-0.17.2 → basic_memory-0.17.4}/src/basic_memory/mcp/prompts/continue_conversation.py +0 -0
- {basic_memory-0.17.2 → basic_memory-0.17.4}/src/basic_memory/mcp/prompts/search.py +0 -0
- {basic_memory-0.17.2 → basic_memory-0.17.4}/src/basic_memory/mcp/resources/ai_assistant_guide.md +0 -0
- {basic_memory-0.17.2 → basic_memory-0.17.4}/src/basic_memory/mcp/resources/project_info.py +0 -0
- {basic_memory-0.17.2 → basic_memory-0.17.4}/src/basic_memory/mcp/tools/__init__.py +0 -0
- {basic_memory-0.17.2 → basic_memory-0.17.4}/src/basic_memory/mcp/tools/view_note.py +0 -0
- {basic_memory-0.17.2 → basic_memory-0.17.4}/src/basic_memory/models/__init__.py +0 -0
- {basic_memory-0.17.2 → basic_memory-0.17.4}/src/basic_memory/models/base.py +0 -0
- {basic_memory-0.17.2 → basic_memory-0.17.4}/src/basic_memory/repository/__init__.py +0 -0
- {basic_memory-0.17.2 → basic_memory-0.17.4}/src/basic_memory/repository/observation_repository.py +0 -0
- {basic_memory-0.17.2 → basic_memory-0.17.4}/src/basic_memory/repository/project_info_repository.py +0 -0
- {basic_memory-0.17.2 → basic_memory-0.17.4}/src/basic_memory/repository/repository.py +0 -0
- {basic_memory-0.17.2 → basic_memory-0.17.4}/src/basic_memory/repository/search_index_row.py +0 -0
- {basic_memory-0.17.2 → basic_memory-0.17.4}/src/basic_memory/schemas/__init__.py +0 -0
- {basic_memory-0.17.2 → basic_memory-0.17.4}/src/basic_memory/schemas/cloud.py +0 -0
- {basic_memory-0.17.2 → basic_memory-0.17.4}/src/basic_memory/schemas/delete.py +0 -0
- {basic_memory-0.17.2 → basic_memory-0.17.4}/src/basic_memory/schemas/importer.py +0 -0
- {basic_memory-0.17.2 → basic_memory-0.17.4}/src/basic_memory/schemas/prompt.py +0 -0
- {basic_memory-0.17.2 → basic_memory-0.17.4}/src/basic_memory/schemas/request.py +0 -0
- {basic_memory-0.17.2 → basic_memory-0.17.4}/src/basic_memory/schemas/search.py +0 -0
- {basic_memory-0.17.2 → basic_memory-0.17.4}/src/basic_memory/schemas/v2/__init__.py +0 -0
- {basic_memory-0.17.2 → basic_memory-0.17.4}/src/basic_memory/services/__init__.py +0 -0
- {basic_memory-0.17.2 → basic_memory-0.17.4}/src/basic_memory/services/entity_service.py +0 -0
- {basic_memory-0.17.2 → basic_memory-0.17.4}/src/basic_memory/services/exceptions.py +0 -0
- {basic_memory-0.17.2 → basic_memory-0.17.4}/src/basic_memory/services/initialization.py +0 -0
- {basic_memory-0.17.2 → basic_memory-0.17.4}/src/basic_memory/services/link_resolver.py +0 -0
- {basic_memory-0.17.2 → basic_memory-0.17.4}/src/basic_memory/services/service.py +0 -0
- {basic_memory-0.17.2 → basic_memory-0.17.4}/src/basic_memory/sync/background_sync.py +0 -0
- {basic_memory-0.17.2 → basic_memory-0.17.4}/src/basic_memory/telemetry.py +0 -0
- {basic_memory-0.17.2 → basic_memory-0.17.4}/src/basic_memory/templates/prompts/continue_conversation.hbs +0 -0
- {basic_memory-0.17.2 → basic_memory-0.17.4}/src/basic_memory/templates/prompts/search.hbs +0 -0
- {basic_memory-0.17.2 → basic_memory-0.17.4}/test-int/BENCHMARKS.md +0 -0
- {basic_memory-0.17.2 → basic_memory-0.17.4}/test-int/cli/test_project_commands_integration.py +0 -0
- {basic_memory-0.17.2 → basic_memory-0.17.4}/test-int/cli/test_version_integration.py +0 -0
- {basic_memory-0.17.2 → basic_memory-0.17.4}/test-int/mcp/test_build_context_underscore.py +0 -0
- {basic_memory-0.17.2 → basic_memory-0.17.4}/test-int/mcp/test_build_context_validation.py +0 -0
- {basic_memory-0.17.2 → basic_memory-0.17.4}/test-int/mcp/test_chatgpt_tools_integration.py +0 -0
- {basic_memory-0.17.2 → basic_memory-0.17.4}/test-int/mcp/test_default_project_mode_integration.py +0 -0
- {basic_memory-0.17.2 → basic_memory-0.17.4}/test-int/mcp/test_delete_note_integration.py +0 -0
- {basic_memory-0.17.2 → basic_memory-0.17.4}/test-int/mcp/test_edit_note_integration.py +0 -0
- {basic_memory-0.17.2 → basic_memory-0.17.4}/test-int/mcp/test_list_directory_integration.py +0 -0
- {basic_memory-0.17.2 → basic_memory-0.17.4}/test-int/mcp/test_move_note_integration.py +0 -0
- {basic_memory-0.17.2 → basic_memory-0.17.4}/test-int/mcp/test_project_management_integration.py +0 -0
- {basic_memory-0.17.2 → basic_memory-0.17.4}/test-int/mcp/test_project_state_sync_integration.py +0 -0
- {basic_memory-0.17.2 → basic_memory-0.17.4}/test-int/mcp/test_read_content_integration.py +0 -0
- {basic_memory-0.17.2 → basic_memory-0.17.4}/test-int/mcp/test_read_note_integration.py +0 -0
- {basic_memory-0.17.2 → basic_memory-0.17.4}/test-int/mcp/test_search_integration.py +0 -0
- {basic_memory-0.17.2 → basic_memory-0.17.4}/test-int/mcp/test_single_project_mcp_integration.py +0 -0
- {basic_memory-0.17.2 → basic_memory-0.17.4}/test-int/test_db_wal_mode.py +0 -0
- {basic_memory-0.17.2 → basic_memory-0.17.4}/test-int/test_disable_permalinks_integration.py +0 -0
- {basic_memory-0.17.2 → basic_memory-0.17.4}/tests/Non-MarkdownFileSupport.pdf +0 -0
- {basic_memory-0.17.2 → basic_memory-0.17.4}/tests/README.md +0 -0
- {basic_memory-0.17.2 → basic_memory-0.17.4}/tests/Screenshot.png +0 -0
- {basic_memory-0.17.2 → basic_memory-0.17.4}/tests/__init__.py +0 -0
- {basic_memory-0.17.2 → basic_memory-0.17.4}/tests/api/conftest.py +0 -0
- {basic_memory-0.17.2 → basic_memory-0.17.4}/tests/api/test_continue_conversation_template.py +0 -0
- {basic_memory-0.17.2 → basic_memory-0.17.4}/tests/api/test_importer_router.py +0 -0
- {basic_memory-0.17.2 → basic_memory-0.17.4}/tests/api/test_memory_router.py +0 -0
- {basic_memory-0.17.2 → basic_memory-0.17.4}/tests/api/test_project_router.py +0 -0
- {basic_memory-0.17.2 → basic_memory-0.17.4}/tests/api/test_project_router_operations.py +0 -0
- {basic_memory-0.17.2 → basic_memory-0.17.4}/tests/api/test_prompt_router.py +0 -0
- {basic_memory-0.17.2 → basic_memory-0.17.4}/tests/api/test_resource_router.py +0 -0
- {basic_memory-0.17.2 → basic_memory-0.17.4}/tests/api/test_search_router.py +0 -0
- {basic_memory-0.17.2 → basic_memory-0.17.4}/tests/api/test_search_template.py +0 -0
- {basic_memory-0.17.2 → basic_memory-0.17.4}/tests/api/test_template_loader.py +0 -0
- {basic_memory-0.17.2 → basic_memory-0.17.4}/tests/api/test_template_loader_helpers.py +0 -0
- {basic_memory-0.17.2 → basic_memory-0.17.4}/tests/api/v2/__init__.py +0 -0
- {basic_memory-0.17.2 → basic_memory-0.17.4}/tests/api/v2/test_directory_router.py +0 -0
- {basic_memory-0.17.2 → basic_memory-0.17.4}/tests/api/v2/test_importer_router.py +0 -0
- {basic_memory-0.17.2 → basic_memory-0.17.4}/tests/api/v2/test_memory_router.py +0 -0
- {basic_memory-0.17.2 → basic_memory-0.17.4}/tests/api/v2/test_prompt_router.py +0 -0
- {basic_memory-0.17.2 → basic_memory-0.17.4}/tests/api/v2/test_search_router.py +0 -0
- {basic_memory-0.17.2 → basic_memory-0.17.4}/tests/cli/conftest.py +0 -0
- {basic_memory-0.17.2 → basic_memory-0.17.4}/tests/cli/test_cli_exit.py +0 -0
- {basic_memory-0.17.2 → basic_memory-0.17.4}/tests/cli/test_ignore_utils.py +0 -0
- {basic_memory-0.17.2 → basic_memory-0.17.4}/tests/cli/test_import_chatgpt.py +0 -0
- {basic_memory-0.17.2 → basic_memory-0.17.4}/tests/cli/test_import_claude_conversations.py +0 -0
- {basic_memory-0.17.2 → basic_memory-0.17.4}/tests/cli/test_import_claude_projects.py +0 -0
- {basic_memory-0.17.2 → basic_memory-0.17.4}/tests/db/test_issue_254_foreign_key_constraints.py +0 -0
- {basic_memory-0.17.2 → basic_memory-0.17.4}/tests/importers/test_importer_utils.py +0 -0
- {basic_memory-0.17.2 → basic_memory-0.17.4}/tests/markdown/__init__.py +0 -0
- {basic_memory-0.17.2 → basic_memory-0.17.4}/tests/markdown/test_date_frontmatter_parsing.py +0 -0
- {basic_memory-0.17.2 → basic_memory-0.17.4}/tests/markdown/test_entity_parser.py +0 -0
- {basic_memory-0.17.2 → basic_memory-0.17.4}/tests/markdown/test_entity_parser_error_handling.py +0 -0
- {basic_memory-0.17.2 → basic_memory-0.17.4}/tests/markdown/test_markdown_plugins.py +0 -0
- {basic_memory-0.17.2 → basic_memory-0.17.4}/tests/markdown/test_markdown_processor.py +0 -0
- {basic_memory-0.17.2 → basic_memory-0.17.4}/tests/markdown/test_observation_edge_cases.py +0 -0
- {basic_memory-0.17.2 → basic_memory-0.17.4}/tests/markdown/test_parser_edge_cases.py +0 -0
- {basic_memory-0.17.2 → basic_memory-0.17.4}/tests/markdown/test_relation_edge_cases.py +0 -0
- {basic_memory-0.17.2 → basic_memory-0.17.4}/tests/markdown/test_task_detection.py +0 -0
- {basic_memory-0.17.2 → basic_memory-0.17.4}/tests/mcp/conftest.py +0 -0
- {basic_memory-0.17.2 → basic_memory-0.17.4}/tests/mcp/test_obsidian_yaml_formatting.py +0 -0
- {basic_memory-0.17.2 → basic_memory-0.17.4}/tests/mcp/test_permalink_collision_file_overwrite.py +0 -0
- {basic_memory-0.17.2 → basic_memory-0.17.4}/tests/mcp/test_prompts.py +0 -0
- {basic_memory-0.17.2 → basic_memory-0.17.4}/tests/mcp/test_resources.py +0 -0
- {basic_memory-0.17.2 → basic_memory-0.17.4}/tests/mcp/test_tool_build_context.py +0 -0
- {basic_memory-0.17.2 → basic_memory-0.17.4}/tests/mcp/test_tool_canvas.py +0 -0
- {basic_memory-0.17.2 → basic_memory-0.17.4}/tests/mcp/test_tool_delete_note.py +0 -0
- {basic_memory-0.17.2 → basic_memory-0.17.4}/tests/mcp/test_tool_edit_note.py +0 -0
- {basic_memory-0.17.2 → basic_memory-0.17.4}/tests/mcp/test_tool_list_directory.py +0 -0
- {basic_memory-0.17.2 → basic_memory-0.17.4}/tests/mcp/test_tool_resource.py +0 -0
- {basic_memory-0.17.2 → basic_memory-0.17.4}/tests/mcp/test_tool_write_note.py +0 -0
- {basic_memory-0.17.2 → basic_memory-0.17.4}/tests/mcp/test_tool_write_note_kebab_filenames.py +0 -0
- {basic_memory-0.17.2 → basic_memory-0.17.4}/tests/repository/test_entity_repository.py +0 -0
- {basic_memory-0.17.2 → basic_memory-0.17.4}/tests/repository/test_entity_repository_upsert.py +0 -0
- {basic_memory-0.17.2 → basic_memory-0.17.4}/tests/repository/test_entity_upsert_issue_187.py +0 -0
- {basic_memory-0.17.2 → basic_memory-0.17.4}/tests/repository/test_observation_repository.py +0 -0
- {basic_memory-0.17.2 → basic_memory-0.17.4}/tests/repository/test_project_info_repository.py +0 -0
- {basic_memory-0.17.2 → basic_memory-0.17.4}/tests/repository/test_project_repository.py +0 -0
- {basic_memory-0.17.2 → basic_memory-0.17.4}/tests/repository/test_relation_repository.py +0 -0
- {basic_memory-0.17.2 → basic_memory-0.17.4}/tests/repository/test_repository.py +0 -0
- {basic_memory-0.17.2 → basic_memory-0.17.4}/tests/repository/test_search_repository_edit_bug_fix.py +0 -0
- {basic_memory-0.17.2 → basic_memory-0.17.4}/tests/schemas/test_base_timeframe_minimum.py +0 -0
- {basic_memory-0.17.2 → basic_memory-0.17.4}/tests/schemas/test_memory_serialization.py +0 -0
- {basic_memory-0.17.2 → basic_memory-0.17.4}/tests/schemas/test_memory_url.py +0 -0
- {basic_memory-0.17.2 → basic_memory-0.17.4}/tests/schemas/test_memory_url_validation.py +0 -0
- {basic_memory-0.17.2 → basic_memory-0.17.4}/tests/schemas/test_search.py +0 -0
- {basic_memory-0.17.2 → basic_memory-0.17.4}/tests/services/test_context_service.py +0 -0
- {basic_memory-0.17.2 → basic_memory-0.17.4}/tests/services/test_directory_service.py +0 -0
- {basic_memory-0.17.2 → basic_memory-0.17.4}/tests/services/test_entity_service_disable_permalinks.py +0 -0
- {basic_memory-0.17.2 → basic_memory-0.17.4}/tests/services/test_link_resolver.py +0 -0
- {basic_memory-0.17.2 → basic_memory-0.17.4}/tests/services/test_project_removal_bug.py +0 -0
- {basic_memory-0.17.2 → basic_memory-0.17.4}/tests/sync/test_character_conflicts.py +0 -0
- {basic_memory-0.17.2 → basic_memory-0.17.4}/tests/sync/test_sync_service_incremental.py +0 -0
- {basic_memory-0.17.2 → basic_memory-0.17.4}/tests/sync/test_sync_wikilink_issue.py +0 -0
- {basic_memory-0.17.2 → basic_memory-0.17.4}/tests/sync/test_tmp_files.py +0 -0
- {basic_memory-0.17.2 → basic_memory-0.17.4}/tests/test_config.py +0 -0
- {basic_memory-0.17.2 → basic_memory-0.17.4}/tests/test_production_cascade_delete.py +0 -0
- {basic_memory-0.17.2 → basic_memory-0.17.4}/tests/utils/test_file_utils.py +0 -0
- {basic_memory-0.17.2 → basic_memory-0.17.4}/tests/utils/test_frontmatter_obsidian_compatible.py +0 -0
- {basic_memory-0.17.2 → basic_memory-0.17.4}/tests/utils/test_parse_tags.py +0 -0
- {basic_memory-0.17.2 → basic_memory-0.17.4}/tests/utils/test_permalink_formatting.py +0 -0
- {basic_memory-0.17.2 → basic_memory-0.17.4}/tests/utils/test_utf8_handling.py +0 -0
- {basic_memory-0.17.2 → basic_memory-0.17.4}/tests/utils/test_validate_project_path.py +0 -0
|
@@ -54,6 +54,7 @@ jobs:
|
|
|
54
54
|
- [ ] Unit tests for new functions/methods
|
|
55
55
|
- [ ] Integration tests for new MCP tools
|
|
56
56
|
- [ ] Test coverage for edge cases
|
|
57
|
+
- [ ] **100% test coverage maintained** (use `# pragma: no cover` only for truly hard-to-test code)
|
|
57
58
|
- [ ] Documentation updated (README, docstrings)
|
|
58
59
|
- [ ] CLAUDE.md updated if conventions change
|
|
59
60
|
|
|
@@ -110,4 +110,58 @@ jobs:
|
|
|
110
110
|
- name: Run tests (Postgres via testcontainers)
|
|
111
111
|
run: |
|
|
112
112
|
uv pip install pytest pytest-cov
|
|
113
|
-
just test-postgres
|
|
113
|
+
just test-postgres
|
|
114
|
+
|
|
115
|
+
coverage:
|
|
116
|
+
name: Coverage Summary (combined, Python 3.12)
|
|
117
|
+
runs-on: ubuntu-latest
|
|
118
|
+
|
|
119
|
+
steps:
|
|
120
|
+
- uses: actions/checkout@v4
|
|
121
|
+
with:
|
|
122
|
+
submodules: true
|
|
123
|
+
|
|
124
|
+
- name: Set up Python 3.12
|
|
125
|
+
uses: actions/setup-python@v4
|
|
126
|
+
with:
|
|
127
|
+
python-version: "3.12"
|
|
128
|
+
cache: "pip"
|
|
129
|
+
|
|
130
|
+
- name: Install uv
|
|
131
|
+
run: |
|
|
132
|
+
pip install uv
|
|
133
|
+
|
|
134
|
+
- name: Install just
|
|
135
|
+
run: |
|
|
136
|
+
curl --proto '=https' --tlsv1.2 -sSf https://just.systems/install.sh | bash -s -- --to /usr/local/bin
|
|
137
|
+
|
|
138
|
+
- name: Create virtual env
|
|
139
|
+
run: |
|
|
140
|
+
uv venv
|
|
141
|
+
|
|
142
|
+
- name: Install dependencies
|
|
143
|
+
run: |
|
|
144
|
+
uv pip install -e .[dev]
|
|
145
|
+
|
|
146
|
+
- name: Run combined coverage (SQLite + Postgres)
|
|
147
|
+
run: |
|
|
148
|
+
uv pip install pytest pytest-cov
|
|
149
|
+
just coverage
|
|
150
|
+
|
|
151
|
+
- name: Add coverage report to job summary
|
|
152
|
+
if: always()
|
|
153
|
+
run: |
|
|
154
|
+
{
|
|
155
|
+
echo "## Coverage"
|
|
156
|
+
echo ""
|
|
157
|
+
echo '```'
|
|
158
|
+
uv run coverage report -m
|
|
159
|
+
echo '```'
|
|
160
|
+
} >> "$GITHUB_STEP_SUMMARY"
|
|
161
|
+
|
|
162
|
+
- name: Upload HTML coverage report
|
|
163
|
+
if: always()
|
|
164
|
+
uses: actions/upload-artifact@v4
|
|
165
|
+
with:
|
|
166
|
+
name: htmlcov
|
|
167
|
+
path: htmlcov/
|
|
@@ -1,5 +1,65 @@
|
|
|
1
1
|
# CHANGELOG
|
|
2
2
|
|
|
3
|
+
## v0.17.4 (2026-01-05)
|
|
4
|
+
|
|
5
|
+
### Bug Fixes
|
|
6
|
+
|
|
7
|
+
- **#503**: Preserve search index across server restarts
|
|
8
|
+
([`26f7e98`](https://github.com/basicmachines-co/basic-memory/commit/26f7e98))
|
|
9
|
+
- Fixes critical bug where search index was wiped on every MCP server restart
|
|
10
|
+
- Bug was introduced in v0.16.3, affecting v0.16.3-v0.17.3
|
|
11
|
+
- **User action**: Run `basic-memory reset` once after updating to rebuild search index
|
|
12
|
+
|
|
13
|
+
### Internal
|
|
14
|
+
|
|
15
|
+
- **#502**: Major architecture refactor with composition roots and typed API clients
|
|
16
|
+
([`5947f04`](https://github.com/basicmachines-co/basic-memory/commit/5947f04))
|
|
17
|
+
- Add composition roots for API, MCP, and CLI entrypoints
|
|
18
|
+
- Split deps.py into feature-scoped modules (config, db, projects, repositories, services, importers)
|
|
19
|
+
- Add ProjectResolver for unified project selection
|
|
20
|
+
- Add SyncCoordinator for centralized sync/watch lifecycle
|
|
21
|
+
- Introduce typed API clients for MCP tools (KnowledgeClient, SearchClient, MemoryClient, etc.)
|
|
22
|
+
|
|
23
|
+
## v0.17.3 (2026-01-03)
|
|
24
|
+
|
|
25
|
+
### Features
|
|
26
|
+
|
|
27
|
+
- **#485**: Add stable external_id (UUID) to Project and Entity models
|
|
28
|
+
([`a4000f6`](https://github.com/basicmachines-co/basic-memory/commit/a4000f6))
|
|
29
|
+
- Projects and entities now have immutable UUID identifiers
|
|
30
|
+
- API v2 endpoints use external_id for stable references
|
|
31
|
+
- Directory responses include external_id for entities
|
|
32
|
+
|
|
33
|
+
### Bug Fixes
|
|
34
|
+
|
|
35
|
+
- **#501**: Update mcp dependency to support protocol version 2025-11-25
|
|
36
|
+
([`c6baf58`](https://github.com/basicmachines-co/basic-memory/commit/c6baf58))
|
|
37
|
+
- Fixes "Unsupported protocol version" error when using Claude Code
|
|
38
|
+
- Bump mcp from >=1.2.0 to >=1.23.1
|
|
39
|
+
|
|
40
|
+
- **#499**: Fix route ordering for cloud deployments
|
|
41
|
+
([`53c4c20`](https://github.com/basicmachines-co/basic-memory/commit/53c4c20))
|
|
42
|
+
|
|
43
|
+
- **#486**: Skip config file update for set_default_project in cloud mode
|
|
44
|
+
([`fd732aa`](https://github.com/basicmachines-co/basic-memory/commit/fd732aa))
|
|
45
|
+
|
|
46
|
+
- **#484**: Make RelationResponse.from_id optional to handle null permalinks
|
|
47
|
+
([`537e58a`](https://github.com/basicmachines-co/basic-memory/commit/537e58a))
|
|
48
|
+
|
|
49
|
+
- Use upsert to prevent IntegrityError during parallel search indexing
|
|
50
|
+
([`4ce2198`](https://github.com/basicmachines-co/basic-memory/commit/4ce2198))
|
|
51
|
+
|
|
52
|
+
- Use relative file paths in importers for cloud storage compatibility
|
|
53
|
+
([`8adf1f4`](https://github.com/basicmachines-co/basic-memory/commit/8adf1f4))
|
|
54
|
+
|
|
55
|
+
### Internal
|
|
56
|
+
|
|
57
|
+
- Refactor importers to use FileService for cloud compatibility
|
|
58
|
+
([`45ce181`](https://github.com/basicmachines-co/basic-memory/commit/45ce181))
|
|
59
|
+
|
|
60
|
+
- Strengthen integration test coverage, remove stdlib mocks
|
|
61
|
+
([`b4486d2`](https://github.com/basicmachines-co/basic-memory/commit/b4486d2))
|
|
62
|
+
|
|
3
63
|
## v0.17.2 (2025-12-29)
|
|
4
64
|
|
|
5
65
|
### Bug Fixes
|
|
@@ -117,17 +117,38 @@ counter += 1 # track retries for backoff calculation
|
|
|
117
117
|
|
|
118
118
|
### Codebase Architecture
|
|
119
119
|
|
|
120
|
+
See [docs/ARCHITECTURE.md](docs/ARCHITECTURE.md) for detailed architecture documentation.
|
|
121
|
+
|
|
122
|
+
**Directory Structure:**
|
|
120
123
|
- `/alembic` - Alembic db migrations
|
|
121
|
-
- `/api` - FastAPI
|
|
122
|
-
- `/cli` - Typer
|
|
124
|
+
- `/api` - FastAPI REST endpoints + `container.py` composition root
|
|
125
|
+
- `/cli` - Typer CLI + `container.py` composition root
|
|
126
|
+
- `/deps` - Feature-scoped FastAPI dependencies (config, db, projects, repositories, services, importers)
|
|
123
127
|
- `/importers` - Import functionality for Claude, ChatGPT, and other sources
|
|
124
128
|
- `/markdown` - Markdown parsing and processing
|
|
125
|
-
- `/mcp` -
|
|
129
|
+
- `/mcp` - MCP server + `container.py` composition root + `clients/` typed API clients
|
|
126
130
|
- `/models` - SQLAlchemy ORM models
|
|
127
131
|
- `/repository` - Data access layer
|
|
128
132
|
- `/schemas` - Pydantic models for validation
|
|
129
133
|
- `/services` - Business logic layer
|
|
130
|
-
- `/sync` - File synchronization services
|
|
134
|
+
- `/sync` - File synchronization services + `coordinator.py` for lifecycle management
|
|
135
|
+
|
|
136
|
+
**Composition Roots:**
|
|
137
|
+
Each entrypoint (API, MCP, CLI) has a composition root that:
|
|
138
|
+
- Reads `ConfigManager` (the only place that reads global config)
|
|
139
|
+
- Resolves runtime mode via `RuntimeMode` enum (TEST > CLOUD > LOCAL)
|
|
140
|
+
- Provides dependencies to downstream code explicitly
|
|
141
|
+
|
|
142
|
+
**Typed API Clients (MCP):**
|
|
143
|
+
MCP tools use typed clients in `mcp/clients/` to communicate with the API:
|
|
144
|
+
- `KnowledgeClient` - Entity CRUD operations
|
|
145
|
+
- `SearchClient` - Search operations
|
|
146
|
+
- `MemoryClient` - Context building
|
|
147
|
+
- `DirectoryClient` - Directory listing
|
|
148
|
+
- `ResourceClient` - Resource reading
|
|
149
|
+
- `ProjectClient` - Project management
|
|
150
|
+
|
|
151
|
+
Flow: MCP Tool → Typed Client → HTTP API → Router → Service → Repository
|
|
131
152
|
|
|
132
153
|
### Development Notes
|
|
133
154
|
|
|
@@ -146,6 +167,7 @@ counter += 1 # track retries for backoff calculation
|
|
|
146
167
|
- CI runs SQLite and Postgres tests in parallel for faster feedback
|
|
147
168
|
- Performance benchmarks are in `test-int/test_sync_performance_benchmark.py`
|
|
148
169
|
- Use pytest markers: `@pytest.mark.benchmark` for benchmarks, `@pytest.mark.slow` for slow tests
|
|
170
|
+
- **Coverage must stay at 100%**: Write tests for new code. Only use `# pragma: no cover` when tests would require excessive mocking (e.g., TYPE_CHECKING blocks, error handlers that need failure injection, runtime-mode-dependent code paths)
|
|
149
171
|
|
|
150
172
|
### Async Client Pattern (Important!)
|
|
151
173
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: basic-memory
|
|
3
|
-
Version: 0.17.
|
|
3
|
+
Version: 0.17.4
|
|
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
|
|
@@ -19,7 +19,7 @@ Requires-Dist: fastmcp==2.12.3
|
|
|
19
19
|
Requires-Dist: greenlet>=3.1.1
|
|
20
20
|
Requires-Dist: loguru>=0.7.3
|
|
21
21
|
Requires-Dist: markdown-it-py>=3.0.0
|
|
22
|
-
Requires-Dist: mcp>=1.
|
|
22
|
+
Requires-Dist: mcp>=1.23.1
|
|
23
23
|
Requires-Dist: mdformat-frontmatter>=2.0.8
|
|
24
24
|
Requires-Dist: mdformat-gfm>=0.3.7
|
|
25
25
|
Requires-Dist: mdformat>=0.7.22
|
|
@@ -0,0 +1,412 @@
|
|
|
1
|
+
# Basic Memory Architecture
|
|
2
|
+
|
|
3
|
+
This document describes the architectural patterns and composition structure of Basic Memory.
|
|
4
|
+
|
|
5
|
+
## Overview
|
|
6
|
+
|
|
7
|
+
Basic Memory is a local-first knowledge management system with three entrypoints:
|
|
8
|
+
- **API** - FastAPI REST server for HTTP access
|
|
9
|
+
- **MCP** - Model Context Protocol server for LLM integration
|
|
10
|
+
- **CLI** - Typer command-line interface
|
|
11
|
+
|
|
12
|
+
Each entrypoint uses a **composition root** pattern to manage configuration and dependencies.
|
|
13
|
+
|
|
14
|
+
## Composition Roots
|
|
15
|
+
|
|
16
|
+
### What is a Composition Root?
|
|
17
|
+
|
|
18
|
+
A composition root is the single place in an application where dependencies are wired together. In Basic Memory, each entrypoint has its own composition root that:
|
|
19
|
+
|
|
20
|
+
1. Reads configuration from `ConfigManager`
|
|
21
|
+
2. Resolves runtime mode (cloud/local/test)
|
|
22
|
+
3. Creates and provides dependencies to downstream code
|
|
23
|
+
|
|
24
|
+
**Key principle**: Only composition roots read global configuration. All other modules receive configuration explicitly.
|
|
25
|
+
|
|
26
|
+
### Container Structure
|
|
27
|
+
|
|
28
|
+
Each entrypoint has a container dataclass in its package:
|
|
29
|
+
|
|
30
|
+
```
|
|
31
|
+
src/basic_memory/
|
|
32
|
+
├── api/
|
|
33
|
+
│ └── container.py # ApiContainer
|
|
34
|
+
├── mcp/
|
|
35
|
+
│ └── container.py # McpContainer
|
|
36
|
+
├── cli/
|
|
37
|
+
│ └── container.py # CliContainer
|
|
38
|
+
└── runtime.py # RuntimeMode enum and resolver
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
### Container Pattern
|
|
42
|
+
|
|
43
|
+
All containers follow the same structure:
|
|
44
|
+
|
|
45
|
+
```python
|
|
46
|
+
@dataclass
|
|
47
|
+
class Container:
|
|
48
|
+
config: BasicMemoryConfig
|
|
49
|
+
mode: RuntimeMode
|
|
50
|
+
|
|
51
|
+
@classmethod
|
|
52
|
+
def create(cls) -> "Container":
|
|
53
|
+
"""Create container by reading ConfigManager."""
|
|
54
|
+
config = ConfigManager().config
|
|
55
|
+
mode = resolve_runtime_mode(
|
|
56
|
+
cloud_mode_enabled=config.cloud_mode_enabled,
|
|
57
|
+
is_test_env=config.is_test_env,
|
|
58
|
+
)
|
|
59
|
+
return cls(config=config, mode=mode)
|
|
60
|
+
|
|
61
|
+
@property
|
|
62
|
+
def some_computed_property(self) -> bool:
|
|
63
|
+
"""Derived values based on config and mode."""
|
|
64
|
+
return self.mode.is_local and self.config.some_setting
|
|
65
|
+
|
|
66
|
+
# Module-level singleton
|
|
67
|
+
_container: Container | None = None
|
|
68
|
+
|
|
69
|
+
def get_container() -> Container:
|
|
70
|
+
if _container is None:
|
|
71
|
+
raise RuntimeError("Container not initialized")
|
|
72
|
+
return _container
|
|
73
|
+
|
|
74
|
+
def set_container(container: Container) -> None:
|
|
75
|
+
global _container
|
|
76
|
+
_container = container
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
### Runtime Mode Resolution
|
|
80
|
+
|
|
81
|
+
The `RuntimeMode` enum centralizes mode detection:
|
|
82
|
+
|
|
83
|
+
```python
|
|
84
|
+
class RuntimeMode(Enum):
|
|
85
|
+
LOCAL = "local"
|
|
86
|
+
CLOUD = "cloud"
|
|
87
|
+
TEST = "test"
|
|
88
|
+
|
|
89
|
+
@property
|
|
90
|
+
def is_cloud(self) -> bool:
|
|
91
|
+
return self == RuntimeMode.CLOUD
|
|
92
|
+
|
|
93
|
+
@property
|
|
94
|
+
def is_local(self) -> bool:
|
|
95
|
+
return self == RuntimeMode.LOCAL
|
|
96
|
+
|
|
97
|
+
@property
|
|
98
|
+
def is_test(self) -> bool:
|
|
99
|
+
return self == RuntimeMode.TEST
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
Resolution follows this precedence: **TEST > CLOUD > LOCAL**
|
|
103
|
+
|
|
104
|
+
```python
|
|
105
|
+
def resolve_runtime_mode(cloud_mode_enabled: bool, is_test_env: bool) -> RuntimeMode:
|
|
106
|
+
if is_test_env:
|
|
107
|
+
return RuntimeMode.TEST
|
|
108
|
+
if cloud_mode_enabled:
|
|
109
|
+
return RuntimeMode.CLOUD
|
|
110
|
+
return RuntimeMode.LOCAL
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
## Dependencies Package
|
|
114
|
+
|
|
115
|
+
### Structure
|
|
116
|
+
|
|
117
|
+
The `deps/` package provides FastAPI dependencies organized by feature:
|
|
118
|
+
|
|
119
|
+
```
|
|
120
|
+
src/basic_memory/deps/
|
|
121
|
+
├── __init__.py # Re-exports for backwards compatibility
|
|
122
|
+
├── config.py # Configuration access
|
|
123
|
+
├── db.py # Database/session management
|
|
124
|
+
├── projects.py # Project resolution
|
|
125
|
+
├── repositories.py # Data access layer
|
|
126
|
+
├── services.py # Business logic layer
|
|
127
|
+
└── importers.py # Import functionality
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
### Usage in Routers
|
|
131
|
+
|
|
132
|
+
```python
|
|
133
|
+
from basic_memory.deps.services import get_entity_service
|
|
134
|
+
from basic_memory.deps.projects import get_project_config
|
|
135
|
+
|
|
136
|
+
@router.get("/entities/{id}")
|
|
137
|
+
async def get_entity(
|
|
138
|
+
id: int,
|
|
139
|
+
entity_service: EntityService = Depends(get_entity_service),
|
|
140
|
+
project: ProjectConfig = Depends(get_project_config),
|
|
141
|
+
):
|
|
142
|
+
return await entity_service.get(id)
|
|
143
|
+
```
|
|
144
|
+
|
|
145
|
+
### Backwards Compatibility
|
|
146
|
+
|
|
147
|
+
The old `deps.py` file still exists as a thin re-export shim:
|
|
148
|
+
|
|
149
|
+
```python
|
|
150
|
+
# deps.py - backwards compatibility shim
|
|
151
|
+
from basic_memory.deps import *
|
|
152
|
+
```
|
|
153
|
+
|
|
154
|
+
New code should import from specific submodules (`basic_memory.deps.services`) for clarity.
|
|
155
|
+
|
|
156
|
+
## MCP Tools Architecture
|
|
157
|
+
|
|
158
|
+
### Typed API Clients
|
|
159
|
+
|
|
160
|
+
MCP tools communicate with the API through typed clients that encapsulate HTTP paths and response validation:
|
|
161
|
+
|
|
162
|
+
```
|
|
163
|
+
src/basic_memory/mcp/clients/
|
|
164
|
+
├── __init__.py # Re-exports all clients
|
|
165
|
+
├── base.py # BaseClient with common logic
|
|
166
|
+
├── knowledge.py # KnowledgeClient - entity CRUD
|
|
167
|
+
├── search.py # SearchClient - search operations
|
|
168
|
+
├── memory.py # MemoryClient - context building
|
|
169
|
+
├── directory.py # DirectoryClient - directory listing
|
|
170
|
+
├── resource.py # ResourceClient - resource reading
|
|
171
|
+
└── project.py # ProjectClient - project management
|
|
172
|
+
```
|
|
173
|
+
|
|
174
|
+
### Client Pattern
|
|
175
|
+
|
|
176
|
+
Each client encapsulates API paths and validates responses:
|
|
177
|
+
|
|
178
|
+
```python
|
|
179
|
+
class KnowledgeClient(BaseClient):
|
|
180
|
+
"""Client for knowledge/entity operations."""
|
|
181
|
+
|
|
182
|
+
async def resolve_entity(self, identifier: str) -> int:
|
|
183
|
+
"""Resolve identifier to entity ID."""
|
|
184
|
+
response = await call_get(
|
|
185
|
+
self.http_client,
|
|
186
|
+
f"{self._base_path}/resolve/{identifier}",
|
|
187
|
+
)
|
|
188
|
+
return int(response.text)
|
|
189
|
+
|
|
190
|
+
async def get_entity(self, entity_id: int) -> EntityResponse:
|
|
191
|
+
"""Get entity by ID."""
|
|
192
|
+
response = await call_get(
|
|
193
|
+
self.http_client,
|
|
194
|
+
f"{self._base_path}/entities/{entity_id}",
|
|
195
|
+
)
|
|
196
|
+
return EntityResponse.model_validate(response.json())
|
|
197
|
+
```
|
|
198
|
+
|
|
199
|
+
### Tool → Client → API Flow
|
|
200
|
+
|
|
201
|
+
```
|
|
202
|
+
MCP Tool (thin adapter)
|
|
203
|
+
↓
|
|
204
|
+
Typed Client (encapsulates paths, validates responses)
|
|
205
|
+
↓
|
|
206
|
+
HTTP API (FastAPI router)
|
|
207
|
+
↓
|
|
208
|
+
Service Layer (business logic)
|
|
209
|
+
↓
|
|
210
|
+
Repository Layer (data access)
|
|
211
|
+
```
|
|
212
|
+
|
|
213
|
+
Example tool using typed client:
|
|
214
|
+
|
|
215
|
+
```python
|
|
216
|
+
@mcp.tool()
|
|
217
|
+
async def search_notes(query: str, project: str | None = None) -> SearchResponse:
|
|
218
|
+
async with get_client() as client:
|
|
219
|
+
active_project = await get_active_project(client, project)
|
|
220
|
+
|
|
221
|
+
# Import client inside function to avoid circular imports
|
|
222
|
+
from basic_memory.mcp.clients import SearchClient
|
|
223
|
+
|
|
224
|
+
search_client = SearchClient(client, active_project.external_id)
|
|
225
|
+
return await search_client.search(query)
|
|
226
|
+
```
|
|
227
|
+
|
|
228
|
+
## Sync Coordination
|
|
229
|
+
|
|
230
|
+
### SyncCoordinator
|
|
231
|
+
|
|
232
|
+
The `SyncCoordinator` centralizes sync/watch lifecycle management:
|
|
233
|
+
|
|
234
|
+
```python
|
|
235
|
+
@dataclass
|
|
236
|
+
class SyncCoordinator:
|
|
237
|
+
"""Coordinates file sync and watch operations."""
|
|
238
|
+
|
|
239
|
+
status: SyncStatus = SyncStatus.NOT_STARTED
|
|
240
|
+
sync_task: asyncio.Task | None = None
|
|
241
|
+
watch_service: WatchService | None = None
|
|
242
|
+
|
|
243
|
+
async def start(self, ...):
|
|
244
|
+
"""Start sync and watch operations."""
|
|
245
|
+
|
|
246
|
+
async def stop(self):
|
|
247
|
+
"""Stop all sync operations gracefully."""
|
|
248
|
+
|
|
249
|
+
def get_status_info(self) -> dict:
|
|
250
|
+
"""Get current sync status for observability."""
|
|
251
|
+
```
|
|
252
|
+
|
|
253
|
+
### Status Enum
|
|
254
|
+
|
|
255
|
+
```python
|
|
256
|
+
class SyncStatus(Enum):
|
|
257
|
+
NOT_STARTED = "not_started"
|
|
258
|
+
STARTING = "starting"
|
|
259
|
+
RUNNING = "running"
|
|
260
|
+
STOPPING = "stopping"
|
|
261
|
+
STOPPED = "stopped"
|
|
262
|
+
ERROR = "error"
|
|
263
|
+
```
|
|
264
|
+
|
|
265
|
+
## Project Resolution
|
|
266
|
+
|
|
267
|
+
### ProjectResolver
|
|
268
|
+
|
|
269
|
+
Unified project selection across all entrypoints:
|
|
270
|
+
|
|
271
|
+
```python
|
|
272
|
+
class ProjectResolver:
|
|
273
|
+
"""Resolves which project to use based on context."""
|
|
274
|
+
|
|
275
|
+
def resolve(
|
|
276
|
+
self,
|
|
277
|
+
explicit_project: str | None = None,
|
|
278
|
+
) -> ResolvedProject:
|
|
279
|
+
"""Resolve project using three-tier hierarchy:
|
|
280
|
+
1. Explicit project parameter
|
|
281
|
+
2. Default project from config
|
|
282
|
+
3. Single available project
|
|
283
|
+
"""
|
|
284
|
+
```
|
|
285
|
+
|
|
286
|
+
### Resolution Modes
|
|
287
|
+
|
|
288
|
+
```python
|
|
289
|
+
class ResolutionMode(Enum):
|
|
290
|
+
EXPLICIT = "explicit" # User specified project
|
|
291
|
+
DEFAULT = "default" # Using configured default
|
|
292
|
+
SINGLE_PROJECT = "single" # Only one project exists
|
|
293
|
+
FALLBACK = "fallback" # Using first available
|
|
294
|
+
```
|
|
295
|
+
|
|
296
|
+
## Testing Patterns
|
|
297
|
+
|
|
298
|
+
### Container Testing
|
|
299
|
+
|
|
300
|
+
Each container has corresponding tests:
|
|
301
|
+
|
|
302
|
+
```
|
|
303
|
+
tests/
|
|
304
|
+
├── api/test_api_container.py
|
|
305
|
+
├── mcp/test_mcp_container.py
|
|
306
|
+
└── cli/test_cli_container.py
|
|
307
|
+
```
|
|
308
|
+
|
|
309
|
+
Tests verify:
|
|
310
|
+
- Container creation from config
|
|
311
|
+
- Runtime mode properties
|
|
312
|
+
- Container accessor functions (get/set)
|
|
313
|
+
|
|
314
|
+
### Mocking Typed Clients
|
|
315
|
+
|
|
316
|
+
When testing MCP tools, mock at the client level:
|
|
317
|
+
|
|
318
|
+
```python
|
|
319
|
+
def test_search_notes(monkeypatch):
|
|
320
|
+
import basic_memory.mcp.clients as clients_mod
|
|
321
|
+
|
|
322
|
+
class MockSearchClient:
|
|
323
|
+
async def search(self, query):
|
|
324
|
+
return SearchResponse(results=[...])
|
|
325
|
+
|
|
326
|
+
monkeypatch.setattr(clients_mod, "SearchClient", MockSearchClient)
|
|
327
|
+
```
|
|
328
|
+
|
|
329
|
+
## Design Principles
|
|
330
|
+
|
|
331
|
+
### 1. Explicit Dependencies
|
|
332
|
+
|
|
333
|
+
Modules receive configuration explicitly rather than reading globals:
|
|
334
|
+
|
|
335
|
+
```python
|
|
336
|
+
# Good - explicit injection
|
|
337
|
+
async def sync_files(config: BasicMemoryConfig):
|
|
338
|
+
...
|
|
339
|
+
|
|
340
|
+
# Avoid - hidden global access
|
|
341
|
+
async def sync_files():
|
|
342
|
+
config = ConfigManager().config # Hidden coupling
|
|
343
|
+
```
|
|
344
|
+
|
|
345
|
+
### 2. Single Responsibility
|
|
346
|
+
|
|
347
|
+
Each layer has a clear responsibility:
|
|
348
|
+
- **Containers**: Wire dependencies
|
|
349
|
+
- **Clients**: Encapsulate HTTP communication
|
|
350
|
+
- **Services**: Business logic
|
|
351
|
+
- **Repositories**: Data access
|
|
352
|
+
- **Tools/Routers**: Thin adapters
|
|
353
|
+
|
|
354
|
+
### 3. Deferred Imports
|
|
355
|
+
|
|
356
|
+
To avoid circular imports, typed clients are imported inside functions:
|
|
357
|
+
|
|
358
|
+
```python
|
|
359
|
+
async def my_tool():
|
|
360
|
+
async with get_client() as client:
|
|
361
|
+
# Import here to avoid circular dependency
|
|
362
|
+
from basic_memory.mcp.clients import KnowledgeClient
|
|
363
|
+
|
|
364
|
+
knowledge_client = KnowledgeClient(client, project_id)
|
|
365
|
+
```
|
|
366
|
+
|
|
367
|
+
### 4. Backwards Compatibility
|
|
368
|
+
|
|
369
|
+
When refactoring, maintain backwards compatibility via shims:
|
|
370
|
+
|
|
371
|
+
```python
|
|
372
|
+
# Old module becomes a shim
|
|
373
|
+
from basic_memory.new_location import *
|
|
374
|
+
|
|
375
|
+
# Docstring explains migration path
|
|
376
|
+
"""
|
|
377
|
+
DEPRECATED: Import from basic_memory.new_location instead.
|
|
378
|
+
This shim will be removed in a future version.
|
|
379
|
+
"""
|
|
380
|
+
```
|
|
381
|
+
|
|
382
|
+
## File Organization
|
|
383
|
+
|
|
384
|
+
```
|
|
385
|
+
src/basic_memory/
|
|
386
|
+
├── api/
|
|
387
|
+
│ ├── container.py # API composition root
|
|
388
|
+
│ ├── routers/ # FastAPI routers
|
|
389
|
+
│ └── ...
|
|
390
|
+
├── mcp/
|
|
391
|
+
│ ├── container.py # MCP composition root
|
|
392
|
+
│ ├── clients/ # Typed API clients
|
|
393
|
+
│ ├── tools/ # MCP tool definitions
|
|
394
|
+
│ └── server.py # MCP server setup
|
|
395
|
+
├── cli/
|
|
396
|
+
│ ├── container.py # CLI composition root
|
|
397
|
+
│ ├── app.py # Typer app
|
|
398
|
+
│ └── commands/ # CLI command groups
|
|
399
|
+
├── deps/
|
|
400
|
+
│ ├── config.py # Config dependencies
|
|
401
|
+
│ ├── db.py # Database dependencies
|
|
402
|
+
│ ├── projects.py # Project dependencies
|
|
403
|
+
│ ├── repositories.py # Repository dependencies
|
|
404
|
+
│ ├── services.py # Service dependencies
|
|
405
|
+
│ └── importers.py # Importer dependencies
|
|
406
|
+
├── sync/
|
|
407
|
+
│ ├── coordinator.py # SyncCoordinator
|
|
408
|
+
│ └── ...
|
|
409
|
+
├── runtime.py # RuntimeMode resolution
|
|
410
|
+
├── project_resolver.py # Unified project selection
|
|
411
|
+
└── config.py # Configuration management
|
|
412
|
+
```
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
## Coverage policy (practical 100%)
|
|
2
|
+
|
|
3
|
+
Basic Memory’s test suite intentionally mixes:
|
|
4
|
+
- unit tests (fast, deterministic)
|
|
5
|
+
- integration tests (real filesystem + real DB via `test-int/`)
|
|
6
|
+
|
|
7
|
+
To keep the default CI signal **stable and meaningful**, the default `pytest` coverage report targets **core library logic** and **excludes** a small set of modules that are either:
|
|
8
|
+
- highly environment-dependent (OS/DB tuning)
|
|
9
|
+
- inherently interactive (CLI)
|
|
10
|
+
- background-task orchestration (watchers/sync runners)
|
|
11
|
+
- external analytics
|
|
12
|
+
|
|
13
|
+
### What’s excluded (and why)
|
|
14
|
+
|
|
15
|
+
Coverage excludes are configured in `pyproject.toml` under `[tool.coverage.report].omit`.
|
|
16
|
+
|
|
17
|
+
Current exclusions include:
|
|
18
|
+
- `src/basic_memory/cli/**`: interactive wrappers; behavior is validated via higher-level tests and smoke tests.
|
|
19
|
+
- `src/basic_memory/db.py`: platform/backend tuning paths (SQLite/Postgres/Windows), covered by integration tests and targeted runs.
|
|
20
|
+
- `src/basic_memory/services/initialization.py`: startup orchestration/background tasks; covered indirectly by app/MCP entrypoints.
|
|
21
|
+
- `src/basic_memory/sync/sync_service.py`: heavy filesystem↔DB integration; validated in integration suite (not enforced in unit coverage).
|
|
22
|
+
- `src/basic_memory/telemetry.py`: external analytics; exercised lightly but excluded from strict coverage gate.
|
|
23
|
+
|
|
24
|
+
### Recommended additional runs
|
|
25
|
+
|
|
26
|
+
If you want extra confidence locally/CI:
|
|
27
|
+
- **Postgres backend**: run tests with `BASIC_MEMORY_TEST_POSTGRES=1`.
|
|
28
|
+
- **Strict backend-complete coverage**: run coverage on SQLite + Postgres and combine the results (recommended).
|
|
29
|
+
|
|
30
|
+
|