basic-memory 0.21.4__tar.gz → 0.21.5__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.21.4 → basic_memory-0.21.5}/CHANGELOG.md +16 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/PKG-INFO +1 -1
- {basic_memory-0.21.4 → basic_memory-0.21.5}/server.json +2 -2
- {basic_memory-0.21.4 → basic_memory-0.21.5}/src/basic_memory/__init__.py +1 -1
- {basic_memory-0.21.4 → basic_memory-0.21.5}/src/basic_memory/mcp/async_client.py +197 -9
- {basic_memory-0.21.4 → basic_memory-0.21.5}/src/basic_memory/mcp/tools/project_management.py +91 -9
- {basic_memory-0.21.4 → basic_memory-0.21.5}/src/basic_memory/mcp/tools/write_note.py +19 -4
- {basic_memory-0.21.4 → basic_memory-0.21.5}/src/basic_memory/repository/sqlite_search_repository.py +19 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/src/basic_memory/services/search_service.py +13 -9
- {basic_memory-0.21.4 → basic_memory-0.21.5}/test-int/mcp/test_workspace_permalink_integration.py +50 -4
- {basic_memory-0.21.4 → basic_memory-0.21.5}/tests/mcp/test_async_client_modes.py +232 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/tests/mcp/test_tool_project_management.py +216 -1
- {basic_memory-0.21.4 → basic_memory-0.21.5}/tests/services/test_semantic_search.py +94 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/.agents/skills/instrumentation/SKILL.md +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/.agents/skills/instrumentation/references/javascript/frameworks.md +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/.agents/skills/instrumentation/references/javascript/patterns.md +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/.agents/skills/instrumentation/references/python/integrations.md +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/.agents/skills/instrumentation/references/python/logging-patterns.md +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/.agents/skills/instrumentation/references/rust/patterns.md +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/.claude/commands/release/beta.md +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/.claude/commands/release/changelog.md +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/.claude/commands/release/release-check.md +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/.claude/commands/release/release.md +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/.claude/commands/spec.md +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/.claude/commands/test-live.md +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/.claude/settings.json +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/.dockerignore +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/.env.example +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/.github/ISSUE_TEMPLATE/bug_report.md +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/.github/ISSUE_TEMPLATE/config.yml +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/.github/ISSUE_TEMPLATE/documentation.md +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/.github/ISSUE_TEMPLATE/feature_request.md +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/.github/dependabot.yml +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/.github/workflows/claude-code-review.yml +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/.github/workflows/claude-issue-triage.yml +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/.github/workflows/claude.yml +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/.github/workflows/dev-release.yml +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/.github/workflows/docker.yml +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/.github/workflows/pr-title.yml +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/.github/workflows/release.yml +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/.github/workflows/test.yml +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/.gitignore +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/.python-version +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/AGENTS.md +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/CITATION.cff +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/CLA.md +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/CLAUDE.md +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/CODE_OF_CONDUCT.md +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/CONTRIBUTING.md +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/Dockerfile +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/LICENSE +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/NOTE-FORMAT.md +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/README.md +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/SECURITY.md +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/docker-compose-postgres.yml +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/docker-compose.yml +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/docs/ARCHITECTURE.md +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/docs/Docker.md +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/docs/NOTE-FORMAT.md +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/docs/SPEC-PER-PROJECT-ROUTING.md +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/docs/ai-assistant-guide-extended.md +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/docs/character-handling.md +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/docs/cloud-cli.md +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/docs/cloud-semantic-search-value.md +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/docs/logfire-instrumentation-strategy.md +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/docs/mcp-ui-bakeoff-instructions.md +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/docs/metadata-search.md +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/docs/post-v0.18.0-test-plan.md +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/docs/releases/v0.19.0.md +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/docs/semantic-search-test-log.md +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/docs/semantic-search.md +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/docs/specs/SPEC-LOCAL-PLUS-PUBLISH.md +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/docs/specs/SPEC-SCHEMA-IMPL.md +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/docs/specs/SPEC-SCHEMA.md +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/docs/testing-coverage.md +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/justfile +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/llms-install.md +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/pyproject.toml +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/skills-lock.json +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/smithery.yaml +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/src/basic_memory/alembic/alembic.ini +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/src/basic_memory/alembic/env.py +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/src/basic_memory/alembic/migrations.py +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/src/basic_memory/alembic/script.py.mako +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/src/basic_memory/alembic/versions/314f1ea54dc4_add_postgres_full_text_search_support_.py +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/src/basic_memory/alembic/versions/3dae7c7b1564_initial_schema.py +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/src/basic_memory/alembic/versions/502b60eaa905_remove_required_from_entity_permalink.py +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/src/basic_memory/alembic/versions/5fe1ab1ccebe_add_projects_table.py +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/src/basic_memory/alembic/versions/647e7a75e2cd_project_constraint_fix.py +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/src/basic_memory/alembic/versions/6830751f5fb6_merge_multiple_heads.py +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/src/basic_memory/alembic/versions/9d9c1cb7d8f5_add_mtime_and_size_columns_to_entity_.py +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/src/basic_memory/alembic/versions/a1b2c3d4e5f6_fix_project_foreign_keys.py +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/src/basic_memory/alembic/versions/a2b3c4d5e6f7_add_search_index_entity_cascade.py +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/src/basic_memory/alembic/versions/b3c3938bacdb_relation_to_name_unique_index.py +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/src/basic_memory/alembic/versions/cc7172b46608_update_search_index_schema.py +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/src/basic_memory/alembic/versions/d7e8f9a0b1c2_add_structured_metadata_indexes.py +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/src/basic_memory/alembic/versions/e7e1f4367280_add_scan_watermark_tracking_to_project.py +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/src/basic_memory/alembic/versions/f8a9b2c3d4e5_add_pg_trgm_for_fuzzy_link_resolution.py +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/src/basic_memory/alembic/versions/g9a0b3c4d5e6_add_external_id_to_project_and_entity.py +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/src/basic_memory/alembic/versions/h1b2c3d4e5f6_add_postgres_vector_search_tables.py +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/src/basic_memory/alembic/versions/i2c3d4e5f6g7_auto_backfill_semantic_embeddings.py +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/src/basic_memory/alembic/versions/j3d4e5f6g7h8_rename_entity_type_to_note_type.py +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/src/basic_memory/alembic/versions/k4e5f6g7h8i9_add_created_by_and_last_updated_by_to_entity.py +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/src/basic_memory/alembic/versions/l5g6h7i8j9k0_add_note_content_table.py +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/src/basic_memory/alembic/versions/m6h7i8j9k0l1_add_vector_sync_fingerprints.py +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/src/basic_memory/alembic/versions/n7i8j9k0l1m2_cleanup_sqlite_search_orphans.py +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/src/basic_memory/api/__init__.py +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/src/basic_memory/api/app.py +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/src/basic_memory/api/container.py +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/src/basic_memory/api/template_loader.py +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/src/basic_memory/api/v2/__init__.py +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/src/basic_memory/api/v2/routers/__init__.py +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/src/basic_memory/api/v2/routers/directory_router.py +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/src/basic_memory/api/v2/routers/importer_router.py +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/src/basic_memory/api/v2/routers/knowledge_router.py +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/src/basic_memory/api/v2/routers/memory_router.py +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/src/basic_memory/api/v2/routers/project_router.py +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/src/basic_memory/api/v2/routers/prompt_router.py +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/src/basic_memory/api/v2/routers/resource_router.py +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/src/basic_memory/api/v2/routers/schema_router.py +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/src/basic_memory/api/v2/routers/search_router.py +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/src/basic_memory/api/v2/utils.py +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/src/basic_memory/cli/__init__.py +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/src/basic_memory/cli/analytics.py +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/src/basic_memory/cli/app.py +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/src/basic_memory/cli/auth.py +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/src/basic_memory/cli/auto_update.py +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/src/basic_memory/cli/commands/__init__.py +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/src/basic_memory/cli/commands/cloud/__init__.py +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/src/basic_memory/cli/commands/cloud/api_client.py +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/src/basic_memory/cli/commands/cloud/bisync_commands.py +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/src/basic_memory/cli/commands/cloud/cloud_utils.py +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/src/basic_memory/cli/commands/cloud/core_commands.py +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/src/basic_memory/cli/commands/cloud/project_sync.py +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/src/basic_memory/cli/commands/cloud/rclone_commands.py +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/src/basic_memory/cli/commands/cloud/rclone_config.py +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/src/basic_memory/cli/commands/cloud/rclone_installer.py +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/src/basic_memory/cli/commands/cloud/restore.py +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/src/basic_memory/cli/commands/cloud/schemas.py +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/src/basic_memory/cli/commands/cloud/snapshot.py +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/src/basic_memory/cli/commands/cloud/upload.py +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/src/basic_memory/cli/commands/cloud/upload_command.py +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/src/basic_memory/cli/commands/cloud/workspace.py +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/src/basic_memory/cli/commands/command_utils.py +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/src/basic_memory/cli/commands/db.py +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/src/basic_memory/cli/commands/doctor.py +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/src/basic_memory/cli/commands/format.py +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/src/basic_memory/cli/commands/import_chatgpt.py +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/src/basic_memory/cli/commands/import_claude_conversations.py +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/src/basic_memory/cli/commands/import_claude_projects.py +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/src/basic_memory/cli/commands/import_memory_json.py +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/src/basic_memory/cli/commands/mcp.py +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/src/basic_memory/cli/commands/orphans.py +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/src/basic_memory/cli/commands/project.py +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/src/basic_memory/cli/commands/routing.py +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/src/basic_memory/cli/commands/schema.py +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/src/basic_memory/cli/commands/status.py +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/src/basic_memory/cli/commands/tool.py +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/src/basic_memory/cli/commands/update.py +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/src/basic_memory/cli/container.py +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/src/basic_memory/cli/main.py +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/src/basic_memory/cli/promo.py +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/src/basic_memory/config.py +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/src/basic_memory/db.py +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/src/basic_memory/deps/__init__.py +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/src/basic_memory/deps/config.py +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/src/basic_memory/deps/db.py +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/src/basic_memory/deps/importers.py +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/src/basic_memory/deps/projects.py +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/src/basic_memory/deps/repositories.py +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/src/basic_memory/deps/services.py +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/src/basic_memory/deps.py +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/src/basic_memory/file_utils.py +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/src/basic_memory/ignore_utils.py +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/src/basic_memory/importers/__init__.py +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/src/basic_memory/importers/base.py +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/src/basic_memory/importers/chatgpt_importer.py +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/src/basic_memory/importers/claude_conversations_importer.py +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/src/basic_memory/importers/claude_projects_importer.py +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/src/basic_memory/importers/memory_json_importer.py +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/src/basic_memory/importers/utils.py +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/src/basic_memory/indexing/__init__.py +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/src/basic_memory/indexing/batch_indexer.py +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/src/basic_memory/indexing/batching.py +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/src/basic_memory/indexing/models.py +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/src/basic_memory/markdown/__init__.py +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/src/basic_memory/markdown/entity_parser.py +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/src/basic_memory/markdown/markdown_processor.py +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/src/basic_memory/markdown/plugins.py +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/src/basic_memory/markdown/schemas.py +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/src/basic_memory/markdown/utils.py +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/src/basic_memory/mcp/__init__.py +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/src/basic_memory/mcp/clients/__init__.py +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/src/basic_memory/mcp/clients/directory.py +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/src/basic_memory/mcp/clients/knowledge.py +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/src/basic_memory/mcp/clients/memory.py +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/src/basic_memory/mcp/clients/project.py +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/src/basic_memory/mcp/clients/resource.py +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/src/basic_memory/mcp/clients/schema.py +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/src/basic_memory/mcp/clients/search.py +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/src/basic_memory/mcp/container.py +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/src/basic_memory/mcp/formatting.py +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/src/basic_memory/mcp/project_context.py +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/src/basic_memory/mcp/prompts/__init__.py +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/src/basic_memory/mcp/prompts/ai_assistant_guide.py +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/src/basic_memory/mcp/prompts/continue_conversation.py +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/src/basic_memory/mcp/prompts/recent_activity.py +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/src/basic_memory/mcp/prompts/search.py +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/src/basic_memory/mcp/prompts/utils.py +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/src/basic_memory/mcp/resources/__init__.py +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/src/basic_memory/mcp/resources/ai_assistant_guide.md +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/src/basic_memory/mcp/resources/cloud_info.md +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/src/basic_memory/mcp/resources/project_info.py +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/src/basic_memory/mcp/resources/release_notes.md +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/src/basic_memory/mcp/resources/ui.py +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/src/basic_memory/mcp/server.py +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/src/basic_memory/mcp/tools/__init__.py +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/src/basic_memory/mcp/tools/build_context.py +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/src/basic_memory/mcp/tools/canvas.py +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/src/basic_memory/mcp/tools/chatgpt_tools.py +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/src/basic_memory/mcp/tools/cloud_info.py +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/src/basic_memory/mcp/tools/delete_note.py +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/src/basic_memory/mcp/tools/edit_note.py +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/src/basic_memory/mcp/tools/list_directory.py +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/src/basic_memory/mcp/tools/move_note.py +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/src/basic_memory/mcp/tools/read_content.py +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/src/basic_memory/mcp/tools/read_note.py +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/src/basic_memory/mcp/tools/recent_activity.py +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/src/basic_memory/mcp/tools/release_notes.py +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/src/basic_memory/mcp/tools/schema.py +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/src/basic_memory/mcp/tools/search.py +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/src/basic_memory/mcp/tools/ui_sdk.py +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/src/basic_memory/mcp/tools/utils.py +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/src/basic_memory/mcp/tools/view_note.py +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/src/basic_memory/mcp/tools/workspaces.py +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/src/basic_memory/mcp/ui/__init__.py +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/src/basic_memory/mcp/ui/html/note-preview-mcp-ui.html +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/src/basic_memory/mcp/ui/html/note-preview-tool-ui.html +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/src/basic_memory/mcp/ui/html/note-preview-vanilla.html +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/src/basic_memory/mcp/ui/html/search-results-mcp-ui.html +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/src/basic_memory/mcp/ui/html/search-results-tool-ui.html +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/src/basic_memory/mcp/ui/html/search-results-vanilla.html +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/src/basic_memory/mcp/ui/sdk.py +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/src/basic_memory/mcp/ui/templates.py +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/src/basic_memory/models/__init__.py +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/src/basic_memory/models/base.py +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/src/basic_memory/models/knowledge.py +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/src/basic_memory/models/project.py +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/src/basic_memory/models/search.py +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/src/basic_memory/project_resolver.py +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/src/basic_memory/repository/__init__.py +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/src/basic_memory/repository/embedding_provider.py +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/src/basic_memory/repository/embedding_provider_factory.py +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/src/basic_memory/repository/entity_repository.py +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/src/basic_memory/repository/fastembed_provider.py +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/src/basic_memory/repository/metadata_filters.py +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/src/basic_memory/repository/note_content_repository.py +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/src/basic_memory/repository/observation_repository.py +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/src/basic_memory/repository/openai_provider.py +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/src/basic_memory/repository/postgres_search_repository.py +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/src/basic_memory/repository/project_info_repository.py +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/src/basic_memory/repository/project_repository.py +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/src/basic_memory/repository/relation_repository.py +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/src/basic_memory/repository/repository.py +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/src/basic_memory/repository/search_index_row.py +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/src/basic_memory/repository/search_repository.py +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/src/basic_memory/repository/search_repository_base.py +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/src/basic_memory/repository/semantic_errors.py +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/src/basic_memory/runtime.py +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/src/basic_memory/schema/__init__.py +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/src/basic_memory/schema/diff.py +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/src/basic_memory/schema/inference.py +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/src/basic_memory/schema/parser.py +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/src/basic_memory/schema/resolver.py +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/src/basic_memory/schema/validator.py +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/src/basic_memory/schemas/__init__.py +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/src/basic_memory/schemas/base.py +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/src/basic_memory/schemas/cloud.py +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/src/basic_memory/schemas/delete.py +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/src/basic_memory/schemas/directory.py +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/src/basic_memory/schemas/importer.py +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/src/basic_memory/schemas/memory.py +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/src/basic_memory/schemas/project_info.py +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/src/basic_memory/schemas/prompt.py +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/src/basic_memory/schemas/request.py +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/src/basic_memory/schemas/response.py +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/src/basic_memory/schemas/schema.py +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/src/basic_memory/schemas/search.py +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/src/basic_memory/schemas/sync_report.py +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/src/basic_memory/schemas/v2/__init__.py +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/src/basic_memory/schemas/v2/entity.py +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/src/basic_memory/schemas/v2/graph.py +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/src/basic_memory/schemas/v2/resource.py +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/src/basic_memory/services/__init__.py +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/src/basic_memory/services/context_service.py +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/src/basic_memory/services/directory_service.py +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/src/basic_memory/services/entity_service.py +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/src/basic_memory/services/exceptions.py +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/src/basic_memory/services/file_service.py +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/src/basic_memory/services/initialization.py +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/src/basic_memory/services/link_resolver.py +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/src/basic_memory/services/project_service.py +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/src/basic_memory/services/service.py +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/src/basic_memory/sync/__init__.py +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/src/basic_memory/sync/background_sync.py +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/src/basic_memory/sync/coordinator.py +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/src/basic_memory/sync/sync_service.py +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/src/basic_memory/sync/watch_service.py +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/src/basic_memory/telemetry.py +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/src/basic_memory/templates/prompts/continue_conversation.hbs +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/src/basic_memory/templates/prompts/search.hbs +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/src/basic_memory/utils.py +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/src/basic_memory/workspace_context.py +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/test-int/BENCHMARKS.md +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/test-int/cli/test_cli_tool_edit_note_integration.py +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/test-int/cli/test_cli_tool_json_failure_integration.py +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/test-int/cli/test_cli_tool_json_integration.py +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/test-int/cli/test_project_commands_integration.py +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/test-int/cli/test_routing_integration.py +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/test-int/cli/test_search_notes_meta_integration.py +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/test-int/cli/test_version_integration.py +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/test-int/compare_search_benchmarks.py +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/test-int/conftest.py +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/test-int/fixtures/schema/drift/people/drift-person-01.md +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/test-int/fixtures/schema/drift/people/drift-person-02.md +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/test-int/fixtures/schema/drift/people/drift-person-03.md +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/test-int/fixtures/schema/drift/people/drift-person-04.md +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/test-int/fixtures/schema/drift/people/drift-person-05.md +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/test-int/fixtures/schema/drift/people/drift-person-06.md +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/test-int/fixtures/schema/drift/people/drift-person-07.md +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/test-int/fixtures/schema/drift/people/drift-person-08.md +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/test-int/fixtures/schema/drift/people/drift-person-09.md +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/test-int/fixtures/schema/drift/people/drift-person-10.md +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/test-int/fixtures/schema/drift/people/drift-person-11.md +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/test-int/fixtures/schema/drift/people/drift-person-12.md +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/test-int/fixtures/schema/drift/people/drift-person-13.md +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/test-int/fixtures/schema/drift/people/drift-person-14.md +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/test-int/fixtures/schema/drift/people/drift-person-15.md +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/test-int/fixtures/schema/drift/people/drift-person-16.md +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/test-int/fixtures/schema/drift/people/drift-person-17.md +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/test-int/fixtures/schema/drift/people/drift-person-18.md +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/test-int/fixtures/schema/drift/people/drift-person-19.md +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/test-int/fixtures/schema/drift/people/drift-person-20.md +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/test-int/fixtures/schema/drift/schema/Person.md +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/test-int/fixtures/schema/edge-cases/array-single.md +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/test-int/fixtures/schema/edge-cases/empty-note.md +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/test-int/fixtures/schema/edge-cases/explicit-overrides-type.md +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/test-int/fixtures/schema/edge-cases/inline-and-type.md +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/test-int/fixtures/schema/edge-cases/no-frontmatter.md +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/test-int/fixtures/schema/edge-cases/relation-only.md +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/test-int/fixtures/schema/edge-cases/type-no-schema.md +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/test-int/fixtures/schema/edge-cases/unicode-fields.md +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/test-int/fixtures/schema/inference/people/ada-lovelace.md +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/test-int/fixtures/schema/inference/people/alan-turing.md +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/test-int/fixtures/schema/inference/people/anders-hejlsberg.md +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/test-int/fixtures/schema/inference/people/andrej-karpathy.md +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/test-int/fixtures/schema/inference/people/barbara-liskov.md +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/test-int/fixtures/schema/inference/people/bjarne-stroustrup.md +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/test-int/fixtures/schema/inference/people/brendan-eich.md +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/test-int/fixtures/schema/inference/people/claude-shannon.md +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/test-int/fixtures/schema/inference/people/dennis-ritchie.md +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/test-int/fixtures/schema/inference/people/dijkstra.md +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/test-int/fixtures/schema/inference/people/donald-knuth.md +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/test-int/fixtures/schema/inference/people/fei-fei-li.md +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/test-int/fixtures/schema/inference/people/geoffrey-hinton.md +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/test-int/fixtures/schema/inference/people/grace-hopper.md +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/test-int/fixtures/schema/inference/people/guido-van-rossum.md +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/test-int/fixtures/schema/inference/people/james-gosling.md +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/test-int/fixtures/schema/inference/people/john-carmack.md +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/test-int/fixtures/schema/inference/people/ken-thompson.md +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/test-int/fixtures/schema/inference/people/larry-page.md +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/test-int/fixtures/schema/inference/people/leslie-lamport.md +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/test-int/fixtures/schema/inference/people/linus-torvalds.md +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/test-int/fixtures/schema/inference/people/margaret-hamilton.md +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/test-int/fixtures/schema/inference/people/rasmus-lerdorf.md +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/test-int/fixtures/schema/inference/people/richard-stallman.md +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/test-int/fixtures/schema/inference/people/rob-pike.md +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/test-int/fixtures/schema/inference/people/satoshi-nakamoto.md +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/test-int/fixtures/schema/inference/people/tim-berners-lee.md +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/test-int/fixtures/schema/inference/people/vint-cerf.md +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/test-int/fixtures/schema/inference/people/yann-lecun.md +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/test-int/fixtures/schema/inference/people/yukihiro-matsumoto.md +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/test-int/fixtures/schema/schemas/Book.md +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/test-int/fixtures/schema/schemas/Meeting.md +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/test-int/fixtures/schema/schemas/Person.md +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/test-int/fixtures/schema/schemas/SoftwareProject.md +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/test-int/fixtures/schema/schemas/StrictSchema.md +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/test-int/fixtures/schema/valid/basic-memory.md +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/test-int/fixtures/schema/valid/explicit-ref-note.md +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/test-int/fixtures/schema/valid/no-schema-note.md +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/test-int/fixtures/schema/valid/paul-graham.md +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/test-int/fixtures/schema/valid/rich-hickey.md +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/test-int/fixtures/schema/valid/standup-2024-01-15.md +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/test-int/fixtures/schema/warnings/extra-observations.md +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/test-int/fixtures/schema/warnings/missing-multiple.md +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/test-int/fixtures/schema/warnings/missing-required.md +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/test-int/fixtures/schema/warnings/wrong-enum-value.md +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/test-int/mcp/test_build_context_underscore.py +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/test-int/mcp/test_build_context_validation.py +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/test-int/mcp/test_chatgpt_tools_integration.py +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/test-int/mcp/test_default_project_mode_integration.py +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/test-int/mcp/test_delete_directory_integration.py +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/test-int/mcp/test_delete_note_integration.py +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/test-int/mcp/test_edit_note_integration.py +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/test-int/mcp/test_lifespan_shutdown_sync_task_cancellation_integration.py +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/test-int/mcp/test_list_directory_integration.py +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/test-int/mcp/test_long_relation_type_integration.py +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/test-int/mcp/test_move_directory_integration.py +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/test-int/mcp/test_move_note_integration.py +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/test-int/mcp/test_output_format_json_integration.py +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/test-int/mcp/test_pagination_integration.py +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/test-int/mcp/test_param_aliases_integration.py +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/test-int/mcp/test_permalink_collision_integration.py +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/test-int/mcp/test_project_management_integration.py +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/test-int/mcp/test_project_state_sync_integration.py +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/test-int/mcp/test_read_content_integration.py +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/test-int/mcp/test_read_note_integration.py +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/test-int/mcp/test_search_integration.py +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/test-int/mcp/test_single_project_mcp_integration.py +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/test-int/mcp/test_smoke_integration.py +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/test-int/mcp/test_string_params_integration.py +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/test-int/mcp/test_ui_sdk_integration.py +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/test-int/mcp/test_write_note_integration.py +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/test-int/semantic/__init__.py +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/test-int/semantic/conftest.py +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/test-int/semantic/corpus.py +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/test-int/semantic/metrics.py +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/test-int/semantic/report.py +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/test-int/semantic/test_multiterm_semantic_queries.py +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/test-int/semantic/test_search_diagnostics.py +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/test-int/semantic/test_semantic_coverage.py +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/test-int/semantic/test_semantic_quality.py +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/test-int/test_db_wal_mode.py +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/test-int/test_disable_permalinks_integration.py +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/test-int/test_schema/__init__.py +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/test-int/test_schema/conftest.py +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/test-int/test_schema/helpers.py +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/test-int/test_schema/test_diff_integration.py +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/test-int/test_schema/test_inference_integration.py +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/test-int/test_schema/test_parser_integration.py +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/test-int/test_schema/test_validator_integration.py +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/test-int/test_search_performance_benchmark.py +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/test-int/test_sync_batching_integration.py +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/tests/Non-MarkdownFileSupport.pdf +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/tests/README.md +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/tests/Screenshot.png +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/tests/__init__.py +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/tests/api/v2/__init__.py +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/tests/api/v2/conftest.py +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/tests/api/v2/test_directory_router.py +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/tests/api/v2/test_importer_router.py +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/tests/api/v2/test_knowledge_router.py +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/tests/api/v2/test_knowledge_router_telemetry.py +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/tests/api/v2/test_memory_hydration.py +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/tests/api/v2/test_memory_router.py +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/tests/api/v2/test_orphan_router.py +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/tests/api/v2/test_project_router.py +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/tests/api/v2/test_prompt_router.py +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/tests/api/v2/test_resource_router.py +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/tests/api/v2/test_schema_router.py +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/tests/api/v2/test_search_hydration.py +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/tests/api/v2/test_search_router.py +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/tests/api/v2/test_search_router_telemetry.py +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/tests/api/v2/test_utils_telemetry.py +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/tests/api/v2/test_workspace_permalink_headers.py +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/tests/cli/cloud/test_cloud_api_client_and_utils.py +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/tests/cli/cloud/test_project_sync_command.py +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/tests/cli/cloud/test_rclone_config_and_bmignore_filters.py +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/tests/cli/cloud/test_rclone_installer.py +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/tests/cli/cloud/test_upload_command_routing.py +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/tests/cli/cloud/test_upload_path.py +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/tests/cli/conftest.py +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/tests/cli/test_analytics.py +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/tests/cli/test_auth_cli_auth.py +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/tests/cli/test_auto_update.py +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/tests/cli/test_cli_container.py +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/tests/cli/test_cli_exit.py +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/tests/cli/test_cli_schema.py +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/tests/cli/test_cli_telemetry.py +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/tests/cli/test_cli_tool_exit.py +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/tests/cli/test_cli_tool_json_output.py +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/tests/cli/test_cli_tools.py +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/tests/cli/test_cloud_authentication.py +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/tests/cli/test_cloud_promo.py +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/tests/cli/test_cloud_status.py +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/tests/cli/test_db_reindex.py +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/tests/cli/test_db_reset_exit.py +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/tests/cli/test_db_reset_zombie_check.py +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/tests/cli/test_ignore_utils.py +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/tests/cli/test_import_chatgpt.py +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/tests/cli/test_import_claude_conversations.py +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/tests/cli/test_import_claude_projects.py +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/tests/cli/test_import_memory_json.py +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/tests/cli/test_json_output.py +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/tests/cli/test_orphans_command.py +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/tests/cli/test_project_add_with_local_path.py +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/tests/cli/test_project_info_cloud_status.py +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/tests/cli/test_project_info_errors.py +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/tests/cli/test_project_list_and_ls.py +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/tests/cli/test_project_set_cloud_local.py +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/tests/cli/test_restore_commands.py +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/tests/cli/test_routing.py +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/tests/cli/test_snapshot_commands.py +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/tests/cli/test_update_command.py +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/tests/cli/test_upload.py +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/tests/cli/test_workspace_commands.py +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/tests/conftest.py +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/tests/db/test_issue_254_foreign_key_constraints.py +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/tests/deps/test_task_failure_callback.py +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/tests/importers/test_conversation_indexing.py +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/tests/importers/test_importer_base.py +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/tests/importers/test_importer_utils.py +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/tests/indexing/test_batch_indexer.py +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/tests/indexing/test_batching.py +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/tests/markdown/__init__.py +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/tests/markdown/test_date_frontmatter_parsing.py +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/tests/markdown/test_entity_parser.py +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/tests/markdown/test_entity_parser_error_handling.py +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/tests/markdown/test_markdown_plugins.py +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/tests/markdown/test_markdown_processor.py +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/tests/markdown/test_markdown_utils.py +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/tests/markdown/test_observation_edge_cases.py +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/tests/markdown/test_parser_edge_cases.py +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/tests/markdown/test_relation_edge_cases.py +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/tests/markdown/test_task_detection.py +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/tests/mcp/clients/__init__.py +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/tests/mcp/clients/test_clients.py +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/tests/mcp/conftest.py +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/tests/mcp/test_async_client_force_local.py +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/tests/mcp/test_async_client_telemetry.py +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/tests/mcp/test_client_schema.py +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/tests/mcp/test_client_telemetry.py +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/tests/mcp/test_mcp_container.py +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/tests/mcp/test_obsidian_yaml_formatting.py +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/tests/mcp/test_permalink_collision_file_overwrite.py +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/tests/mcp/test_project_context.py +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/tests/mcp/test_project_context_telemetry.py +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/tests/mcp/test_prompt_tool_delegation.py +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/tests/mcp/test_prompts.py +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/tests/mcp/test_recent_activity_prompt_modes.py +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/tests/mcp/test_resources.py +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/tests/mcp/test_server_lifespan_branches.py +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/tests/mcp/test_server_telemetry.py +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/tests/mcp/test_tool_build_context.py +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/tests/mcp/test_tool_canvas.py +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/tests/mcp/test_tool_cloud_discovery.py +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/tests/mcp/test_tool_contracts.py +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/tests/mcp/test_tool_delete_note.py +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/tests/mcp/test_tool_edit_note.py +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/tests/mcp/test_tool_json_output_modes.py +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/tests/mcp/test_tool_list_directory.py +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/tests/mcp/test_tool_move_note.py +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/tests/mcp/test_tool_read_content.py +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/tests/mcp/test_tool_read_note.py +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/tests/mcp/test_tool_recent_activity.py +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/tests/mcp/test_tool_resource.py +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/tests/mcp/test_tool_schema.py +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/tests/mcp/test_tool_search.py +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/tests/mcp/test_tool_telemetry.py +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/tests/mcp/test_tool_utils.py +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/tests/mcp/test_tool_utils_cloud_auth.py +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/tests/mcp/test_tool_view_note.py +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/tests/mcp/test_tool_workspace_management.py +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/tests/mcp/test_tool_write_note.py +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/tests/mcp/test_tool_write_note_kebab_filenames.py +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/tests/mcp/test_tool_write_note_metadata.py +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/tests/mcp/test_ui_resources.py +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/tests/mcp/test_ui_sdk.py +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/tests/mcp/test_ui_templates.py +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/tests/mcp/test_workspace_permalink_resolution.py +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/tests/mcp/tools/test_chatgpt_tools.py +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/tests/mcp/tools/test_search_notes_multi_project.py +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/tests/repository/test_distance_to_similarity.py +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/tests/repository/test_entity_repository.py +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/tests/repository/test_entity_repository_upsert.py +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/tests/repository/test_entity_upsert_issue_187.py +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/tests/repository/test_fastembed_provider.py +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/tests/repository/test_hybrid_fusion.py +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/tests/repository/test_metadata_filters.py +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/tests/repository/test_metadata_filters_edge_cases.py +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/tests/repository/test_note_content_repository.py +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/tests/repository/test_observation_repository.py +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/tests/repository/test_openai_provider.py +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/tests/repository/test_postgres_search_repository.py +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/tests/repository/test_postgres_search_repository_unit.py +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/tests/repository/test_project_info_repository.py +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/tests/repository/test_project_repository.py +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/tests/repository/test_relation_repository.py +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/tests/repository/test_repository.py +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/tests/repository/test_search_index_row.py +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/tests/repository/test_search_repository.py +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/tests/repository/test_search_repository_edit_bug_fix.py +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/tests/repository/test_search_text_with_metadata_filters.py +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/tests/repository/test_semantic_search_base.py +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/tests/repository/test_sqlite_vector_search_repository.py +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/tests/repository/test_vector_pagination.py +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/tests/repository/test_vector_threshold.py +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/tests/schema/__init__.py +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/tests/schema/test_diff.py +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/tests/schema/test_inference.py +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/tests/schema/test_parser.py +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/tests/schema/test_resolver.py +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/tests/schema/test_validator.py +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/tests/schemas/test_base_timeframe_minimum.py +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/tests/schemas/test_memory_serialization.py +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/tests/schemas/test_memory_url.py +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/tests/schemas/test_memory_url_validation.py +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/tests/schemas/test_relation_response_reference_resolution.py +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/tests/schemas/test_schemas.py +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/tests/schemas/test_search.py +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/tests/services/test_context_service.py +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/tests/services/test_directory_service.py +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/tests/services/test_entity_service.py +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/tests/services/test_entity_service_disable_permalinks.py +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/tests/services/test_entity_service_prepare.py +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/tests/services/test_entity_service_telemetry.py +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/tests/services/test_entity_service_write_result.py +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/tests/services/test_file_service.py +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/tests/services/test_initialization.py +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/tests/services/test_initialization_cloud_mode_branches.py +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/tests/services/test_link_resolver.py +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/tests/services/test_project_removal_bug.py +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/tests/services/test_project_service.py +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/tests/services/test_project_service_cloud_info.py +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/tests/services/test_project_service_embedding_status.py +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/tests/services/test_project_service_operations.py +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/tests/services/test_search_service.py +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/tests/services/test_search_service_telemetry.py +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/tests/services/test_task_scheduler_semantic.py +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/tests/services/test_upsert_entity_optimization.py +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/tests/sync/test_character_conflicts.py +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/tests/sync/test_coordinator.py +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/tests/sync/test_sync_one_markdown_file.py +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/tests/sync/test_sync_service.py +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/tests/sync/test_sync_service_batching.py +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/tests/sync/test_sync_service_incremental.py +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/tests/sync/test_sync_service_subprocess.py +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/tests/sync/test_sync_service_telemetry.py +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/tests/sync/test_sync_wikilink_issue.py +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/tests/sync/test_tmp_files.py +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/tests/sync/test_watch_service.py +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/tests/sync/test_watch_service_atomic_adds.py +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/tests/sync/test_watch_service_edge_cases.py +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/tests/sync/test_watch_service_reload.py +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/tests/sync/test_watch_service_stress.py +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/tests/test_alembic_env.py +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/tests/test_coerce.py +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/tests/test_config.py +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/tests/test_deps.py +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/tests/test_note_content_migration.py +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/tests/test_permalink_utils.py +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/tests/test_production_cascade_delete.py +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/tests/test_project_resolver.py +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/tests/test_rclone_commands.py +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/tests/test_runtime.py +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/tests/test_telemetry.py +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/tests/utils/test_file_utils.py +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/tests/utils/test_frontmatter_obsidian_compatible.py +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/tests/utils/test_parse_tags.py +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/tests/utils/test_permalink_formatting.py +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/tests/utils/test_setup_logging.py +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/tests/utils/test_timezone_utils.py +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/tests/utils/test_utf8_handling.py +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/tests/utils/test_validate_project_path.py +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/tests/utils/test_workspace_context.py +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/ui/tool-ui-react/.gitignore +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/ui/tool-ui-react/build.mjs +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/ui/tool-ui-react/package-lock.json +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/ui/tool-ui-react/package.json +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/ui/tool-ui-react/src/components/tool-ui/data-table/_adapter.tsx +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/ui/tool-ui-react/src/components/tool-ui/data-table/data-table.tsx +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/ui/tool-ui-react/src/components/tool-ui/data-table/error-boundary.tsx +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/ui/tool-ui-react/src/components/tool-ui/data-table/formatters.tsx +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/ui/tool-ui-react/src/components/tool-ui/data-table/index.tsx +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/ui/tool-ui-react/src/components/tool-ui/data-table/schema.ts +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/ui/tool-ui-react/src/components/tool-ui/data-table/types.ts +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/ui/tool-ui-react/src/components/tool-ui/data-table/utilities.ts +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/ui/tool-ui-react/src/components/tool-ui/shared/_adapter.tsx +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/ui/tool-ui-react/src/components/tool-ui/shared/action-buttons.tsx +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/ui/tool-ui-react/src/components/tool-ui/shared/actions-config.ts +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/ui/tool-ui-react/src/components/tool-ui/shared/error-boundary.tsx +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/ui/tool-ui-react/src/components/tool-ui/shared/index.ts +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/ui/tool-ui-react/src/components/tool-ui/shared/media/aspect-ratio.ts +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/ui/tool-ui-react/src/components/tool-ui/shared/media/format-utils.ts +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/ui/tool-ui-react/src/components/tool-ui/shared/media/index.ts +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/ui/tool-ui-react/src/components/tool-ui/shared/media/overlay-gradient.ts +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/ui/tool-ui-react/src/components/tool-ui/shared/media/sanitize-href.ts +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/ui/tool-ui-react/src/components/tool-ui/shared/parse.ts +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/ui/tool-ui-react/src/components/tool-ui/shared/schema.ts +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/ui/tool-ui-react/src/components/tool-ui/shared/use-action-buttons.tsx +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/ui/tool-ui-react/src/components/tool-ui/shared/use-copy-to-clipboard.ts +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/ui/tool-ui-react/src/components/tool-ui/shared/utils.ts +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/ui/tool-ui-react/src/components/ui/accordion.tsx +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/ui/tool-ui-react/src/components/ui/badge.tsx +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/ui/tool-ui-react/src/components/ui/button.tsx +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/ui/tool-ui-react/src/components/ui/dropdown-menu.tsx +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/ui/tool-ui-react/src/components/ui/table.tsx +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/ui/tool-ui-react/src/components/ui/tooltip.tsx +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/ui/tool-ui-react/src/note-preview.tsx +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/ui/tool-ui-react/src/search-results.tsx +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/ui/tool-ui-react/src/styles.css +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/ui/tool-ui-react/tailwind.config.js +0 -0
- {basic_memory-0.21.4 → basic_memory-0.21.5}/uv.lock +0 -0
|
@@ -1,5 +1,21 @@
|
|
|
1
1
|
# CHANGELOG
|
|
2
2
|
|
|
3
|
+
## v0.21.5 (2026-05-26)
|
|
4
|
+
|
|
5
|
+
Workspace/project routing fixes for MCP, plus a SQLite vector reindex stability fix.
|
|
6
|
+
|
|
7
|
+
### Bug Fixes
|
|
8
|
+
|
|
9
|
+
- **#854**: MCP project listing now keeps duplicate cloud project rows distinct by
|
|
10
|
+
workspace, so only the selected workspace row inherits local project state.
|
|
11
|
+
- **#853**: `write_note` returns workspace-qualified permalinks for cloud
|
|
12
|
+
workspace writes, allowing follow-up `memory://` reads to route back to the
|
|
13
|
+
correct workspace/project.
|
|
14
|
+
- **#852**: Full SQLite vector reindex now loads `sqlite-vec` before dropping
|
|
15
|
+
`vec0` virtual tables, preventing reindex crashes.
|
|
16
|
+
- **#838**: Local ASGI database initialization is preloaded so MCP routing can
|
|
17
|
+
safely enter local project contexts.
|
|
18
|
+
|
|
3
19
|
## v0.21.1 (2026-05-16)
|
|
4
20
|
|
|
5
21
|
CI-only release. No user-facing changes.
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: basic-memory
|
|
3
|
-
Version: 0.21.
|
|
3
|
+
Version: 0.21.5
|
|
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
|
|
@@ -6,12 +6,12 @@
|
|
|
6
6
|
"url": "https://github.com/basicmachines-co/basic-memory.git",
|
|
7
7
|
"source": "github"
|
|
8
8
|
},
|
|
9
|
-
"version": "0.21.
|
|
9
|
+
"version": "0.21.5",
|
|
10
10
|
"packages": [
|
|
11
11
|
{
|
|
12
12
|
"registryType": "pypi",
|
|
13
13
|
"identifier": "basic-memory",
|
|
14
|
-
"version": "0.21.
|
|
14
|
+
"version": "0.21.5",
|
|
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.21.
|
|
4
|
+
__version__ = "0.21.5"
|
|
5
5
|
|
|
6
6
|
# API version for FastAPI - independent of package version
|
|
7
7
|
__api_version__ = "v0"
|
|
@@ -1,13 +1,36 @@
|
|
|
1
1
|
import os
|
|
2
|
-
from
|
|
3
|
-
from
|
|
2
|
+
from asyncio import Lock
|
|
3
|
+
from contextlib import AbstractAsyncContextManager, AsyncExitStack, asynccontextmanager
|
|
4
|
+
from dataclasses import dataclass
|
|
5
|
+
from threading import RLock
|
|
6
|
+
from typing import TYPE_CHECKING, Annotated, Any, AsyncIterator, Callable, Optional
|
|
4
7
|
|
|
8
|
+
from fastapi import Depends, FastAPI, Request
|
|
5
9
|
from httpx import ASGITransport, AsyncClient, Timeout
|
|
6
10
|
from loguru import logger
|
|
7
11
|
|
|
8
12
|
import logfire
|
|
9
13
|
from basic_memory.config import ConfigManager, ProjectMode
|
|
10
14
|
|
|
15
|
+
if TYPE_CHECKING:
|
|
16
|
+
from sqlalchemy.ext.asyncio import AsyncEngine, AsyncSession, async_sessionmaker
|
|
17
|
+
|
|
18
|
+
LocalDatabaseState = tuple["AsyncEngine", "async_sessionmaker[AsyncSession]"]
|
|
19
|
+
_MISSING_STATE_VALUE = object()
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
@dataclass
|
|
23
|
+
class _PreparedLocalAsgiDatabase:
|
|
24
|
+
active_count: int
|
|
25
|
+
previous_engine: object
|
|
26
|
+
previous_session_maker: object
|
|
27
|
+
dependency_context: AbstractAsyncContextManager[LocalDatabaseState]
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
_prepared_local_asgi_database_lock = RLock()
|
|
31
|
+
_prepared_local_asgi_database_prepare_locks: dict[FastAPI, Lock] = {}
|
|
32
|
+
_prepared_local_asgi_databases: dict[FastAPI, _PreparedLocalAsgiDatabase] = {}
|
|
33
|
+
|
|
11
34
|
|
|
12
35
|
def _force_local_mode() -> bool:
|
|
13
36
|
"""Check if local mode is forced via environment variable."""
|
|
@@ -34,15 +57,12 @@ def _build_timeout() -> Timeout:
|
|
|
34
57
|
)
|
|
35
58
|
|
|
36
59
|
|
|
37
|
-
def
|
|
38
|
-
"""Create a local ASGI client."""
|
|
39
|
-
# Import on first local-client use so CLI help/version paths can import
|
|
40
|
-
# routing helpers without constructing the full FastAPI router graph.
|
|
41
|
-
from basic_memory.api.app import app as fastapi_app
|
|
60
|
+
def _build_asgi_client(app: FastAPI, timeout: Timeout) -> AsyncClient:
|
|
61
|
+
"""Create a local ASGI client for an already-prepared FastAPI app."""
|
|
42
62
|
from basic_memory.workspace_context import workspace_permalink_headers
|
|
43
63
|
|
|
44
64
|
return AsyncClient(
|
|
45
|
-
transport=ASGITransport(app=
|
|
65
|
+
transport=ASGITransport(app=app),
|
|
46
66
|
base_url="http://test",
|
|
47
67
|
timeout=timeout,
|
|
48
68
|
# Local ASGI calls still cross the HTTP boundary, so request handlers need
|
|
@@ -51,6 +71,169 @@ def _asgi_client(timeout: Timeout) -> AsyncClient:
|
|
|
51
71
|
)
|
|
52
72
|
|
|
53
73
|
|
|
74
|
+
def _get_prepared_local_asgi_database_prepare_lock(app: FastAPI) -> Lock:
|
|
75
|
+
"""Get the async lock that serializes first-time DB preparation for an app."""
|
|
76
|
+
with _prepared_local_asgi_database_lock:
|
|
77
|
+
prepare_lock = _prepared_local_asgi_database_prepare_locks.get(app)
|
|
78
|
+
if prepare_lock is None:
|
|
79
|
+
prepare_lock = Lock()
|
|
80
|
+
_prepared_local_asgi_database_prepare_locks[app] = prepare_lock
|
|
81
|
+
return prepare_lock
|
|
82
|
+
|
|
83
|
+
|
|
84
|
+
@asynccontextmanager
|
|
85
|
+
async def _resolve_local_asgi_database(app: FastAPI) -> AsyncIterator[LocalDatabaseState]:
|
|
86
|
+
"""Resolve database state for a local ASGI request."""
|
|
87
|
+
from fastapi.dependencies.utils import get_dependant, solve_dependencies
|
|
88
|
+
|
|
89
|
+
from basic_memory.deps import get_engine_factory
|
|
90
|
+
|
|
91
|
+
async def resolve_database_state(
|
|
92
|
+
database_state: Annotated[LocalDatabaseState, Depends(get_engine_factory)],
|
|
93
|
+
) -> LocalDatabaseState:
|
|
94
|
+
return database_state
|
|
95
|
+
|
|
96
|
+
scope: dict[str, Any] = {
|
|
97
|
+
"type": "http",
|
|
98
|
+
"asgi": {"version": "3.0"},
|
|
99
|
+
"method": "GET",
|
|
100
|
+
"scheme": "http",
|
|
101
|
+
"path": "/",
|
|
102
|
+
"raw_path": b"/",
|
|
103
|
+
"root_path": "",
|
|
104
|
+
"query_string": b"",
|
|
105
|
+
"headers": [],
|
|
106
|
+
"client": ("testclient", 50000),
|
|
107
|
+
"server": ("testserver", 80),
|
|
108
|
+
"app": app,
|
|
109
|
+
"path_params": {},
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
async with AsyncExitStack() as request_stack, AsyncExitStack() as function_stack:
|
|
113
|
+
scope["fastapi_inner_astack"] = request_stack
|
|
114
|
+
scope["fastapi_function_astack"] = function_stack
|
|
115
|
+
request = Request(scope)
|
|
116
|
+
dependant = get_dependant(path="/", call=resolve_database_state)
|
|
117
|
+
solved = await solve_dependencies(
|
|
118
|
+
request=request,
|
|
119
|
+
dependant=dependant,
|
|
120
|
+
dependency_overrides_provider=app,
|
|
121
|
+
async_exit_stack=request_stack,
|
|
122
|
+
embed_body_fields=False,
|
|
123
|
+
)
|
|
124
|
+
if solved.errors:
|
|
125
|
+
raise RuntimeError(f"Failed to resolve local ASGI database dependency: {solved.errors}")
|
|
126
|
+
|
|
127
|
+
yield await resolve_database_state(**solved.values)
|
|
128
|
+
|
|
129
|
+
|
|
130
|
+
def _retain_prepared_local_asgi_database(app: FastAPI) -> bool:
|
|
131
|
+
"""Retain an active local ASGI database preparation if one exists."""
|
|
132
|
+
with _prepared_local_asgi_database_lock:
|
|
133
|
+
active = _prepared_local_asgi_databases.get(app)
|
|
134
|
+
if active is None:
|
|
135
|
+
return False
|
|
136
|
+
|
|
137
|
+
active.active_count += 1
|
|
138
|
+
return True
|
|
139
|
+
|
|
140
|
+
|
|
141
|
+
def _install_prepared_local_asgi_database(
|
|
142
|
+
app: FastAPI,
|
|
143
|
+
database_state: LocalDatabaseState,
|
|
144
|
+
dependency_context: AbstractAsyncContextManager[LocalDatabaseState],
|
|
145
|
+
) -> None:
|
|
146
|
+
"""Install local ASGI database state after dependency resolution."""
|
|
147
|
+
with _prepared_local_asgi_database_lock:
|
|
148
|
+
active = _prepared_local_asgi_databases.get(app)
|
|
149
|
+
if active is not None:
|
|
150
|
+
raise RuntimeError("Local ASGI database state installed while another state is active")
|
|
151
|
+
|
|
152
|
+
previous_engine = getattr(app.state, "engine", _MISSING_STATE_VALUE)
|
|
153
|
+
previous_session_maker = getattr(app.state, "session_maker", _MISSING_STATE_VALUE)
|
|
154
|
+
engine, session_maker = database_state
|
|
155
|
+
|
|
156
|
+
app.state.engine = engine
|
|
157
|
+
app.state.session_maker = session_maker
|
|
158
|
+
_prepared_local_asgi_databases[app] = _PreparedLocalAsgiDatabase(
|
|
159
|
+
active_count=1,
|
|
160
|
+
previous_engine=previous_engine,
|
|
161
|
+
previous_session_maker=previous_session_maker,
|
|
162
|
+
dependency_context=dependency_context,
|
|
163
|
+
)
|
|
164
|
+
|
|
165
|
+
|
|
166
|
+
def _restore_local_asgi_state_attribute(app: FastAPI, name: str, previous_value: object) -> None:
|
|
167
|
+
"""Restore a FastAPI app.state attribute captured before local ASGI preparation."""
|
|
168
|
+
if previous_value is _MISSING_STATE_VALUE:
|
|
169
|
+
if hasattr(app.state, name):
|
|
170
|
+
delattr(app.state, name)
|
|
171
|
+
else:
|
|
172
|
+
setattr(app.state, name, previous_value)
|
|
173
|
+
|
|
174
|
+
|
|
175
|
+
def _release_prepared_local_asgi_database(
|
|
176
|
+
app: FastAPI,
|
|
177
|
+
) -> AbstractAsyncContextManager[LocalDatabaseState] | None:
|
|
178
|
+
"""Release local ASGI database state after a client context exits."""
|
|
179
|
+
with _prepared_local_asgi_database_lock:
|
|
180
|
+
active = _prepared_local_asgi_databases.get(app)
|
|
181
|
+
if active is None:
|
|
182
|
+
raise RuntimeError("Local ASGI database state released without a matching retain")
|
|
183
|
+
|
|
184
|
+
active.active_count -= 1
|
|
185
|
+
if active.active_count > 0:
|
|
186
|
+
return None
|
|
187
|
+
|
|
188
|
+
del _prepared_local_asgi_databases[app]
|
|
189
|
+
_restore_local_asgi_state_attribute(app, "engine", active.previous_engine)
|
|
190
|
+
_restore_local_asgi_state_attribute(
|
|
191
|
+
app,
|
|
192
|
+
"session_maker",
|
|
193
|
+
active.previous_session_maker,
|
|
194
|
+
)
|
|
195
|
+
return active.dependency_context
|
|
196
|
+
|
|
197
|
+
|
|
198
|
+
@asynccontextmanager
|
|
199
|
+
async def _prepared_local_asgi_database(app: FastAPI) -> AsyncIterator[None]:
|
|
200
|
+
"""Initialize local ASGI database state before the first request."""
|
|
201
|
+
prepare_lock = _get_prepared_local_asgi_database_prepare_lock(app)
|
|
202
|
+
async with prepare_lock:
|
|
203
|
+
if not _retain_prepared_local_asgi_database(app):
|
|
204
|
+
database_context = _resolve_local_asgi_database(app)
|
|
205
|
+
database_state = await database_context.__aenter__()
|
|
206
|
+
try:
|
|
207
|
+
_install_prepared_local_asgi_database(app, database_state, database_context)
|
|
208
|
+
except Exception:
|
|
209
|
+
await database_context.__aexit__(None, None, None)
|
|
210
|
+
raise
|
|
211
|
+
|
|
212
|
+
try:
|
|
213
|
+
yield
|
|
214
|
+
finally:
|
|
215
|
+
database_context = _release_prepared_local_asgi_database(app)
|
|
216
|
+
if database_context is not None:
|
|
217
|
+
await database_context.__aexit__(None, None, None)
|
|
218
|
+
|
|
219
|
+
|
|
220
|
+
@asynccontextmanager
|
|
221
|
+
async def _asgi_client(timeout: Timeout) -> AsyncIterator[AsyncClient]:
|
|
222
|
+
"""Create a local ASGI client."""
|
|
223
|
+
# Import on first local-client use so CLI help/version paths can import
|
|
224
|
+
# routing helpers without constructing the full FastAPI router graph.
|
|
225
|
+
from basic_memory.api.app import app as fastapi_app
|
|
226
|
+
|
|
227
|
+
# Trigger: local ASGITransport does not execute FastAPI lifespan startup.
|
|
228
|
+
# Why: letting request dependencies initialize Postgres can run asyncpg DDL
|
|
229
|
+
# under Starlette's request loop and trigger CPython's empty-ready-queue race.
|
|
230
|
+
# Outcome: request handling sees the same app.state database objects as API
|
|
231
|
+
# lifespan startup would have provided.
|
|
232
|
+
async with _prepared_local_asgi_database(fastapi_app):
|
|
233
|
+
async with _build_asgi_client(fastapi_app, timeout) as client:
|
|
234
|
+
yield client
|
|
235
|
+
|
|
236
|
+
|
|
54
237
|
async def _resolve_cloud_token(config) -> str:
|
|
55
238
|
"""Resolve cloud token with API key preferred, OAuth fallback."""
|
|
56
239
|
with logfire.span(
|
|
@@ -260,7 +443,12 @@ def create_client() -> AsyncClient:
|
|
|
260
443
|
|
|
261
444
|
if _force_local_mode() or not _force_cloud_mode():
|
|
262
445
|
logger.info("Creating ASGI client for local Basic Memory API")
|
|
263
|
-
|
|
446
|
+
# Deprecated sync path: create_client() cannot await the local ASGI
|
|
447
|
+
# pre-initialization used by get_client(), so callers that need proper
|
|
448
|
+
# resource setup should use the async context manager instead.
|
|
449
|
+
from basic_memory.api.app import app as fastapi_app
|
|
450
|
+
|
|
451
|
+
return _build_asgi_client(fastapi_app, timeout)
|
|
264
452
|
|
|
265
453
|
logger.info("Creating HTTP client for cloud proxy (legacy create_client path)")
|
|
266
454
|
config = ConfigManager().config
|
{basic_memory-0.21.4 → basic_memory-0.21.5}/src/basic_memory/mcp/tools/project_management.py
RENAMED
|
@@ -10,7 +10,12 @@ from typing import Literal
|
|
|
10
10
|
from fastmcp import Context
|
|
11
11
|
from loguru import logger
|
|
12
12
|
|
|
13
|
-
from basic_memory.config import
|
|
13
|
+
from basic_memory.config import (
|
|
14
|
+
BasicMemoryConfig,
|
|
15
|
+
ConfigManager,
|
|
16
|
+
ProjectEntry,
|
|
17
|
+
has_cloud_credentials,
|
|
18
|
+
)
|
|
14
19
|
from basic_memory.mcp.async_client import (
|
|
15
20
|
_explicit_routing,
|
|
16
21
|
_force_local_mode,
|
|
@@ -131,9 +136,66 @@ def _merge_projects(
|
|
|
131
136
|
return merged
|
|
132
137
|
|
|
133
138
|
|
|
139
|
+
def _workspace_entry_priority(entry: WorkspaceProjectEntry) -> tuple[bool, int, str, str]:
|
|
140
|
+
"""Prefer default/personal workspaces when duplicate project permalinks exist."""
|
|
141
|
+
workspace_type_rank = 0 if entry.workspace.workspace_type == "personal" else 1
|
|
142
|
+
return (
|
|
143
|
+
# False sorts before True, so the cloud/default workspace comes first.
|
|
144
|
+
not entry.workspace.is_default,
|
|
145
|
+
workspace_type_rank,
|
|
146
|
+
entry.workspace.name.casefold(),
|
|
147
|
+
entry.workspace.tenant_id,
|
|
148
|
+
)
|
|
149
|
+
|
|
150
|
+
|
|
151
|
+
def _select_attached_cloud_entry(
|
|
152
|
+
cloud_entries: tuple[WorkspaceProjectEntry, ...],
|
|
153
|
+
*,
|
|
154
|
+
config_entry: ProjectEntry | None,
|
|
155
|
+
config: BasicMemoryConfig | None,
|
|
156
|
+
) -> WorkspaceProjectEntry | None:
|
|
157
|
+
"""Choose the single cloud row that should inherit local project state."""
|
|
158
|
+
if not cloud_entries:
|
|
159
|
+
return None
|
|
160
|
+
|
|
161
|
+
preferred_workspace_ids: list[str] = []
|
|
162
|
+
if config_entry and config_entry.workspace_id:
|
|
163
|
+
preferred_workspace_ids.append(config_entry.workspace_id)
|
|
164
|
+
if (
|
|
165
|
+
config
|
|
166
|
+
and config.default_workspace
|
|
167
|
+
and config.default_workspace not in preferred_workspace_ids
|
|
168
|
+
):
|
|
169
|
+
preferred_workspace_ids.append(config.default_workspace)
|
|
170
|
+
|
|
171
|
+
# The configured default workspace can differ from the cloud-side default.
|
|
172
|
+
# Use the cloud default only after explicit local config preferences.
|
|
173
|
+
default_workspace_entry = next(
|
|
174
|
+
(entry for entry in cloud_entries if entry.workspace.is_default),
|
|
175
|
+
None,
|
|
176
|
+
)
|
|
177
|
+
if (
|
|
178
|
+
default_workspace_entry is not None
|
|
179
|
+
and default_workspace_entry.workspace.tenant_id not in preferred_workspace_ids
|
|
180
|
+
):
|
|
181
|
+
preferred_workspace_ids.append(default_workspace_entry.workspace.tenant_id)
|
|
182
|
+
|
|
183
|
+
for workspace_id in preferred_workspace_ids:
|
|
184
|
+
for entry in cloud_entries:
|
|
185
|
+
if entry.workspace.tenant_id == workspace_id:
|
|
186
|
+
return entry
|
|
187
|
+
|
|
188
|
+
if len(cloud_entries) == 1:
|
|
189
|
+
return cloud_entries[0]
|
|
190
|
+
|
|
191
|
+
return sorted(cloud_entries, key=_workspace_entry_priority)[0]
|
|
192
|
+
|
|
193
|
+
|
|
134
194
|
def _merge_workspace_projects(
|
|
135
195
|
local_list: ProjectList | None,
|
|
136
196
|
cloud_entries: tuple[WorkspaceProjectEntry, ...],
|
|
197
|
+
*,
|
|
198
|
+
config: BasicMemoryConfig | None = None,
|
|
137
199
|
) -> list[dict]:
|
|
138
200
|
"""Merge local projects with cloud projects from every accessible workspace."""
|
|
139
201
|
local_by_permalink: dict[str, ProjectItem] = {}
|
|
@@ -141,20 +203,40 @@ def _merge_workspace_projects(
|
|
|
141
203
|
for project in local_list.projects:
|
|
142
204
|
local_by_permalink[project.permalink] = project
|
|
143
205
|
|
|
206
|
+
config_by_permalink: dict[str, ProjectEntry] = {}
|
|
207
|
+
if config:
|
|
208
|
+
config_by_permalink = {
|
|
209
|
+
generate_permalink(project_name): entry
|
|
210
|
+
for project_name, entry in config.projects.items()
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
cloud_entries_by_permalink: dict[str, list[WorkspaceProjectEntry]] = {}
|
|
214
|
+
for entry in cloud_entries:
|
|
215
|
+
cloud_entries_by_permalink.setdefault(entry.project.permalink, []).append(entry)
|
|
216
|
+
|
|
217
|
+
attached_entry_by_permalink: dict[str, WorkspaceProjectEntry | None] = {}
|
|
218
|
+
for permalink in local_by_permalink:
|
|
219
|
+
attached_entry_by_permalink[permalink] = _select_attached_cloud_entry(
|
|
220
|
+
tuple(cloud_entries_by_permalink.get(permalink, ())),
|
|
221
|
+
config_entry=config_by_permalink.get(permalink),
|
|
222
|
+
config=config,
|
|
223
|
+
)
|
|
224
|
+
|
|
144
225
|
cloud_permalinks = {entry.project.permalink for entry in cloud_entries}
|
|
145
226
|
merged: list[dict] = []
|
|
146
227
|
|
|
147
228
|
for entry in sorted(
|
|
148
229
|
cloud_entries,
|
|
149
|
-
key=lambda item: (
|
|
150
|
-
not item.workspace.is_default,
|
|
151
|
-
item.workspace.workspace_type != "personal",
|
|
152
|
-
item.workspace.name.casefold(),
|
|
153
|
-
item.project.permalink,
|
|
154
|
-
),
|
|
230
|
+
key=lambda item: (*_workspace_entry_priority(item), item.project.permalink),
|
|
155
231
|
):
|
|
156
232
|
permalink = entry.project.permalink
|
|
157
|
-
local_proj =
|
|
233
|
+
local_proj = (
|
|
234
|
+
local_by_permalink.get(permalink)
|
|
235
|
+
# WorkspaceProjectEntry is a frozen dataclass containing Pydantic
|
|
236
|
+
# models, so value equality is the intended comparison here.
|
|
237
|
+
if attached_entry_by_permalink.get(permalink) == entry
|
|
238
|
+
else None
|
|
239
|
+
)
|
|
158
240
|
cloud_proj = entry.project
|
|
159
241
|
source = "local+cloud" if local_proj else "cloud"
|
|
160
242
|
local_path = local_proj.path if local_proj else None
|
|
@@ -339,7 +421,7 @@ async def list_memory_projects(
|
|
|
339
421
|
)
|
|
340
422
|
|
|
341
423
|
if cloud_entries:
|
|
342
|
-
merged = _merge_workspace_projects(local_list, cloud_entries)
|
|
424
|
+
merged = _merge_workspace_projects(local_list, cloud_entries, config=config)
|
|
343
425
|
else:
|
|
344
426
|
merged = _merge_projects(
|
|
345
427
|
local_list,
|
|
@@ -12,7 +12,13 @@ from basic_memory.mcp.project_context import get_project_client, add_project_met
|
|
|
12
12
|
from basic_memory.mcp.server import mcp
|
|
13
13
|
from fastmcp import Context
|
|
14
14
|
from basic_memory.schemas.base import Entity
|
|
15
|
-
from basic_memory.utils import
|
|
15
|
+
from basic_memory.utils import (
|
|
16
|
+
build_qualified_permalink_reference,
|
|
17
|
+
coerce_dict,
|
|
18
|
+
parse_tags,
|
|
19
|
+
validate_project_path,
|
|
20
|
+
)
|
|
21
|
+
from basic_memory.workspace_context import current_workspace_permalink_context
|
|
16
22
|
|
|
17
23
|
# Define TagType as a Union that can accept either a string or a list of strings or None
|
|
18
24
|
TagType = Union[List[str], str, None]
|
|
@@ -274,11 +280,20 @@ async def write_note(
|
|
|
274
280
|
else:
|
|
275
281
|
# Re-raise if it's not a conflict error
|
|
276
282
|
raise # pragma: no cover
|
|
283
|
+
response_permalink = result.permalink
|
|
284
|
+
workspace_context = current_workspace_permalink_context()
|
|
285
|
+
if response_permalink and workspace_context is not None:
|
|
286
|
+
response_permalink = build_qualified_permalink_reference(
|
|
287
|
+
active_project.permalink,
|
|
288
|
+
response_permalink,
|
|
289
|
+
workspace_permalink=workspace_context.workspace_slug,
|
|
290
|
+
)
|
|
291
|
+
|
|
277
292
|
summary = [
|
|
278
293
|
f"# {action} note",
|
|
279
294
|
f"project: {active_project.name}",
|
|
280
295
|
f"file_path: {result.file_path}",
|
|
281
|
-
f"permalink: {
|
|
296
|
+
f"permalink: {response_permalink}",
|
|
282
297
|
f"checksum: {result.checksum[:8] if result.checksum else 'unknown'}",
|
|
283
298
|
]
|
|
284
299
|
|
|
@@ -315,12 +330,12 @@ async def write_note(
|
|
|
315
330
|
|
|
316
331
|
# Log the response with structured data
|
|
317
332
|
logger.info(
|
|
318
|
-
f"MCP tool response: tool=write_note project={active_project.name} action={action} permalink={
|
|
333
|
+
f"MCP tool response: tool=write_note project={active_project.name} action={action} permalink={response_permalink} observations_count={len(result.observations)} relations_count={len(result.relations)} resolved_relations={resolved} unresolved_relations={unresolved}"
|
|
319
334
|
)
|
|
320
335
|
if output_format == "json":
|
|
321
336
|
return {
|
|
322
337
|
"title": result.title,
|
|
323
|
-
"permalink":
|
|
338
|
+
"permalink": response_permalink,
|
|
324
339
|
"file_path": result.file_path,
|
|
325
340
|
"checksum": result.checksum,
|
|
326
341
|
"action": action.lower(),
|
{basic_memory-0.21.4 → basic_memory-0.21.5}/src/basic_memory/repository/sqlite_search_repository.py
RENAMED
|
@@ -620,6 +620,25 @@ class SQLiteSearchRepository(SearchRepositoryBase):
|
|
|
620
620
|
)
|
|
621
621
|
await session.commit()
|
|
622
622
|
|
|
623
|
+
async def drop_vector_tables(self) -> None:
|
|
624
|
+
"""Drop SQLite vector tables on a sqlite-vec-enabled connection."""
|
|
625
|
+
async with db.scoped_session(self.session_maker) as session:
|
|
626
|
+
vector_sql_result = await session.execute(
|
|
627
|
+
text(
|
|
628
|
+
"SELECT sql FROM sqlite_master "
|
|
629
|
+
"WHERE type = 'table' AND name = 'search_vector_embeddings'"
|
|
630
|
+
)
|
|
631
|
+
)
|
|
632
|
+
vector_sql = vector_sql_result.scalar()
|
|
633
|
+
if vector_sql and "using vec0" in vector_sql.lower():
|
|
634
|
+
await self._ensure_sqlite_vec_loaded(session)
|
|
635
|
+
|
|
636
|
+
await session.execute(text("DROP TABLE IF EXISTS search_vector_embeddings"))
|
|
637
|
+
await session.execute(text("DROP TABLE IF EXISTS search_vector_chunks"))
|
|
638
|
+
await session.execute(text("DROP TABLE IF EXISTS search_vector_index"))
|
|
639
|
+
await session.commit()
|
|
640
|
+
self._vector_tables_initialized = False
|
|
641
|
+
|
|
623
642
|
async def delete_stale_vector_rows(self) -> None:
|
|
624
643
|
"""Delete vector rows whose source entities no longer exist."""
|
|
625
644
|
await self._ensure_vector_tables()
|
|
@@ -126,19 +126,23 @@ class SearchService:
|
|
|
126
126
|
|
|
127
127
|
async def reindex_all(self, background_tasks: Optional[BackgroundTasks] = None) -> None:
|
|
128
128
|
"""Reindex all content from database."""
|
|
129
|
+
from basic_memory.repository.sqlite_search_repository import SQLiteSearchRepository
|
|
129
130
|
|
|
130
131
|
logger.info("Starting full reindex")
|
|
131
132
|
# Clear and recreate search index
|
|
132
133
|
await self.repository.execute_query(text("DROP TABLE IF EXISTS search_index"), params={})
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
134
|
+
if isinstance(self.repository, SQLiteSearchRepository):
|
|
135
|
+
await self.repository.drop_vector_tables()
|
|
136
|
+
else:
|
|
137
|
+
await self.repository.execute_query(
|
|
138
|
+
text("DROP TABLE IF EXISTS search_vector_embeddings"), params={}
|
|
139
|
+
)
|
|
140
|
+
await self.repository.execute_query(
|
|
141
|
+
text("DROP TABLE IF EXISTS search_vector_chunks"), params={}
|
|
142
|
+
)
|
|
143
|
+
await self.repository.execute_query(
|
|
144
|
+
text("DROP TABLE IF EXISTS search_vector_index"), params={}
|
|
145
|
+
)
|
|
142
146
|
await self.init_search_index()
|
|
143
147
|
|
|
144
148
|
# Reindex all entities
|
{basic_memory-0.21.4 → basic_memory-0.21.5}/test-int/mcp/test_workspace_permalink_integration.py
RENAMED
|
@@ -70,8 +70,12 @@ def team_workspace() -> WorkspaceInfo:
|
|
|
70
70
|
@pytest.fixture
|
|
71
71
|
def route_workspaces(app):
|
|
72
72
|
@contextmanager
|
|
73
|
-
def route(*workspaces: WorkspaceInfo):
|
|
74
|
-
with _workspace_routing(
|
|
73
|
+
def route(*workspaces: WorkspaceInfo, forward_permalink_headers: bool = True):
|
|
74
|
+
with _workspace_routing(
|
|
75
|
+
app,
|
|
76
|
+
workspaces,
|
|
77
|
+
forward_permalink_headers=forward_permalink_headers,
|
|
78
|
+
):
|
|
75
79
|
yield
|
|
76
80
|
|
|
77
81
|
return route
|
|
@@ -117,7 +121,12 @@ def _save_permalink_config(
|
|
|
117
121
|
|
|
118
122
|
|
|
119
123
|
@contextmanager
|
|
120
|
-
def _workspace_routing(
|
|
124
|
+
def _workspace_routing(
|
|
125
|
+
app,
|
|
126
|
+
workspaces: Iterable[WorkspaceInfo],
|
|
127
|
+
*,
|
|
128
|
+
forward_permalink_headers: bool = True,
|
|
129
|
+
):
|
|
121
130
|
"""Route MCP tool HTTP calls through an ASGI-backed cloud workspace seam."""
|
|
122
131
|
workspace_list = tuple(workspaces)
|
|
123
132
|
workspace_ids = {workspace.tenant_id for workspace in workspace_list}
|
|
@@ -128,10 +137,11 @@ def _workspace_routing(app, workspaces: Iterable[WorkspaceInfo]):
|
|
|
128
137
|
@asynccontextmanager
|
|
129
138
|
async def factory(workspace: str | None = None):
|
|
130
139
|
assert workspace is None or workspace in workspace_ids
|
|
140
|
+
headers = workspace_permalink_headers() if forward_permalink_headers else {}
|
|
131
141
|
async with HttpxAsyncClient(
|
|
132
142
|
transport=ASGITransport(app=app),
|
|
133
143
|
base_url="http://test",
|
|
134
|
-
headers=
|
|
144
|
+
headers=headers,
|
|
135
145
|
) as inner:
|
|
136
146
|
yield inner
|
|
137
147
|
|
|
@@ -461,3 +471,39 @@ async def test_team_workspace_permalink_routes_to_specific_workspace(
|
|
|
461
471
|
|
|
462
472
|
workspace_read = await _read_json(mcp_server, identifier=expected_permalink)
|
|
463
473
|
assert workspace_read["permalink"] == expected_permalink
|
|
474
|
+
|
|
475
|
+
|
|
476
|
+
@pytest.mark.asyncio
|
|
477
|
+
async def test_write_note_by_project_id_qualifies_permalink_when_headers_not_forwarded(
|
|
478
|
+
mcp_server,
|
|
479
|
+
test_project,
|
|
480
|
+
app_config,
|
|
481
|
+
team_workspace,
|
|
482
|
+
route_workspaces,
|
|
483
|
+
):
|
|
484
|
+
"""MCP writes should return self-routing IDs even if the API omits slug headers."""
|
|
485
|
+
_save_permalink_config(app_config, include_project=True, default_project=None)
|
|
486
|
+
|
|
487
|
+
title = "Project Id Workspace Permalink"
|
|
488
|
+
short_permalink = "permalink-suite/project-id-workspace-permalink"
|
|
489
|
+
expected_permalink = f"{team_workspace.slug}/{test_project.name}/{short_permalink}"
|
|
490
|
+
|
|
491
|
+
with route_workspaces(team_workspace, forward_permalink_headers=False):
|
|
492
|
+
write_payload = await _call_json(
|
|
493
|
+
mcp_server,
|
|
494
|
+
"write_note",
|
|
495
|
+
{
|
|
496
|
+
"project_id": test_project.external_id,
|
|
497
|
+
"title": title,
|
|
498
|
+
"directory": "permalink-suite",
|
|
499
|
+
"content": f"# {title}\n\nProject ID workspace body.",
|
|
500
|
+
"output_format": "json",
|
|
501
|
+
},
|
|
502
|
+
)
|
|
503
|
+
assert write_payload["permalink"] == expected_permalink
|
|
504
|
+
|
|
505
|
+
workspace_read = await _read_json(
|
|
506
|
+
mcp_server,
|
|
507
|
+
identifier=f"memory://{write_payload['permalink']}",
|
|
508
|
+
)
|
|
509
|
+
assert workspace_read["title"] == title
|