basic-memory 0.17.9__tar.gz → 0.18.0__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.9 → basic_memory-0.18.0}/CHANGELOG.md +31 -0
- {basic_memory-0.17.9 → basic_memory-0.18.0}/CLAUDE.md +24 -4
- {basic_memory-0.17.9 → basic_memory-0.18.0}/PKG-INFO +18 -1
- {basic_memory-0.17.9 → basic_memory-0.18.0}/README.md +17 -0
- {basic_memory-0.17.9 → basic_memory-0.18.0}/server.json +2 -2
- {basic_memory-0.17.9 → basic_memory-0.18.0}/src/basic_memory/__init__.py +1 -1
- {basic_memory-0.17.9 → basic_memory-0.18.0}/src/basic_memory/api/routers/importer_router.py +12 -12
- {basic_memory-0.17.9 → basic_memory-0.18.0}/src/basic_memory/api/routers/knowledge_router.py +46 -1
- {basic_memory-0.17.9 → basic_memory-0.18.0}/src/basic_memory/api/v2/routers/importer_router.py +15 -15
- {basic_memory-0.17.9 → basic_memory-0.18.0}/src/basic_memory/api/v2/routers/knowledge_router.py +105 -1
- basic_memory-0.18.0/src/basic_memory/cli/commands/mcp.py +80 -0
- {basic_memory-0.17.9 → basic_memory-0.18.0}/src/basic_memory/cli/commands/project.py +136 -44
- basic_memory-0.18.0/src/basic_memory/cli/commands/routing.py +73 -0
- {basic_memory-0.17.9 → basic_memory-0.18.0}/src/basic_memory/cli/commands/status.py +16 -2
- {basic_memory-0.17.9 → basic_memory-0.18.0}/src/basic_memory/cli/commands/tool.py +155 -73
- {basic_memory-0.17.9 → basic_memory-0.18.0}/src/basic_memory/file_utils.py +4 -4
- {basic_memory-0.17.9 → basic_memory-0.18.0}/src/basic_memory/mcp/async_client.py +32 -2
- {basic_memory-0.17.9 → basic_memory-0.18.0}/src/basic_memory/mcp/clients/knowledge.py +50 -1
- {basic_memory-0.17.9 → basic_memory-0.18.0}/src/basic_memory/mcp/prompts/continue_conversation.py +1 -2
- basic_memory-0.18.0/src/basic_memory/mcp/prompts/recent_activity.py +100 -0
- {basic_memory-0.17.9 → basic_memory-0.18.0}/src/basic_memory/mcp/prompts/search.py +1 -2
- {basic_memory-0.17.9 → basic_memory-0.18.0}/src/basic_memory/mcp/prompts/utils.py +1 -2
- {basic_memory-0.17.9 → basic_memory-0.18.0}/src/basic_memory/mcp/tools/canvas.py +11 -11
- {basic_memory-0.17.9 → basic_memory-0.18.0}/src/basic_memory/mcp/tools/delete_note.py +94 -14
- {basic_memory-0.17.9 → basic_memory-0.18.0}/src/basic_memory/mcp/tools/move_note.py +92 -11
- {basic_memory-0.17.9 → basic_memory-0.18.0}/src/basic_memory/mcp/tools/search.py +1 -1
- {basic_memory-0.17.9 → basic_memory-0.18.0}/src/basic_memory/mcp/tools/write_note.py +18 -18
- {basic_memory-0.17.9 → basic_memory-0.18.0}/src/basic_memory/repository/entity_repository.py +12 -3
- {basic_memory-0.17.9 → basic_memory-0.18.0}/src/basic_memory/schemas/base.py +7 -5
- {basic_memory-0.17.9 → basic_memory-0.18.0}/src/basic_memory/schemas/request.py +24 -0
- {basic_memory-0.17.9 → basic_memory-0.18.0}/src/basic_memory/schemas/response.py +68 -0
- {basic_memory-0.17.9 → basic_memory-0.18.0}/src/basic_memory/schemas/v2/__init__.py +4 -0
- {basic_memory-0.17.9 → basic_memory-0.18.0}/src/basic_memory/schemas/v2/entity.py +48 -0
- {basic_memory-0.17.9 → basic_memory-0.18.0}/src/basic_memory/services/entity_service.py +175 -1
- basic_memory-0.18.0/src/basic_memory/services/link_resolver.py +251 -0
- basic_memory-0.18.0/test-int/cli/test_routing_integration.py +181 -0
- {basic_memory-0.17.9 → basic_memory-0.18.0}/test-int/mcp/test_build_context_underscore.py +5 -5
- {basic_memory-0.17.9 → basic_memory-0.18.0}/test-int/mcp/test_build_context_validation.py +2 -2
- {basic_memory-0.17.9 → basic_memory-0.18.0}/test-int/mcp/test_chatgpt_tools_integration.py +10 -10
- {basic_memory-0.17.9 → basic_memory-0.18.0}/test-int/mcp/test_default_project_mode_integration.py +9 -9
- basic_memory-0.18.0/test-int/mcp/test_delete_directory_integration.py +268 -0
- {basic_memory-0.17.9 → basic_memory-0.18.0}/test-int/mcp/test_delete_note_integration.py +8 -8
- {basic_memory-0.17.9 → basic_memory-0.18.0}/test-int/mcp/test_edit_note_integration.py +11 -11
- {basic_memory-0.17.9 → basic_memory-0.18.0}/test-int/mcp/test_list_directory_integration.py +23 -23
- basic_memory-0.18.0/test-int/mcp/test_move_directory_integration.py +343 -0
- {basic_memory-0.17.9 → basic_memory-0.18.0}/test-int/mcp/test_move_note_integration.py +14 -14
- {basic_memory-0.17.9 → basic_memory-0.18.0}/test-int/mcp/test_project_management_integration.py +5 -5
- {basic_memory-0.17.9 → basic_memory-0.18.0}/test-int/mcp/test_project_state_sync_integration.py +1 -1
- {basic_memory-0.17.9 → basic_memory-0.18.0}/test-int/mcp/test_read_content_integration.py +8 -8
- {basic_memory-0.17.9 → basic_memory-0.18.0}/test-int/mcp/test_read_note_integration.py +2 -2
- {basic_memory-0.17.9 → basic_memory-0.18.0}/test-int/mcp/test_search_integration.py +20 -20
- {basic_memory-0.17.9 → basic_memory-0.18.0}/test-int/mcp/test_single_project_mcp_integration.py +6 -6
- {basic_memory-0.17.9 → basic_memory-0.18.0}/test-int/mcp/test_write_note_integration.py +13 -13
- {basic_memory-0.17.9 → basic_memory-0.18.0}/test-int/test_disable_permalinks_integration.py +1 -1
- {basic_memory-0.17.9 → basic_memory-0.18.0}/tests/api/test_importer_router.py +11 -11
- {basic_memory-0.17.9 → basic_memory-0.18.0}/tests/api/test_knowledge_router.py +161 -44
- {basic_memory-0.17.9 → basic_memory-0.18.0}/tests/api/test_resource_router.py +7 -7
- {basic_memory-0.17.9 → basic_memory-0.18.0}/tests/api/test_search_router.py +1 -1
- {basic_memory-0.17.9 → basic_memory-0.18.0}/tests/api/v2/test_importer_router.py +16 -16
- {basic_memory-0.17.9 → basic_memory-0.18.0}/tests/api/v2/test_knowledge_router.py +237 -11
- basic_memory-0.18.0/tests/cli/test_routing.py +102 -0
- {basic_memory-0.17.9 → basic_memory-0.18.0}/tests/conftest.py +6 -6
- basic_memory-0.18.0/tests/mcp/test_async_client_force_local.py +79 -0
- {basic_memory-0.17.9 → basic_memory-0.18.0}/tests/mcp/test_obsidian_yaml_formatting.py +8 -8
- {basic_memory-0.17.9 → basic_memory-0.18.0}/tests/mcp/test_permalink_collision_file_overwrite.py +5 -5
- {basic_memory-0.17.9 → basic_memory-0.18.0}/tests/mcp/test_prompts.py +8 -6
- basic_memory-0.18.0/tests/mcp/test_recent_activity_prompt_modes.py +91 -0
- {basic_memory-0.17.9 → basic_memory-0.18.0}/tests/mcp/test_tool_canvas.py +6 -6
- {basic_memory-0.17.9 → basic_memory-0.18.0}/tests/mcp/test_tool_edit_note.py +16 -16
- {basic_memory-0.17.9 → basic_memory-0.18.0}/tests/mcp/test_tool_list_directory.py +3 -3
- {basic_memory-0.17.9 → basic_memory-0.18.0}/tests/mcp/test_tool_move_note.py +28 -28
- {basic_memory-0.17.9 → basic_memory-0.18.0}/tests/mcp/test_tool_read_content.py +1 -1
- {basic_memory-0.17.9 → basic_memory-0.18.0}/tests/mcp/test_tool_read_note.py +8 -8
- {basic_memory-0.17.9 → basic_memory-0.18.0}/tests/mcp/test_tool_recent_activity.py +2 -2
- {basic_memory-0.17.9 → basic_memory-0.18.0}/tests/mcp/test_tool_resource.py +3 -3
- {basic_memory-0.17.9 → basic_memory-0.18.0}/tests/mcp/test_tool_search.py +8 -8
- {basic_memory-0.17.9 → basic_memory-0.18.0}/tests/mcp/test_tool_view_note.py +12 -12
- {basic_memory-0.17.9 → basic_memory-0.18.0}/tests/mcp/test_tool_write_note.py +39 -39
- {basic_memory-0.17.9 → basic_memory-0.18.0}/tests/mcp/test_tool_write_note_kebab_filenames.py +20 -20
- {basic_memory-0.17.9 → basic_memory-0.18.0}/tests/mcp/tools/test_chatgpt_tools.py +3 -3
- {basic_memory-0.17.9 → basic_memory-0.18.0}/tests/repository/test_entity_repository.py +60 -0
- {basic_memory-0.17.9 → basic_memory-0.18.0}/tests/schemas/test_schemas.py +8 -8
- {basic_memory-0.17.9 → basic_memory-0.18.0}/tests/services/test_entity_service.py +53 -53
- {basic_memory-0.17.9 → basic_memory-0.18.0}/tests/services/test_entity_service_disable_permalinks.py +4 -4
- basic_memory-0.18.0/tests/services/test_link_resolver.py +831 -0
- {basic_memory-0.17.9 → basic_memory-0.18.0}/tests/sync/test_sync_service.py +4 -3
- {basic_memory-0.17.9 → basic_memory-0.18.0}/tests/utils/test_file_utils.py +19 -19
- basic_memory-0.17.9/src/basic_memory/cli/commands/mcp.py +0 -76
- basic_memory-0.17.9/src/basic_memory/mcp/prompts/recent_activity.py +0 -188
- basic_memory-0.17.9/src/basic_memory/services/link_resolver.py +0 -121
- basic_memory-0.17.9/tests/mcp/test_recent_activity_prompt_modes.py +0 -111
- basic_memory-0.17.9/tests/services/test_link_resolver.py +0 -359
- {basic_memory-0.17.9 → basic_memory-0.18.0}/.claude/commands/release/beta.md +0 -0
- {basic_memory-0.17.9 → basic_memory-0.18.0}/.claude/commands/release/changelog.md +0 -0
- {basic_memory-0.17.9 → basic_memory-0.18.0}/.claude/commands/release/release-check.md +0 -0
- {basic_memory-0.17.9 → basic_memory-0.18.0}/.claude/commands/release/release.md +0 -0
- {basic_memory-0.17.9 → basic_memory-0.18.0}/.claude/commands/spec.md +0 -0
- {basic_memory-0.17.9 → basic_memory-0.18.0}/.claude/commands/test-live.md +0 -0
- {basic_memory-0.17.9 → basic_memory-0.18.0}/.claude/settings.json +0 -0
- {basic_memory-0.17.9 → basic_memory-0.18.0}/.dockerignore +0 -0
- {basic_memory-0.17.9 → basic_memory-0.18.0}/.env.example +0 -0
- {basic_memory-0.17.9 → basic_memory-0.18.0}/.github/ISSUE_TEMPLATE/bug_report.md +0 -0
- {basic_memory-0.17.9 → basic_memory-0.18.0}/.github/ISSUE_TEMPLATE/config.yml +0 -0
- {basic_memory-0.17.9 → basic_memory-0.18.0}/.github/ISSUE_TEMPLATE/documentation.md +0 -0
- {basic_memory-0.17.9 → basic_memory-0.18.0}/.github/ISSUE_TEMPLATE/feature_request.md +0 -0
- {basic_memory-0.17.9 → basic_memory-0.18.0}/.github/dependabot.yml +0 -0
- {basic_memory-0.17.9 → basic_memory-0.18.0}/.github/workflows/claude-code-review.yml +0 -0
- {basic_memory-0.17.9 → basic_memory-0.18.0}/.github/workflows/claude-issue-triage.yml +0 -0
- {basic_memory-0.17.9 → basic_memory-0.18.0}/.github/workflows/claude.yml +0 -0
- {basic_memory-0.17.9 → basic_memory-0.18.0}/.github/workflows/dev-release.yml +0 -0
- {basic_memory-0.17.9 → basic_memory-0.18.0}/.github/workflows/docker.yml +0 -0
- {basic_memory-0.17.9 → basic_memory-0.18.0}/.github/workflows/pr-title.yml +0 -0
- {basic_memory-0.17.9 → basic_memory-0.18.0}/.github/workflows/release.yml +0 -0
- {basic_memory-0.17.9 → basic_memory-0.18.0}/.github/workflows/test.yml +0 -0
- {basic_memory-0.17.9 → basic_memory-0.18.0}/.gitignore +0 -0
- {basic_memory-0.17.9 → basic_memory-0.18.0}/.python-version +0 -0
- {basic_memory-0.17.9 → basic_memory-0.18.0}/CITATION.cff +0 -0
- {basic_memory-0.17.9 → basic_memory-0.18.0}/CLA.md +0 -0
- {basic_memory-0.17.9 → basic_memory-0.18.0}/CODE_OF_CONDUCT.md +0 -0
- {basic_memory-0.17.9 → basic_memory-0.18.0}/CONTRIBUTING.md +0 -0
- {basic_memory-0.17.9 → basic_memory-0.18.0}/Dockerfile +0 -0
- {basic_memory-0.17.9 → basic_memory-0.18.0}/LICENSE +0 -0
- {basic_memory-0.17.9 → basic_memory-0.18.0}/SECURITY.md +0 -0
- {basic_memory-0.17.9 → basic_memory-0.18.0}/docker-compose-postgres.yml +0 -0
- {basic_memory-0.17.9 → basic_memory-0.18.0}/docker-compose.yml +0 -0
- {basic_memory-0.17.9 → basic_memory-0.18.0}/docs/ARCHITECTURE.md +0 -0
- {basic_memory-0.17.9 → basic_memory-0.18.0}/docs/Docker.md +0 -0
- {basic_memory-0.17.9 → basic_memory-0.18.0}/docs/ai-assistant-guide-extended.md +0 -0
- {basic_memory-0.17.9 → basic_memory-0.18.0}/docs/character-handling.md +0 -0
- {basic_memory-0.17.9 → basic_memory-0.18.0}/docs/cloud-cli.md +0 -0
- {basic_memory-0.17.9 → basic_memory-0.18.0}/docs/testing-coverage.md +0 -0
- {basic_memory-0.17.9 → basic_memory-0.18.0}/justfile +0 -0
- {basic_memory-0.17.9 → basic_memory-0.18.0}/llms-install.md +0 -0
- {basic_memory-0.17.9 → basic_memory-0.18.0}/pyproject.toml +0 -0
- {basic_memory-0.17.9 → basic_memory-0.18.0}/smithery.yaml +0 -0
- {basic_memory-0.17.9 → basic_memory-0.18.0}/src/basic_memory/alembic/alembic.ini +0 -0
- {basic_memory-0.17.9 → basic_memory-0.18.0}/src/basic_memory/alembic/env.py +0 -0
- {basic_memory-0.17.9 → basic_memory-0.18.0}/src/basic_memory/alembic/migrations.py +0 -0
- {basic_memory-0.17.9 → basic_memory-0.18.0}/src/basic_memory/alembic/script.py.mako +0 -0
- {basic_memory-0.17.9 → basic_memory-0.18.0}/src/basic_memory/alembic/versions/314f1ea54dc4_add_postgres_full_text_search_support_.py +0 -0
- {basic_memory-0.17.9 → basic_memory-0.18.0}/src/basic_memory/alembic/versions/3dae7c7b1564_initial_schema.py +0 -0
- {basic_memory-0.17.9 → basic_memory-0.18.0}/src/basic_memory/alembic/versions/502b60eaa905_remove_required_from_entity_permalink.py +0 -0
- {basic_memory-0.17.9 → basic_memory-0.18.0}/src/basic_memory/alembic/versions/5fe1ab1ccebe_add_projects_table.py +0 -0
- {basic_memory-0.17.9 → basic_memory-0.18.0}/src/basic_memory/alembic/versions/647e7a75e2cd_project_constraint_fix.py +0 -0
- {basic_memory-0.17.9 → basic_memory-0.18.0}/src/basic_memory/alembic/versions/6830751f5fb6_merge_multiple_heads.py +0 -0
- {basic_memory-0.17.9 → basic_memory-0.18.0}/src/basic_memory/alembic/versions/9d9c1cb7d8f5_add_mtime_and_size_columns_to_entity_.py +0 -0
- {basic_memory-0.17.9 → basic_memory-0.18.0}/src/basic_memory/alembic/versions/a1b2c3d4e5f6_fix_project_foreign_keys.py +0 -0
- {basic_memory-0.17.9 → basic_memory-0.18.0}/src/basic_memory/alembic/versions/a2b3c4d5e6f7_add_search_index_entity_cascade.py +0 -0
- {basic_memory-0.17.9 → basic_memory-0.18.0}/src/basic_memory/alembic/versions/b3c3938bacdb_relation_to_name_unique_index.py +0 -0
- {basic_memory-0.17.9 → basic_memory-0.18.0}/src/basic_memory/alembic/versions/cc7172b46608_update_search_index_schema.py +0 -0
- {basic_memory-0.17.9 → basic_memory-0.18.0}/src/basic_memory/alembic/versions/e7e1f4367280_add_scan_watermark_tracking_to_project.py +0 -0
- {basic_memory-0.17.9 → basic_memory-0.18.0}/src/basic_memory/alembic/versions/f8a9b2c3d4e5_add_pg_trgm_for_fuzzy_link_resolution.py +0 -0
- {basic_memory-0.17.9 → basic_memory-0.18.0}/src/basic_memory/alembic/versions/g9a0b3c4d5e6_add_external_id_to_project_and_entity.py +0 -0
- {basic_memory-0.17.9 → basic_memory-0.18.0}/src/basic_memory/api/__init__.py +0 -0
- {basic_memory-0.17.9 → basic_memory-0.18.0}/src/basic_memory/api/app.py +0 -0
- {basic_memory-0.17.9 → basic_memory-0.18.0}/src/basic_memory/api/container.py +0 -0
- {basic_memory-0.17.9 → basic_memory-0.18.0}/src/basic_memory/api/routers/__init__.py +0 -0
- {basic_memory-0.17.9 → basic_memory-0.18.0}/src/basic_memory/api/routers/directory_router.py +0 -0
- {basic_memory-0.17.9 → basic_memory-0.18.0}/src/basic_memory/api/routers/management_router.py +0 -0
- {basic_memory-0.17.9 → basic_memory-0.18.0}/src/basic_memory/api/routers/memory_router.py +0 -0
- {basic_memory-0.17.9 → basic_memory-0.18.0}/src/basic_memory/api/routers/project_router.py +0 -0
- {basic_memory-0.17.9 → basic_memory-0.18.0}/src/basic_memory/api/routers/prompt_router.py +0 -0
- {basic_memory-0.17.9 → basic_memory-0.18.0}/src/basic_memory/api/routers/resource_router.py +0 -0
- {basic_memory-0.17.9 → basic_memory-0.18.0}/src/basic_memory/api/routers/search_router.py +0 -0
- {basic_memory-0.17.9 → basic_memory-0.18.0}/src/basic_memory/api/routers/utils.py +0 -0
- {basic_memory-0.17.9 → basic_memory-0.18.0}/src/basic_memory/api/template_loader.py +0 -0
- {basic_memory-0.17.9 → basic_memory-0.18.0}/src/basic_memory/api/v2/__init__.py +0 -0
- {basic_memory-0.17.9 → basic_memory-0.18.0}/src/basic_memory/api/v2/routers/__init__.py +0 -0
- {basic_memory-0.17.9 → basic_memory-0.18.0}/src/basic_memory/api/v2/routers/directory_router.py +0 -0
- {basic_memory-0.17.9 → basic_memory-0.18.0}/src/basic_memory/api/v2/routers/memory_router.py +0 -0
- {basic_memory-0.17.9 → basic_memory-0.18.0}/src/basic_memory/api/v2/routers/project_router.py +0 -0
- {basic_memory-0.17.9 → basic_memory-0.18.0}/src/basic_memory/api/v2/routers/prompt_router.py +0 -0
- {basic_memory-0.17.9 → basic_memory-0.18.0}/src/basic_memory/api/v2/routers/resource_router.py +0 -0
- {basic_memory-0.17.9 → basic_memory-0.18.0}/src/basic_memory/api/v2/routers/search_router.py +0 -0
- {basic_memory-0.17.9 → basic_memory-0.18.0}/src/basic_memory/cli/__init__.py +0 -0
- {basic_memory-0.17.9 → basic_memory-0.18.0}/src/basic_memory/cli/app.py +0 -0
- {basic_memory-0.17.9 → basic_memory-0.18.0}/src/basic_memory/cli/auth.py +0 -0
- {basic_memory-0.17.9 → basic_memory-0.18.0}/src/basic_memory/cli/commands/__init__.py +0 -0
- {basic_memory-0.17.9 → basic_memory-0.18.0}/src/basic_memory/cli/commands/cloud/__init__.py +0 -0
- {basic_memory-0.17.9 → basic_memory-0.18.0}/src/basic_memory/cli/commands/cloud/api_client.py +0 -0
- {basic_memory-0.17.9 → basic_memory-0.18.0}/src/basic_memory/cli/commands/cloud/bisync_commands.py +0 -0
- {basic_memory-0.17.9 → basic_memory-0.18.0}/src/basic_memory/cli/commands/cloud/cloud_utils.py +0 -0
- {basic_memory-0.17.9 → basic_memory-0.18.0}/src/basic_memory/cli/commands/cloud/core_commands.py +0 -0
- {basic_memory-0.17.9 → basic_memory-0.18.0}/src/basic_memory/cli/commands/cloud/rclone_commands.py +0 -0
- {basic_memory-0.17.9 → basic_memory-0.18.0}/src/basic_memory/cli/commands/cloud/rclone_config.py +0 -0
- {basic_memory-0.17.9 → basic_memory-0.18.0}/src/basic_memory/cli/commands/cloud/rclone_installer.py +0 -0
- {basic_memory-0.17.9 → basic_memory-0.18.0}/src/basic_memory/cli/commands/cloud/restore.py +0 -0
- {basic_memory-0.17.9 → basic_memory-0.18.0}/src/basic_memory/cli/commands/cloud/schemas.py +0 -0
- {basic_memory-0.17.9 → basic_memory-0.18.0}/src/basic_memory/cli/commands/cloud/snapshot.py +0 -0
- {basic_memory-0.17.9 → basic_memory-0.18.0}/src/basic_memory/cli/commands/cloud/upload.py +0 -0
- {basic_memory-0.17.9 → basic_memory-0.18.0}/src/basic_memory/cli/commands/cloud/upload_command.py +0 -0
- {basic_memory-0.17.9 → basic_memory-0.18.0}/src/basic_memory/cli/commands/command_utils.py +0 -0
- {basic_memory-0.17.9 → basic_memory-0.18.0}/src/basic_memory/cli/commands/db.py +0 -0
- {basic_memory-0.17.9 → basic_memory-0.18.0}/src/basic_memory/cli/commands/format.py +0 -0
- {basic_memory-0.17.9 → basic_memory-0.18.0}/src/basic_memory/cli/commands/import_chatgpt.py +0 -0
- {basic_memory-0.17.9 → basic_memory-0.18.0}/src/basic_memory/cli/commands/import_claude_conversations.py +0 -0
- {basic_memory-0.17.9 → basic_memory-0.18.0}/src/basic_memory/cli/commands/import_claude_projects.py +0 -0
- {basic_memory-0.17.9 → basic_memory-0.18.0}/src/basic_memory/cli/commands/import_memory_json.py +0 -0
- {basic_memory-0.17.9 → basic_memory-0.18.0}/src/basic_memory/cli/container.py +0 -0
- {basic_memory-0.17.9 → basic_memory-0.18.0}/src/basic_memory/cli/main.py +0 -0
- {basic_memory-0.17.9 → basic_memory-0.18.0}/src/basic_memory/config.py +0 -0
- {basic_memory-0.17.9 → basic_memory-0.18.0}/src/basic_memory/db.py +0 -0
- {basic_memory-0.17.9 → basic_memory-0.18.0}/src/basic_memory/deps/__init__.py +0 -0
- {basic_memory-0.17.9 → basic_memory-0.18.0}/src/basic_memory/deps/config.py +0 -0
- {basic_memory-0.17.9 → basic_memory-0.18.0}/src/basic_memory/deps/db.py +0 -0
- {basic_memory-0.17.9 → basic_memory-0.18.0}/src/basic_memory/deps/importers.py +0 -0
- {basic_memory-0.17.9 → basic_memory-0.18.0}/src/basic_memory/deps/projects.py +0 -0
- {basic_memory-0.17.9 → basic_memory-0.18.0}/src/basic_memory/deps/repositories.py +0 -0
- {basic_memory-0.17.9 → basic_memory-0.18.0}/src/basic_memory/deps/services.py +0 -0
- {basic_memory-0.17.9 → basic_memory-0.18.0}/src/basic_memory/deps.py +0 -0
- {basic_memory-0.17.9 → basic_memory-0.18.0}/src/basic_memory/ignore_utils.py +0 -0
- {basic_memory-0.17.9 → basic_memory-0.18.0}/src/basic_memory/importers/__init__.py +0 -0
- {basic_memory-0.17.9 → basic_memory-0.18.0}/src/basic_memory/importers/base.py +0 -0
- {basic_memory-0.17.9 → basic_memory-0.18.0}/src/basic_memory/importers/chatgpt_importer.py +0 -0
- {basic_memory-0.17.9 → basic_memory-0.18.0}/src/basic_memory/importers/claude_conversations_importer.py +0 -0
- {basic_memory-0.17.9 → basic_memory-0.18.0}/src/basic_memory/importers/claude_projects_importer.py +0 -0
- {basic_memory-0.17.9 → basic_memory-0.18.0}/src/basic_memory/importers/memory_json_importer.py +0 -0
- {basic_memory-0.17.9 → basic_memory-0.18.0}/src/basic_memory/importers/utils.py +0 -0
- {basic_memory-0.17.9 → basic_memory-0.18.0}/src/basic_memory/markdown/__init__.py +0 -0
- {basic_memory-0.17.9 → basic_memory-0.18.0}/src/basic_memory/markdown/entity_parser.py +0 -0
- {basic_memory-0.17.9 → basic_memory-0.18.0}/src/basic_memory/markdown/markdown_processor.py +0 -0
- {basic_memory-0.17.9 → basic_memory-0.18.0}/src/basic_memory/markdown/plugins.py +0 -0
- {basic_memory-0.17.9 → basic_memory-0.18.0}/src/basic_memory/markdown/schemas.py +0 -0
- {basic_memory-0.17.9 → basic_memory-0.18.0}/src/basic_memory/markdown/utils.py +0 -0
- {basic_memory-0.17.9 → basic_memory-0.18.0}/src/basic_memory/mcp/__init__.py +0 -0
- {basic_memory-0.17.9 → basic_memory-0.18.0}/src/basic_memory/mcp/clients/__init__.py +0 -0
- {basic_memory-0.17.9 → basic_memory-0.18.0}/src/basic_memory/mcp/clients/directory.py +0 -0
- {basic_memory-0.17.9 → basic_memory-0.18.0}/src/basic_memory/mcp/clients/memory.py +0 -0
- {basic_memory-0.17.9 → basic_memory-0.18.0}/src/basic_memory/mcp/clients/project.py +0 -0
- {basic_memory-0.17.9 → basic_memory-0.18.0}/src/basic_memory/mcp/clients/resource.py +0 -0
- {basic_memory-0.17.9 → basic_memory-0.18.0}/src/basic_memory/mcp/clients/search.py +0 -0
- {basic_memory-0.17.9 → basic_memory-0.18.0}/src/basic_memory/mcp/container.py +0 -0
- {basic_memory-0.17.9 → basic_memory-0.18.0}/src/basic_memory/mcp/project_context.py +0 -0
- {basic_memory-0.17.9 → basic_memory-0.18.0}/src/basic_memory/mcp/prompts/__init__.py +0 -0
- {basic_memory-0.17.9 → basic_memory-0.18.0}/src/basic_memory/mcp/prompts/ai_assistant_guide.py +0 -0
- {basic_memory-0.17.9 → basic_memory-0.18.0}/src/basic_memory/mcp/resources/ai_assistant_guide.md +0 -0
- {basic_memory-0.17.9 → basic_memory-0.18.0}/src/basic_memory/mcp/resources/project_info.py +0 -0
- {basic_memory-0.17.9 → basic_memory-0.18.0}/src/basic_memory/mcp/server.py +0 -0
- {basic_memory-0.17.9 → basic_memory-0.18.0}/src/basic_memory/mcp/tools/__init__.py +0 -0
- {basic_memory-0.17.9 → basic_memory-0.18.0}/src/basic_memory/mcp/tools/build_context.py +0 -0
- {basic_memory-0.17.9 → basic_memory-0.18.0}/src/basic_memory/mcp/tools/chatgpt_tools.py +0 -0
- {basic_memory-0.17.9 → basic_memory-0.18.0}/src/basic_memory/mcp/tools/edit_note.py +0 -0
- {basic_memory-0.17.9 → basic_memory-0.18.0}/src/basic_memory/mcp/tools/list_directory.py +0 -0
- {basic_memory-0.17.9 → basic_memory-0.18.0}/src/basic_memory/mcp/tools/project_management.py +0 -0
- {basic_memory-0.17.9 → basic_memory-0.18.0}/src/basic_memory/mcp/tools/read_content.py +0 -0
- {basic_memory-0.17.9 → basic_memory-0.18.0}/src/basic_memory/mcp/tools/read_note.py +0 -0
- {basic_memory-0.17.9 → basic_memory-0.18.0}/src/basic_memory/mcp/tools/recent_activity.py +0 -0
- {basic_memory-0.17.9 → basic_memory-0.18.0}/src/basic_memory/mcp/tools/utils.py +0 -0
- {basic_memory-0.17.9 → basic_memory-0.18.0}/src/basic_memory/mcp/tools/view_note.py +0 -0
- {basic_memory-0.17.9 → basic_memory-0.18.0}/src/basic_memory/models/__init__.py +0 -0
- {basic_memory-0.17.9 → basic_memory-0.18.0}/src/basic_memory/models/base.py +0 -0
- {basic_memory-0.17.9 → basic_memory-0.18.0}/src/basic_memory/models/knowledge.py +0 -0
- {basic_memory-0.17.9 → basic_memory-0.18.0}/src/basic_memory/models/project.py +0 -0
- {basic_memory-0.17.9 → basic_memory-0.18.0}/src/basic_memory/models/search.py +0 -0
- {basic_memory-0.17.9 → basic_memory-0.18.0}/src/basic_memory/project_resolver.py +0 -0
- {basic_memory-0.17.9 → basic_memory-0.18.0}/src/basic_memory/repository/__init__.py +0 -0
- {basic_memory-0.17.9 → basic_memory-0.18.0}/src/basic_memory/repository/observation_repository.py +0 -0
- {basic_memory-0.17.9 → basic_memory-0.18.0}/src/basic_memory/repository/postgres_search_repository.py +0 -0
- {basic_memory-0.17.9 → basic_memory-0.18.0}/src/basic_memory/repository/project_info_repository.py +0 -0
- {basic_memory-0.17.9 → basic_memory-0.18.0}/src/basic_memory/repository/project_repository.py +0 -0
- {basic_memory-0.17.9 → basic_memory-0.18.0}/src/basic_memory/repository/relation_repository.py +0 -0
- {basic_memory-0.17.9 → basic_memory-0.18.0}/src/basic_memory/repository/repository.py +0 -0
- {basic_memory-0.17.9 → basic_memory-0.18.0}/src/basic_memory/repository/search_index_row.py +0 -0
- {basic_memory-0.17.9 → basic_memory-0.18.0}/src/basic_memory/repository/search_repository.py +0 -0
- {basic_memory-0.17.9 → basic_memory-0.18.0}/src/basic_memory/repository/search_repository_base.py +0 -0
- {basic_memory-0.17.9 → basic_memory-0.18.0}/src/basic_memory/repository/sqlite_search_repository.py +0 -0
- {basic_memory-0.17.9 → basic_memory-0.18.0}/src/basic_memory/runtime.py +0 -0
- {basic_memory-0.17.9 → basic_memory-0.18.0}/src/basic_memory/schemas/__init__.py +0 -0
- {basic_memory-0.17.9 → basic_memory-0.18.0}/src/basic_memory/schemas/cloud.py +0 -0
- {basic_memory-0.17.9 → basic_memory-0.18.0}/src/basic_memory/schemas/delete.py +0 -0
- {basic_memory-0.17.9 → basic_memory-0.18.0}/src/basic_memory/schemas/directory.py +0 -0
- {basic_memory-0.17.9 → basic_memory-0.18.0}/src/basic_memory/schemas/importer.py +0 -0
- {basic_memory-0.17.9 → basic_memory-0.18.0}/src/basic_memory/schemas/memory.py +0 -0
- {basic_memory-0.17.9 → basic_memory-0.18.0}/src/basic_memory/schemas/project_info.py +0 -0
- {basic_memory-0.17.9 → basic_memory-0.18.0}/src/basic_memory/schemas/prompt.py +0 -0
- {basic_memory-0.17.9 → basic_memory-0.18.0}/src/basic_memory/schemas/search.py +0 -0
- {basic_memory-0.17.9 → basic_memory-0.18.0}/src/basic_memory/schemas/sync_report.py +0 -0
- {basic_memory-0.17.9 → basic_memory-0.18.0}/src/basic_memory/schemas/v2/resource.py +0 -0
- {basic_memory-0.17.9 → basic_memory-0.18.0}/src/basic_memory/services/__init__.py +0 -0
- {basic_memory-0.17.9 → basic_memory-0.18.0}/src/basic_memory/services/context_service.py +0 -0
- {basic_memory-0.17.9 → basic_memory-0.18.0}/src/basic_memory/services/directory_service.py +0 -0
- {basic_memory-0.17.9 → basic_memory-0.18.0}/src/basic_memory/services/exceptions.py +0 -0
- {basic_memory-0.17.9 → basic_memory-0.18.0}/src/basic_memory/services/file_service.py +0 -0
- {basic_memory-0.17.9 → basic_memory-0.18.0}/src/basic_memory/services/initialization.py +0 -0
- {basic_memory-0.17.9 → basic_memory-0.18.0}/src/basic_memory/services/project_service.py +0 -0
- {basic_memory-0.17.9 → basic_memory-0.18.0}/src/basic_memory/services/search_service.py +0 -0
- {basic_memory-0.17.9 → basic_memory-0.18.0}/src/basic_memory/services/service.py +0 -0
- {basic_memory-0.17.9 → basic_memory-0.18.0}/src/basic_memory/sync/__init__.py +0 -0
- {basic_memory-0.17.9 → basic_memory-0.18.0}/src/basic_memory/sync/background_sync.py +0 -0
- {basic_memory-0.17.9 → basic_memory-0.18.0}/src/basic_memory/sync/coordinator.py +0 -0
- {basic_memory-0.17.9 → basic_memory-0.18.0}/src/basic_memory/sync/sync_service.py +0 -0
- {basic_memory-0.17.9 → basic_memory-0.18.0}/src/basic_memory/sync/watch_service.py +0 -0
- {basic_memory-0.17.9 → basic_memory-0.18.0}/src/basic_memory/templates/prompts/continue_conversation.hbs +0 -0
- {basic_memory-0.17.9 → basic_memory-0.18.0}/src/basic_memory/templates/prompts/search.hbs +0 -0
- {basic_memory-0.17.9 → basic_memory-0.18.0}/src/basic_memory/utils.py +0 -0
- {basic_memory-0.17.9 → basic_memory-0.18.0}/test-int/BENCHMARKS.md +0 -0
- {basic_memory-0.17.9 → basic_memory-0.18.0}/test-int/cli/test_project_commands_integration.py +0 -0
- {basic_memory-0.17.9 → basic_memory-0.18.0}/test-int/cli/test_version_integration.py +0 -0
- {basic_memory-0.17.9 → basic_memory-0.18.0}/test-int/conftest.py +0 -0
- {basic_memory-0.17.9 → basic_memory-0.18.0}/test-int/mcp/test_lifespan_shutdown_sync_task_cancellation_integration.py +0 -0
- {basic_memory-0.17.9 → basic_memory-0.18.0}/test-int/test_db_wal_mode.py +0 -0
- {basic_memory-0.17.9 → basic_memory-0.18.0}/tests/Non-MarkdownFileSupport.pdf +0 -0
- {basic_memory-0.17.9 → basic_memory-0.18.0}/tests/README.md +0 -0
- {basic_memory-0.17.9 → basic_memory-0.18.0}/tests/Screenshot.png +0 -0
- {basic_memory-0.17.9 → basic_memory-0.18.0}/tests/__init__.py +0 -0
- {basic_memory-0.17.9 → basic_memory-0.18.0}/tests/api/conftest.py +0 -0
- {basic_memory-0.17.9 → basic_memory-0.18.0}/tests/api/test_api_container.py +0 -0
- {basic_memory-0.17.9 → basic_memory-0.18.0}/tests/api/test_async_client.py +0 -0
- {basic_memory-0.17.9 → basic_memory-0.18.0}/tests/api/test_continue_conversation_template.py +0 -0
- {basic_memory-0.17.9 → basic_memory-0.18.0}/tests/api/test_directory_router.py +0 -0
- {basic_memory-0.17.9 → basic_memory-0.18.0}/tests/api/test_management_router.py +0 -0
- {basic_memory-0.17.9 → basic_memory-0.18.0}/tests/api/test_memory_router.py +0 -0
- {basic_memory-0.17.9 → basic_memory-0.18.0}/tests/api/test_project_router.py +0 -0
- {basic_memory-0.17.9 → basic_memory-0.18.0}/tests/api/test_project_router_operations.py +0 -0
- {basic_memory-0.17.9 → basic_memory-0.18.0}/tests/api/test_prompt_router.py +0 -0
- {basic_memory-0.17.9 → basic_memory-0.18.0}/tests/api/test_relation_background_resolution.py +0 -0
- {basic_memory-0.17.9 → basic_memory-0.18.0}/tests/api/test_search_template.py +0 -0
- {basic_memory-0.17.9 → basic_memory-0.18.0}/tests/api/test_template_loader.py +0 -0
- {basic_memory-0.17.9 → basic_memory-0.18.0}/tests/api/test_template_loader_helpers.py +0 -0
- {basic_memory-0.17.9 → basic_memory-0.18.0}/tests/api/v2/__init__.py +0 -0
- {basic_memory-0.17.9 → basic_memory-0.18.0}/tests/api/v2/conftest.py +0 -0
- {basic_memory-0.17.9 → basic_memory-0.18.0}/tests/api/v2/test_directory_router.py +0 -0
- {basic_memory-0.17.9 → basic_memory-0.18.0}/tests/api/v2/test_memory_router.py +0 -0
- {basic_memory-0.17.9 → basic_memory-0.18.0}/tests/api/v2/test_project_router.py +0 -0
- {basic_memory-0.17.9 → basic_memory-0.18.0}/tests/api/v2/test_prompt_router.py +0 -0
- {basic_memory-0.17.9 → basic_memory-0.18.0}/tests/api/v2/test_resource_router.py +0 -0
- {basic_memory-0.17.9 → basic_memory-0.18.0}/tests/api/v2/test_search_router.py +0 -0
- {basic_memory-0.17.9 → basic_memory-0.18.0}/tests/cli/cloud/test_cloud_api_client_and_utils.py +0 -0
- {basic_memory-0.17.9 → basic_memory-0.18.0}/tests/cli/cloud/test_rclone_config_and_bmignore_filters.py +0 -0
- {basic_memory-0.17.9 → basic_memory-0.18.0}/tests/cli/cloud/test_upload_path.py +0 -0
- {basic_memory-0.17.9 → basic_memory-0.18.0}/tests/cli/conftest.py +0 -0
- {basic_memory-0.17.9 → basic_memory-0.18.0}/tests/cli/test_auth_cli_auth.py +0 -0
- {basic_memory-0.17.9 → basic_memory-0.18.0}/tests/cli/test_cli_container.py +0 -0
- {basic_memory-0.17.9 → basic_memory-0.18.0}/tests/cli/test_cli_exit.py +0 -0
- {basic_memory-0.17.9 → basic_memory-0.18.0}/tests/cli/test_cli_tool_exit.py +0 -0
- {basic_memory-0.17.9 → basic_memory-0.18.0}/tests/cli/test_cli_tools.py +0 -0
- {basic_memory-0.17.9 → basic_memory-0.18.0}/tests/cli/test_cloud_authentication.py +0 -0
- {basic_memory-0.17.9 → basic_memory-0.18.0}/tests/cli/test_ignore_utils.py +0 -0
- {basic_memory-0.17.9 → basic_memory-0.18.0}/tests/cli/test_import_chatgpt.py +0 -0
- {basic_memory-0.17.9 → basic_memory-0.18.0}/tests/cli/test_import_claude_conversations.py +0 -0
- {basic_memory-0.17.9 → basic_memory-0.18.0}/tests/cli/test_import_claude_projects.py +0 -0
- {basic_memory-0.17.9 → basic_memory-0.18.0}/tests/cli/test_import_memory_json.py +0 -0
- {basic_memory-0.17.9 → basic_memory-0.18.0}/tests/cli/test_project_add_with_local_path.py +0 -0
- {basic_memory-0.17.9 → basic_memory-0.18.0}/tests/cli/test_restore_commands.py +0 -0
- {basic_memory-0.17.9 → basic_memory-0.18.0}/tests/cli/test_snapshot_commands.py +0 -0
- {basic_memory-0.17.9 → basic_memory-0.18.0}/tests/cli/test_upload.py +0 -0
- {basic_memory-0.17.9 → basic_memory-0.18.0}/tests/db/test_issue_254_foreign_key_constraints.py +0 -0
- {basic_memory-0.17.9 → basic_memory-0.18.0}/tests/importers/test_conversation_indexing.py +0 -0
- {basic_memory-0.17.9 → basic_memory-0.18.0}/tests/importers/test_importer_base.py +0 -0
- {basic_memory-0.17.9 → basic_memory-0.18.0}/tests/importers/test_importer_utils.py +0 -0
- {basic_memory-0.17.9 → basic_memory-0.18.0}/tests/markdown/__init__.py +0 -0
- {basic_memory-0.17.9 → basic_memory-0.18.0}/tests/markdown/test_date_frontmatter_parsing.py +0 -0
- {basic_memory-0.17.9 → basic_memory-0.18.0}/tests/markdown/test_entity_parser.py +0 -0
- {basic_memory-0.17.9 → basic_memory-0.18.0}/tests/markdown/test_entity_parser_error_handling.py +0 -0
- {basic_memory-0.17.9 → basic_memory-0.18.0}/tests/markdown/test_markdown_plugins.py +0 -0
- {basic_memory-0.17.9 → basic_memory-0.18.0}/tests/markdown/test_markdown_processor.py +0 -0
- {basic_memory-0.17.9 → basic_memory-0.18.0}/tests/markdown/test_markdown_utils.py +0 -0
- {basic_memory-0.17.9 → basic_memory-0.18.0}/tests/markdown/test_observation_edge_cases.py +0 -0
- {basic_memory-0.17.9 → basic_memory-0.18.0}/tests/markdown/test_parser_edge_cases.py +0 -0
- {basic_memory-0.17.9 → basic_memory-0.18.0}/tests/markdown/test_relation_edge_cases.py +0 -0
- {basic_memory-0.17.9 → basic_memory-0.18.0}/tests/markdown/test_task_detection.py +0 -0
- {basic_memory-0.17.9 → basic_memory-0.18.0}/tests/mcp/clients/__init__.py +0 -0
- {basic_memory-0.17.9 → basic_memory-0.18.0}/tests/mcp/clients/test_clients.py +0 -0
- {basic_memory-0.17.9 → basic_memory-0.18.0}/tests/mcp/conftest.py +0 -0
- {basic_memory-0.17.9 → basic_memory-0.18.0}/tests/mcp/test_async_client_modes.py +0 -0
- {basic_memory-0.17.9 → basic_memory-0.18.0}/tests/mcp/test_mcp_container.py +0 -0
- {basic_memory-0.17.9 → basic_memory-0.18.0}/tests/mcp/test_project_context.py +0 -0
- {basic_memory-0.17.9 → basic_memory-0.18.0}/tests/mcp/test_resources.py +0 -0
- {basic_memory-0.17.9 → basic_memory-0.18.0}/tests/mcp/test_server_lifespan_branches.py +0 -0
- {basic_memory-0.17.9 → basic_memory-0.18.0}/tests/mcp/test_tool_build_context.py +0 -0
- {basic_memory-0.17.9 → basic_memory-0.18.0}/tests/mcp/test_tool_delete_note.py +0 -0
- {basic_memory-0.17.9 → basic_memory-0.18.0}/tests/mcp/test_tool_project_management.py +0 -0
- {basic_memory-0.17.9 → basic_memory-0.18.0}/tests/mcp/test_tool_utils.py +0 -0
- {basic_memory-0.17.9 → basic_memory-0.18.0}/tests/repository/test_entity_repository_upsert.py +0 -0
- {basic_memory-0.17.9 → basic_memory-0.18.0}/tests/repository/test_entity_upsert_issue_187.py +0 -0
- {basic_memory-0.17.9 → basic_memory-0.18.0}/tests/repository/test_observation_repository.py +0 -0
- {basic_memory-0.17.9 → basic_memory-0.18.0}/tests/repository/test_postgres_search_repository.py +0 -0
- {basic_memory-0.17.9 → basic_memory-0.18.0}/tests/repository/test_project_info_repository.py +0 -0
- {basic_memory-0.17.9 → basic_memory-0.18.0}/tests/repository/test_project_repository.py +0 -0
- {basic_memory-0.17.9 → basic_memory-0.18.0}/tests/repository/test_relation_repository.py +0 -0
- {basic_memory-0.17.9 → basic_memory-0.18.0}/tests/repository/test_repository.py +0 -0
- {basic_memory-0.17.9 → basic_memory-0.18.0}/tests/repository/test_search_repository.py +0 -0
- {basic_memory-0.17.9 → basic_memory-0.18.0}/tests/repository/test_search_repository_edit_bug_fix.py +0 -0
- {basic_memory-0.17.9 → basic_memory-0.18.0}/tests/schemas/test_base_timeframe_minimum.py +0 -0
- {basic_memory-0.17.9 → basic_memory-0.18.0}/tests/schemas/test_memory_serialization.py +0 -0
- {basic_memory-0.17.9 → basic_memory-0.18.0}/tests/schemas/test_memory_url.py +0 -0
- {basic_memory-0.17.9 → basic_memory-0.18.0}/tests/schemas/test_memory_url_validation.py +0 -0
- {basic_memory-0.17.9 → basic_memory-0.18.0}/tests/schemas/test_relation_response_reference_resolution.py +0 -0
- {basic_memory-0.17.9 → basic_memory-0.18.0}/tests/schemas/test_search.py +0 -0
- {basic_memory-0.17.9 → basic_memory-0.18.0}/tests/services/test_context_service.py +0 -0
- {basic_memory-0.17.9 → basic_memory-0.18.0}/tests/services/test_directory_service.py +0 -0
- {basic_memory-0.17.9 → basic_memory-0.18.0}/tests/services/test_file_service.py +0 -0
- {basic_memory-0.17.9 → basic_memory-0.18.0}/tests/services/test_initialization.py +0 -0
- {basic_memory-0.17.9 → basic_memory-0.18.0}/tests/services/test_initialization_cloud_mode_branches.py +0 -0
- {basic_memory-0.17.9 → basic_memory-0.18.0}/tests/services/test_project_removal_bug.py +0 -0
- {basic_memory-0.17.9 → basic_memory-0.18.0}/tests/services/test_project_service.py +0 -0
- {basic_memory-0.17.9 → basic_memory-0.18.0}/tests/services/test_project_service_operations.py +0 -0
- {basic_memory-0.17.9 → basic_memory-0.18.0}/tests/services/test_search_service.py +0 -0
- {basic_memory-0.17.9 → basic_memory-0.18.0}/tests/sync/test_character_conflicts.py +0 -0
- {basic_memory-0.17.9 → basic_memory-0.18.0}/tests/sync/test_coordinator.py +0 -0
- {basic_memory-0.17.9 → basic_memory-0.18.0}/tests/sync/test_sync_service_incremental.py +0 -0
- {basic_memory-0.17.9 → basic_memory-0.18.0}/tests/sync/test_sync_wikilink_issue.py +0 -0
- {basic_memory-0.17.9 → basic_memory-0.18.0}/tests/sync/test_tmp_files.py +0 -0
- {basic_memory-0.17.9 → basic_memory-0.18.0}/tests/sync/test_watch_service.py +0 -0
- {basic_memory-0.17.9 → basic_memory-0.18.0}/tests/sync/test_watch_service_atomic_adds.py +0 -0
- {basic_memory-0.17.9 → basic_memory-0.18.0}/tests/sync/test_watch_service_edge_cases.py +0 -0
- {basic_memory-0.17.9 → basic_memory-0.18.0}/tests/sync/test_watch_service_reload.py +0 -0
- {basic_memory-0.17.9 → basic_memory-0.18.0}/tests/test_config.py +0 -0
- {basic_memory-0.17.9 → basic_memory-0.18.0}/tests/test_deps.py +0 -0
- {basic_memory-0.17.9 → basic_memory-0.18.0}/tests/test_production_cascade_delete.py +0 -0
- {basic_memory-0.17.9 → basic_memory-0.18.0}/tests/test_project_resolver.py +0 -0
- {basic_memory-0.17.9 → basic_memory-0.18.0}/tests/test_rclone_commands.py +0 -0
- {basic_memory-0.17.9 → basic_memory-0.18.0}/tests/test_runtime.py +0 -0
- {basic_memory-0.17.9 → basic_memory-0.18.0}/tests/utils/test_frontmatter_obsidian_compatible.py +0 -0
- {basic_memory-0.17.9 → basic_memory-0.18.0}/tests/utils/test_parse_tags.py +0 -0
- {basic_memory-0.17.9 → basic_memory-0.18.0}/tests/utils/test_permalink_formatting.py +0 -0
- {basic_memory-0.17.9 → basic_memory-0.18.0}/tests/utils/test_timezone_utils.py +0 -0
- {basic_memory-0.17.9 → basic_memory-0.18.0}/tests/utils/test_utf8_handling.py +0 -0
- {basic_memory-0.17.9 → basic_memory-0.18.0}/tests/utils/test_validate_project_path.py +0 -0
- {basic_memory-0.17.9 → basic_memory-0.18.0}/uv.lock +0 -0
|
@@ -1,5 +1,36 @@
|
|
|
1
1
|
# CHANGELOG
|
|
2
2
|
|
|
3
|
+
## v0.18.0 (2026-01-28)
|
|
4
|
+
|
|
5
|
+
### Features
|
|
6
|
+
|
|
7
|
+
- **#527**: Add context-aware wiki link resolution with source_path support
|
|
8
|
+
([`0023e73`](https://github.com/basicmachines-co/basic-memory/commit/0023e73))
|
|
9
|
+
- Add `source_path` parameter to `resolve_link()` for context-aware resolution
|
|
10
|
+
- Relative path resolution: `[[nested/note]]` from `folder/file.md` → `folder/nested/note.md`
|
|
11
|
+
- Proximity-based resolution for duplicate titles (prefers notes in same folder)
|
|
12
|
+
- Strict mode to disable fuzzy search fallback for wiki links
|
|
13
|
+
|
|
14
|
+
- **#518**: Add directory support to move_note and delete_note tools
|
|
15
|
+
([`0b20801`](https://github.com/basicmachines-co/basic-memory/commit/0b20801))
|
|
16
|
+
- Add `is_directory` parameter to `move_note` and `delete_note` MCP tools
|
|
17
|
+
- New `POST /move-directory` and delete directory API endpoints
|
|
18
|
+
- Rename `folder` → `directory` parameter across codebase for consistency
|
|
19
|
+
|
|
20
|
+
- **#522**: Local MCP cloud mode routing
|
|
21
|
+
([`8730067`](https://github.com/basicmachines-co/basic-memory/commit/8730067))
|
|
22
|
+
- Add `--local` and `--cloud` CLI routing flags
|
|
23
|
+
- Local MCP server (`basic-memory mcp`) automatically uses local routing
|
|
24
|
+
- Enables simultaneous use of local Claude Desktop and cloud-based clients
|
|
25
|
+
- Environment variable `BASIC_MEMORY_FORCE_LOCAL=true` for global override
|
|
26
|
+
|
|
27
|
+
### Bug Fixes
|
|
28
|
+
|
|
29
|
+
- **#524**: Fix MCP prompt rendering errors
|
|
30
|
+
([`e14ba92`](https://github.com/basicmachines-co/basic-memory/commit/e14ba92))
|
|
31
|
+
- Fix "Error rendering prompt recent_activity" error
|
|
32
|
+
- Change `TimeFrame` to `str` in prompt type annotations for FastMCP compatibility
|
|
33
|
+
|
|
3
34
|
## v0.17.9 (2026-01-24)
|
|
4
35
|
|
|
5
36
|
### Bug Fixes
|
|
@@ -248,13 +248,13 @@ See SPEC-16 for full context manager refactor details.
|
|
|
248
248
|
- Basic Memory exposes these MCP tools to LLMs:
|
|
249
249
|
|
|
250
250
|
**Content Management:**
|
|
251
|
-
- `write_note(title, content,
|
|
251
|
+
- `write_note(title, content, directory, tags)` - Create/update markdown notes with semantic observations and relations
|
|
252
252
|
- `read_note(identifier, page, page_size)` - Read notes by title, permalink, or memory:// URL with knowledge graph awareness
|
|
253
253
|
- `read_content(path)` - Read raw file content (text, images, binaries) without knowledge graph processing
|
|
254
254
|
- `view_note(identifier, page, page_size)` - View notes as formatted artifacts for better readability
|
|
255
255
|
- `edit_note(identifier, operation, content)` - Edit notes incrementally (append, prepend, find/replace, replace_section)
|
|
256
|
-
- `move_note(identifier, destination_path)` - Move notes to new locations, updating database and maintaining links
|
|
257
|
-
- `delete_note(identifier)` - Delete notes from the knowledge base
|
|
256
|
+
- `move_note(identifier, destination_path, is_directory)` - Move notes or directories to new locations, updating database and maintaining links
|
|
257
|
+
- `delete_note(identifier, is_directory)` - Delete notes or directories from the knowledge base
|
|
258
258
|
|
|
259
259
|
**Knowledge Graph Navigation:**
|
|
260
260
|
- `build_context(url, depth, timeframe)` - Navigate the knowledge graph via memory:// URLs for conversation continuity
|
|
@@ -270,7 +270,7 @@ See SPEC-16 for full context manager refactor details.
|
|
|
270
270
|
- `delete_project(project_name)` - Delete a project from configuration
|
|
271
271
|
|
|
272
272
|
**Visualization:**
|
|
273
|
-
- `canvas(nodes, edges, title,
|
|
273
|
+
- `canvas(nodes, edges, title, directory)` - Generate Obsidian canvas files for knowledge graph visualization
|
|
274
274
|
|
|
275
275
|
**ChatGPT-Compatible Tools:**
|
|
276
276
|
- `search(query)` - Search across knowledge base (OpenAI actions compatible)
|
|
@@ -310,6 +310,26 @@ Basic Memory now supports cloud synchronization and storage (requires active sub
|
|
|
310
310
|
- Background relation resolution (non-blocking startup)
|
|
311
311
|
- API performance optimizations (SPEC-11)
|
|
312
312
|
|
|
313
|
+
**CLI Routing Flags:**
|
|
314
|
+
|
|
315
|
+
When cloud mode is enabled, CLI commands route to the cloud API by default. Use `--local` and `--cloud` flags to override:
|
|
316
|
+
|
|
317
|
+
```bash
|
|
318
|
+
# Force local routing (ignore cloud mode)
|
|
319
|
+
basic-memory status --local
|
|
320
|
+
basic-memory project list --local
|
|
321
|
+
|
|
322
|
+
# Force cloud routing (when cloud mode is disabled)
|
|
323
|
+
basic-memory status --cloud
|
|
324
|
+
basic-memory project info my-project --cloud
|
|
325
|
+
```
|
|
326
|
+
|
|
327
|
+
Key behaviors:
|
|
328
|
+
- The local MCP server (`basic-memory mcp`) automatically uses local routing
|
|
329
|
+
- This allows simultaneous use of local Claude Desktop and cloud-based clients
|
|
330
|
+
- Some commands (like `project default`, `project sync-config`, `project move`) require `--local` in cloud mode since they modify local configuration
|
|
331
|
+
- Environment variable `BASIC_MEMORY_FORCE_LOCAL=true` forces local routing globally
|
|
332
|
+
|
|
313
333
|
## AI-Human Collaborative Development
|
|
314
334
|
|
|
315
335
|
Basic Memory emerged from and enables a new kind of development process that combines human and AI capabilities. Instead
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: basic-memory
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.18.0
|
|
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
|
|
@@ -405,6 +405,22 @@ basic-memory cloud check
|
|
|
405
405
|
basic-memory cloud mount
|
|
406
406
|
```
|
|
407
407
|
|
|
408
|
+
**Routing Flags** (for users with cloud subscriptions):
|
|
409
|
+
|
|
410
|
+
When cloud mode is enabled, CLI commands communicate with the cloud API by default. Use routing flags to override this:
|
|
411
|
+
|
|
412
|
+
```bash
|
|
413
|
+
# Force local routing (useful for local MCP server while cloud mode is enabled)
|
|
414
|
+
basic-memory status --local
|
|
415
|
+
basic-memory project list --local
|
|
416
|
+
|
|
417
|
+
# Force cloud routing (when cloud mode is disabled but you want cloud access)
|
|
418
|
+
basic-memory status --cloud
|
|
419
|
+
basic-memory project info my-project --cloud
|
|
420
|
+
```
|
|
421
|
+
|
|
422
|
+
The local MCP server (`basic-memory mcp`) automatically uses local routing, so you can use both local Claude Desktop and cloud-based clients simultaneously.
|
|
423
|
+
|
|
408
424
|
4. In Claude Desktop, the LLM can now use these tools:
|
|
409
425
|
|
|
410
426
|
**Content Management:**
|
|
@@ -481,6 +497,7 @@ Basic Memory uses [Loguru](https://github.com/Delgan/loguru) for logging. The lo
|
|
|
481
497
|
|----------|---------|-------------|
|
|
482
498
|
| `BASIC_MEMORY_LOG_LEVEL` | `INFO` | Log level: DEBUG, INFO, WARNING, ERROR |
|
|
483
499
|
| `BASIC_MEMORY_CLOUD_MODE` | `false` | When `true`, API logs to stdout with structured context |
|
|
500
|
+
| `BASIC_MEMORY_FORCE_LOCAL` | `false` | When `true`, forces local API routing (ignores cloud mode) |
|
|
484
501
|
| `BASIC_MEMORY_ENV` | `dev` | Set to `test` for test mode (stderr only) |
|
|
485
502
|
|
|
486
503
|
### Examples
|
|
@@ -357,6 +357,22 @@ basic-memory cloud check
|
|
|
357
357
|
basic-memory cloud mount
|
|
358
358
|
```
|
|
359
359
|
|
|
360
|
+
**Routing Flags** (for users with cloud subscriptions):
|
|
361
|
+
|
|
362
|
+
When cloud mode is enabled, CLI commands communicate with the cloud API by default. Use routing flags to override this:
|
|
363
|
+
|
|
364
|
+
```bash
|
|
365
|
+
# Force local routing (useful for local MCP server while cloud mode is enabled)
|
|
366
|
+
basic-memory status --local
|
|
367
|
+
basic-memory project list --local
|
|
368
|
+
|
|
369
|
+
# Force cloud routing (when cloud mode is disabled but you want cloud access)
|
|
370
|
+
basic-memory status --cloud
|
|
371
|
+
basic-memory project info my-project --cloud
|
|
372
|
+
```
|
|
373
|
+
|
|
374
|
+
The local MCP server (`basic-memory mcp`) automatically uses local routing, so you can use both local Claude Desktop and cloud-based clients simultaneously.
|
|
375
|
+
|
|
360
376
|
4. In Claude Desktop, the LLM can now use these tools:
|
|
361
377
|
|
|
362
378
|
**Content Management:**
|
|
@@ -433,6 +449,7 @@ Basic Memory uses [Loguru](https://github.com/Delgan/loguru) for logging. The lo
|
|
|
433
449
|
|----------|---------|-------------|
|
|
434
450
|
| `BASIC_MEMORY_LOG_LEVEL` | `INFO` | Log level: DEBUG, INFO, WARNING, ERROR |
|
|
435
451
|
| `BASIC_MEMORY_CLOUD_MODE` | `false` | When `true`, API logs to stdout with structured context |
|
|
452
|
+
| `BASIC_MEMORY_FORCE_LOCAL` | `false` | When `true`, forces local API routing (ignores cloud mode) |
|
|
436
453
|
| `BASIC_MEMORY_ENV` | `dev` | Set to `test` for test mode (stderr only) |
|
|
437
454
|
|
|
438
455
|
### Examples
|
|
@@ -6,12 +6,12 @@
|
|
|
6
6
|
"url": "https://github.com/basicmachines-co/basic-memory.git",
|
|
7
7
|
"source": "github"
|
|
8
8
|
},
|
|
9
|
-
"version": "0.
|
|
9
|
+
"version": "0.18.0",
|
|
10
10
|
"packages": [
|
|
11
11
|
{
|
|
12
12
|
"registryType": "pypi",
|
|
13
13
|
"identifier": "basic-memory",
|
|
14
|
-
"version": "0.
|
|
14
|
+
"version": "0.18.0",
|
|
15
15
|
"runtimeHint": "uvx",
|
|
16
16
|
"runtimeArguments": [
|
|
17
17
|
{"type": "positional", "value": "basic-memory"},
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
"""basic-memory - Local-first knowledge management combining Zettelkasten with knowledge graphs"""
|
|
2
2
|
|
|
3
3
|
# Package version - updated by release automation
|
|
4
|
-
__version__ = "0.
|
|
4
|
+
__version__ = "0.18.0"
|
|
5
5
|
|
|
6
6
|
# API version for FastAPI - independent of package version
|
|
7
7
|
__api_version__ = "v0"
|
|
@@ -27,13 +27,13 @@ router = APIRouter(prefix="/import", tags=["import"])
|
|
|
27
27
|
async def import_chatgpt(
|
|
28
28
|
importer: ChatGPTImporterDep,
|
|
29
29
|
file: UploadFile,
|
|
30
|
-
|
|
30
|
+
directory: str = Form("conversations"),
|
|
31
31
|
) -> ChatImportResult:
|
|
32
32
|
"""Import conversations from ChatGPT JSON export.
|
|
33
33
|
|
|
34
34
|
Args:
|
|
35
35
|
file: The ChatGPT conversations.json file.
|
|
36
|
-
|
|
36
|
+
directory: The directory to place the files in.
|
|
37
37
|
markdown_processor: MarkdownProcessor instance.
|
|
38
38
|
|
|
39
39
|
Returns:
|
|
@@ -42,20 +42,20 @@ async def import_chatgpt(
|
|
|
42
42
|
Raises:
|
|
43
43
|
HTTPException: If import fails.
|
|
44
44
|
"""
|
|
45
|
-
return await import_file(importer, file,
|
|
45
|
+
return await import_file(importer, file, directory)
|
|
46
46
|
|
|
47
47
|
|
|
48
48
|
@router.post("/claude/conversations", response_model=ChatImportResult)
|
|
49
49
|
async def import_claude_conversations(
|
|
50
50
|
importer: ClaudeConversationsImporterDep,
|
|
51
51
|
file: UploadFile,
|
|
52
|
-
|
|
52
|
+
directory: str = Form("conversations"),
|
|
53
53
|
) -> ChatImportResult:
|
|
54
54
|
"""Import conversations from Claude conversations.json export.
|
|
55
55
|
|
|
56
56
|
Args:
|
|
57
57
|
file: The Claude conversations.json file.
|
|
58
|
-
|
|
58
|
+
directory: The directory to place the files in.
|
|
59
59
|
markdown_processor: MarkdownProcessor instance.
|
|
60
60
|
|
|
61
61
|
Returns:
|
|
@@ -64,20 +64,20 @@ async def import_claude_conversations(
|
|
|
64
64
|
Raises:
|
|
65
65
|
HTTPException: If import fails.
|
|
66
66
|
"""
|
|
67
|
-
return await import_file(importer, file,
|
|
67
|
+
return await import_file(importer, file, directory)
|
|
68
68
|
|
|
69
69
|
|
|
70
70
|
@router.post("/claude/projects", response_model=ProjectImportResult)
|
|
71
71
|
async def import_claude_projects(
|
|
72
72
|
importer: ClaudeProjectsImporterDep,
|
|
73
73
|
file: UploadFile,
|
|
74
|
-
|
|
74
|
+
directory: str = Form("projects"),
|
|
75
75
|
) -> ProjectImportResult:
|
|
76
76
|
"""Import projects from Claude projects.json export.
|
|
77
77
|
|
|
78
78
|
Args:
|
|
79
79
|
file: The Claude projects.json file.
|
|
80
|
-
|
|
80
|
+
directory: The directory to place the files in.
|
|
81
81
|
markdown_processor: MarkdownProcessor instance.
|
|
82
82
|
|
|
83
83
|
Returns:
|
|
@@ -86,20 +86,20 @@ async def import_claude_projects(
|
|
|
86
86
|
Raises:
|
|
87
87
|
HTTPException: If import fails.
|
|
88
88
|
"""
|
|
89
|
-
return await import_file(importer, file,
|
|
89
|
+
return await import_file(importer, file, directory)
|
|
90
90
|
|
|
91
91
|
|
|
92
92
|
@router.post("/memory-json", response_model=EntityImportResult)
|
|
93
93
|
async def import_memory_json(
|
|
94
94
|
importer: MemoryJsonImporterDep,
|
|
95
95
|
file: UploadFile,
|
|
96
|
-
|
|
96
|
+
directory: str = Form("conversations"),
|
|
97
97
|
) -> EntityImportResult:
|
|
98
98
|
"""Import entities and relations from a memory.json file.
|
|
99
99
|
|
|
100
100
|
Args:
|
|
101
101
|
file: The memory.json file.
|
|
102
|
-
|
|
102
|
+
directory: Optional destination directory within the project.
|
|
103
103
|
markdown_processor: MarkdownProcessor instance.
|
|
104
104
|
|
|
105
105
|
Returns:
|
|
@@ -116,7 +116,7 @@ async def import_memory_json(
|
|
|
116
116
|
json_data = json.loads(line)
|
|
117
117
|
file_data.append(json_data)
|
|
118
118
|
|
|
119
|
-
result = await importer.import_data(file_data,
|
|
119
|
+
result = await importer.import_data(file_data, directory)
|
|
120
120
|
if not result.success: # pragma: no cover
|
|
121
121
|
raise HTTPException(
|
|
122
122
|
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
|
{basic_memory-0.17.9 → basic_memory-0.18.0}/src/basic_memory/api/routers/knowledge_router.py
RENAMED
|
@@ -29,7 +29,8 @@ from basic_memory.schemas import (
|
|
|
29
29
|
DeleteEntitiesResponse,
|
|
30
30
|
DeleteEntitiesRequest,
|
|
31
31
|
)
|
|
32
|
-
from basic_memory.schemas.request import EditEntityRequest, MoveEntityRequest
|
|
32
|
+
from basic_memory.schemas.request import EditEntityRequest, MoveEntityRequest, MoveDirectoryRequest
|
|
33
|
+
from basic_memory.schemas.response import DirectoryMoveResult
|
|
33
34
|
from basic_memory.schemas.base import Permalink, Entity
|
|
34
35
|
|
|
35
36
|
router = APIRouter(
|
|
@@ -231,6 +232,50 @@ async def move_entity(
|
|
|
231
232
|
raise HTTPException(status_code=400, detail=str(e))
|
|
232
233
|
|
|
233
234
|
|
|
235
|
+
@router.post("/move-directory")
|
|
236
|
+
async def move_directory(
|
|
237
|
+
data: MoveDirectoryRequest,
|
|
238
|
+
background_tasks: BackgroundTasks,
|
|
239
|
+
entity_service: EntityServiceDep,
|
|
240
|
+
project_config: ProjectConfigDep,
|
|
241
|
+
app_config: AppConfigDep,
|
|
242
|
+
search_service: SearchServiceDep,
|
|
243
|
+
) -> DirectoryMoveResult:
|
|
244
|
+
"""Move all entities in a directory to a new location.
|
|
245
|
+
|
|
246
|
+
This endpoint moves all files within a source directory to a destination
|
|
247
|
+
directory, updating database records and optionally updating permalinks.
|
|
248
|
+
"""
|
|
249
|
+
logger.info(
|
|
250
|
+
f"API request: endpoint='move_directory', source='{data.source_directory}', destination='{data.destination_directory}'"
|
|
251
|
+
)
|
|
252
|
+
|
|
253
|
+
try:
|
|
254
|
+
# Move the directory using the service
|
|
255
|
+
result = await entity_service.move_directory(
|
|
256
|
+
source_directory=data.source_directory,
|
|
257
|
+
destination_directory=data.destination_directory,
|
|
258
|
+
project_config=project_config,
|
|
259
|
+
app_config=app_config,
|
|
260
|
+
)
|
|
261
|
+
|
|
262
|
+
# Reindex moved entities
|
|
263
|
+
for file_path in result.moved_files:
|
|
264
|
+
entity = await entity_service.link_resolver.resolve_link(file_path)
|
|
265
|
+
if entity:
|
|
266
|
+
await search_service.index_entity(entity, background_tasks=background_tasks)
|
|
267
|
+
|
|
268
|
+
logger.info(
|
|
269
|
+
f"API response: endpoint='move_directory', "
|
|
270
|
+
f"total={result.total_files}, success={result.successful_moves}, failed={result.failed_moves}"
|
|
271
|
+
)
|
|
272
|
+
return result
|
|
273
|
+
|
|
274
|
+
except Exception as e:
|
|
275
|
+
logger.error(f"Error moving directory: {e}")
|
|
276
|
+
raise HTTPException(status_code=400, detail=str(e))
|
|
277
|
+
|
|
278
|
+
|
|
234
279
|
## Read endpoints
|
|
235
280
|
|
|
236
281
|
|
{basic_memory-0.17.9 → basic_memory-0.18.0}/src/basic_memory/api/v2/routers/importer_router.py
RENAMED
|
@@ -32,14 +32,14 @@ async def import_chatgpt(
|
|
|
32
32
|
importer: ChatGPTImporterV2ExternalDep,
|
|
33
33
|
file: UploadFile,
|
|
34
34
|
project_id: str = Path(..., description="Project external UUID"),
|
|
35
|
-
|
|
35
|
+
directory: str = Form("conversations"),
|
|
36
36
|
) -> ChatImportResult:
|
|
37
37
|
"""Import conversations from ChatGPT JSON export.
|
|
38
38
|
|
|
39
39
|
Args:
|
|
40
40
|
project_id: Project external UUID from URL path
|
|
41
41
|
file: The ChatGPT conversations.json file.
|
|
42
|
-
|
|
42
|
+
directory: The directory to place the files in.
|
|
43
43
|
importer: ChatGPT importer instance.
|
|
44
44
|
|
|
45
45
|
Returns:
|
|
@@ -49,7 +49,7 @@ async def import_chatgpt(
|
|
|
49
49
|
HTTPException: If import fails.
|
|
50
50
|
"""
|
|
51
51
|
logger.info(f"V2 Importing ChatGPT conversations for project {project_id}")
|
|
52
|
-
return await import_file(importer, file,
|
|
52
|
+
return await import_file(importer, file, directory)
|
|
53
53
|
|
|
54
54
|
|
|
55
55
|
@router.post("/claude/conversations", response_model=ChatImportResult)
|
|
@@ -57,14 +57,14 @@ async def import_claude_conversations(
|
|
|
57
57
|
importer: ClaudeConversationsImporterV2ExternalDep,
|
|
58
58
|
file: UploadFile,
|
|
59
59
|
project_id: str = Path(..., description="Project external UUID"),
|
|
60
|
-
|
|
60
|
+
directory: str = Form("conversations"),
|
|
61
61
|
) -> ChatImportResult:
|
|
62
62
|
"""Import conversations from Claude conversations.json export.
|
|
63
63
|
|
|
64
64
|
Args:
|
|
65
65
|
project_id: Project external UUID from URL path
|
|
66
66
|
file: The Claude conversations.json file.
|
|
67
|
-
|
|
67
|
+
directory: The directory to place the files in.
|
|
68
68
|
importer: Claude conversations importer instance.
|
|
69
69
|
|
|
70
70
|
Returns:
|
|
@@ -74,7 +74,7 @@ async def import_claude_conversations(
|
|
|
74
74
|
HTTPException: If import fails.
|
|
75
75
|
"""
|
|
76
76
|
logger.info(f"V2 Importing Claude conversations for project {project_id}")
|
|
77
|
-
return await import_file(importer, file,
|
|
77
|
+
return await import_file(importer, file, directory)
|
|
78
78
|
|
|
79
79
|
|
|
80
80
|
@router.post("/claude/projects", response_model=ProjectImportResult)
|
|
@@ -82,14 +82,14 @@ async def import_claude_projects(
|
|
|
82
82
|
importer: ClaudeProjectsImporterV2ExternalDep,
|
|
83
83
|
file: UploadFile,
|
|
84
84
|
project_id: str = Path(..., description="Project external UUID"),
|
|
85
|
-
|
|
85
|
+
directory: str = Form("projects"),
|
|
86
86
|
) -> ProjectImportResult:
|
|
87
87
|
"""Import projects from Claude projects.json export.
|
|
88
88
|
|
|
89
89
|
Args:
|
|
90
90
|
project_id: Project external UUID from URL path
|
|
91
91
|
file: The Claude projects.json file.
|
|
92
|
-
|
|
92
|
+
directory: The base directory to place the files in.
|
|
93
93
|
importer: Claude projects importer instance.
|
|
94
94
|
|
|
95
95
|
Returns:
|
|
@@ -99,7 +99,7 @@ async def import_claude_projects(
|
|
|
99
99
|
HTTPException: If import fails.
|
|
100
100
|
"""
|
|
101
101
|
logger.info(f"V2 Importing Claude projects for project {project_id}")
|
|
102
|
-
return await import_file(importer, file,
|
|
102
|
+
return await import_file(importer, file, directory)
|
|
103
103
|
|
|
104
104
|
|
|
105
105
|
@router.post("/memory-json", response_model=EntityImportResult)
|
|
@@ -107,14 +107,14 @@ async def import_memory_json(
|
|
|
107
107
|
importer: MemoryJsonImporterV2ExternalDep,
|
|
108
108
|
file: UploadFile,
|
|
109
109
|
project_id: str = Path(..., description="Project external UUID"),
|
|
110
|
-
|
|
110
|
+
directory: str = Form("conversations"),
|
|
111
111
|
) -> EntityImportResult:
|
|
112
112
|
"""Import entities and relations from a memory.json file.
|
|
113
113
|
|
|
114
114
|
Args:
|
|
115
115
|
project_id: Project external UUID from URL path
|
|
116
116
|
file: The memory.json file.
|
|
117
|
-
|
|
117
|
+
directory: Optional destination directory within the project.
|
|
118
118
|
importer: Memory JSON importer instance.
|
|
119
119
|
|
|
120
120
|
Returns:
|
|
@@ -132,7 +132,7 @@ async def import_memory_json(
|
|
|
132
132
|
json_data = json.loads(line)
|
|
133
133
|
file_data.append(json_data)
|
|
134
134
|
|
|
135
|
-
result = await importer.import_data(file_data,
|
|
135
|
+
result = await importer.import_data(file_data, directory)
|
|
136
136
|
if not result.success: # pragma: no cover
|
|
137
137
|
raise HTTPException(
|
|
138
138
|
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
|
|
@@ -147,13 +147,13 @@ async def import_memory_json(
|
|
|
147
147
|
return result
|
|
148
148
|
|
|
149
149
|
|
|
150
|
-
async def import_file(importer: Importer, file: UploadFile,
|
|
150
|
+
async def import_file(importer: Importer, file: UploadFile, destination_directory: str):
|
|
151
151
|
"""Helper function to import a file using an importer instance.
|
|
152
152
|
|
|
153
153
|
Args:
|
|
154
154
|
importer: The importer instance to use
|
|
155
155
|
file: The file to import
|
|
156
|
-
|
|
156
|
+
destination_directory: Destination directory for imported content
|
|
157
157
|
|
|
158
158
|
Returns:
|
|
159
159
|
Import result from the importer
|
|
@@ -164,7 +164,7 @@ async def import_file(importer: Importer, file: UploadFile, destination_folder:
|
|
|
164
164
|
try:
|
|
165
165
|
# Process file
|
|
166
166
|
json_data = json.load(file.file)
|
|
167
|
-
result = await importer.import_data(json_data,
|
|
167
|
+
result = await importer.import_data(json_data, destination_directory)
|
|
168
168
|
if not result.success: # pragma: no cover
|
|
169
169
|
raise HTTPException(
|
|
170
170
|
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
|
{basic_memory-0.17.9 → basic_memory-0.18.0}/src/basic_memory/api/v2/routers/knowledge_router.py
RENAMED
|
@@ -31,7 +31,10 @@ from basic_memory.schemas.v2 import (
|
|
|
31
31
|
EntityResolveResponse,
|
|
32
32
|
EntityResponseV2,
|
|
33
33
|
MoveEntityRequestV2,
|
|
34
|
+
MoveDirectoryRequestV2,
|
|
35
|
+
DeleteDirectoryRequestV2,
|
|
34
36
|
)
|
|
37
|
+
from basic_memory.schemas.response import DirectoryMoveResult, DirectoryDeleteResult
|
|
35
38
|
|
|
36
39
|
router = APIRouter(prefix="/knowledge", tags=["knowledge-v2"])
|
|
37
40
|
|
|
@@ -100,8 +103,12 @@ async def resolve_identifier(
|
|
|
100
103
|
resolution_method = "external_id" if entity else "search"
|
|
101
104
|
|
|
102
105
|
# If not found by external_id, try other resolution methods
|
|
106
|
+
# Pass source_path for context-aware resolution (prefers notes closer to source)
|
|
107
|
+
# Pass strict to control fuzzy search fallback (default False allows fuzzy matching)
|
|
103
108
|
if not entity:
|
|
104
|
-
entity = await link_resolver.resolve_link(
|
|
109
|
+
entity = await link_resolver.resolve_link(
|
|
110
|
+
data.identifier, source_path=data.source_path, strict=data.strict
|
|
111
|
+
)
|
|
105
112
|
if entity:
|
|
106
113
|
# Determine resolution method
|
|
107
114
|
if entity.permalink == data.identifier:
|
|
@@ -423,3 +430,100 @@ async def move_entity(
|
|
|
423
430
|
except Exception as e:
|
|
424
431
|
logger.error(f"Error moving entity: {e}")
|
|
425
432
|
raise HTTPException(status_code=400, detail=str(e))
|
|
433
|
+
|
|
434
|
+
|
|
435
|
+
## Move directory endpoint
|
|
436
|
+
|
|
437
|
+
|
|
438
|
+
@router.post("/move-directory", response_model=DirectoryMoveResult)
|
|
439
|
+
async def move_directory(
|
|
440
|
+
data: MoveDirectoryRequestV2,
|
|
441
|
+
background_tasks: BackgroundTasks,
|
|
442
|
+
project_id: ProjectExternalIdPathDep,
|
|
443
|
+
entity_service: EntityServiceV2ExternalDep,
|
|
444
|
+
project_config: ProjectConfigV2ExternalDep,
|
|
445
|
+
app_config: AppConfigDep,
|
|
446
|
+
search_service: SearchServiceV2ExternalDep,
|
|
447
|
+
) -> DirectoryMoveResult:
|
|
448
|
+
"""Move all entities in a directory to a new location.
|
|
449
|
+
|
|
450
|
+
V2 API uses project external_id in the URL path for stable references.
|
|
451
|
+
Moves all files within a source directory to a destination directory,
|
|
452
|
+
updating database records and optionally updating permalinks.
|
|
453
|
+
|
|
454
|
+
Args:
|
|
455
|
+
project_id: Project external ID from URL path
|
|
456
|
+
data: Move request with source and destination directories
|
|
457
|
+
|
|
458
|
+
Returns:
|
|
459
|
+
DirectoryMoveResult with counts and details of moved files
|
|
460
|
+
"""
|
|
461
|
+
logger.info(
|
|
462
|
+
f"API v2 request: move_directory source='{data.source_directory}', destination='{data.destination_directory}'"
|
|
463
|
+
)
|
|
464
|
+
|
|
465
|
+
try:
|
|
466
|
+
# Move the directory using the service
|
|
467
|
+
result = await entity_service.move_directory(
|
|
468
|
+
source_directory=data.source_directory,
|
|
469
|
+
destination_directory=data.destination_directory,
|
|
470
|
+
project_config=project_config,
|
|
471
|
+
app_config=app_config,
|
|
472
|
+
)
|
|
473
|
+
|
|
474
|
+
# Reindex moved entities
|
|
475
|
+
for file_path in result.moved_files:
|
|
476
|
+
entity = await entity_service.link_resolver.resolve_link(file_path)
|
|
477
|
+
if entity:
|
|
478
|
+
await search_service.index_entity(entity, background_tasks=background_tasks)
|
|
479
|
+
|
|
480
|
+
logger.info(
|
|
481
|
+
f"API v2 response: move_directory "
|
|
482
|
+
f"total={result.total_files}, success={result.successful_moves}, failed={result.failed_moves}"
|
|
483
|
+
)
|
|
484
|
+
return result
|
|
485
|
+
|
|
486
|
+
except Exception as e:
|
|
487
|
+
logger.error(f"Error moving directory: {e}")
|
|
488
|
+
raise HTTPException(status_code=400, detail=str(e))
|
|
489
|
+
|
|
490
|
+
|
|
491
|
+
## Delete directory endpoint
|
|
492
|
+
|
|
493
|
+
|
|
494
|
+
@router.post("/delete-directory", response_model=DirectoryDeleteResult)
|
|
495
|
+
async def delete_directory(
|
|
496
|
+
data: DeleteDirectoryRequestV2,
|
|
497
|
+
project_id: ProjectExternalIdPathDep,
|
|
498
|
+
entity_service: EntityServiceV2ExternalDep,
|
|
499
|
+
) -> DirectoryDeleteResult:
|
|
500
|
+
"""Delete all entities in a directory.
|
|
501
|
+
|
|
502
|
+
V2 API uses project external_id in the URL path for stable references.
|
|
503
|
+
Deletes all files within a directory, updating database records and
|
|
504
|
+
removing files from the filesystem.
|
|
505
|
+
|
|
506
|
+
Args:
|
|
507
|
+
project_id: Project external ID from URL path
|
|
508
|
+
data: Delete request with directory path
|
|
509
|
+
|
|
510
|
+
Returns:
|
|
511
|
+
DirectoryDeleteResult with counts and details of deleted files
|
|
512
|
+
"""
|
|
513
|
+
logger.info(f"API v2 request: delete_directory directory='{data.directory}'")
|
|
514
|
+
|
|
515
|
+
try:
|
|
516
|
+
# Delete the directory using the service
|
|
517
|
+
result = await entity_service.delete_directory(
|
|
518
|
+
directory=data.directory,
|
|
519
|
+
)
|
|
520
|
+
|
|
521
|
+
logger.info(
|
|
522
|
+
f"API v2 response: delete_directory "
|
|
523
|
+
f"total={result.total_files}, success={result.successful_deletes}, failed={result.failed_deletes}"
|
|
524
|
+
)
|
|
525
|
+
return result
|
|
526
|
+
|
|
527
|
+
except Exception as e:
|
|
528
|
+
logger.error(f"Error deleting directory: {e}")
|
|
529
|
+
raise HTTPException(status_code=400, detail=str(e))
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
"""MCP server command with streamable HTTP transport."""
|
|
2
|
+
|
|
3
|
+
import os
|
|
4
|
+
import typer
|
|
5
|
+
from typing import Optional
|
|
6
|
+
|
|
7
|
+
from basic_memory.cli.app import app
|
|
8
|
+
from basic_memory.config import ConfigManager, init_mcp_logging
|
|
9
|
+
|
|
10
|
+
# Import mcp instance (has lifespan that handles initialization and file sync)
|
|
11
|
+
from basic_memory.mcp.server import mcp as mcp_server # pragma: no cover
|
|
12
|
+
|
|
13
|
+
# Import mcp tools to register them
|
|
14
|
+
import basic_memory.mcp.tools # noqa: F401 # pragma: no cover
|
|
15
|
+
|
|
16
|
+
# Import prompts to register them
|
|
17
|
+
import basic_memory.mcp.prompts # noqa: F401 # pragma: no cover
|
|
18
|
+
from loguru import logger
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
@app.command()
|
|
22
|
+
def mcp(
|
|
23
|
+
transport: str = typer.Option("stdio", help="Transport type: stdio, streamable-http, or sse"),
|
|
24
|
+
host: str = typer.Option(
|
|
25
|
+
"0.0.0.0", help="Host for HTTP transports (use 0.0.0.0 to allow external connections)"
|
|
26
|
+
),
|
|
27
|
+
port: int = typer.Option(8000, help="Port for HTTP transports"),
|
|
28
|
+
path: str = typer.Option("/mcp", help="Path prefix for streamable-http transport"),
|
|
29
|
+
project: Optional[str] = typer.Option(None, help="Restrict MCP server to single project"),
|
|
30
|
+
): # pragma: no cover
|
|
31
|
+
"""Run the MCP server with configurable transport options.
|
|
32
|
+
|
|
33
|
+
This command starts an MCP server using one of three transport options:
|
|
34
|
+
|
|
35
|
+
- stdio: Standard I/O (good for local usage)
|
|
36
|
+
- streamable-http: Recommended for web deployments (default)
|
|
37
|
+
- sse: Server-Sent Events (for compatibility with existing clients)
|
|
38
|
+
|
|
39
|
+
Initialization, file sync, and cleanup are handled by the MCP server's lifespan.
|
|
40
|
+
|
|
41
|
+
Note: This command is available regardless of cloud mode setting.
|
|
42
|
+
Users who have cloud mode enabled can still use local MCP for Claude Code
|
|
43
|
+
and Claude Desktop while using cloud MCP for web and mobile access.
|
|
44
|
+
"""
|
|
45
|
+
# Force local routing for local MCP server
|
|
46
|
+
# Why: The local MCP server should always talk to the local API, not the cloud proxy.
|
|
47
|
+
# Even when cloud_mode_enabled is True, stdio MCP runs locally and needs local API access.
|
|
48
|
+
os.environ["BASIC_MEMORY_FORCE_LOCAL"] = "true"
|
|
49
|
+
|
|
50
|
+
# Initialize logging for MCP (file only, stdout breaks protocol)
|
|
51
|
+
init_mcp_logging()
|
|
52
|
+
|
|
53
|
+
# Validate and set project constraint if specified
|
|
54
|
+
if project:
|
|
55
|
+
config_manager = ConfigManager()
|
|
56
|
+
project_name, _ = config_manager.get_project(project)
|
|
57
|
+
if not project_name:
|
|
58
|
+
typer.echo(f"No project found named: {project}", err=True)
|
|
59
|
+
raise typer.Exit(1)
|
|
60
|
+
|
|
61
|
+
# Set env var with validated project name
|
|
62
|
+
os.environ["BASIC_MEMORY_MCP_PROJECT"] = project_name
|
|
63
|
+
logger.info(f"MCP server constrained to project: {project_name}")
|
|
64
|
+
|
|
65
|
+
# Run the MCP server (blocks)
|
|
66
|
+
# Lifespan handles: initialization, migrations, file sync, cleanup
|
|
67
|
+
logger.info(f"Starting MCP server with {transport.upper()} transport")
|
|
68
|
+
|
|
69
|
+
if transport == "stdio":
|
|
70
|
+
mcp_server.run(
|
|
71
|
+
transport=transport,
|
|
72
|
+
)
|
|
73
|
+
elif transport == "streamable-http" or transport == "sse":
|
|
74
|
+
mcp_server.run(
|
|
75
|
+
transport=transport,
|
|
76
|
+
host=host,
|
|
77
|
+
port=port,
|
|
78
|
+
path=path,
|
|
79
|
+
log_level="INFO",
|
|
80
|
+
)
|