basic-memory 0.10.1__tar.gz → 0.11.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of basic-memory might be problematic. Click here for more details.
- {basic_memory-0.10.1 → basic_memory-0.11.0}/CHANGELOG.md +37 -0
- {basic_memory-0.10.1 → basic_memory-0.11.0}/CLAUDE.md +2 -2
- {basic_memory-0.10.1 → basic_memory-0.11.0}/PKG-INFO +5 -4
- {basic_memory-0.10.1 → basic_memory-0.11.0}/README.md +4 -3
- {basic_memory-0.10.1 → basic_memory-0.11.0}/docs/AI Assistant Guide.md +5 -5
- {basic_memory-0.10.1 → basic_memory-0.11.0}/docs/Technical Information.md +1 -1
- {basic_memory-0.10.1 → basic_memory-0.11.0}/pyproject.toml +2 -1
- {basic_memory-0.10.1 → basic_memory-0.11.0}/src/basic_memory/__init__.py +1 -1
- {basic_memory-0.10.1 → basic_memory-0.11.0}/src/basic_memory/cli/commands/db.py +15 -2
- {basic_memory-0.10.1 → basic_memory-0.11.0}/src/basic_memory/cli/commands/tool.py +3 -3
- {basic_memory-0.10.1 → basic_memory-0.11.0}/src/basic_memory/config.py +45 -10
- {basic_memory-0.10.1 → basic_memory-0.11.0}/src/basic_memory/mcp/prompts/continue_conversation.py +3 -3
- {basic_memory-0.10.1 → basic_memory-0.11.0}/src/basic_memory/mcp/prompts/search.py +4 -4
- {basic_memory-0.10.1 → basic_memory-0.11.0}/src/basic_memory/mcp/resources/ai_assistant_guide.md +5 -5
- {basic_memory-0.10.1 → basic_memory-0.11.0}/src/basic_memory/mcp/tools/__init__.py +2 -2
- {basic_memory-0.10.1 → basic_memory-0.11.0}/src/basic_memory/mcp/tools/read_note.py +3 -3
- {basic_memory-0.10.1 → basic_memory-0.11.0}/src/basic_memory/mcp/tools/search.py +9 -9
- {basic_memory-0.10.1 → basic_memory-0.11.0}/static/ai_assistant_guide.md +5 -5
- {basic_memory-0.10.1 → basic_memory-0.11.0}/tests/cli/test_cli_tools.py +2 -2
- {basic_memory-0.10.1 → basic_memory-0.11.0}/tests/mcp/test_tool_read_note.py +1 -1
- {basic_memory-0.10.1 → basic_memory-0.11.0}/tests/mcp/test_tool_search.py +5 -5
- {basic_memory-0.10.1 → basic_memory-0.11.0}/uv.lock +10 -9
- {basic_memory-0.10.1 → basic_memory-0.11.0}/.github/ISSUE_TEMPLATE/bug_report.md +0 -0
- {basic_memory-0.10.1 → basic_memory-0.11.0}/.github/ISSUE_TEMPLATE/config.yml +0 -0
- {basic_memory-0.10.1 → basic_memory-0.11.0}/.github/ISSUE_TEMPLATE/documentation.md +0 -0
- {basic_memory-0.10.1 → basic_memory-0.11.0}/.github/ISSUE_TEMPLATE/feature_request.md +0 -0
- {basic_memory-0.10.1 → basic_memory-0.11.0}/.github/dependabot.yml +0 -0
- {basic_memory-0.10.1 → basic_memory-0.11.0}/.github/workflows/pr-title.yml +0 -0
- {basic_memory-0.10.1 → basic_memory-0.11.0}/.github/workflows/release.yml +0 -0
- {basic_memory-0.10.1 → basic_memory-0.11.0}/.github/workflows/test.yml +0 -0
- {basic_memory-0.10.1 → basic_memory-0.11.0}/.gitignore +0 -0
- {basic_memory-0.10.1 → basic_memory-0.11.0}/.python-version +0 -0
- {basic_memory-0.10.1 → basic_memory-0.11.0}/CITATION.cff +0 -0
- {basic_memory-0.10.1 → basic_memory-0.11.0}/CLA.md +0 -0
- {basic_memory-0.10.1 → basic_memory-0.11.0}/CODE_OF_CONDUCT.md +0 -0
- {basic_memory-0.10.1 → basic_memory-0.11.0}/CONTRIBUTING.md +0 -0
- {basic_memory-0.10.1 → basic_memory-0.11.0}/Dockerfile +0 -0
- {basic_memory-0.10.1 → basic_memory-0.11.0}/LICENSE +0 -0
- {basic_memory-0.10.1 → basic_memory-0.11.0}/Makefile +0 -0
- {basic_memory-0.10.1 → basic_memory-0.11.0}/SECURITY.md +0 -0
- {basic_memory-0.10.1 → basic_memory-0.11.0}/basic-memory.md +0 -0
- {basic_memory-0.10.1 → basic_memory-0.11.0}/docs/CLI Reference.md +0 -0
- {basic_memory-0.10.1 → basic_memory-0.11.0}/docs/Canvas.md +0 -0
- {basic_memory-0.10.1 → basic_memory-0.11.0}/docs/Getting Started with Basic Memory.md +0 -0
- {basic_memory-0.10.1 → basic_memory-0.11.0}/docs/Knowledge Format.md +0 -0
- {basic_memory-0.10.1 → basic_memory-0.11.0}/docs/Obsidian Integration.md +0 -0
- {basic_memory-0.10.1 → basic_memory-0.11.0}/docs/User Guide.md +0 -0
- {basic_memory-0.10.1 → basic_memory-0.11.0}/docs/Welcome to Basic memory.md +0 -0
- {basic_memory-0.10.1 → basic_memory-0.11.0}/docs/attachments/Canvas.png +0 -0
- {basic_memory-0.10.1 → basic_memory-0.11.0}/docs/attachments/Claude-Obsidian-Demo.mp4 +0 -0
- {basic_memory-0.10.1 → basic_memory-0.11.0}/docs/attachments/Prompt.png +0 -0
- {basic_memory-0.10.1 → basic_memory-0.11.0}/docs/attachments/disk-ai-logo-400x400.png +0 -0
- {basic_memory-0.10.1 → basic_memory-0.11.0}/docs/attachments/disk-ai-logo.png +0 -0
- {basic_memory-0.10.1 → basic_memory-0.11.0}/docs/attachments/prompt 1.png +0 -0
- {basic_memory-0.10.1 → basic_memory-0.11.0}/docs/attachments/prompt2.png +0 -0
- {basic_memory-0.10.1 → basic_memory-0.11.0}/docs/attachments/prompt3.png +0 -0
- {basic_memory-0.10.1 → basic_memory-0.11.0}/docs/attachments/prompt4.png +0 -0
- {basic_memory-0.10.1 → basic_memory-0.11.0}/docs/publish.js +0 -0
- {basic_memory-0.10.1 → basic_memory-0.11.0}/examples/Coffee Notes/Brewing Equipment.md +0 -0
- {basic_memory-0.10.1 → basic_memory-0.11.0}/examples/Coffee Notes/Coffee Bean Origins.md +0 -0
- {basic_memory-0.10.1 → basic_memory-0.11.0}/examples/Coffee Notes/Coffee Brewing Methods.md +0 -0
- {basic_memory-0.10.1 → basic_memory-0.11.0}/examples/Coffee Notes/Coffee Flavor Map.md +0 -0
- {basic_memory-0.10.1 → basic_memory-0.11.0}/examples/Coffee Notes/Coffee Knowledge Base.md +0 -0
- {basic_memory-0.10.1 → basic_memory-0.11.0}/examples/Coffee Notes/Flavor Extraction.md +0 -0
- {basic_memory-0.10.1 → basic_memory-0.11.0}/examples/Coffee Notes/Perfect Pour Over Coffee Method.canvas +0 -0
- {basic_memory-0.10.1 → basic_memory-0.11.0}/examples/Coffee Notes/Tasting Notes.md +0 -0
- {basic_memory-0.10.1 → basic_memory-0.11.0}/installer/Basic.icns +0 -0
- {basic_memory-0.10.1 → basic_memory-0.11.0}/installer/README.md +0 -0
- {basic_memory-0.10.1 → basic_memory-0.11.0}/installer/icon.svg +0 -0
- {basic_memory-0.10.1 → basic_memory-0.11.0}/installer/installer.py +0 -0
- {basic_memory-0.10.1 → basic_memory-0.11.0}/installer/make_icons.sh +0 -0
- {basic_memory-0.10.1 → basic_memory-0.11.0}/installer/setup.py +0 -0
- {basic_memory-0.10.1 → basic_memory-0.11.0}/llms-install.md +0 -0
- {basic_memory-0.10.1 → basic_memory-0.11.0}/memory.json +0 -0
- {basic_memory-0.10.1 → basic_memory-0.11.0}/scripts/install.sh +0 -0
- {basic_memory-0.10.1 → basic_memory-0.11.0}/smithery.yaml +0 -0
- {basic_memory-0.10.1 → basic_memory-0.11.0}/src/basic_memory/alembic/alembic.ini +0 -0
- {basic_memory-0.10.1 → basic_memory-0.11.0}/src/basic_memory/alembic/env.py +0 -0
- {basic_memory-0.10.1 → basic_memory-0.11.0}/src/basic_memory/alembic/migrations.py +0 -0
- {basic_memory-0.10.1 → basic_memory-0.11.0}/src/basic_memory/alembic/script.py.mako +0 -0
- {basic_memory-0.10.1 → basic_memory-0.11.0}/src/basic_memory/alembic/versions/3dae7c7b1564_initial_schema.py +0 -0
- {basic_memory-0.10.1 → basic_memory-0.11.0}/src/basic_memory/alembic/versions/502b60eaa905_remove_required_from_entity_permalink.py +0 -0
- {basic_memory-0.10.1 → basic_memory-0.11.0}/src/basic_memory/alembic/versions/b3c3938bacdb_relation_to_name_unique_index.py +0 -0
- {basic_memory-0.10.1 → basic_memory-0.11.0}/src/basic_memory/alembic/versions/cc7172b46608_update_search_index_schema.py +0 -0
- {basic_memory-0.10.1 → basic_memory-0.11.0}/src/basic_memory/api/__init__.py +0 -0
- {basic_memory-0.10.1 → basic_memory-0.11.0}/src/basic_memory/api/app.py +0 -0
- {basic_memory-0.10.1 → basic_memory-0.11.0}/src/basic_memory/api/routers/__init__.py +0 -0
- {basic_memory-0.10.1 → basic_memory-0.11.0}/src/basic_memory/api/routers/knowledge_router.py +0 -0
- {basic_memory-0.10.1 → basic_memory-0.11.0}/src/basic_memory/api/routers/memory_router.py +0 -0
- {basic_memory-0.10.1 → basic_memory-0.11.0}/src/basic_memory/api/routers/project_info_router.py +0 -0
- {basic_memory-0.10.1 → basic_memory-0.11.0}/src/basic_memory/api/routers/resource_router.py +0 -0
- {basic_memory-0.10.1 → basic_memory-0.11.0}/src/basic_memory/api/routers/search_router.py +0 -0
- {basic_memory-0.10.1 → basic_memory-0.11.0}/src/basic_memory/cli/__init__.py +0 -0
- {basic_memory-0.10.1 → basic_memory-0.11.0}/src/basic_memory/cli/app.py +0 -0
- {basic_memory-0.10.1 → basic_memory-0.11.0}/src/basic_memory/cli/commands/__init__.py +0 -0
- {basic_memory-0.10.1 → basic_memory-0.11.0}/src/basic_memory/cli/commands/import_chatgpt.py +0 -0
- {basic_memory-0.10.1 → basic_memory-0.11.0}/src/basic_memory/cli/commands/import_claude_conversations.py +0 -0
- {basic_memory-0.10.1 → basic_memory-0.11.0}/src/basic_memory/cli/commands/import_claude_projects.py +0 -0
- {basic_memory-0.10.1 → basic_memory-0.11.0}/src/basic_memory/cli/commands/import_memory_json.py +0 -0
- {basic_memory-0.10.1 → basic_memory-0.11.0}/src/basic_memory/cli/commands/mcp.py +0 -0
- {basic_memory-0.10.1 → basic_memory-0.11.0}/src/basic_memory/cli/commands/project.py +0 -0
- {basic_memory-0.10.1 → basic_memory-0.11.0}/src/basic_memory/cli/commands/status.py +0 -0
- {basic_memory-0.10.1 → basic_memory-0.11.0}/src/basic_memory/cli/commands/sync.py +0 -0
- {basic_memory-0.10.1 → basic_memory-0.11.0}/src/basic_memory/cli/main.py +0 -0
- {basic_memory-0.10.1 → basic_memory-0.11.0}/src/basic_memory/db.py +0 -0
- {basic_memory-0.10.1 → basic_memory-0.11.0}/src/basic_memory/deps.py +0 -0
- {basic_memory-0.10.1 → basic_memory-0.11.0}/src/basic_memory/file_utils.py +0 -0
- {basic_memory-0.10.1 → basic_memory-0.11.0}/src/basic_memory/markdown/__init__.py +0 -0
- {basic_memory-0.10.1 → basic_memory-0.11.0}/src/basic_memory/markdown/entity_parser.py +0 -0
- {basic_memory-0.10.1 → basic_memory-0.11.0}/src/basic_memory/markdown/markdown_processor.py +0 -0
- {basic_memory-0.10.1 → basic_memory-0.11.0}/src/basic_memory/markdown/plugins.py +0 -0
- {basic_memory-0.10.1 → basic_memory-0.11.0}/src/basic_memory/markdown/schemas.py +0 -0
- {basic_memory-0.10.1 → basic_memory-0.11.0}/src/basic_memory/markdown/utils.py +0 -0
- {basic_memory-0.10.1 → basic_memory-0.11.0}/src/basic_memory/mcp/__init__.py +0 -0
- {basic_memory-0.10.1 → basic_memory-0.11.0}/src/basic_memory/mcp/async_client.py +0 -0
- {basic_memory-0.10.1 → basic_memory-0.11.0}/src/basic_memory/mcp/main.py +0 -0
- {basic_memory-0.10.1 → basic_memory-0.11.0}/src/basic_memory/mcp/prompts/__init__.py +0 -0
- {basic_memory-0.10.1 → basic_memory-0.11.0}/src/basic_memory/mcp/prompts/ai_assistant_guide.py +0 -0
- {basic_memory-0.10.1 → basic_memory-0.11.0}/src/basic_memory/mcp/prompts/recent_activity.py +0 -0
- {basic_memory-0.10.1 → basic_memory-0.11.0}/src/basic_memory/mcp/prompts/utils.py +0 -0
- {basic_memory-0.10.1 → basic_memory-0.11.0}/src/basic_memory/mcp/server.py +0 -0
- {basic_memory-0.10.1 → basic_memory-0.11.0}/src/basic_memory/mcp/tools/build_context.py +0 -0
- {basic_memory-0.10.1 → basic_memory-0.11.0}/src/basic_memory/mcp/tools/canvas.py +0 -0
- {basic_memory-0.10.1 → basic_memory-0.11.0}/src/basic_memory/mcp/tools/delete_note.py +0 -0
- {basic_memory-0.10.1 → basic_memory-0.11.0}/src/basic_memory/mcp/tools/project_info.py +0 -0
- {basic_memory-0.10.1 → basic_memory-0.11.0}/src/basic_memory/mcp/tools/read_content.py +0 -0
- {basic_memory-0.10.1 → basic_memory-0.11.0}/src/basic_memory/mcp/tools/recent_activity.py +0 -0
- {basic_memory-0.10.1 → basic_memory-0.11.0}/src/basic_memory/mcp/tools/utils.py +0 -0
- {basic_memory-0.10.1 → basic_memory-0.11.0}/src/basic_memory/mcp/tools/write_note.py +0 -0
- {basic_memory-0.10.1 → basic_memory-0.11.0}/src/basic_memory/models/__init__.py +0 -0
- {basic_memory-0.10.1 → basic_memory-0.11.0}/src/basic_memory/models/base.py +0 -0
- {basic_memory-0.10.1 → basic_memory-0.11.0}/src/basic_memory/models/knowledge.py +0 -0
- {basic_memory-0.10.1 → basic_memory-0.11.0}/src/basic_memory/models/search.py +0 -0
- {basic_memory-0.10.1 → basic_memory-0.11.0}/src/basic_memory/repository/__init__.py +0 -0
- {basic_memory-0.10.1 → basic_memory-0.11.0}/src/basic_memory/repository/entity_repository.py +0 -0
- {basic_memory-0.10.1 → basic_memory-0.11.0}/src/basic_memory/repository/observation_repository.py +0 -0
- {basic_memory-0.10.1 → basic_memory-0.11.0}/src/basic_memory/repository/project_info_repository.py +0 -0
- {basic_memory-0.10.1 → basic_memory-0.11.0}/src/basic_memory/repository/relation_repository.py +0 -0
- {basic_memory-0.10.1 → basic_memory-0.11.0}/src/basic_memory/repository/repository.py +0 -0
- {basic_memory-0.10.1 → basic_memory-0.11.0}/src/basic_memory/repository/search_repository.py +0 -0
- {basic_memory-0.10.1 → basic_memory-0.11.0}/src/basic_memory/schemas/__init__.py +0 -0
- {basic_memory-0.10.1 → basic_memory-0.11.0}/src/basic_memory/schemas/base.py +0 -0
- {basic_memory-0.10.1 → basic_memory-0.11.0}/src/basic_memory/schemas/delete.py +0 -0
- {basic_memory-0.10.1 → basic_memory-0.11.0}/src/basic_memory/schemas/memory.py +0 -0
- {basic_memory-0.10.1 → basic_memory-0.11.0}/src/basic_memory/schemas/project_info.py +0 -0
- {basic_memory-0.10.1 → basic_memory-0.11.0}/src/basic_memory/schemas/request.py +0 -0
- {basic_memory-0.10.1 → basic_memory-0.11.0}/src/basic_memory/schemas/response.py +0 -0
- {basic_memory-0.10.1 → basic_memory-0.11.0}/src/basic_memory/schemas/search.py +0 -0
- {basic_memory-0.10.1 → basic_memory-0.11.0}/src/basic_memory/services/__init__.py +0 -0
- {basic_memory-0.10.1 → basic_memory-0.11.0}/src/basic_memory/services/context_service.py +0 -0
- {basic_memory-0.10.1 → basic_memory-0.11.0}/src/basic_memory/services/entity_service.py +0 -0
- {basic_memory-0.10.1 → basic_memory-0.11.0}/src/basic_memory/services/exceptions.py +0 -0
- {basic_memory-0.10.1 → basic_memory-0.11.0}/src/basic_memory/services/file_service.py +0 -0
- {basic_memory-0.10.1 → basic_memory-0.11.0}/src/basic_memory/services/link_resolver.py +0 -0
- {basic_memory-0.10.1 → basic_memory-0.11.0}/src/basic_memory/services/search_service.py +0 -0
- {basic_memory-0.10.1 → basic_memory-0.11.0}/src/basic_memory/services/service.py +0 -0
- {basic_memory-0.10.1 → basic_memory-0.11.0}/src/basic_memory/sync/__init__.py +0 -0
- {basic_memory-0.10.1 → basic_memory-0.11.0}/src/basic_memory/sync/sync_service.py +0 -0
- {basic_memory-0.10.1 → basic_memory-0.11.0}/src/basic_memory/sync/watch_service.py +0 -0
- {basic_memory-0.10.1 → basic_memory-0.11.0}/src/basic_memory/utils.py +0 -0
- {basic_memory-0.10.1 → basic_memory-0.11.0}/static/json_canvas_spec_1_0.md +0 -0
- {basic_memory-0.10.1 → basic_memory-0.11.0}/tests/Non-MarkdownFileSupport.pdf +0 -0
- {basic_memory-0.10.1 → basic_memory-0.11.0}/tests/Screenshot.png +0 -0
- {basic_memory-0.10.1 → basic_memory-0.11.0}/tests/__init__.py +0 -0
- {basic_memory-0.10.1 → basic_memory-0.11.0}/tests/api/conftest.py +0 -0
- {basic_memory-0.10.1 → basic_memory-0.11.0}/tests/api/test_knowledge_router.py +0 -0
- {basic_memory-0.10.1 → basic_memory-0.11.0}/tests/api/test_memory_router.py +0 -0
- {basic_memory-0.10.1 → basic_memory-0.11.0}/tests/api/test_project_info_router.py +0 -0
- {basic_memory-0.10.1 → basic_memory-0.11.0}/tests/api/test_resource_router.py +0 -0
- {basic_memory-0.10.1 → basic_memory-0.11.0}/tests/api/test_search_router.py +0 -0
- {basic_memory-0.10.1 → basic_memory-0.11.0}/tests/cli/conftest.py +0 -0
- {basic_memory-0.10.1 → basic_memory-0.11.0}/tests/cli/test_import_chatgpt.py +0 -0
- {basic_memory-0.10.1 → basic_memory-0.11.0}/tests/cli/test_import_claude_conversations.py +0 -0
- {basic_memory-0.10.1 → basic_memory-0.11.0}/tests/cli/test_import_claude_projects.py +0 -0
- {basic_memory-0.10.1 → basic_memory-0.11.0}/tests/cli/test_import_memory_json.py +0 -0
- {basic_memory-0.10.1 → basic_memory-0.11.0}/tests/cli/test_project_commands.py +0 -0
- {basic_memory-0.10.1 → basic_memory-0.11.0}/tests/cli/test_project_info.py +0 -0
- {basic_memory-0.10.1 → basic_memory-0.11.0}/tests/cli/test_status.py +0 -0
- {basic_memory-0.10.1 → basic_memory-0.11.0}/tests/cli/test_sync.py +0 -0
- {basic_memory-0.10.1 → basic_memory-0.11.0}/tests/cli/test_version.py +0 -0
- {basic_memory-0.10.1 → basic_memory-0.11.0}/tests/conftest.py +0 -0
- {basic_memory-0.10.1 → basic_memory-0.11.0}/tests/edit_file_test.py +0 -0
- {basic_memory-0.10.1 → basic_memory-0.11.0}/tests/markdown/__init__.py +0 -0
- {basic_memory-0.10.1 → basic_memory-0.11.0}/tests/markdown/test_entity_parser.py +0 -0
- {basic_memory-0.10.1 → basic_memory-0.11.0}/tests/markdown/test_markdown_plugins.py +0 -0
- {basic_memory-0.10.1 → basic_memory-0.11.0}/tests/markdown/test_markdown_processor.py +0 -0
- {basic_memory-0.10.1 → basic_memory-0.11.0}/tests/markdown/test_observation_edge_cases.py +0 -0
- {basic_memory-0.10.1 → basic_memory-0.11.0}/tests/markdown/test_parser_edge_cases.py +0 -0
- {basic_memory-0.10.1 → basic_memory-0.11.0}/tests/markdown/test_relation_edge_cases.py +0 -0
- {basic_memory-0.10.1 → basic_memory-0.11.0}/tests/markdown/test_task_detection.py +0 -0
- {basic_memory-0.10.1 → basic_memory-0.11.0}/tests/mcp/conftest.py +0 -0
- {basic_memory-0.10.1 → basic_memory-0.11.0}/tests/mcp/test_prompts.py +0 -0
- {basic_memory-0.10.1 → basic_memory-0.11.0}/tests/mcp/test_resources.py +0 -0
- {basic_memory-0.10.1 → basic_memory-0.11.0}/tests/mcp/test_tool_canvas.py +0 -0
- {basic_memory-0.10.1 → basic_memory-0.11.0}/tests/mcp/test_tool_memory.py +0 -0
- {basic_memory-0.10.1 → basic_memory-0.11.0}/tests/mcp/test_tool_notes.py +0 -0
- {basic_memory-0.10.1 → basic_memory-0.11.0}/tests/mcp/test_tool_project_info.py +0 -0
- {basic_memory-0.10.1 → basic_memory-0.11.0}/tests/mcp/test_tool_resource.py +0 -0
- {basic_memory-0.10.1 → basic_memory-0.11.0}/tests/mcp/test_tool_utils.py +0 -0
- {basic_memory-0.10.1 → basic_memory-0.11.0}/tests/repository/test_entity_repository.py +0 -0
- {basic_memory-0.10.1 → basic_memory-0.11.0}/tests/repository/test_observation_repository.py +0 -0
- {basic_memory-0.10.1 → basic_memory-0.11.0}/tests/repository/test_relation_repository.py +0 -0
- {basic_memory-0.10.1 → basic_memory-0.11.0}/tests/repository/test_repository.py +0 -0
- {basic_memory-0.10.1 → basic_memory-0.11.0}/tests/schemas/test_memory_url.py +0 -0
- {basic_memory-0.10.1 → basic_memory-0.11.0}/tests/schemas/test_schemas.py +0 -0
- {basic_memory-0.10.1 → basic_memory-0.11.0}/tests/schemas/test_search.py +0 -0
- {basic_memory-0.10.1 → basic_memory-0.11.0}/tests/services/test_context_service.py +0 -0
- {basic_memory-0.10.1 → basic_memory-0.11.0}/tests/services/test_entity_service.py +0 -0
- {basic_memory-0.10.1 → basic_memory-0.11.0}/tests/services/test_file_service.py +0 -0
- {basic_memory-0.10.1 → basic_memory-0.11.0}/tests/services/test_link_resolver.py +0 -0
- {basic_memory-0.10.1 → basic_memory-0.11.0}/tests/services/test_search_service.py +0 -0
- {basic_memory-0.10.1 → basic_memory-0.11.0}/tests/sync/test_sync_service.py +0 -0
- {basic_memory-0.10.1 → basic_memory-0.11.0}/tests/sync/test_tmp_files.py +0 -0
- {basic_memory-0.10.1 → basic_memory-0.11.0}/tests/sync/test_watch_service.py +0 -0
- {basic_memory-0.10.1 → basic_memory-0.11.0}/tests/sync/test_watch_service_edge_cases.py +0 -0
- {basic_memory-0.10.1 → basic_memory-0.11.0}/tests/test_basic_memory.py +0 -0
- {basic_memory-0.10.1 → basic_memory-0.11.0}/tests/test_config.py +0 -0
- {basic_memory-0.10.1 → basic_memory-0.11.0}/tests/utils/test_file_utils.py +0 -0
- {basic_memory-0.10.1 → basic_memory-0.11.0}/tests/utils/test_permalink_formatting.py +0 -0
- {basic_memory-0.10.1 → basic_memory-0.11.0}/tests/utils/test_utf8_handling.py +0 -0
|
@@ -1,6 +1,43 @@
|
|
|
1
1
|
# CHANGELOG
|
|
2
2
|
|
|
3
3
|
|
|
4
|
+
## v0.11.0 (2025-03-29)
|
|
5
|
+
|
|
6
|
+
### Bug Fixes
|
|
7
|
+
|
|
8
|
+
- Just delete db for reset db instead of using migrations.
|
|
9
|
+
([#65](https://github.com/basicmachines-co/basic-memory/pull/65),
|
|
10
|
+
[`0743ade`](https://github.com/basicmachines-co/basic-memory/commit/0743ade5fc07440f95ecfd816ba7e4cfd74bca12))
|
|
11
|
+
|
|
12
|
+
Signed-off-by: phernandez <paul@basicmachines.co>
|
|
13
|
+
|
|
14
|
+
- Make logs for each process - mcp, sync, cli
|
|
15
|
+
([#64](https://github.com/basicmachines-co/basic-memory/pull/64),
|
|
16
|
+
[`f1c9570`](https://github.com/basicmachines-co/basic-memory/commit/f1c95709cbffb1b88292547b0b8f29fcca22d186))
|
|
17
|
+
|
|
18
|
+
Signed-off-by: phernandez <paul@basicmachines.co>
|
|
19
|
+
|
|
20
|
+
### Documentation
|
|
21
|
+
|
|
22
|
+
- Update broken "Multiple Projects" link in README.md
|
|
23
|
+
([#55](https://github.com/basicmachines-co/basic-memory/pull/55),
|
|
24
|
+
[`3c68b7d`](https://github.com/basicmachines-co/basic-memory/commit/3c68b7d5dd689322205c67637dca7d188111ee6b))
|
|
25
|
+
|
|
26
|
+
### Features
|
|
27
|
+
|
|
28
|
+
- Add bm command alias for basic-memory
|
|
29
|
+
([#67](https://github.com/basicmachines-co/basic-memory/pull/67),
|
|
30
|
+
[`069c0a2`](https://github.com/basicmachines-co/basic-memory/commit/069c0a21c630784e1bf47d2b7de5d6d1f6fadd7a))
|
|
31
|
+
|
|
32
|
+
Signed-off-by: phernandez <paul@basicmachines.co>
|
|
33
|
+
|
|
34
|
+
- Rename search tool to search_notes
|
|
35
|
+
([#66](https://github.com/basicmachines-co/basic-memory/pull/66),
|
|
36
|
+
[`b278276`](https://github.com/basicmachines-co/basic-memory/commit/b27827671dc010be3e261b8b221aca6b7f836661))
|
|
37
|
+
|
|
38
|
+
Signed-off-by: phernandez <paul@basicmachines.co>
|
|
39
|
+
|
|
40
|
+
|
|
4
41
|
## v0.10.1 (2025-03-25)
|
|
5
42
|
|
|
6
43
|
### Bug Fixes
|
|
@@ -107,7 +107,7 @@ See the [README.md](README.md) file for a project overview.
|
|
|
107
107
|
1d", "1 week")
|
|
108
108
|
|
|
109
109
|
**Search & Discovery:**
|
|
110
|
-
- `
|
|
110
|
+
- `search_notes(query, page, page_size)` - Full-text search across all content with filtering options
|
|
111
111
|
|
|
112
112
|
**Visualization:**
|
|
113
113
|
- `canvas(nodes, edges, title, folder)` - Generate Obsidian canvas files for knowledge graph visualization
|
|
@@ -115,7 +115,7 @@ See the [README.md](README.md) file for a project overview.
|
|
|
115
115
|
- MCP Prompts for better AI interaction:
|
|
116
116
|
- `ai_assistant_guide()` - Guidance on effectively using Basic Memory tools for AI assistants
|
|
117
117
|
- `continue_conversation(topic, timeframe)` - Continue previous conversations with relevant historical context
|
|
118
|
-
- `
|
|
118
|
+
- `search_notes(query, after_date)` - Search with detailed, formatted results for better context understanding
|
|
119
119
|
- `recent_activity(timeframe)` - View recently changed items with formatted output
|
|
120
120
|
- `json_canvas_spec()` - Full JSON Canvas specification for Obsidian visualization
|
|
121
121
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: basic-memory
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.11.0
|
|
4
4
|
Summary: Local-first knowledge management combining Zettelkasten with knowledge graphs
|
|
5
5
|
Project-URL: Homepage, https://github.com/basicmachines-co/basic-memory
|
|
6
6
|
Project-URL: Repository, https://github.com/basicmachines-co/basic-memory
|
|
@@ -319,7 +319,8 @@ for OS X):
|
|
|
319
319
|
}
|
|
320
320
|
```
|
|
321
321
|
|
|
322
|
-
If you want to use a specific project (see [Multiple Projects](#multiple-projects)
|
|
322
|
+
If you want to use a specific project (see [Multiple Projects](docs/User%20Guide.md#multiple-projects)), update your
|
|
323
|
+
Claude Desktop
|
|
323
324
|
config:
|
|
324
325
|
|
|
325
326
|
```json
|
|
@@ -354,7 +355,7 @@ basic-memory sync --watch
|
|
|
354
355
|
write_note(title, content, folder, tags) - Create or update notes
|
|
355
356
|
read_note(identifier, page, page_size) - Read notes by title or permalink
|
|
356
357
|
build_context(url, depth, timeframe) - Navigate knowledge graph via memory:// URLs
|
|
357
|
-
|
|
358
|
+
search_notes(query, page, page_size) - Search across your knowledge base
|
|
358
359
|
recent_activity(type, depth, timeframe) - Find recently updated information
|
|
359
360
|
canvas(nodes, edges, title, folder) - Generate knowledge visualizations
|
|
360
361
|
```
|
|
@@ -395,4 +396,4 @@ and submitting PRs.
|
|
|
395
396
|
</picture>
|
|
396
397
|
</a>
|
|
397
398
|
|
|
398
|
-
Built with ♥️ by Basic Machines
|
|
399
|
+
Built with ♥️ by Basic Machines
|
|
@@ -285,7 +285,8 @@ for OS X):
|
|
|
285
285
|
}
|
|
286
286
|
```
|
|
287
287
|
|
|
288
|
-
If you want to use a specific project (see [Multiple Projects](#multiple-projects)
|
|
288
|
+
If you want to use a specific project (see [Multiple Projects](docs/User%20Guide.md#multiple-projects)), update your
|
|
289
|
+
Claude Desktop
|
|
289
290
|
config:
|
|
290
291
|
|
|
291
292
|
```json
|
|
@@ -320,7 +321,7 @@ basic-memory sync --watch
|
|
|
320
321
|
write_note(title, content, folder, tags) - Create or update notes
|
|
321
322
|
read_note(identifier, page, page_size) - Read notes by title or permalink
|
|
322
323
|
build_context(url, depth, timeframe) - Navigate knowledge graph via memory:// URLs
|
|
323
|
-
|
|
324
|
+
search_notes(query, page, page_size) - Search across your knowledge base
|
|
324
325
|
recent_activity(type, depth, timeframe) - Find recently updated information
|
|
325
326
|
canvas(nodes, edges, title, folder) - Generate knowledge visualizations
|
|
326
327
|
```
|
|
@@ -361,4 +362,4 @@ and submitting PRs.
|
|
|
361
362
|
</picture>
|
|
362
363
|
</a>
|
|
363
364
|
|
|
364
|
-
Built with ♥️ by Basic Machines
|
|
365
|
+
Built with ♥️ by Basic Machines
|
|
@@ -53,7 +53,7 @@ content = await read_note("specs/search-design") # By path
|
|
|
53
53
|
content = await read_note("memory://specs/search") # By memory URL
|
|
54
54
|
|
|
55
55
|
# Searching for knowledge
|
|
56
|
-
results = await
|
|
56
|
+
results = await search_notes(
|
|
57
57
|
query="authentication system", # Text to search for
|
|
58
58
|
page=1, # Optional: Pagination
|
|
59
59
|
page_size=10 # Optional: Results per page
|
|
@@ -154,7 +154,7 @@ Users will interact with Basic Memory in patterns like:
|
|
|
154
154
|
Human: "What were our decisions about auth?"
|
|
155
155
|
|
|
156
156
|
You: Let me find that information for you.
|
|
157
|
-
[Use
|
|
157
|
+
[Use search_notes() to find relevant notes]
|
|
158
158
|
[Then build_context() to understand connections]
|
|
159
159
|
```
|
|
160
160
|
|
|
@@ -251,7 +251,7 @@ When creating relations, you can:
|
|
|
251
251
|
# Example workflow for creating notes with effective relations
|
|
252
252
|
async def create_note_with_effective_relations():
|
|
253
253
|
# Search for existing entities to reference
|
|
254
|
-
search_results = await
|
|
254
|
+
search_results = await search_notes("travel")
|
|
255
255
|
existing_entities = [result.title for result in search_results.primary_results]
|
|
256
256
|
|
|
257
257
|
# Check if specific entities exist
|
|
@@ -323,7 +323,7 @@ Common issues to watch for:
|
|
|
323
323
|
content = await read_note("Document")
|
|
324
324
|
except:
|
|
325
325
|
# Try search instead
|
|
326
|
-
results = await
|
|
326
|
+
results = await search_notes("Document")
|
|
327
327
|
if results and results.primary_results:
|
|
328
328
|
# Found something similar
|
|
329
329
|
content = await read_note(results.primary_results[0].permalink)
|
|
@@ -369,7 +369,7 @@ Common issues to watch for:
|
|
|
369
369
|
- **Create deliberate relations**: Connect each note to at least 2-3 related entities
|
|
370
370
|
- **Use existing entities**: Before creating a new relation, search for existing entities
|
|
371
371
|
- **Verify wikilinks**: When referencing `[[Entity]]`, use exact titles of existing notes
|
|
372
|
-
- **Check accuracy**: Use `
|
|
372
|
+
- **Check accuracy**: Use `search_notes()` or `recent_activity()` to confirm entity titles
|
|
373
373
|
- **Use precise relation types**: Choose specific relation types that convey meaning (e.g., "implements" instead of "relates_to")
|
|
374
374
|
- **Consider bidirectional relations**: When appropriate, create inverse relations in both entities
|
|
375
375
|
|
|
@@ -196,7 +196,7 @@ flowchart TD
|
|
|
196
196
|
end
|
|
197
197
|
|
|
198
198
|
BMCP <-->|"write_note() read_note()"| KnowledgeFiles
|
|
199
|
-
BMCP <-->|"
|
|
199
|
+
BMCP <-->|"search_notes() build_context()"| KnowledgeIndex
|
|
200
200
|
KnowledgeFiles <-.->|Sync Process| KnowledgeIndex
|
|
201
201
|
KnowledgeFiles <-->|Direct Editing| Editors((Text Editors & Git))
|
|
202
202
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[project]
|
|
2
2
|
name = "basic-memory"
|
|
3
|
-
version = "0.
|
|
3
|
+
version = "0.11.0"
|
|
4
4
|
description = "Local-first knowledge management combining Zettelkasten with knowledge graphs"
|
|
5
5
|
readme = "README.md"
|
|
6
6
|
requires-python = ">=3.12.1"
|
|
@@ -40,6 +40,7 @@ Documentation = "https://github.com/basicmachines-co/basic-memory#readme"
|
|
|
40
40
|
|
|
41
41
|
[project.scripts]
|
|
42
42
|
basic-memory = "basic_memory.cli.main:app"
|
|
43
|
+
bm = "basic_memory.cli.main:app"
|
|
43
44
|
|
|
44
45
|
[build-system]
|
|
45
46
|
requires = ["hatchling"]
|
|
@@ -1,10 +1,13 @@
|
|
|
1
1
|
"""Database management commands."""
|
|
2
2
|
|
|
3
|
+
import asyncio
|
|
4
|
+
|
|
3
5
|
import typer
|
|
4
6
|
from loguru import logger
|
|
5
7
|
|
|
6
|
-
from basic_memory
|
|
8
|
+
from basic_memory import db
|
|
7
9
|
from basic_memory.cli.app import app
|
|
10
|
+
from basic_memory.config import config
|
|
8
11
|
|
|
9
12
|
|
|
10
13
|
@app.command()
|
|
@@ -14,7 +17,17 @@ def reset(
|
|
|
14
17
|
"""Reset database (drop all tables and recreate)."""
|
|
15
18
|
if typer.confirm("This will delete all data in your db. Are you sure?"):
|
|
16
19
|
logger.info("Resetting database...")
|
|
17
|
-
|
|
20
|
+
# Get database path
|
|
21
|
+
db_path = config.database_path
|
|
22
|
+
|
|
23
|
+
# Delete the database file if it exists
|
|
24
|
+
if db_path.exists():
|
|
25
|
+
db_path.unlink()
|
|
26
|
+
logger.info(f"Database file deleted: {db_path}")
|
|
27
|
+
|
|
28
|
+
# Create a new empty database
|
|
29
|
+
asyncio.run(db.run_migrations(config))
|
|
30
|
+
logger.info("Database reset complete")
|
|
18
31
|
|
|
19
32
|
if reindex:
|
|
20
33
|
# Import and run sync
|
|
@@ -12,7 +12,7 @@ from basic_memory.cli.app import app
|
|
|
12
12
|
from basic_memory.mcp.tools import build_context as mcp_build_context
|
|
13
13
|
from basic_memory.mcp.tools import read_note as mcp_read_note
|
|
14
14
|
from basic_memory.mcp.tools import recent_activity as mcp_recent_activity
|
|
15
|
-
from basic_memory.mcp.tools import
|
|
15
|
+
from basic_memory.mcp.tools import search_notes as mcp_search
|
|
16
16
|
from basic_memory.mcp.tools import write_note as mcp_write_note
|
|
17
17
|
|
|
18
18
|
# Import prompts
|
|
@@ -180,8 +180,8 @@ def recent_activity(
|
|
|
180
180
|
raise
|
|
181
181
|
|
|
182
182
|
|
|
183
|
-
@tool_app.command()
|
|
184
|
-
def
|
|
183
|
+
@tool_app.command("search-notes")
|
|
184
|
+
def search_notes(
|
|
185
185
|
query: str,
|
|
186
186
|
permalink: Annotated[bool, typer.Option("--permalink", help="Search permalink values")] = False,
|
|
187
187
|
title: Annotated[bool, typer.Option("--title", help="Search title values")] = False,
|
|
@@ -5,12 +5,13 @@ import os
|
|
|
5
5
|
from pathlib import Path
|
|
6
6
|
from typing import Any, Dict, Literal, Optional
|
|
7
7
|
|
|
8
|
-
import basic_memory
|
|
9
|
-
from basic_memory.utils import setup_logging
|
|
10
8
|
from loguru import logger
|
|
11
9
|
from pydantic import Field, field_validator
|
|
12
10
|
from pydantic_settings import BaseSettings, SettingsConfigDict
|
|
13
11
|
|
|
12
|
+
import basic_memory
|
|
13
|
+
from basic_memory.utils import setup_logging
|
|
14
|
+
|
|
14
15
|
DATABASE_NAME = "memory.db"
|
|
15
16
|
DATA_DIR_NAME = ".basic-memory"
|
|
16
17
|
CONFIG_FILE_NAME = "config.json"
|
|
@@ -213,11 +214,45 @@ user_home = Path.home()
|
|
|
213
214
|
log_dir = user_home / DATA_DIR_NAME
|
|
214
215
|
log_dir.mkdir(parents=True, exist_ok=True)
|
|
215
216
|
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
217
|
+
|
|
218
|
+
def get_process_name(): # pragma: no cover
|
|
219
|
+
"""
|
|
220
|
+
get the type of process for logging
|
|
221
|
+
"""
|
|
222
|
+
import sys
|
|
223
|
+
|
|
224
|
+
if "sync" in sys.argv:
|
|
225
|
+
return "sync"
|
|
226
|
+
elif "mcp" in sys.argv:
|
|
227
|
+
return "mcp"
|
|
228
|
+
else:
|
|
229
|
+
return "cli"
|
|
230
|
+
|
|
231
|
+
|
|
232
|
+
process_name = get_process_name()
|
|
233
|
+
|
|
234
|
+
# Global flag to track if logging has been set up
|
|
235
|
+
_LOGGING_SETUP = False
|
|
236
|
+
|
|
237
|
+
def setup_basic_memory_logging(): # pragma: no cover
|
|
238
|
+
"""Set up logging for basic-memory, ensuring it only happens once."""
|
|
239
|
+
global _LOGGING_SETUP
|
|
240
|
+
if _LOGGING_SETUP:
|
|
241
|
+
# We can't log before logging is set up
|
|
242
|
+
# print("Skipping duplicate logging setup")
|
|
243
|
+
return
|
|
244
|
+
|
|
245
|
+
setup_logging(
|
|
246
|
+
env=config.env,
|
|
247
|
+
home_dir=user_home, # Use user home for logs
|
|
248
|
+
log_level=config.log_level,
|
|
249
|
+
log_file=f"{DATA_DIR_NAME}/basic-memory-{process_name}.log",
|
|
250
|
+
console=False,
|
|
251
|
+
)
|
|
252
|
+
|
|
253
|
+
logger.info(f"Starting Basic Memory {basic_memory.__version__} (Project: {config.project})")
|
|
254
|
+
_LOGGING_SETUP = True
|
|
255
|
+
|
|
256
|
+
|
|
257
|
+
# Set up logging
|
|
258
|
+
setup_basic_memory_logging()
|
{basic_memory-0.10.1 → basic_memory-0.11.0}/src/basic_memory/mcp/prompts/continue_conversation.py
RENAMED
|
@@ -14,7 +14,7 @@ from basic_memory.mcp.prompts.utils import format_prompt_context, PromptContext,
|
|
|
14
14
|
from basic_memory.mcp.server import mcp
|
|
15
15
|
from basic_memory.mcp.tools.build_context import build_context
|
|
16
16
|
from basic_memory.mcp.tools.recent_activity import recent_activity
|
|
17
|
-
from basic_memory.mcp.tools.search import
|
|
17
|
+
from basic_memory.mcp.tools.search import search_notes
|
|
18
18
|
from basic_memory.schemas.base import TimeFrame
|
|
19
19
|
from basic_memory.schemas.memory import GraphContext
|
|
20
20
|
from basic_memory.schemas.search import SearchQuery, SearchItemType
|
|
@@ -47,7 +47,7 @@ async def continue_conversation(
|
|
|
47
47
|
|
|
48
48
|
# If topic provided, search for it
|
|
49
49
|
if topic:
|
|
50
|
-
search_results = await
|
|
50
|
+
search_results = await search_notes(
|
|
51
51
|
SearchQuery(text=topic, after_date=timeframe, types=[SearchItemType.ENTITY])
|
|
52
52
|
)
|
|
53
53
|
|
|
@@ -93,7 +93,7 @@ async def continue_conversation(
|
|
|
93
93
|
## Next Steps
|
|
94
94
|
|
|
95
95
|
You can:
|
|
96
|
-
- Explore more with: `
|
|
96
|
+
- Explore more with: `search_notes({{"text": "{topic}"}})`
|
|
97
97
|
- See what's changed: `recent_activity(timeframe="{timeframe or "7d"}")`
|
|
98
98
|
- **Record new learnings or decisions from this conversation:** `write_note(title="[Create a meaningful title]", content="[Content with observations and relations]")`
|
|
99
99
|
|
|
@@ -10,7 +10,7 @@ from loguru import logger
|
|
|
10
10
|
from pydantic import Field
|
|
11
11
|
|
|
12
12
|
from basic_memory.mcp.server import mcp
|
|
13
|
-
from basic_memory.mcp.tools.search import
|
|
13
|
+
from basic_memory.mcp.tools.search import search_notes as search_tool
|
|
14
14
|
from basic_memory.schemas.base import TimeFrame
|
|
15
15
|
from basic_memory.schemas.search import SearchQuery, SearchResponse
|
|
16
16
|
|
|
@@ -144,9 +144,9 @@ def format_search_results(
|
|
|
144
144
|
## Next Steps
|
|
145
145
|
|
|
146
146
|
You can:
|
|
147
|
-
- Refine your search: `
|
|
148
|
-
- Exclude terms: `
|
|
149
|
-
- View more results: `
|
|
147
|
+
- Refine your search: `search_notes("{query} AND additional_term")`
|
|
148
|
+
- Exclude terms: `search_notes("{query} NOT exclude_term")`
|
|
149
|
+
- View more results: `search_notes("{query}", after_date=None)`
|
|
150
150
|
- Check recent activity: `recent_activity()`
|
|
151
151
|
|
|
152
152
|
## Synthesize and Capture Knowledge
|
{basic_memory-0.10.1 → basic_memory-0.11.0}/src/basic_memory/mcp/resources/ai_assistant_guide.md
RENAMED
|
@@ -49,7 +49,7 @@ content = await read_note("specs/search-design") # By path
|
|
|
49
49
|
content = await read_note("memory://specs/search") # By memory URL
|
|
50
50
|
|
|
51
51
|
# Searching for knowledge
|
|
52
|
-
results = await
|
|
52
|
+
results = await search_notes(
|
|
53
53
|
query="authentication system", # Text to search for
|
|
54
54
|
page=1, # Optional: Pagination
|
|
55
55
|
page_size=10 # Optional: Results per page
|
|
@@ -154,7 +154,7 @@ Users will interact with Basic Memory in patterns like:
|
|
|
154
154
|
Human: "What were our decisions about auth?"
|
|
155
155
|
|
|
156
156
|
You: Let me find that information for you.
|
|
157
|
-
[Use
|
|
157
|
+
[Use search_notes() to find relevant notes]
|
|
158
158
|
[Then build_context() to understand connections]
|
|
159
159
|
```
|
|
160
160
|
|
|
@@ -263,7 +263,7 @@ When creating relations, you can:
|
|
|
263
263
|
# Example workflow for creating notes with effective relations
|
|
264
264
|
async def create_note_with_effective_relations():
|
|
265
265
|
# Search for existing entities to reference
|
|
266
|
-
search_results = await
|
|
266
|
+
search_results = await search_notes("travel")
|
|
267
267
|
existing_entities = [result.title for result in search_results.primary_results]
|
|
268
268
|
|
|
269
269
|
# Check if specific entities exist
|
|
@@ -335,7 +335,7 @@ Common issues to watch for:
|
|
|
335
335
|
content = await read_note("Document")
|
|
336
336
|
except:
|
|
337
337
|
# Try search instead
|
|
338
|
-
results = await
|
|
338
|
+
results = await search_notes("Document")
|
|
339
339
|
if results and results.primary_results:
|
|
340
340
|
# Found something similar
|
|
341
341
|
content = await read_note(results.primary_results[0].permalink)
|
|
@@ -381,7 +381,7 @@ Common issues to watch for:
|
|
|
381
381
|
- **Create deliberate relations**: Connect each note to at least 2-3 related entities
|
|
382
382
|
- **Use existing entities**: Before creating a new relation, search for existing entities
|
|
383
383
|
- **Verify wikilinks**: When referencing `[[Entity]]`, use exact titles of existing notes
|
|
384
|
-
- **Check accuracy**: Use `
|
|
384
|
+
- **Check accuracy**: Use `search_notes()` or `recent_activity()` to confirm entity titles
|
|
385
385
|
- **Use precise relation types**: Choose specific relation types that convey meaning (e.g., "implements" instead
|
|
386
386
|
of "relates_to")
|
|
387
387
|
- **Consider bidirectional relations**: When appropriate, create inverse relations in both entities
|
|
@@ -12,7 +12,7 @@ from basic_memory.mcp.tools.build_context import build_context
|
|
|
12
12
|
from basic_memory.mcp.tools.recent_activity import recent_activity
|
|
13
13
|
from basic_memory.mcp.tools.read_note import read_note
|
|
14
14
|
from basic_memory.mcp.tools.write_note import write_note
|
|
15
|
-
from basic_memory.mcp.tools.search import
|
|
15
|
+
from basic_memory.mcp.tools.search import search_notes
|
|
16
16
|
from basic_memory.mcp.tools.canvas import canvas
|
|
17
17
|
|
|
18
18
|
__all__ = [
|
|
@@ -22,6 +22,6 @@ __all__ = [
|
|
|
22
22
|
"read_content",
|
|
23
23
|
"read_note",
|
|
24
24
|
"recent_activity",
|
|
25
|
-
"
|
|
25
|
+
"search_notes",
|
|
26
26
|
"write_note",
|
|
27
27
|
]
|
|
@@ -6,7 +6,7 @@ from loguru import logger
|
|
|
6
6
|
|
|
7
7
|
from basic_memory.mcp.async_client import client
|
|
8
8
|
from basic_memory.mcp.server import mcp
|
|
9
|
-
from basic_memory.mcp.tools.search import
|
|
9
|
+
from basic_memory.mcp.tools.search import search_notes
|
|
10
10
|
from basic_memory.mcp.tools.utils import call_get
|
|
11
11
|
from basic_memory.schemas.memory import memory_url_path
|
|
12
12
|
from basic_memory.schemas.search import SearchQuery
|
|
@@ -63,7 +63,7 @@ async def read_note(identifier: str, page: int = 1, page_size: int = 10) -> str:
|
|
|
63
63
|
|
|
64
64
|
# Fallback 1: Try title search via API
|
|
65
65
|
logger.info(f"Search title for: {identifier}")
|
|
66
|
-
title_results = await
|
|
66
|
+
title_results = await search_notes(SearchQuery(title=identifier))
|
|
67
67
|
|
|
68
68
|
if title_results and title_results.results:
|
|
69
69
|
result = title_results.results[0] # Get the first/best match
|
|
@@ -87,7 +87,7 @@ async def read_note(identifier: str, page: int = 1, page_size: int = 10) -> str:
|
|
|
87
87
|
|
|
88
88
|
# Fallback 2: Text search as a last resort
|
|
89
89
|
logger.info(f"Title search failed, trying text search for: {identifier}")
|
|
90
|
-
text_results = await
|
|
90
|
+
text_results = await search_notes(SearchQuery(text=identifier))
|
|
91
91
|
|
|
92
92
|
# We didn't find a direct match, construct a helpful error message
|
|
93
93
|
if not text_results or not text_results.results:
|
|
@@ -11,7 +11,7 @@ from basic_memory.mcp.async_client import client
|
|
|
11
11
|
@mcp.tool(
|
|
12
12
|
description="Search across all content in the knowledge base.",
|
|
13
13
|
)
|
|
14
|
-
async def
|
|
14
|
+
async def search_notes(query: SearchQuery, page: int = 1, page_size: int = 10) -> SearchResponse:
|
|
15
15
|
"""Search across all content in the knowledge base.
|
|
16
16
|
|
|
17
17
|
This tool searches the knowledge base using full-text search, pattern matching,
|
|
@@ -36,34 +36,34 @@ async def search(query: SearchQuery, page: int = 1, page_size: int = 10) -> Sear
|
|
|
36
36
|
|
|
37
37
|
Examples:
|
|
38
38
|
# Basic text search
|
|
39
|
-
results = await
|
|
39
|
+
results = await search_notes(SearchQuery(text="project planning"))
|
|
40
40
|
|
|
41
41
|
# Boolean AND search (both terms must be present)
|
|
42
|
-
results = await
|
|
42
|
+
results = await search_notes(SearchQuery(text="project AND planning"))
|
|
43
43
|
|
|
44
44
|
# Boolean OR search (either term can be present)
|
|
45
|
-
results = await
|
|
45
|
+
results = await search_notes(SearchQuery(text="project OR meeting"))
|
|
46
46
|
|
|
47
47
|
# Boolean NOT search (exclude terms)
|
|
48
|
-
results = await
|
|
48
|
+
results = await search_notes(SearchQuery(text="project NOT meeting"))
|
|
49
49
|
|
|
50
50
|
# Boolean search with grouping
|
|
51
|
-
results = await
|
|
51
|
+
results = await search_notes(SearchQuery(text="(project OR planning) AND notes"))
|
|
52
52
|
|
|
53
53
|
# Search with type filter
|
|
54
|
-
results = await
|
|
54
|
+
results = await search_notes(SearchQuery(
|
|
55
55
|
text="meeting notes",
|
|
56
56
|
types=["entity"],
|
|
57
57
|
))
|
|
58
58
|
|
|
59
59
|
# Search for recent content
|
|
60
|
-
results = await
|
|
60
|
+
results = await search_notes(SearchQuery(
|
|
61
61
|
text="bug report",
|
|
62
62
|
after_date="1 week"
|
|
63
63
|
))
|
|
64
64
|
|
|
65
65
|
# Pattern matching on permalinks
|
|
66
|
-
results = await
|
|
66
|
+
results = await search_notes(SearchQuery(
|
|
67
67
|
permalink_match="docs/meeting-*"
|
|
68
68
|
))
|
|
69
69
|
"""
|
|
@@ -49,7 +49,7 @@ content = await read_note("specs/search-design") # By path
|
|
|
49
49
|
content = await read_note("memory://specs/search") # By memory URL
|
|
50
50
|
|
|
51
51
|
# Searching for knowledge
|
|
52
|
-
results = await
|
|
52
|
+
results = await search_notes(
|
|
53
53
|
query="authentication system", # Text to search for
|
|
54
54
|
page=1, # Optional: Pagination
|
|
55
55
|
page_size=10 # Optional: Results per page
|
|
@@ -154,7 +154,7 @@ Users will interact with Basic Memory in patterns like:
|
|
|
154
154
|
Human: "What were our decisions about auth?"
|
|
155
155
|
|
|
156
156
|
You: Let me find that information for you.
|
|
157
|
-
[Use
|
|
157
|
+
[Use search_notes() to find relevant notes]
|
|
158
158
|
[Then build_context() to understand connections]
|
|
159
159
|
```
|
|
160
160
|
|
|
@@ -263,7 +263,7 @@ When creating relations, you can:
|
|
|
263
263
|
# Example workflow for creating notes with effective relations
|
|
264
264
|
async def create_note_with_effective_relations():
|
|
265
265
|
# Search for existing entities to reference
|
|
266
|
-
search_results = await
|
|
266
|
+
search_results = await search_notes("travel")
|
|
267
267
|
existing_entities = [result.title for result in search_results.primary_results]
|
|
268
268
|
|
|
269
269
|
# Check if specific entities exist
|
|
@@ -335,7 +335,7 @@ Common issues to watch for:
|
|
|
335
335
|
content = await read_note("Document")
|
|
336
336
|
except:
|
|
337
337
|
# Try search instead
|
|
338
|
-
results = await
|
|
338
|
+
results = await search_notes("Document")
|
|
339
339
|
if results and results.primary_results:
|
|
340
340
|
# Found something similar
|
|
341
341
|
content = await read_note(results.primary_results[0].permalink)
|
|
@@ -381,7 +381,7 @@ Common issues to watch for:
|
|
|
381
381
|
- **Create deliberate relations**: Connect each note to at least 2-3 related entities
|
|
382
382
|
- **Use existing entities**: Before creating a new relation, search for existing entities
|
|
383
383
|
- **Verify wikilinks**: When referencing `[[Entity]]`, use exact titles of existing notes
|
|
384
|
-
- **Check accuracy**: Use `
|
|
384
|
+
- **Check accuracy**: Use `search_notes()` or `recent_activity()` to confirm entity titles
|
|
385
385
|
- **Use precise relation types**: Choose specific relation types that convey meaning (e.g., "implements" instead
|
|
386
386
|
of "relates_to")
|
|
387
387
|
- **Consider bidirectional relations**: When appropriate, create inverse relations in both entities
|
|
@@ -211,7 +211,7 @@ def test_search_basic(cli_env, setup_test_note):
|
|
|
211
211
|
"""Test basic search command."""
|
|
212
212
|
result = runner.invoke(
|
|
213
213
|
tool_app,
|
|
214
|
-
["search", "test observation"],
|
|
214
|
+
["search-notes", "test observation"],
|
|
215
215
|
)
|
|
216
216
|
assert result.exit_code == 0
|
|
217
217
|
|
|
@@ -235,7 +235,7 @@ def test_search_permalink(cli_env, setup_test_note):
|
|
|
235
235
|
|
|
236
236
|
result = runner.invoke(
|
|
237
237
|
tool_app,
|
|
238
|
-
["search", permalink, "--permalink"],
|
|
238
|
+
["search-notes", permalink, "--permalink"],
|
|
239
239
|
)
|
|
240
240
|
assert result.exit_code == 0
|
|
241
241
|
|
|
@@ -26,7 +26,7 @@ async def mock_call_get():
|
|
|
26
26
|
@pytest_asyncio.fixture
|
|
27
27
|
async def mock_search():
|
|
28
28
|
"""Mock for search tool."""
|
|
29
|
-
with patch("basic_memory.mcp.tools.read_note.
|
|
29
|
+
with patch("basic_memory.mcp.tools.read_note.search_notes") as mock:
|
|
30
30
|
# Default to empty results
|
|
31
31
|
mock.return_value = SearchResponse(results=[], current_page=1, page_size=1)
|
|
32
32
|
yield mock
|
|
@@ -4,7 +4,7 @@ import pytest
|
|
|
4
4
|
from datetime import datetime, timedelta
|
|
5
5
|
|
|
6
6
|
from basic_memory.mcp.tools import write_note
|
|
7
|
-
from basic_memory.mcp.tools.search import
|
|
7
|
+
from basic_memory.mcp.tools.search import search_notes
|
|
8
8
|
from basic_memory.schemas.search import SearchQuery, SearchItemType
|
|
9
9
|
|
|
10
10
|
|
|
@@ -22,7 +22,7 @@ async def test_search_basic(client):
|
|
|
22
22
|
|
|
23
23
|
# Search for it
|
|
24
24
|
query = SearchQuery(text="searchable")
|
|
25
|
-
response = await
|
|
25
|
+
response = await search_notes(query)
|
|
26
26
|
|
|
27
27
|
# Verify results
|
|
28
28
|
assert len(response.results) > 0
|
|
@@ -43,7 +43,7 @@ async def test_search_pagination(client):
|
|
|
43
43
|
|
|
44
44
|
# Search for it
|
|
45
45
|
query = SearchQuery(text="searchable")
|
|
46
|
-
response = await
|
|
46
|
+
response = await search_notes(query, page=1, page_size=1)
|
|
47
47
|
|
|
48
48
|
# Verify results
|
|
49
49
|
assert len(response.results) == 1
|
|
@@ -62,7 +62,7 @@ async def test_search_with_type_filter(client):
|
|
|
62
62
|
|
|
63
63
|
# Search with type filter
|
|
64
64
|
query = SearchQuery(text="type", types=[SearchItemType.ENTITY])
|
|
65
|
-
response = await
|
|
65
|
+
response = await search_notes(query)
|
|
66
66
|
|
|
67
67
|
# Verify all results are entities
|
|
68
68
|
assert all(r.type == "entity" for r in response.results)
|
|
@@ -81,7 +81,7 @@ async def test_search_with_date_filter(client):
|
|
|
81
81
|
# Search with date filter
|
|
82
82
|
one_hour_ago = datetime.now() - timedelta(hours=1)
|
|
83
83
|
query = SearchQuery(text="recent", after_date=one_hour_ago)
|
|
84
|
-
response = await
|
|
84
|
+
response = await search_notes(query)
|
|
85
85
|
|
|
86
86
|
# Verify we get results within timeframe
|
|
87
87
|
assert len(response.results) > 0
|