basic-memory 0.19.0__tar.gz → 0.19.1__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.19.0 → basic_memory-0.19.1}/CHANGELOG.md +17 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/PKG-INFO +13 -1
- {basic_memory-0.19.0 → basic_memory-0.19.1}/README.md +12 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/server.json +2 -2
- {basic_memory-0.19.0 → basic_memory-0.19.1}/src/basic_memory/__init__.py +1 -1
- {basic_memory-0.19.0 → basic_memory-0.19.1}/src/basic_memory/api/v2/routers/knowledge_router.py +48 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/src/basic_memory/mcp/tools/delete_note.py +1 -1
- {basic_memory-0.19.0 → basic_memory-0.19.1}/src/basic_memory/mcp/tools/edit_note.py +19 -5
- {basic_memory-0.19.0 → basic_memory-0.19.1}/src/basic_memory/mcp/tools/move_note.py +21 -2
- {basic_memory-0.19.0 → basic_memory-0.19.1}/src/basic_memory/schemas/base.py +5 -3
- {basic_memory-0.19.0 → basic_memory-0.19.1}/src/basic_memory/schemas/request.py +18 -3
- {basic_memory-0.19.0 → basic_memory-0.19.1}/src/basic_memory/schemas/v2/__init__.py +8 -0
- basic_memory-0.19.1/src/basic_memory/schemas/v2/graph.py +31 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/src/basic_memory/services/entity_service.py +75 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/test-int/cli/test_cli_tool_edit_note_integration.py +1 -1
- {basic_memory-0.19.0 → basic_memory-0.19.1}/test-int/mcp/test_delete_note_integration.py +30 -5
- {basic_memory-0.19.0 → basic_memory-0.19.1}/test-int/mcp/test_edit_note_integration.py +78 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/test-int/mcp/test_move_note_integration.py +53 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/tests/mcp/test_tool_delete_note.py +27 -3
- {basic_memory-0.19.0 → basic_memory-0.19.1}/tests/mcp/test_tool_edit_note.py +160 -1
- {basic_memory-0.19.0 → basic_memory-0.19.1}/tests/mcp/test_tool_move_note.py +25 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/tests/schemas/test_schemas.py +43 -3
- {basic_memory-0.19.0 → basic_memory-0.19.1}/tests/services/test_entity_service.py +261 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/uv.lock +9 -3
- {basic_memory-0.19.0 → basic_memory-0.19.1}/.claude/commands/release/beta.md +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/.claude/commands/release/changelog.md +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/.claude/commands/release/release-check.md +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/.claude/commands/release/release.md +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/.claude/commands/spec.md +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/.claude/commands/test-live.md +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/.claude/settings.json +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/.dockerignore +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/.env.example +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/.github/ISSUE_TEMPLATE/bug_report.md +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/.github/ISSUE_TEMPLATE/config.yml +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/.github/ISSUE_TEMPLATE/documentation.md +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/.github/ISSUE_TEMPLATE/feature_request.md +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/.github/dependabot.yml +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/.github/workflows/claude-code-review.yml +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/.github/workflows/claude-issue-triage.yml +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/.github/workflows/claude.yml +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/.github/workflows/dev-release.yml +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/.github/workflows/docker.yml +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/.github/workflows/pr-title.yml +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/.github/workflows/release.yml +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/.github/workflows/test.yml +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/.gitignore +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/.python-version +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/AGENTS.md +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/CITATION.cff +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/CLA.md +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/CLAUDE.md +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/CODE_OF_CONDUCT.md +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/CONTRIBUTING.md +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/Dockerfile +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/LICENSE +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/NOTE-FORMAT.md +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/SECURITY.md +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/docker-compose-postgres.yml +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/docker-compose.yml +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/docs/ARCHITECTURE.md +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/docs/Docker.md +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/docs/NOTE-FORMAT.md +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/docs/SPEC-PER-PROJECT-ROUTING.md +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/docs/ai-assistant-guide-extended.md +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/docs/character-handling.md +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/docs/cloud-cli.md +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/docs/cloud-semantic-search-value.md +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/docs/mcp-ui-bakeoff-instructions.md +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/docs/metadata-search.md +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/docs/post-v0.18.0-test-plan.md +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/docs/releases/v0.19.0.md +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/docs/semantic-search-test-log.md +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/docs/semantic-search.md +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/docs/specs/SPEC-LOCAL-PLUS-PUBLISH.md +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/docs/specs/SPEC-SCHEMA-IMPL.md +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/docs/specs/SPEC-SCHEMA.md +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/docs/testing-coverage.md +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/justfile +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/llms-install.md +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/pyproject.toml +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/smithery.yaml +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/src/basic_memory/alembic/alembic.ini +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/src/basic_memory/alembic/env.py +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/src/basic_memory/alembic/migrations.py +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/src/basic_memory/alembic/script.py.mako +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/src/basic_memory/alembic/versions/314f1ea54dc4_add_postgres_full_text_search_support_.py +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/src/basic_memory/alembic/versions/3dae7c7b1564_initial_schema.py +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/src/basic_memory/alembic/versions/502b60eaa905_remove_required_from_entity_permalink.py +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/src/basic_memory/alembic/versions/5fe1ab1ccebe_add_projects_table.py +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/src/basic_memory/alembic/versions/647e7a75e2cd_project_constraint_fix.py +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/src/basic_memory/alembic/versions/6830751f5fb6_merge_multiple_heads.py +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/src/basic_memory/alembic/versions/9d9c1cb7d8f5_add_mtime_and_size_columns_to_entity_.py +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/src/basic_memory/alembic/versions/a1b2c3d4e5f6_fix_project_foreign_keys.py +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/src/basic_memory/alembic/versions/a2b3c4d5e6f7_add_search_index_entity_cascade.py +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/src/basic_memory/alembic/versions/b3c3938bacdb_relation_to_name_unique_index.py +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/src/basic_memory/alembic/versions/cc7172b46608_update_search_index_schema.py +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/src/basic_memory/alembic/versions/d7e8f9a0b1c2_add_structured_metadata_indexes.py +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/src/basic_memory/alembic/versions/e7e1f4367280_add_scan_watermark_tracking_to_project.py +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/src/basic_memory/alembic/versions/f8a9b2c3d4e5_add_pg_trgm_for_fuzzy_link_resolution.py +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/src/basic_memory/alembic/versions/g9a0b3c4d5e6_add_external_id_to_project_and_entity.py +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/src/basic_memory/alembic/versions/h1b2c3d4e5f6_add_postgres_vector_search_tables.py +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/src/basic_memory/alembic/versions/i2c3d4e5f6g7_auto_backfill_semantic_embeddings.py +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/src/basic_memory/alembic/versions/j3d4e5f6g7h8_rename_entity_type_to_note_type.py +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/src/basic_memory/alembic/versions/k4e5f6g7h8i9_add_created_by_and_last_updated_by_to_entity.py +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/src/basic_memory/api/__init__.py +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/src/basic_memory/api/app.py +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/src/basic_memory/api/container.py +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/src/basic_memory/api/template_loader.py +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/src/basic_memory/api/v2/__init__.py +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/src/basic_memory/api/v2/routers/__init__.py +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/src/basic_memory/api/v2/routers/directory_router.py +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/src/basic_memory/api/v2/routers/importer_router.py +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/src/basic_memory/api/v2/routers/memory_router.py +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/src/basic_memory/api/v2/routers/project_router.py +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/src/basic_memory/api/v2/routers/prompt_router.py +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/src/basic_memory/api/v2/routers/resource_router.py +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/src/basic_memory/api/v2/routers/schema_router.py +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/src/basic_memory/api/v2/routers/search_router.py +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/src/basic_memory/api/v2/utils.py +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/src/basic_memory/cli/__init__.py +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/src/basic_memory/cli/analytics.py +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/src/basic_memory/cli/app.py +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/src/basic_memory/cli/auth.py +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/src/basic_memory/cli/commands/__init__.py +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/src/basic_memory/cli/commands/cloud/__init__.py +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/src/basic_memory/cli/commands/cloud/api_client.py +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/src/basic_memory/cli/commands/cloud/bisync_commands.py +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/src/basic_memory/cli/commands/cloud/cloud_utils.py +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/src/basic_memory/cli/commands/cloud/core_commands.py +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/src/basic_memory/cli/commands/cloud/project_sync.py +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/src/basic_memory/cli/commands/cloud/rclone_commands.py +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/src/basic_memory/cli/commands/cloud/rclone_config.py +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/src/basic_memory/cli/commands/cloud/rclone_installer.py +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/src/basic_memory/cli/commands/cloud/restore.py +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/src/basic_memory/cli/commands/cloud/schemas.py +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/src/basic_memory/cli/commands/cloud/snapshot.py +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/src/basic_memory/cli/commands/cloud/upload.py +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/src/basic_memory/cli/commands/cloud/upload_command.py +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/src/basic_memory/cli/commands/cloud/workspace.py +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/src/basic_memory/cli/commands/command_utils.py +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/src/basic_memory/cli/commands/db.py +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/src/basic_memory/cli/commands/doctor.py +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/src/basic_memory/cli/commands/format.py +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/src/basic_memory/cli/commands/import_chatgpt.py +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/src/basic_memory/cli/commands/import_claude_conversations.py +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/src/basic_memory/cli/commands/import_claude_projects.py +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/src/basic_memory/cli/commands/import_memory_json.py +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/src/basic_memory/cli/commands/mcp.py +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/src/basic_memory/cli/commands/project.py +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/src/basic_memory/cli/commands/routing.py +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/src/basic_memory/cli/commands/schema.py +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/src/basic_memory/cli/commands/status.py +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/src/basic_memory/cli/commands/tool.py +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/src/basic_memory/cli/container.py +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/src/basic_memory/cli/main.py +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/src/basic_memory/cli/promo.py +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/src/basic_memory/config.py +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/src/basic_memory/db.py +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/src/basic_memory/deps/__init__.py +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/src/basic_memory/deps/config.py +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/src/basic_memory/deps/db.py +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/src/basic_memory/deps/importers.py +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/src/basic_memory/deps/projects.py +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/src/basic_memory/deps/repositories.py +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/src/basic_memory/deps/services.py +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/src/basic_memory/deps.py +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/src/basic_memory/file_utils.py +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/src/basic_memory/ignore_utils.py +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/src/basic_memory/importers/__init__.py +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/src/basic_memory/importers/base.py +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/src/basic_memory/importers/chatgpt_importer.py +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/src/basic_memory/importers/claude_conversations_importer.py +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/src/basic_memory/importers/claude_projects_importer.py +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/src/basic_memory/importers/memory_json_importer.py +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/src/basic_memory/importers/utils.py +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/src/basic_memory/markdown/__init__.py +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/src/basic_memory/markdown/entity_parser.py +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/src/basic_memory/markdown/markdown_processor.py +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/src/basic_memory/markdown/plugins.py +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/src/basic_memory/markdown/schemas.py +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/src/basic_memory/markdown/utils.py +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/src/basic_memory/mcp/__init__.py +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/src/basic_memory/mcp/async_client.py +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/src/basic_memory/mcp/clients/__init__.py +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/src/basic_memory/mcp/clients/directory.py +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/src/basic_memory/mcp/clients/knowledge.py +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/src/basic_memory/mcp/clients/memory.py +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/src/basic_memory/mcp/clients/project.py +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/src/basic_memory/mcp/clients/resource.py +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/src/basic_memory/mcp/clients/schema.py +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/src/basic_memory/mcp/clients/search.py +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/src/basic_memory/mcp/container.py +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/src/basic_memory/mcp/formatting.py +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/src/basic_memory/mcp/project_context.py +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/src/basic_memory/mcp/prompts/__init__.py +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/src/basic_memory/mcp/prompts/ai_assistant_guide.py +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/src/basic_memory/mcp/prompts/continue_conversation.py +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/src/basic_memory/mcp/prompts/recent_activity.py +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/src/basic_memory/mcp/prompts/search.py +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/src/basic_memory/mcp/prompts/utils.py +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/src/basic_memory/mcp/resources/__init__.py +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/src/basic_memory/mcp/resources/ai_assistant_guide.md +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/src/basic_memory/mcp/resources/cloud_info.md +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/src/basic_memory/mcp/resources/project_info.py +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/src/basic_memory/mcp/resources/release_notes.md +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/src/basic_memory/mcp/resources/ui.py +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/src/basic_memory/mcp/server.py +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/src/basic_memory/mcp/tools/__init__.py +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/src/basic_memory/mcp/tools/build_context.py +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/src/basic_memory/mcp/tools/canvas.py +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/src/basic_memory/mcp/tools/chatgpt_tools.py +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/src/basic_memory/mcp/tools/cloud_info.py +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/src/basic_memory/mcp/tools/list_directory.py +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/src/basic_memory/mcp/tools/project_management.py +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/src/basic_memory/mcp/tools/read_content.py +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/src/basic_memory/mcp/tools/read_note.py +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/src/basic_memory/mcp/tools/recent_activity.py +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/src/basic_memory/mcp/tools/release_notes.py +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/src/basic_memory/mcp/tools/schema.py +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/src/basic_memory/mcp/tools/search.py +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/src/basic_memory/mcp/tools/ui_sdk.py +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/src/basic_memory/mcp/tools/utils.py +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/src/basic_memory/mcp/tools/view_note.py +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/src/basic_memory/mcp/tools/workspaces.py +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/src/basic_memory/mcp/tools/write_note.py +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/src/basic_memory/mcp/ui/__init__.py +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/src/basic_memory/mcp/ui/html/note-preview-mcp-ui.html +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/src/basic_memory/mcp/ui/html/note-preview-tool-ui.html +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/src/basic_memory/mcp/ui/html/note-preview-vanilla.html +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/src/basic_memory/mcp/ui/html/search-results-mcp-ui.html +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/src/basic_memory/mcp/ui/html/search-results-tool-ui.html +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/src/basic_memory/mcp/ui/html/search-results-vanilla.html +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/src/basic_memory/mcp/ui/sdk.py +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/src/basic_memory/mcp/ui/templates.py +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/src/basic_memory/models/__init__.py +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/src/basic_memory/models/base.py +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/src/basic_memory/models/knowledge.py +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/src/basic_memory/models/project.py +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/src/basic_memory/models/search.py +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/src/basic_memory/project_resolver.py +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/src/basic_memory/repository/__init__.py +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/src/basic_memory/repository/embedding_provider.py +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/src/basic_memory/repository/embedding_provider_factory.py +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/src/basic_memory/repository/entity_repository.py +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/src/basic_memory/repository/fastembed_provider.py +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/src/basic_memory/repository/metadata_filters.py +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/src/basic_memory/repository/observation_repository.py +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/src/basic_memory/repository/openai_provider.py +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/src/basic_memory/repository/postgres_search_repository.py +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/src/basic_memory/repository/project_info_repository.py +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/src/basic_memory/repository/project_repository.py +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/src/basic_memory/repository/relation_repository.py +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/src/basic_memory/repository/repository.py +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/src/basic_memory/repository/search_index_row.py +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/src/basic_memory/repository/search_repository.py +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/src/basic_memory/repository/search_repository_base.py +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/src/basic_memory/repository/semantic_errors.py +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/src/basic_memory/repository/sqlite_search_repository.py +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/src/basic_memory/runtime.py +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/src/basic_memory/schema/__init__.py +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/src/basic_memory/schema/diff.py +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/src/basic_memory/schema/inference.py +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/src/basic_memory/schema/parser.py +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/src/basic_memory/schema/resolver.py +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/src/basic_memory/schema/validator.py +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/src/basic_memory/schemas/__init__.py +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/src/basic_memory/schemas/cloud.py +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/src/basic_memory/schemas/delete.py +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/src/basic_memory/schemas/directory.py +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/src/basic_memory/schemas/importer.py +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/src/basic_memory/schemas/memory.py +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/src/basic_memory/schemas/project_info.py +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/src/basic_memory/schemas/prompt.py +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/src/basic_memory/schemas/response.py +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/src/basic_memory/schemas/schema.py +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/src/basic_memory/schemas/search.py +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/src/basic_memory/schemas/sync_report.py +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/src/basic_memory/schemas/v2/entity.py +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/src/basic_memory/schemas/v2/resource.py +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/src/basic_memory/services/__init__.py +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/src/basic_memory/services/context_service.py +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/src/basic_memory/services/directory_service.py +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/src/basic_memory/services/exceptions.py +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/src/basic_memory/services/file_service.py +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/src/basic_memory/services/initialization.py +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/src/basic_memory/services/link_resolver.py +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/src/basic_memory/services/project_service.py +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/src/basic_memory/services/search_service.py +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/src/basic_memory/services/service.py +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/src/basic_memory/sync/__init__.py +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/src/basic_memory/sync/background_sync.py +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/src/basic_memory/sync/coordinator.py +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/src/basic_memory/sync/sync_service.py +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/src/basic_memory/sync/watch_service.py +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/src/basic_memory/templates/prompts/continue_conversation.hbs +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/src/basic_memory/templates/prompts/search.hbs +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/src/basic_memory/utils.py +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/test-int/BENCHMARKS.md +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/test-int/cli/test_cli_tool_json_failure_integration.py +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/test-int/cli/test_cli_tool_json_integration.py +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/test-int/cli/test_project_commands_integration.py +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/test-int/cli/test_routing_integration.py +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/test-int/cli/test_search_notes_meta_integration.py +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/test-int/cli/test_version_integration.py +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/test-int/compare_search_benchmarks.py +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/test-int/conftest.py +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/test-int/fixtures/schema/drift/people/drift-person-01.md +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/test-int/fixtures/schema/drift/people/drift-person-02.md +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/test-int/fixtures/schema/drift/people/drift-person-03.md +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/test-int/fixtures/schema/drift/people/drift-person-04.md +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/test-int/fixtures/schema/drift/people/drift-person-05.md +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/test-int/fixtures/schema/drift/people/drift-person-06.md +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/test-int/fixtures/schema/drift/people/drift-person-07.md +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/test-int/fixtures/schema/drift/people/drift-person-08.md +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/test-int/fixtures/schema/drift/people/drift-person-09.md +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/test-int/fixtures/schema/drift/people/drift-person-10.md +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/test-int/fixtures/schema/drift/people/drift-person-11.md +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/test-int/fixtures/schema/drift/people/drift-person-12.md +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/test-int/fixtures/schema/drift/people/drift-person-13.md +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/test-int/fixtures/schema/drift/people/drift-person-14.md +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/test-int/fixtures/schema/drift/people/drift-person-15.md +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/test-int/fixtures/schema/drift/people/drift-person-16.md +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/test-int/fixtures/schema/drift/people/drift-person-17.md +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/test-int/fixtures/schema/drift/people/drift-person-18.md +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/test-int/fixtures/schema/drift/people/drift-person-19.md +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/test-int/fixtures/schema/drift/people/drift-person-20.md +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/test-int/fixtures/schema/drift/schema/Person.md +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/test-int/fixtures/schema/edge-cases/array-single.md +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/test-int/fixtures/schema/edge-cases/empty-note.md +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/test-int/fixtures/schema/edge-cases/explicit-overrides-type.md +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/test-int/fixtures/schema/edge-cases/inline-and-type.md +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/test-int/fixtures/schema/edge-cases/no-frontmatter.md +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/test-int/fixtures/schema/edge-cases/relation-only.md +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/test-int/fixtures/schema/edge-cases/type-no-schema.md +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/test-int/fixtures/schema/edge-cases/unicode-fields.md +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/test-int/fixtures/schema/inference/people/ada-lovelace.md +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/test-int/fixtures/schema/inference/people/alan-turing.md +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/test-int/fixtures/schema/inference/people/anders-hejlsberg.md +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/test-int/fixtures/schema/inference/people/andrej-karpathy.md +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/test-int/fixtures/schema/inference/people/barbara-liskov.md +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/test-int/fixtures/schema/inference/people/bjarne-stroustrup.md +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/test-int/fixtures/schema/inference/people/brendan-eich.md +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/test-int/fixtures/schema/inference/people/claude-shannon.md +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/test-int/fixtures/schema/inference/people/dennis-ritchie.md +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/test-int/fixtures/schema/inference/people/dijkstra.md +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/test-int/fixtures/schema/inference/people/donald-knuth.md +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/test-int/fixtures/schema/inference/people/fei-fei-li.md +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/test-int/fixtures/schema/inference/people/geoffrey-hinton.md +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/test-int/fixtures/schema/inference/people/grace-hopper.md +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/test-int/fixtures/schema/inference/people/guido-van-rossum.md +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/test-int/fixtures/schema/inference/people/james-gosling.md +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/test-int/fixtures/schema/inference/people/john-carmack.md +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/test-int/fixtures/schema/inference/people/ken-thompson.md +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/test-int/fixtures/schema/inference/people/larry-page.md +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/test-int/fixtures/schema/inference/people/leslie-lamport.md +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/test-int/fixtures/schema/inference/people/linus-torvalds.md +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/test-int/fixtures/schema/inference/people/margaret-hamilton.md +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/test-int/fixtures/schema/inference/people/rasmus-lerdorf.md +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/test-int/fixtures/schema/inference/people/richard-stallman.md +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/test-int/fixtures/schema/inference/people/rob-pike.md +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/test-int/fixtures/schema/inference/people/satoshi-nakamoto.md +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/test-int/fixtures/schema/inference/people/tim-berners-lee.md +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/test-int/fixtures/schema/inference/people/vint-cerf.md +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/test-int/fixtures/schema/inference/people/yann-lecun.md +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/test-int/fixtures/schema/inference/people/yukihiro-matsumoto.md +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/test-int/fixtures/schema/schemas/Book.md +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/test-int/fixtures/schema/schemas/Meeting.md +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/test-int/fixtures/schema/schemas/Person.md +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/test-int/fixtures/schema/schemas/SoftwareProject.md +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/test-int/fixtures/schema/schemas/StrictSchema.md +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/test-int/fixtures/schema/valid/basic-memory.md +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/test-int/fixtures/schema/valid/explicit-ref-note.md +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/test-int/fixtures/schema/valid/no-schema-note.md +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/test-int/fixtures/schema/valid/paul-graham.md +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/test-int/fixtures/schema/valid/rich-hickey.md +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/test-int/fixtures/schema/valid/standup-2024-01-15.md +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/test-int/fixtures/schema/warnings/extra-observations.md +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/test-int/fixtures/schema/warnings/missing-multiple.md +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/test-int/fixtures/schema/warnings/missing-required.md +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/test-int/fixtures/schema/warnings/wrong-enum-value.md +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/test-int/mcp/test_build_context_underscore.py +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/test-int/mcp/test_build_context_validation.py +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/test-int/mcp/test_chatgpt_tools_integration.py +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/test-int/mcp/test_default_project_mode_integration.py +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/test-int/mcp/test_delete_directory_integration.py +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/test-int/mcp/test_lifespan_shutdown_sync_task_cancellation_integration.py +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/test-int/mcp/test_list_directory_integration.py +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/test-int/mcp/test_move_directory_integration.py +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/test-int/mcp/test_output_format_json_integration.py +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/test-int/mcp/test_pagination_integration.py +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/test-int/mcp/test_permalink_collision_integration.py +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/test-int/mcp/test_project_management_integration.py +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/test-int/mcp/test_project_state_sync_integration.py +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/test-int/mcp/test_read_content_integration.py +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/test-int/mcp/test_read_note_integration.py +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/test-int/mcp/test_search_integration.py +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/test-int/mcp/test_single_project_mcp_integration.py +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/test-int/mcp/test_smoke_integration.py +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/test-int/mcp/test_ui_sdk_integration.py +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/test-int/mcp/test_write_note_integration.py +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/test-int/semantic/__init__.py +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/test-int/semantic/conftest.py +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/test-int/semantic/corpus.py +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/test-int/semantic/metrics.py +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/test-int/semantic/report.py +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/test-int/semantic/test_multiterm_semantic_queries.py +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/test-int/semantic/test_search_diagnostics.py +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/test-int/semantic/test_semantic_coverage.py +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/test-int/semantic/test_semantic_quality.py +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/test-int/test_db_wal_mode.py +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/test-int/test_disable_permalinks_integration.py +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/test-int/test_schema/__init__.py +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/test-int/test_schema/conftest.py +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/test-int/test_schema/helpers.py +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/test-int/test_schema/test_diff_integration.py +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/test-int/test_schema/test_inference_integration.py +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/test-int/test_schema/test_parser_integration.py +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/test-int/test_schema/test_validator_integration.py +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/test-int/test_search_performance_benchmark.py +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/tests/Non-MarkdownFileSupport.pdf +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/tests/README.md +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/tests/Screenshot.png +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/tests/__init__.py +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/tests/api/v2/__init__.py +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/tests/api/v2/conftest.py +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/tests/api/v2/test_directory_router.py +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/tests/api/v2/test_importer_router.py +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/tests/api/v2/test_knowledge_router.py +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/tests/api/v2/test_memory_router.py +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/tests/api/v2/test_project_router.py +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/tests/api/v2/test_prompt_router.py +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/tests/api/v2/test_resource_router.py +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/tests/api/v2/test_schema_router.py +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/tests/api/v2/test_search_router.py +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/tests/cli/cloud/test_cloud_api_client_and_utils.py +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/tests/cli/cloud/test_rclone_config_and_bmignore_filters.py +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/tests/cli/cloud/test_upload_command_routing.py +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/tests/cli/cloud/test_upload_path.py +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/tests/cli/conftest.py +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/tests/cli/test_analytics.py +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/tests/cli/test_auth_cli_auth.py +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/tests/cli/test_cli_container.py +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/tests/cli/test_cli_exit.py +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/tests/cli/test_cli_schema.py +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/tests/cli/test_cli_tool_exit.py +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/tests/cli/test_cli_tool_json_output.py +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/tests/cli/test_cli_tools.py +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/tests/cli/test_cloud_authentication.py +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/tests/cli/test_cloud_promo.py +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/tests/cli/test_cloud_status.py +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/tests/cli/test_db_reset_exit.py +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/tests/cli/test_ignore_utils.py +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/tests/cli/test_import_chatgpt.py +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/tests/cli/test_import_claude_conversations.py +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/tests/cli/test_import_claude_projects.py +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/tests/cli/test_import_memory_json.py +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/tests/cli/test_json_output.py +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/tests/cli/test_project_add_with_local_path.py +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/tests/cli/test_project_info_errors.py +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/tests/cli/test_project_list_and_ls.py +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/tests/cli/test_project_set_cloud_local.py +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/tests/cli/test_restore_commands.py +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/tests/cli/test_routing.py +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/tests/cli/test_snapshot_commands.py +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/tests/cli/test_upload.py +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/tests/cli/test_workspace_commands.py +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/tests/conftest.py +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/tests/db/test_issue_254_foreign_key_constraints.py +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/tests/importers/test_conversation_indexing.py +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/tests/importers/test_importer_base.py +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/tests/importers/test_importer_utils.py +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/tests/markdown/__init__.py +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/tests/markdown/test_date_frontmatter_parsing.py +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/tests/markdown/test_entity_parser.py +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/tests/markdown/test_entity_parser_error_handling.py +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/tests/markdown/test_markdown_plugins.py +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/tests/markdown/test_markdown_processor.py +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/tests/markdown/test_markdown_utils.py +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/tests/markdown/test_observation_edge_cases.py +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/tests/markdown/test_parser_edge_cases.py +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/tests/markdown/test_relation_edge_cases.py +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/tests/markdown/test_task_detection.py +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/tests/mcp/clients/__init__.py +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/tests/mcp/clients/test_clients.py +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/tests/mcp/conftest.py +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/tests/mcp/test_async_client_force_local.py +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/tests/mcp/test_async_client_modes.py +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/tests/mcp/test_client_schema.py +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/tests/mcp/test_mcp_container.py +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/tests/mcp/test_obsidian_yaml_formatting.py +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/tests/mcp/test_permalink_collision_file_overwrite.py +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/tests/mcp/test_project_context.py +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/tests/mcp/test_prompt_tool_delegation.py +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/tests/mcp/test_prompts.py +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/tests/mcp/test_recent_activity_prompt_modes.py +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/tests/mcp/test_resources.py +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/tests/mcp/test_server_lifespan_branches.py +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/tests/mcp/test_tool_build_context.py +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/tests/mcp/test_tool_canvas.py +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/tests/mcp/test_tool_cloud_discovery.py +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/tests/mcp/test_tool_contracts.py +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/tests/mcp/test_tool_json_output_modes.py +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/tests/mcp/test_tool_list_directory.py +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/tests/mcp/test_tool_project_management.py +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/tests/mcp/test_tool_read_content.py +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/tests/mcp/test_tool_read_note.py +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/tests/mcp/test_tool_recent_activity.py +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/tests/mcp/test_tool_resource.py +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/tests/mcp/test_tool_schema.py +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/tests/mcp/test_tool_search.py +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/tests/mcp/test_tool_utils.py +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/tests/mcp/test_tool_utils_cloud_auth.py +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/tests/mcp/test_tool_view_note.py +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/tests/mcp/test_tool_workspace_management.py +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/tests/mcp/test_tool_write_note.py +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/tests/mcp/test_tool_write_note_kebab_filenames.py +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/tests/mcp/test_tool_write_note_metadata.py +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/tests/mcp/test_ui_resources.py +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/tests/mcp/test_ui_sdk.py +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/tests/mcp/test_ui_templates.py +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/tests/mcp/tools/test_chatgpt_tools.py +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/tests/repository/test_distance_to_similarity.py +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/tests/repository/test_entity_repository.py +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/tests/repository/test_entity_repository_upsert.py +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/tests/repository/test_entity_upsert_issue_187.py +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/tests/repository/test_fastembed_provider.py +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/tests/repository/test_hybrid_fusion.py +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/tests/repository/test_metadata_filters.py +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/tests/repository/test_metadata_filters_edge_cases.py +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/tests/repository/test_observation_repository.py +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/tests/repository/test_openai_provider.py +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/tests/repository/test_postgres_search_repository.py +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/tests/repository/test_postgres_search_repository_unit.py +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/tests/repository/test_project_info_repository.py +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/tests/repository/test_project_repository.py +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/tests/repository/test_relation_repository.py +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/tests/repository/test_repository.py +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/tests/repository/test_search_index_row.py +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/tests/repository/test_search_repository.py +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/tests/repository/test_search_repository_edit_bug_fix.py +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/tests/repository/test_search_text_with_metadata_filters.py +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/tests/repository/test_semantic_search_base.py +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/tests/repository/test_sqlite_vector_search_repository.py +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/tests/repository/test_vector_pagination.py +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/tests/repository/test_vector_threshold.py +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/tests/schema/__init__.py +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/tests/schema/test_diff.py +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/tests/schema/test_inference.py +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/tests/schema/test_parser.py +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/tests/schema/test_resolver.py +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/tests/schema/test_validator.py +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/tests/schemas/test_base_timeframe_minimum.py +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/tests/schemas/test_memory_serialization.py +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/tests/schemas/test_memory_url.py +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/tests/schemas/test_memory_url_validation.py +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/tests/schemas/test_relation_response_reference_resolution.py +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/tests/schemas/test_search.py +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/tests/services/test_context_service.py +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/tests/services/test_directory_service.py +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/tests/services/test_entity_service_disable_permalinks.py +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/tests/services/test_file_service.py +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/tests/services/test_initialization.py +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/tests/services/test_initialization_cloud_mode_branches.py +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/tests/services/test_link_resolver.py +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/tests/services/test_project_removal_bug.py +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/tests/services/test_project_service.py +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/tests/services/test_project_service_cloud_info.py +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/tests/services/test_project_service_embedding_status.py +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/tests/services/test_project_service_operations.py +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/tests/services/test_search_service.py +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/tests/services/test_semantic_search.py +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/tests/services/test_task_scheduler_semantic.py +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/tests/sync/test_character_conflicts.py +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/tests/sync/test_coordinator.py +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/tests/sync/test_sync_service.py +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/tests/sync/test_sync_service_incremental.py +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/tests/sync/test_sync_wikilink_issue.py +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/tests/sync/test_tmp_files.py +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/tests/sync/test_watch_service.py +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/tests/sync/test_watch_service_atomic_adds.py +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/tests/sync/test_watch_service_edge_cases.py +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/tests/sync/test_watch_service_reload.py +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/tests/sync/test_watch_service_stress.py +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/tests/test_config.py +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/tests/test_deps.py +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/tests/test_production_cascade_delete.py +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/tests/test_project_resolver.py +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/tests/test_rclone_commands.py +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/tests/test_runtime.py +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/tests/utils/test_file_utils.py +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/tests/utils/test_frontmatter_obsidian_compatible.py +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/tests/utils/test_parse_tags.py +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/tests/utils/test_permalink_formatting.py +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/tests/utils/test_timezone_utils.py +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/tests/utils/test_utf8_handling.py +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/tests/utils/test_validate_project_path.py +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/ui/tool-ui-react/.gitignore +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/ui/tool-ui-react/build.mjs +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/ui/tool-ui-react/package-lock.json +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/ui/tool-ui-react/package.json +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/ui/tool-ui-react/src/components/tool-ui/data-table/_adapter.tsx +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/ui/tool-ui-react/src/components/tool-ui/data-table/data-table.tsx +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/ui/tool-ui-react/src/components/tool-ui/data-table/error-boundary.tsx +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/ui/tool-ui-react/src/components/tool-ui/data-table/formatters.tsx +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/ui/tool-ui-react/src/components/tool-ui/data-table/index.tsx +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/ui/tool-ui-react/src/components/tool-ui/data-table/schema.ts +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/ui/tool-ui-react/src/components/tool-ui/data-table/types.ts +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/ui/tool-ui-react/src/components/tool-ui/data-table/utilities.ts +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/ui/tool-ui-react/src/components/tool-ui/shared/_adapter.tsx +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/ui/tool-ui-react/src/components/tool-ui/shared/action-buttons.tsx +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/ui/tool-ui-react/src/components/tool-ui/shared/actions-config.ts +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/ui/tool-ui-react/src/components/tool-ui/shared/error-boundary.tsx +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/ui/tool-ui-react/src/components/tool-ui/shared/index.ts +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/ui/tool-ui-react/src/components/tool-ui/shared/media/aspect-ratio.ts +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/ui/tool-ui-react/src/components/tool-ui/shared/media/format-utils.ts +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/ui/tool-ui-react/src/components/tool-ui/shared/media/index.ts +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/ui/tool-ui-react/src/components/tool-ui/shared/media/overlay-gradient.ts +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/ui/tool-ui-react/src/components/tool-ui/shared/media/sanitize-href.ts +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/ui/tool-ui-react/src/components/tool-ui/shared/parse.ts +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/ui/tool-ui-react/src/components/tool-ui/shared/schema.ts +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/ui/tool-ui-react/src/components/tool-ui/shared/use-action-buttons.tsx +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/ui/tool-ui-react/src/components/tool-ui/shared/use-copy-to-clipboard.ts +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/ui/tool-ui-react/src/components/tool-ui/shared/utils.ts +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/ui/tool-ui-react/src/components/ui/accordion.tsx +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/ui/tool-ui-react/src/components/ui/badge.tsx +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/ui/tool-ui-react/src/components/ui/button.tsx +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/ui/tool-ui-react/src/components/ui/dropdown-menu.tsx +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/ui/tool-ui-react/src/components/ui/table.tsx +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/ui/tool-ui-react/src/components/ui/tooltip.tsx +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/ui/tool-ui-react/src/note-preview.tsx +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/ui/tool-ui-react/src/search-results.tsx +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/ui/tool-ui-react/src/styles.css +0 -0
- {basic_memory-0.19.0 → basic_memory-0.19.1}/ui/tool-ui-react/tailwind.config.js +0 -0
|
@@ -2,6 +2,23 @@
|
|
|
2
2
|
|
|
3
3
|
## Unreleased
|
|
4
4
|
|
|
5
|
+
## v0.19.1 (2026-03-08)
|
|
6
|
+
|
|
7
|
+
### Bug Fixes
|
|
8
|
+
|
|
9
|
+
- **#649**: Enforce strict entity resolution in destructive MCP tools (`edit_note`, `move_note`, `delete_note`)
|
|
10
|
+
- Prevents fuzzy-match fallback from silently editing/moving/deleting the wrong note
|
|
11
|
+
- DST-related timeframe validation fix (round instead of truncate days)
|
|
12
|
+
|
|
13
|
+
### Features
|
|
14
|
+
|
|
15
|
+
- **#648**: Add `insert_before_section` and `insert_after_section` edit operations
|
|
16
|
+
- Add `GET /knowledge/graph` endpoint for full graph visualization
|
|
17
|
+
|
|
18
|
+
### Dependencies
|
|
19
|
+
|
|
20
|
+
- Bump authlib from 1.6.6 to 1.6.7
|
|
21
|
+
|
|
5
22
|
## v0.19.0 (2026-03-07)
|
|
6
23
|
|
|
7
24
|
### Highlights
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: basic-memory
|
|
3
|
-
Version: 0.19.
|
|
3
|
+
Version: 0.19.1
|
|
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
|
|
@@ -74,6 +74,18 @@ Basic Memory lets you build persistent knowledge through natural conversations w
|
|
|
74
74
|
Claude, while keeping everything in simple Markdown files on your computer. It uses the Model Context Protocol (MCP) to
|
|
75
75
|
enable any compatible LLM to read and write to your local knowledge base.
|
|
76
76
|
|
|
77
|
+
## What's New in v0.19.0
|
|
78
|
+
|
|
79
|
+
- **Semantic Vector Search** — find notes by meaning, not just keywords. Combines full-text and vector similarity for hybrid search with FastEmbed embeddings.
|
|
80
|
+
- **Schema System** — infer, validate, and diff the structure of your knowledge base with `schema_infer`, `schema_validate`, and `schema_diff` tools.
|
|
81
|
+
- **Per-Project Cloud Routing** — route individual projects through the cloud while others stay local, using API key authentication (`basic-memory project set-cloud`).
|
|
82
|
+
- **FastMCP 3.0** — upgraded to FastMCP 3.0 with tool annotations for better client integration.
|
|
83
|
+
- **CLI Overhaul** — JSON output mode (`--json`) for scripting, workspace-aware commands, and an htop-inspired project dashboard.
|
|
84
|
+
- **Smarter Editing** — `edit_note` append/prepend auto-creates notes if they don't exist; `write_note` has an overwrite guard to prevent accidental data loss.
|
|
85
|
+
- **Richer Search Results** — matched chunk text returned in search results for better context.
|
|
86
|
+
|
|
87
|
+
See the full [CHANGELOG](CHANGELOG.md) for details.
|
|
88
|
+
|
|
77
89
|
- Website: [basicmemory.com](https://basicmemory.com?utm_source=github&utm_medium=referral&utm_campaign=readme)
|
|
78
90
|
- Documentation: [docs.basicmemory.com](https://docs.basicmemory.com?utm_source=github&utm_medium=referral&utm_campaign=readme)
|
|
79
91
|
- Community: [Discord](https://discord.gg/tyvKNccgqN?utm_source=github&utm_medium=referral&utm_campaign=readme)
|
|
@@ -23,6 +23,18 @@ Basic Memory lets you build persistent knowledge through natural conversations w
|
|
|
23
23
|
Claude, while keeping everything in simple Markdown files on your computer. It uses the Model Context Protocol (MCP) to
|
|
24
24
|
enable any compatible LLM to read and write to your local knowledge base.
|
|
25
25
|
|
|
26
|
+
## What's New in v0.19.0
|
|
27
|
+
|
|
28
|
+
- **Semantic Vector Search** — find notes by meaning, not just keywords. Combines full-text and vector similarity for hybrid search with FastEmbed embeddings.
|
|
29
|
+
- **Schema System** — infer, validate, and diff the structure of your knowledge base with `schema_infer`, `schema_validate`, and `schema_diff` tools.
|
|
30
|
+
- **Per-Project Cloud Routing** — route individual projects through the cloud while others stay local, using API key authentication (`basic-memory project set-cloud`).
|
|
31
|
+
- **FastMCP 3.0** — upgraded to FastMCP 3.0 with tool annotations for better client integration.
|
|
32
|
+
- **CLI Overhaul** — JSON output mode (`--json`) for scripting, workspace-aware commands, and an htop-inspired project dashboard.
|
|
33
|
+
- **Smarter Editing** — `edit_note` append/prepend auto-creates notes if they don't exist; `write_note` has an overwrite guard to prevent accidental data loss.
|
|
34
|
+
- **Richer Search Results** — matched chunk text returned in search results for better context.
|
|
35
|
+
|
|
36
|
+
See the full [CHANGELOG](CHANGELOG.md) for details.
|
|
37
|
+
|
|
26
38
|
- Website: [basicmemory.com](https://basicmemory.com?utm_source=github&utm_medium=referral&utm_campaign=readme)
|
|
27
39
|
- Documentation: [docs.basicmemory.com](https://docs.basicmemory.com?utm_source=github&utm_medium=referral&utm_campaign=readme)
|
|
28
40
|
- Community: [Discord](https://discord.gg/tyvKNccgqN?utm_source=github&utm_medium=referral&utm_campaign=readme)
|
|
@@ -6,12 +6,12 @@
|
|
|
6
6
|
"url": "https://github.com/basicmachines-co/basic-memory.git",
|
|
7
7
|
"source": "github"
|
|
8
8
|
},
|
|
9
|
-
"version": "0.19.
|
|
9
|
+
"version": "0.19.1",
|
|
10
10
|
"packages": [
|
|
11
11
|
{
|
|
12
12
|
"registryType": "pypi",
|
|
13
13
|
"identifier": "basic-memory",
|
|
14
|
-
"version": "0.19.
|
|
14
|
+
"version": "0.19.1",
|
|
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.19.
|
|
4
|
+
__version__ = "0.19.1"
|
|
5
5
|
|
|
6
6
|
# API version for FastAPI - independent of package version
|
|
7
7
|
__api_version__ = "v0"
|
{basic_memory-0.19.0 → basic_memory-0.19.1}/src/basic_memory/api/v2/routers/knowledge_router.py
RENAMED
|
@@ -20,6 +20,7 @@ from basic_memory.deps import (
|
|
|
20
20
|
ProjectConfigV2ExternalDep,
|
|
21
21
|
AppConfigDep,
|
|
22
22
|
EntityRepositoryV2ExternalDep,
|
|
23
|
+
RelationRepositoryV2ExternalDep,
|
|
23
24
|
ProjectExternalIdPathDep,
|
|
24
25
|
TaskSchedulerDep,
|
|
25
26
|
FileServiceV2ExternalDep,
|
|
@@ -31,6 +32,9 @@ from basic_memory.schemas.v2 import (
|
|
|
31
32
|
EntityResolveRequest,
|
|
32
33
|
EntityResolveResponse,
|
|
33
34
|
EntityResponseV2,
|
|
35
|
+
GraphEdge,
|
|
36
|
+
GraphNode,
|
|
37
|
+
GraphResponse,
|
|
34
38
|
MoveEntityRequestV2,
|
|
35
39
|
MoveDirectoryRequestV2,
|
|
36
40
|
DeleteDirectoryRequestV2,
|
|
@@ -56,6 +60,50 @@ def _schedule_vector_sync_if_enabled(
|
|
|
56
60
|
)
|
|
57
61
|
|
|
58
62
|
|
|
63
|
+
## Graph endpoint
|
|
64
|
+
|
|
65
|
+
|
|
66
|
+
@router.get("/graph", response_model=GraphResponse)
|
|
67
|
+
async def get_graph(
|
|
68
|
+
project_id: ProjectExternalIdPathDep,
|
|
69
|
+
entity_repository: EntityRepositoryV2ExternalDep,
|
|
70
|
+
relation_repository: RelationRepositoryV2ExternalDep,
|
|
71
|
+
) -> GraphResponse:
|
|
72
|
+
"""Return all entities and resolved relations for knowledge graph visualization.
|
|
73
|
+
|
|
74
|
+
Returns a flat node/edge structure optimized for rendering with graph libraries.
|
|
75
|
+
Only includes resolved relations (where to_id is not null).
|
|
76
|
+
"""
|
|
77
|
+
logger.info("API v2 request: get_graph")
|
|
78
|
+
|
|
79
|
+
# Fetch all entities for this project
|
|
80
|
+
entities = await entity_repository.find_all(use_load_options=False)
|
|
81
|
+
nodes = [
|
|
82
|
+
GraphNode(
|
|
83
|
+
external_id=entity.external_id,
|
|
84
|
+
title=entity.title,
|
|
85
|
+
note_type=entity.note_type,
|
|
86
|
+
file_path=entity.file_path,
|
|
87
|
+
)
|
|
88
|
+
for entity in entities
|
|
89
|
+
]
|
|
90
|
+
|
|
91
|
+
# Fetch all resolved relations (to_id is not null) with eager-loaded entities
|
|
92
|
+
relations = await relation_repository.find_all()
|
|
93
|
+
edges = [
|
|
94
|
+
GraphEdge(
|
|
95
|
+
from_id=relation.from_entity.external_id,
|
|
96
|
+
to_id=relation.to_entity.external_id,
|
|
97
|
+
relation_type=relation.relation_type,
|
|
98
|
+
)
|
|
99
|
+
for relation in relations
|
|
100
|
+
if relation.to_entity is not None
|
|
101
|
+
]
|
|
102
|
+
|
|
103
|
+
logger.info(f"API v2 response: graph with {len(nodes)} nodes and {len(edges)} edges")
|
|
104
|
+
return GraphResponse(nodes=nodes, edges=edges)
|
|
105
|
+
|
|
106
|
+
|
|
59
107
|
## Resolution endpoint
|
|
60
108
|
|
|
61
109
|
|
|
@@ -318,7 +318,7 @@ delete_note("path/to/file.md")
|
|
|
318
318
|
note_file_path = None
|
|
319
319
|
try:
|
|
320
320
|
# Resolve identifier to entity ID
|
|
321
|
-
entity_id = await knowledge_client.resolve_entity(identifier)
|
|
321
|
+
entity_id = await knowledge_client.resolve_entity(identifier, strict=True)
|
|
322
322
|
if output_format == "json":
|
|
323
323
|
entity = await knowledge_client.get_entity(entity_id)
|
|
324
324
|
note_title = entity.title
|
|
@@ -158,7 +158,7 @@ Error editing note '{identifier}': {error_message}
|
|
|
158
158
|
|
|
159
159
|
|
|
160
160
|
@mcp.tool(
|
|
161
|
-
description="Edit an existing markdown note using various operations like append, prepend, find_replace, or
|
|
161
|
+
description="Edit an existing markdown note using various operations like append, prepend, find_replace, replace_section, insert_before_section, or insert_after_section.",
|
|
162
162
|
annotations={"destructiveHint": False, "openWorldHint": False},
|
|
163
163
|
)
|
|
164
164
|
async def edit_note(
|
|
@@ -190,6 +190,8 @@ async def edit_note(
|
|
|
190
190
|
- "prepend": Add content to the beginning of the note (creates the note if it doesn't exist)
|
|
191
191
|
- "find_replace": Replace occurrences of find_text with content (note must exist)
|
|
192
192
|
- "replace_section": Replace content under a specific markdown header (note must exist)
|
|
193
|
+
- "insert_before_section": Insert content before a section heading without consuming it (note must exist)
|
|
194
|
+
- "insert_after_section": Insert content after a section heading without consuming it (note must exist)
|
|
193
195
|
content: The content to add or use for replacement
|
|
194
196
|
project: Project name to edit in. Optional - server will resolve using hierarchy.
|
|
195
197
|
If unknown, use list_memory_projects() to discover available projects.
|
|
@@ -257,7 +259,14 @@ async def edit_note(
|
|
|
257
259
|
logger.info("MCP tool call", tool="edit_note", identifier=identifier, operation=operation)
|
|
258
260
|
|
|
259
261
|
# Validate operation
|
|
260
|
-
valid_operations = [
|
|
262
|
+
valid_operations = [
|
|
263
|
+
"append",
|
|
264
|
+
"prepend",
|
|
265
|
+
"find_replace",
|
|
266
|
+
"replace_section",
|
|
267
|
+
"insert_before_section",
|
|
268
|
+
"insert_after_section",
|
|
269
|
+
]
|
|
261
270
|
if operation not in valid_operations:
|
|
262
271
|
raise ValueError(
|
|
263
272
|
f"Invalid operation '{operation}'. Must be one of: {', '.join(valid_operations)}"
|
|
@@ -266,8 +275,9 @@ async def edit_note(
|
|
|
266
275
|
# Validate required parameters for specific operations
|
|
267
276
|
if operation == "find_replace" and not find_text:
|
|
268
277
|
raise ValueError("find_text parameter is required for find_replace operation")
|
|
269
|
-
|
|
270
|
-
|
|
278
|
+
section_ops = ("replace_section", "insert_before_section", "insert_after_section")
|
|
279
|
+
if operation in section_ops and not section:
|
|
280
|
+
raise ValueError("section parameter is required for section-based operations")
|
|
271
281
|
|
|
272
282
|
# Use the PATCH endpoint to edit the entity
|
|
273
283
|
try:
|
|
@@ -283,7 +293,7 @@ async def edit_note(
|
|
|
283
293
|
|
|
284
294
|
# Try to resolve the entity; for append/prepend, create it if not found
|
|
285
295
|
try:
|
|
286
|
-
entity_id = await knowledge_client.resolve_entity(identifier)
|
|
296
|
+
entity_id = await knowledge_client.resolve_entity(identifier, strict=True)
|
|
287
297
|
except Exception as resolve_error:
|
|
288
298
|
# Trigger: entity does not exist yet
|
|
289
299
|
# Why: append/prepend can meaningfully create a new note from the content,
|
|
@@ -389,6 +399,10 @@ async def edit_note(
|
|
|
389
399
|
summary.append("operation: Find and replace operation completed")
|
|
390
400
|
elif operation == "replace_section":
|
|
391
401
|
summary.append(f"operation: Replaced content under section '{section}'")
|
|
402
|
+
elif operation == "insert_before_section":
|
|
403
|
+
summary.append(f"operation: Inserted content before section '{section}'")
|
|
404
|
+
elif operation == "insert_after_section":
|
|
405
|
+
summary.append(f"operation: Inserted content after section '{section}'")
|
|
392
406
|
|
|
393
407
|
# Count observations by category (reuse logic from write_note)
|
|
394
408
|
categories = {}
|
|
@@ -6,6 +6,7 @@ from typing import Optional, Literal
|
|
|
6
6
|
|
|
7
7
|
from loguru import logger
|
|
8
8
|
from fastmcp import Context
|
|
9
|
+
from mcp.server.fastmcp.exceptions import ToolError
|
|
9
10
|
|
|
10
11
|
from basic_memory.mcp.server import mcp
|
|
11
12
|
from basic_memory.mcp.project_context import get_project_client
|
|
@@ -637,7 +638,7 @@ move_note("path/to/file.md", "{destination_path}/file.md")
|
|
|
637
638
|
"""Resolve and cache the source entity ID for the duration of this move."""
|
|
638
639
|
nonlocal resolved_entity_id
|
|
639
640
|
if resolved_entity_id is None:
|
|
640
|
-
resolved_entity_id = await knowledge_client.resolve_entity(identifier)
|
|
641
|
+
resolved_entity_id = await knowledge_client.resolve_entity(identifier, strict=True)
|
|
641
642
|
return resolved_entity_id
|
|
642
643
|
|
|
643
644
|
try:
|
|
@@ -645,8 +646,26 @@ move_note("path/to/file.md", "{destination_path}/file.md")
|
|
|
645
646
|
source_entity = await knowledge_client.get_entity(resolved_entity_id)
|
|
646
647
|
if "." in source_entity.file_path:
|
|
647
648
|
source_ext = source_entity.file_path.split(".")[-1]
|
|
649
|
+
except ToolError as e:
|
|
650
|
+
# Trigger: strict=True resolve_entity raised because the entity was not found.
|
|
651
|
+
# Why: fail fast with a formatted error instead of silently falling through
|
|
652
|
+
# to extension defaults and failing later with a confusing message.
|
|
653
|
+
# Outcome: move_note returns a user-facing not-found error immediately.
|
|
654
|
+
logger.error(f"Move failed for '{identifier}' to '{destination_path}': {e}")
|
|
655
|
+
if output_format == "json":
|
|
656
|
+
return {
|
|
657
|
+
"moved": False,
|
|
658
|
+
"title": None,
|
|
659
|
+
"permalink": None,
|
|
660
|
+
"file_path": None,
|
|
661
|
+
"source": identifier,
|
|
662
|
+
"destination": destination_path,
|
|
663
|
+
"error": str(e),
|
|
664
|
+
}
|
|
665
|
+
return _format_move_error_response(str(e), identifier, destination_path)
|
|
648
666
|
except Exception as e:
|
|
649
|
-
# If we can't fetch source metadata
|
|
667
|
+
# If we can't fetch source metadata (e.g. get_entity or file_path parsing fails),
|
|
668
|
+
# continue with extension defaults — the entity was at least resolved.
|
|
650
669
|
logger.debug(f"Could not fetch source entity for extension check: {e}")
|
|
651
670
|
|
|
652
671
|
# --- Resolve destination_folder into destination_path ---
|
|
@@ -140,10 +140,12 @@ def validate_timeframe(timeframe: str) -> str:
|
|
|
140
140
|
if parsed > now:
|
|
141
141
|
raise ValueError("Timeframe cannot be in the future") # pragma: no cover
|
|
142
142
|
|
|
143
|
-
#
|
|
144
|
-
|
|
143
|
+
# Round to nearest day to handle DST transitions where an hour shift
|
|
144
|
+
# can cause e.g. "7d" to compute as 6 days + 23 hours
|
|
145
|
+
total_seconds = (now - parsed).total_seconds()
|
|
146
|
+
days = round(total_seconds / 86400)
|
|
145
147
|
|
|
146
|
-
#
|
|
148
|
+
# Enforce reasonable limits
|
|
147
149
|
if days > 365:
|
|
148
150
|
raise ValueError("Timeframe should be <= 1 year")
|
|
149
151
|
|
|
@@ -65,7 +65,14 @@ class EditEntityRequest(BaseModel):
|
|
|
65
65
|
Supports various operation types for different editing scenarios.
|
|
66
66
|
"""
|
|
67
67
|
|
|
68
|
-
operation: Literal[
|
|
68
|
+
operation: Literal[
|
|
69
|
+
"append",
|
|
70
|
+
"prepend",
|
|
71
|
+
"find_replace",
|
|
72
|
+
"replace_section",
|
|
73
|
+
"insert_before_section",
|
|
74
|
+
"insert_after_section",
|
|
75
|
+
]
|
|
69
76
|
content: str
|
|
70
77
|
section: Optional[str] = None
|
|
71
78
|
find_text: Optional[str] = None
|
|
@@ -75,8 +82,16 @@ class EditEntityRequest(BaseModel):
|
|
|
75
82
|
@classmethod
|
|
76
83
|
def validate_section_for_replace_section(cls, v, info):
|
|
77
84
|
"""Ensure section is provided for replace_section operation."""
|
|
78
|
-
if
|
|
79
|
-
|
|
85
|
+
if (
|
|
86
|
+
info.data.get("operation")
|
|
87
|
+
in (
|
|
88
|
+
"replace_section",
|
|
89
|
+
"insert_before_section",
|
|
90
|
+
"insert_after_section",
|
|
91
|
+
)
|
|
92
|
+
and not v
|
|
93
|
+
):
|
|
94
|
+
raise ValueError("section parameter is required for section-based operations")
|
|
80
95
|
return v
|
|
81
96
|
|
|
82
97
|
@field_validator("find_text")
|
|
@@ -10,6 +10,11 @@ from basic_memory.schemas.v2.entity import (
|
|
|
10
10
|
ProjectResolveRequest,
|
|
11
11
|
ProjectResolveResponse,
|
|
12
12
|
)
|
|
13
|
+
from basic_memory.schemas.v2.graph import (
|
|
14
|
+
GraphEdge,
|
|
15
|
+
GraphNode,
|
|
16
|
+
GraphResponse,
|
|
17
|
+
)
|
|
13
18
|
from basic_memory.schemas.v2.resource import (
|
|
14
19
|
CreateResourceRequest,
|
|
15
20
|
UpdateResourceRequest,
|
|
@@ -25,6 +30,9 @@ __all__ = [
|
|
|
25
30
|
"DeleteDirectoryRequestV2",
|
|
26
31
|
"ProjectResolveRequest",
|
|
27
32
|
"ProjectResolveResponse",
|
|
33
|
+
"GraphEdge",
|
|
34
|
+
"GraphNode",
|
|
35
|
+
"GraphResponse",
|
|
28
36
|
"CreateResourceRequest",
|
|
29
37
|
"UpdateResourceRequest",
|
|
30
38
|
"ResourceResponse",
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
"""Graph visualization schemas for the knowledge graph endpoint."""
|
|
2
|
+
|
|
3
|
+
from typing import Optional
|
|
4
|
+
|
|
5
|
+
from pydantic import BaseModel, Field
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
class GraphNode(BaseModel):
|
|
9
|
+
"""A node in the knowledge graph visualization."""
|
|
10
|
+
|
|
11
|
+
external_id: str = Field(..., description="Entity external ID (UUID)")
|
|
12
|
+
title: str = Field(..., description="Entity title")
|
|
13
|
+
note_type: Optional[str] = Field(None, description="Note type (e.g., note, spec, task)")
|
|
14
|
+
file_path: str = Field(..., description="Relative file path")
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
class GraphEdge(BaseModel):
|
|
18
|
+
"""An edge in the knowledge graph visualization."""
|
|
19
|
+
|
|
20
|
+
from_id: str = Field(..., description="External ID of source entity")
|
|
21
|
+
to_id: str = Field(..., description="External ID of target entity")
|
|
22
|
+
relation_type: str = Field(..., description="Type of relation")
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
class GraphResponse(BaseModel):
|
|
26
|
+
"""Complete knowledge graph for visualization."""
|
|
27
|
+
|
|
28
|
+
nodes: list[GraphNode] = Field(default_factory=list, description="All entities as nodes")
|
|
29
|
+
edges: list[GraphEdge] = Field(
|
|
30
|
+
default_factory=list, description="All resolved relations as edges"
|
|
31
|
+
)
|
|
@@ -888,6 +888,14 @@ class EntityService(BaseService[EntityModel]):
|
|
|
888
888
|
raise ValueError("section cannot be empty or whitespace only")
|
|
889
889
|
return self.replace_section_content(current_content, section, content)
|
|
890
890
|
|
|
891
|
+
elif operation in ("insert_before_section", "insert_after_section"):
|
|
892
|
+
if not section:
|
|
893
|
+
raise ValueError("section is required for insert section operations")
|
|
894
|
+
if not section.strip():
|
|
895
|
+
raise ValueError("section cannot be empty or whitespace only")
|
|
896
|
+
position = "before" if operation == "insert_before_section" else "after"
|
|
897
|
+
return self.insert_relative_to_section(current_content, section, content, position)
|
|
898
|
+
|
|
891
899
|
else:
|
|
892
900
|
raise ValueError(f"Unsupported operation: {operation}")
|
|
893
901
|
|
|
@@ -979,6 +987,73 @@ class EntityService(BaseService[EntityModel]):
|
|
|
979
987
|
|
|
980
988
|
return "\n".join(result_lines)
|
|
981
989
|
|
|
990
|
+
def insert_relative_to_section(
|
|
991
|
+
self,
|
|
992
|
+
current_content: str,
|
|
993
|
+
section_header: str,
|
|
994
|
+
new_content: str,
|
|
995
|
+
position: str,
|
|
996
|
+
) -> str:
|
|
997
|
+
"""Insert content before or after a section heading without consuming it.
|
|
998
|
+
|
|
999
|
+
Unlike replace_section_content, this preserves the section heading and its
|
|
1000
|
+
existing content. The new content is inserted immediately before or after
|
|
1001
|
+
the heading line.
|
|
1002
|
+
|
|
1003
|
+
Args:
|
|
1004
|
+
current_content: The current markdown content
|
|
1005
|
+
section_header: The section header to anchor on (e.g., "## Section Name")
|
|
1006
|
+
new_content: The content to insert
|
|
1007
|
+
position: "before" to insert above the heading, "after" to insert below it
|
|
1008
|
+
|
|
1009
|
+
Returns:
|
|
1010
|
+
The updated content with new_content inserted relative to the heading
|
|
1011
|
+
|
|
1012
|
+
Raises:
|
|
1013
|
+
ValueError: If the section header is not found or appears more than once
|
|
1014
|
+
"""
|
|
1015
|
+
# Normalize the section header (ensure it starts with #)
|
|
1016
|
+
if not section_header.startswith("#"):
|
|
1017
|
+
section_header = "## " + section_header
|
|
1018
|
+
|
|
1019
|
+
lines = current_content.split("\n")
|
|
1020
|
+
matching_indices = [
|
|
1021
|
+
i for i, line in enumerate(lines) if line.strip() == section_header.strip()
|
|
1022
|
+
]
|
|
1023
|
+
|
|
1024
|
+
if len(matching_indices) == 0:
|
|
1025
|
+
raise ValueError(
|
|
1026
|
+
f"Section '{section_header}' not found in document. "
|
|
1027
|
+
f"Use replace_section to create a new section."
|
|
1028
|
+
)
|
|
1029
|
+
if len(matching_indices) > 1:
|
|
1030
|
+
raise ValueError(
|
|
1031
|
+
f"Multiple sections found with header '{section_header}'. "
|
|
1032
|
+
f"Section insertion requires unique headers."
|
|
1033
|
+
)
|
|
1034
|
+
|
|
1035
|
+
idx = matching_indices[0]
|
|
1036
|
+
|
|
1037
|
+
if position == "before":
|
|
1038
|
+
# Insert new content before the section heading
|
|
1039
|
+
before = lines[:idx]
|
|
1040
|
+
after = lines[idx:]
|
|
1041
|
+
# Ensure blank line separation
|
|
1042
|
+
insert_lines = new_content.rstrip("\n").split("\n")
|
|
1043
|
+
if before and before[-1].strip() != "":
|
|
1044
|
+
insert_lines = [""] + insert_lines
|
|
1045
|
+
return "\n".join(before + insert_lines + [""] + after)
|
|
1046
|
+
else:
|
|
1047
|
+
# Insert new content after the section heading line
|
|
1048
|
+
before = lines[: idx + 1]
|
|
1049
|
+
after = lines[idx + 1 :]
|
|
1050
|
+
insert_lines = new_content.rstrip("\n").split("\n")
|
|
1051
|
+
# Ensure blank line separation so inserted text doesn't merge
|
|
1052
|
+
# with existing section content into a single paragraph
|
|
1053
|
+
if after and after[0].strip() != "":
|
|
1054
|
+
insert_lines = insert_lines + [""]
|
|
1055
|
+
return "\n".join(before + insert_lines + after)
|
|
1056
|
+
|
|
982
1057
|
def _prepend_after_frontmatter(self, current_content: str, content: str) -> str:
|
|
983
1058
|
"""Prepend content after frontmatter, preserving frontmatter structure."""
|
|
984
1059
|
|
{basic_memory-0.19.0 → basic_memory-0.19.1}/test-int/cli/test_cli_tool_edit_note_integration.py
RENAMED
|
@@ -208,7 +208,7 @@ def test_edit_note_replace_section_fails_without_section(
|
|
|
208
208
|
)
|
|
209
209
|
|
|
210
210
|
assert result.exit_code != 0
|
|
211
|
-
assert "section parameter is required for
|
|
211
|
+
assert "section parameter is required for section-based operations" in result.output
|
|
212
212
|
|
|
213
213
|
|
|
214
214
|
def test_edit_note_append_creates_nonexistent_note_cli(
|
|
@@ -307,8 +307,13 @@ async def test_delete_note_by_file_path(mcp_server, app, test_project):
|
|
|
307
307
|
|
|
308
308
|
|
|
309
309
|
@pytest.mark.asyncio
|
|
310
|
-
async def
|
|
311
|
-
"""Test that
|
|
310
|
+
async def test_delete_note_rejects_case_mismatch(mcp_server, app, test_project):
|
|
311
|
+
"""Test that delete_note with wrong case does not fuzzy-match to an existing note.
|
|
312
|
+
|
|
313
|
+
Strict resolution (#649) prevents destructive operations from silently
|
|
314
|
+
resolving to a different note via fuzzy search. Case-mismatched titles
|
|
315
|
+
should be rejected, not resolved to the nearest match.
|
|
316
|
+
"""
|
|
312
317
|
|
|
313
318
|
async with Client(mcp_server) as client:
|
|
314
319
|
# Create a note with mixed case
|
|
@@ -323,7 +328,7 @@ async def test_delete_note_case_insensitive(mcp_server, app, test_project):
|
|
|
323
328
|
},
|
|
324
329
|
)
|
|
325
330
|
|
|
326
|
-
# Try to delete with different case
|
|
331
|
+
# Try to delete with different case — should NOT find the note
|
|
327
332
|
delete_result = await client.call_tool(
|
|
328
333
|
"delete_note",
|
|
329
334
|
{
|
|
@@ -332,8 +337,28 @@ async def test_delete_note_case_insensitive(mcp_server, app, test_project):
|
|
|
332
337
|
},
|
|
333
338
|
)
|
|
334
339
|
|
|
335
|
-
# Should return
|
|
336
|
-
assert "
|
|
340
|
+
# Should return False (not found) — strict mode rejects fuzzy matches
|
|
341
|
+
assert "false" in delete_result.content[0].text.lower()
|
|
342
|
+
|
|
343
|
+
# Verify the note still exists using the exact title
|
|
344
|
+
read_result = await client.call_tool(
|
|
345
|
+
"read_note",
|
|
346
|
+
{
|
|
347
|
+
"project": test_project.name,
|
|
348
|
+
"identifier": "CamelCase Note Title",
|
|
349
|
+
},
|
|
350
|
+
)
|
|
351
|
+
assert "Testing case sensitivity" in read_result.content[0].text
|
|
352
|
+
|
|
353
|
+
# Delete with exact title should succeed
|
|
354
|
+
delete_result2 = await client.call_tool(
|
|
355
|
+
"delete_note",
|
|
356
|
+
{
|
|
357
|
+
"project": test_project.name,
|
|
358
|
+
"identifier": "CamelCase Note Title",
|
|
359
|
+
},
|
|
360
|
+
)
|
|
361
|
+
assert "true" in delete_result2.content[0].text.lower()
|
|
337
362
|
|
|
338
363
|
|
|
339
364
|
@pytest.mark.asyncio
|
|
@@ -710,3 +710,81 @@ async def test_edit_note_using_different_identifiers(mcp_server, app, test_proje
|
|
|
710
710
|
assert "Edited by title." in content
|
|
711
711
|
assert "Edited by permalink." in content
|
|
712
712
|
assert "Edited by folder/title." in content
|
|
713
|
+
|
|
714
|
+
|
|
715
|
+
@pytest.mark.asyncio
|
|
716
|
+
async def test_edit_note_append_autocreate_does_not_fuzzy_match(mcp_server, app, test_project):
|
|
717
|
+
"""Reproduces #649: edit_note append must auto-create, not fuzzy-match to an existing note.
|
|
718
|
+
|
|
719
|
+
Creates two notes, then attempts to append to a nonexistent identifier.
|
|
720
|
+
The tool should create a new note, and neither existing note should be modified.
|
|
721
|
+
"""
|
|
722
|
+
|
|
723
|
+
async with Client(mcp_server) as client:
|
|
724
|
+
# Create two notes that could be fuzzy-matched
|
|
725
|
+
await client.call_tool(
|
|
726
|
+
"write_note",
|
|
727
|
+
{
|
|
728
|
+
"project": test_project.name,
|
|
729
|
+
"title": "Routing Test A",
|
|
730
|
+
"directory": "test",
|
|
731
|
+
"content": "# Routing Test A\n\nContent A.",
|
|
732
|
+
},
|
|
733
|
+
)
|
|
734
|
+
await client.call_tool(
|
|
735
|
+
"write_note",
|
|
736
|
+
{
|
|
737
|
+
"project": test_project.name,
|
|
738
|
+
"title": "Routing Test B",
|
|
739
|
+
"directory": "test",
|
|
740
|
+
"content": "# Routing Test B\n\nContent B.",
|
|
741
|
+
},
|
|
742
|
+
)
|
|
743
|
+
|
|
744
|
+
# Attempt to edit a nonexistent note — should error, not silently edit A or B
|
|
745
|
+
edit_result = await client.call_tool(
|
|
746
|
+
"edit_note",
|
|
747
|
+
{
|
|
748
|
+
"project": test_project.name,
|
|
749
|
+
"identifier": "Routing Test NONEXISTENT",
|
|
750
|
+
"operation": "append",
|
|
751
|
+
"content": "\n\nThis should NOT appear in any note.",
|
|
752
|
+
},
|
|
753
|
+
)
|
|
754
|
+
|
|
755
|
+
edit_text = edit_result.content[0].text
|
|
756
|
+
# append to nonexistent creates a new note — verify it did NOT edit A or B
|
|
757
|
+
assert "Created note (append)" in edit_text
|
|
758
|
+
assert "fileCreated: true" in edit_text
|
|
759
|
+
|
|
760
|
+
# Verify neither A nor B was modified
|
|
761
|
+
read_a = await client.call_tool(
|
|
762
|
+
"read_note",
|
|
763
|
+
{"project": test_project.name, "identifier": "Routing Test A"},
|
|
764
|
+
)
|
|
765
|
+
content_a = read_a.content[0].text
|
|
766
|
+
assert "Content A" in content_a
|
|
767
|
+
assert "This should NOT appear" not in content_a
|
|
768
|
+
|
|
769
|
+
read_b = await client.call_tool(
|
|
770
|
+
"read_note",
|
|
771
|
+
{"project": test_project.name, "identifier": "Routing Test B"},
|
|
772
|
+
)
|
|
773
|
+
content_b = read_b.content[0].text
|
|
774
|
+
assert "Content B" in content_b
|
|
775
|
+
assert "This should NOT appear" not in content_b
|
|
776
|
+
|
|
777
|
+
# Now test find_replace on nonexistent — should error
|
|
778
|
+
edit_result2 = await client.call_tool(
|
|
779
|
+
"edit_note",
|
|
780
|
+
{
|
|
781
|
+
"project": test_project.name,
|
|
782
|
+
"identifier": "Routing Test NONEXISTENT AGAIN",
|
|
783
|
+
"operation": "find_replace",
|
|
784
|
+
"content": "replaced",
|
|
785
|
+
"find_text": "Content",
|
|
786
|
+
},
|
|
787
|
+
)
|
|
788
|
+
|
|
789
|
+
error_text = edit_result2.content[0].text
|
|
790
|
+
assert "Edit Failed" in error_text
|