basic-memory 0.11.0__tar.gz → 0.12.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.12.0/.github/workflows/claude-code-actions.yml +16 -0
- {basic_memory-0.11.0 → basic_memory-0.12.0}/.github/workflows/test.yml +6 -0
- {basic_memory-0.11.0 → basic_memory-0.12.0}/.gitignore +5 -1
- {basic_memory-0.11.0 → basic_memory-0.12.0}/CHANGELOG.md +50 -0
- {basic_memory-0.11.0 → basic_memory-0.12.0}/PKG-INFO +40 -3
- {basic_memory-0.11.0 → basic_memory-0.12.0}/README.md +39 -2
- {basic_memory-0.11.0 → basic_memory-0.12.0}/pyproject.toml +1 -1
- {basic_memory-0.11.0 → basic_memory-0.12.0}/src/basic_memory/__init__.py +1 -1
- basic_memory-0.12.0/src/basic_memory/api/app.py +90 -0
- {basic_memory-0.11.0 → basic_memory-0.12.0}/src/basic_memory/cli/app.py +0 -7
- {basic_memory-0.11.0 → basic_memory-0.12.0}/src/basic_memory/cli/commands/mcp.py +8 -1
- {basic_memory-0.11.0 → basic_memory-0.12.0}/src/basic_memory/cli/commands/sync.py +1 -0
- {basic_memory-0.11.0 → basic_memory-0.12.0}/src/basic_memory/cli/commands/tool.py +28 -15
- {basic_memory-0.11.0 → basic_memory-0.12.0}/src/basic_memory/cli/main.py +16 -7
- {basic_memory-0.11.0 → basic_memory-0.12.0}/src/basic_memory/config.py +28 -4
- {basic_memory-0.11.0 → basic_memory-0.12.0}/src/basic_memory/db.py +3 -1
- {basic_memory-0.11.0 → basic_memory-0.12.0}/src/basic_memory/file_utils.py +3 -0
- {basic_memory-0.11.0 → basic_memory-0.12.0}/src/basic_memory/markdown/entity_parser.py +16 -7
- {basic_memory-0.11.0 → basic_memory-0.12.0}/src/basic_memory/markdown/utils.py +21 -13
- {basic_memory-0.11.0 → basic_memory-0.12.0}/src/basic_memory/mcp/prompts/continue_conversation.py +4 -4
- {basic_memory-0.11.0 → basic_memory-0.12.0}/src/basic_memory/mcp/prompts/search.py +2 -2
- {basic_memory-0.11.0 → basic_memory-0.12.0}/src/basic_memory/mcp/server.py +2 -2
- {basic_memory-0.11.0 → basic_memory-0.12.0}/src/basic_memory/mcp/tools/read_note.py +2 -3
- basic_memory-0.12.0/src/basic_memory/mcp/tools/search.py +113 -0
- {basic_memory-0.11.0 → basic_memory-0.12.0}/src/basic_memory/mcp/tools/write_note.py +3 -1
- {basic_memory-0.11.0 → basic_memory-0.12.0}/src/basic_memory/repository/search_repository.py +11 -11
- {basic_memory-0.11.0 → basic_memory-0.12.0}/src/basic_memory/schemas/search.py +2 -2
- {basic_memory-0.11.0 → basic_memory-0.12.0}/src/basic_memory/services/context_service.py +1 -1
- {basic_memory-0.11.0 → basic_memory-0.12.0}/src/basic_memory/services/entity_service.py +10 -10
- {basic_memory-0.11.0 → basic_memory-0.12.0}/src/basic_memory/services/link_resolver.py +8 -1
- {basic_memory-0.11.0 → basic_memory-0.12.0}/src/basic_memory/services/search_service.py +3 -23
- {basic_memory-0.11.0 → basic_memory-0.12.0}/src/basic_memory/sync/sync_service.py +60 -23
- {basic_memory-0.11.0 → basic_memory-0.12.0}/src/basic_memory/utils.py +10 -2
- {basic_memory-0.11.0 → basic_memory-0.12.0}/tests/api/test_knowledge_router.py +3 -3
- {basic_memory-0.11.0 → basic_memory-0.12.0}/tests/api/test_search_router.py +8 -8
- {basic_memory-0.11.0 → basic_memory-0.12.0}/tests/conftest.py +4 -2
- {basic_memory-0.11.0 → basic_memory-0.12.0}/tests/markdown/test_entity_parser.py +31 -0
- {basic_memory-0.11.0 → basic_memory-0.12.0}/tests/mcp/test_tool_read_note.py +9 -4
- {basic_memory-0.11.0 → basic_memory-0.12.0}/tests/mcp/test_tool_resource.py +27 -0
- basic_memory-0.12.0/tests/mcp/test_tool_search.py +159 -0
- basic_memory-0.11.0/tests/mcp/test_tool_notes.py → basic_memory-0.12.0/tests/mcp/test_tool_write_note.py +63 -6
- {basic_memory-0.11.0 → basic_memory-0.12.0}/tests/schemas/test_search.py +4 -4
- {basic_memory-0.11.0 → basic_memory-0.12.0}/tests/services/test_entity_service.py +34 -2
- {basic_memory-0.11.0 → basic_memory-0.12.0}/tests/services/test_search_service.py +13 -6
- {basic_memory-0.11.0 → basic_memory-0.12.0}/tests/sync/test_sync_service.py +84 -29
- basic_memory-0.12.0/tests/sync/test_sync_wikilink_issue.py +62 -0
- {basic_memory-0.11.0 → basic_memory-0.12.0}/tests/sync/test_watch_service.py +1 -1
- basic_memory-0.12.0/tests/utils/test_parse_tags.py +50 -0
- {basic_memory-0.11.0 → basic_memory-0.12.0}/uv.lock +1 -1
- basic_memory-0.11.0/src/basic_memory/api/app.py +0 -51
- basic_memory-0.11.0/src/basic_memory/mcp/tools/search.py +0 -77
- basic_memory-0.11.0/tests/mcp/test_tool_search.py +0 -87
- {basic_memory-0.11.0 → basic_memory-0.12.0}/.github/ISSUE_TEMPLATE/bug_report.md +0 -0
- {basic_memory-0.11.0 → basic_memory-0.12.0}/.github/ISSUE_TEMPLATE/config.yml +0 -0
- {basic_memory-0.11.0 → basic_memory-0.12.0}/.github/ISSUE_TEMPLATE/documentation.md +0 -0
- {basic_memory-0.11.0 → basic_memory-0.12.0}/.github/ISSUE_TEMPLATE/feature_request.md +0 -0
- {basic_memory-0.11.0 → basic_memory-0.12.0}/.github/dependabot.yml +0 -0
- {basic_memory-0.11.0 → basic_memory-0.12.0}/.github/workflows/pr-title.yml +0 -0
- {basic_memory-0.11.0 → basic_memory-0.12.0}/.github/workflows/release.yml +0 -0
- {basic_memory-0.11.0 → basic_memory-0.12.0}/.python-version +0 -0
- {basic_memory-0.11.0 → basic_memory-0.12.0}/CITATION.cff +0 -0
- {basic_memory-0.11.0 → basic_memory-0.12.0}/CLA.md +0 -0
- {basic_memory-0.11.0 → basic_memory-0.12.0}/CLAUDE.md +0 -0
- {basic_memory-0.11.0 → basic_memory-0.12.0}/CODE_OF_CONDUCT.md +0 -0
- {basic_memory-0.11.0 → basic_memory-0.12.0}/CONTRIBUTING.md +0 -0
- {basic_memory-0.11.0 → basic_memory-0.12.0}/Dockerfile +0 -0
- {basic_memory-0.11.0 → basic_memory-0.12.0}/LICENSE +0 -0
- {basic_memory-0.11.0 → basic_memory-0.12.0}/Makefile +0 -0
- {basic_memory-0.11.0 → basic_memory-0.12.0}/SECURITY.md +0 -0
- {basic_memory-0.11.0 → basic_memory-0.12.0}/basic-memory.md +0 -0
- {basic_memory-0.11.0 → basic_memory-0.12.0}/docs/AI Assistant Guide.md +0 -0
- {basic_memory-0.11.0 → basic_memory-0.12.0}/docs/CLI Reference.md +0 -0
- {basic_memory-0.11.0 → basic_memory-0.12.0}/docs/Canvas.md +0 -0
- {basic_memory-0.11.0 → basic_memory-0.12.0}/docs/Getting Started with Basic Memory.md +0 -0
- {basic_memory-0.11.0 → basic_memory-0.12.0}/docs/Knowledge Format.md +0 -0
- {basic_memory-0.11.0 → basic_memory-0.12.0}/docs/Obsidian Integration.md +0 -0
- {basic_memory-0.11.0 → basic_memory-0.12.0}/docs/Technical Information.md +0 -0
- {basic_memory-0.11.0 → basic_memory-0.12.0}/docs/User Guide.md +0 -0
- {basic_memory-0.11.0 → basic_memory-0.12.0}/docs/Welcome to Basic memory.md +0 -0
- {basic_memory-0.11.0 → basic_memory-0.12.0}/docs/attachments/Canvas.png +0 -0
- {basic_memory-0.11.0 → basic_memory-0.12.0}/docs/attachments/Claude-Obsidian-Demo.mp4 +0 -0
- {basic_memory-0.11.0 → basic_memory-0.12.0}/docs/attachments/Prompt.png +0 -0
- {basic_memory-0.11.0 → basic_memory-0.12.0}/docs/attachments/disk-ai-logo-400x400.png +0 -0
- {basic_memory-0.11.0 → basic_memory-0.12.0}/docs/attachments/disk-ai-logo.png +0 -0
- {basic_memory-0.11.0 → basic_memory-0.12.0}/docs/attachments/prompt 1.png +0 -0
- {basic_memory-0.11.0 → basic_memory-0.12.0}/docs/attachments/prompt2.png +0 -0
- {basic_memory-0.11.0 → basic_memory-0.12.0}/docs/attachments/prompt3.png +0 -0
- {basic_memory-0.11.0 → basic_memory-0.12.0}/docs/attachments/prompt4.png +0 -0
- {basic_memory-0.11.0 → basic_memory-0.12.0}/docs/publish.js +0 -0
- {basic_memory-0.11.0 → basic_memory-0.12.0}/examples/Coffee Notes/Brewing Equipment.md +0 -0
- {basic_memory-0.11.0 → basic_memory-0.12.0}/examples/Coffee Notes/Coffee Bean Origins.md +0 -0
- {basic_memory-0.11.0 → basic_memory-0.12.0}/examples/Coffee Notes/Coffee Brewing Methods.md +0 -0
- {basic_memory-0.11.0 → basic_memory-0.12.0}/examples/Coffee Notes/Coffee Flavor Map.md +0 -0
- {basic_memory-0.11.0 → basic_memory-0.12.0}/examples/Coffee Notes/Coffee Knowledge Base.md +0 -0
- {basic_memory-0.11.0 → basic_memory-0.12.0}/examples/Coffee Notes/Flavor Extraction.md +0 -0
- {basic_memory-0.11.0 → basic_memory-0.12.0}/examples/Coffee Notes/Perfect Pour Over Coffee Method.canvas +0 -0
- {basic_memory-0.11.0 → basic_memory-0.12.0}/examples/Coffee Notes/Tasting Notes.md +0 -0
- {basic_memory-0.11.0 → basic_memory-0.12.0}/installer/Basic.icns +0 -0
- {basic_memory-0.11.0 → basic_memory-0.12.0}/installer/README.md +0 -0
- {basic_memory-0.11.0 → basic_memory-0.12.0}/installer/icon.svg +0 -0
- {basic_memory-0.11.0 → basic_memory-0.12.0}/installer/installer.py +0 -0
- {basic_memory-0.11.0 → basic_memory-0.12.0}/installer/make_icons.sh +0 -0
- {basic_memory-0.11.0 → basic_memory-0.12.0}/installer/setup.py +0 -0
- {basic_memory-0.11.0 → basic_memory-0.12.0}/llms-install.md +0 -0
- {basic_memory-0.11.0 → basic_memory-0.12.0}/memory.json +0 -0
- {basic_memory-0.11.0 → basic_memory-0.12.0}/scripts/install.sh +0 -0
- {basic_memory-0.11.0 → basic_memory-0.12.0}/smithery.yaml +0 -0
- {basic_memory-0.11.0 → basic_memory-0.12.0}/src/basic_memory/alembic/alembic.ini +0 -0
- {basic_memory-0.11.0 → basic_memory-0.12.0}/src/basic_memory/alembic/env.py +0 -0
- {basic_memory-0.11.0 → basic_memory-0.12.0}/src/basic_memory/alembic/migrations.py +0 -0
- {basic_memory-0.11.0 → basic_memory-0.12.0}/src/basic_memory/alembic/script.py.mako +0 -0
- {basic_memory-0.11.0 → basic_memory-0.12.0}/src/basic_memory/alembic/versions/3dae7c7b1564_initial_schema.py +0 -0
- {basic_memory-0.11.0 → basic_memory-0.12.0}/src/basic_memory/alembic/versions/502b60eaa905_remove_required_from_entity_permalink.py +0 -0
- {basic_memory-0.11.0 → basic_memory-0.12.0}/src/basic_memory/alembic/versions/b3c3938bacdb_relation_to_name_unique_index.py +0 -0
- {basic_memory-0.11.0 → basic_memory-0.12.0}/src/basic_memory/alembic/versions/cc7172b46608_update_search_index_schema.py +0 -0
- {basic_memory-0.11.0 → basic_memory-0.12.0}/src/basic_memory/api/__init__.py +0 -0
- {basic_memory-0.11.0 → basic_memory-0.12.0}/src/basic_memory/api/routers/__init__.py +0 -0
- {basic_memory-0.11.0 → basic_memory-0.12.0}/src/basic_memory/api/routers/knowledge_router.py +0 -0
- {basic_memory-0.11.0 → basic_memory-0.12.0}/src/basic_memory/api/routers/memory_router.py +0 -0
- {basic_memory-0.11.0 → basic_memory-0.12.0}/src/basic_memory/api/routers/project_info_router.py +0 -0
- {basic_memory-0.11.0 → basic_memory-0.12.0}/src/basic_memory/api/routers/resource_router.py +0 -0
- {basic_memory-0.11.0 → basic_memory-0.12.0}/src/basic_memory/api/routers/search_router.py +0 -0
- {basic_memory-0.11.0 → basic_memory-0.12.0}/src/basic_memory/cli/__init__.py +0 -0
- {basic_memory-0.11.0 → basic_memory-0.12.0}/src/basic_memory/cli/commands/__init__.py +0 -0
- {basic_memory-0.11.0 → basic_memory-0.12.0}/src/basic_memory/cli/commands/db.py +0 -0
- {basic_memory-0.11.0 → basic_memory-0.12.0}/src/basic_memory/cli/commands/import_chatgpt.py +0 -0
- {basic_memory-0.11.0 → basic_memory-0.12.0}/src/basic_memory/cli/commands/import_claude_conversations.py +0 -0
- {basic_memory-0.11.0 → basic_memory-0.12.0}/src/basic_memory/cli/commands/import_claude_projects.py +0 -0
- {basic_memory-0.11.0 → basic_memory-0.12.0}/src/basic_memory/cli/commands/import_memory_json.py +0 -0
- {basic_memory-0.11.0 → basic_memory-0.12.0}/src/basic_memory/cli/commands/project.py +0 -0
- {basic_memory-0.11.0 → basic_memory-0.12.0}/src/basic_memory/cli/commands/status.py +0 -0
- {basic_memory-0.11.0 → basic_memory-0.12.0}/src/basic_memory/deps.py +0 -0
- {basic_memory-0.11.0 → basic_memory-0.12.0}/src/basic_memory/markdown/__init__.py +0 -0
- {basic_memory-0.11.0 → basic_memory-0.12.0}/src/basic_memory/markdown/markdown_processor.py +0 -0
- {basic_memory-0.11.0 → basic_memory-0.12.0}/src/basic_memory/markdown/plugins.py +0 -0
- {basic_memory-0.11.0 → basic_memory-0.12.0}/src/basic_memory/markdown/schemas.py +0 -0
- {basic_memory-0.11.0 → basic_memory-0.12.0}/src/basic_memory/mcp/__init__.py +0 -0
- {basic_memory-0.11.0 → basic_memory-0.12.0}/src/basic_memory/mcp/async_client.py +0 -0
- {basic_memory-0.11.0 → basic_memory-0.12.0}/src/basic_memory/mcp/main.py +0 -0
- {basic_memory-0.11.0 → basic_memory-0.12.0}/src/basic_memory/mcp/prompts/__init__.py +0 -0
- {basic_memory-0.11.0 → basic_memory-0.12.0}/src/basic_memory/mcp/prompts/ai_assistant_guide.py +0 -0
- {basic_memory-0.11.0 → basic_memory-0.12.0}/src/basic_memory/mcp/prompts/recent_activity.py +0 -0
- {basic_memory-0.11.0 → basic_memory-0.12.0}/src/basic_memory/mcp/prompts/utils.py +0 -0
- {basic_memory-0.11.0 → basic_memory-0.12.0}/src/basic_memory/mcp/resources/ai_assistant_guide.md +0 -0
- {basic_memory-0.11.0 → basic_memory-0.12.0}/src/basic_memory/mcp/tools/__init__.py +0 -0
- {basic_memory-0.11.0 → basic_memory-0.12.0}/src/basic_memory/mcp/tools/build_context.py +0 -0
- {basic_memory-0.11.0 → basic_memory-0.12.0}/src/basic_memory/mcp/tools/canvas.py +0 -0
- {basic_memory-0.11.0 → basic_memory-0.12.0}/src/basic_memory/mcp/tools/delete_note.py +0 -0
- {basic_memory-0.11.0 → basic_memory-0.12.0}/src/basic_memory/mcp/tools/project_info.py +0 -0
- {basic_memory-0.11.0 → basic_memory-0.12.0}/src/basic_memory/mcp/tools/read_content.py +0 -0
- {basic_memory-0.11.0 → basic_memory-0.12.0}/src/basic_memory/mcp/tools/recent_activity.py +0 -0
- {basic_memory-0.11.0 → basic_memory-0.12.0}/src/basic_memory/mcp/tools/utils.py +0 -0
- {basic_memory-0.11.0 → basic_memory-0.12.0}/src/basic_memory/models/__init__.py +0 -0
- {basic_memory-0.11.0 → basic_memory-0.12.0}/src/basic_memory/models/base.py +0 -0
- {basic_memory-0.11.0 → basic_memory-0.12.0}/src/basic_memory/models/knowledge.py +0 -0
- {basic_memory-0.11.0 → basic_memory-0.12.0}/src/basic_memory/models/search.py +0 -0
- {basic_memory-0.11.0 → basic_memory-0.12.0}/src/basic_memory/repository/__init__.py +0 -0
- {basic_memory-0.11.0 → basic_memory-0.12.0}/src/basic_memory/repository/entity_repository.py +0 -0
- {basic_memory-0.11.0 → basic_memory-0.12.0}/src/basic_memory/repository/observation_repository.py +0 -0
- {basic_memory-0.11.0 → basic_memory-0.12.0}/src/basic_memory/repository/project_info_repository.py +0 -0
- {basic_memory-0.11.0 → basic_memory-0.12.0}/src/basic_memory/repository/relation_repository.py +0 -0
- {basic_memory-0.11.0 → basic_memory-0.12.0}/src/basic_memory/repository/repository.py +0 -0
- {basic_memory-0.11.0 → basic_memory-0.12.0}/src/basic_memory/schemas/__init__.py +0 -0
- {basic_memory-0.11.0 → basic_memory-0.12.0}/src/basic_memory/schemas/base.py +0 -0
- {basic_memory-0.11.0 → basic_memory-0.12.0}/src/basic_memory/schemas/delete.py +0 -0
- {basic_memory-0.11.0 → basic_memory-0.12.0}/src/basic_memory/schemas/memory.py +0 -0
- {basic_memory-0.11.0 → basic_memory-0.12.0}/src/basic_memory/schemas/project_info.py +0 -0
- {basic_memory-0.11.0 → basic_memory-0.12.0}/src/basic_memory/schemas/request.py +0 -0
- {basic_memory-0.11.0 → basic_memory-0.12.0}/src/basic_memory/schemas/response.py +0 -0
- {basic_memory-0.11.0 → basic_memory-0.12.0}/src/basic_memory/services/__init__.py +0 -0
- {basic_memory-0.11.0 → basic_memory-0.12.0}/src/basic_memory/services/exceptions.py +0 -0
- {basic_memory-0.11.0 → basic_memory-0.12.0}/src/basic_memory/services/file_service.py +0 -0
- {basic_memory-0.11.0 → basic_memory-0.12.0}/src/basic_memory/services/service.py +0 -0
- {basic_memory-0.11.0 → basic_memory-0.12.0}/src/basic_memory/sync/__init__.py +0 -0
- {basic_memory-0.11.0 → basic_memory-0.12.0}/src/basic_memory/sync/watch_service.py +0 -0
- {basic_memory-0.11.0 → basic_memory-0.12.0}/static/ai_assistant_guide.md +0 -0
- {basic_memory-0.11.0 → basic_memory-0.12.0}/static/json_canvas_spec_1_0.md +0 -0
- {basic_memory-0.11.0 → basic_memory-0.12.0}/tests/Non-MarkdownFileSupport.pdf +0 -0
- {basic_memory-0.11.0 → basic_memory-0.12.0}/tests/Screenshot.png +0 -0
- {basic_memory-0.11.0 → basic_memory-0.12.0}/tests/__init__.py +0 -0
- {basic_memory-0.11.0 → basic_memory-0.12.0}/tests/api/conftest.py +0 -0
- {basic_memory-0.11.0 → basic_memory-0.12.0}/tests/api/test_memory_router.py +0 -0
- {basic_memory-0.11.0 → basic_memory-0.12.0}/tests/api/test_project_info_router.py +0 -0
- {basic_memory-0.11.0 → basic_memory-0.12.0}/tests/api/test_resource_router.py +0 -0
- {basic_memory-0.11.0 → basic_memory-0.12.0}/tests/cli/conftest.py +0 -0
- {basic_memory-0.11.0 → basic_memory-0.12.0}/tests/cli/test_cli_tools.py +0 -0
- {basic_memory-0.11.0 → basic_memory-0.12.0}/tests/cli/test_import_chatgpt.py +0 -0
- {basic_memory-0.11.0 → basic_memory-0.12.0}/tests/cli/test_import_claude_conversations.py +0 -0
- {basic_memory-0.11.0 → basic_memory-0.12.0}/tests/cli/test_import_claude_projects.py +0 -0
- {basic_memory-0.11.0 → basic_memory-0.12.0}/tests/cli/test_import_memory_json.py +0 -0
- {basic_memory-0.11.0 → basic_memory-0.12.0}/tests/cli/test_project_commands.py +0 -0
- {basic_memory-0.11.0 → basic_memory-0.12.0}/tests/cli/test_project_info.py +0 -0
- {basic_memory-0.11.0 → basic_memory-0.12.0}/tests/cli/test_status.py +0 -0
- {basic_memory-0.11.0 → basic_memory-0.12.0}/tests/cli/test_sync.py +0 -0
- {basic_memory-0.11.0 → basic_memory-0.12.0}/tests/cli/test_version.py +0 -0
- {basic_memory-0.11.0 → basic_memory-0.12.0}/tests/edit_file_test.py +0 -0
- {basic_memory-0.11.0 → basic_memory-0.12.0}/tests/markdown/__init__.py +0 -0
- {basic_memory-0.11.0 → basic_memory-0.12.0}/tests/markdown/test_markdown_plugins.py +0 -0
- {basic_memory-0.11.0 → basic_memory-0.12.0}/tests/markdown/test_markdown_processor.py +0 -0
- {basic_memory-0.11.0 → basic_memory-0.12.0}/tests/markdown/test_observation_edge_cases.py +0 -0
- {basic_memory-0.11.0 → basic_memory-0.12.0}/tests/markdown/test_parser_edge_cases.py +0 -0
- {basic_memory-0.11.0 → basic_memory-0.12.0}/tests/markdown/test_relation_edge_cases.py +0 -0
- {basic_memory-0.11.0 → basic_memory-0.12.0}/tests/markdown/test_task_detection.py +0 -0
- {basic_memory-0.11.0 → basic_memory-0.12.0}/tests/mcp/conftest.py +0 -0
- {basic_memory-0.11.0 → basic_memory-0.12.0}/tests/mcp/test_prompts.py +0 -0
- {basic_memory-0.11.0 → basic_memory-0.12.0}/tests/mcp/test_resources.py +0 -0
- {basic_memory-0.11.0 → basic_memory-0.12.0}/tests/mcp/test_tool_canvas.py +0 -0
- {basic_memory-0.11.0 → basic_memory-0.12.0}/tests/mcp/test_tool_memory.py +0 -0
- {basic_memory-0.11.0 → basic_memory-0.12.0}/tests/mcp/test_tool_project_info.py +0 -0
- {basic_memory-0.11.0 → basic_memory-0.12.0}/tests/mcp/test_tool_utils.py +0 -0
- {basic_memory-0.11.0 → basic_memory-0.12.0}/tests/repository/test_entity_repository.py +0 -0
- {basic_memory-0.11.0 → basic_memory-0.12.0}/tests/repository/test_observation_repository.py +0 -0
- {basic_memory-0.11.0 → basic_memory-0.12.0}/tests/repository/test_relation_repository.py +0 -0
- {basic_memory-0.11.0 → basic_memory-0.12.0}/tests/repository/test_repository.py +0 -0
- {basic_memory-0.11.0 → basic_memory-0.12.0}/tests/schemas/test_memory_url.py +0 -0
- {basic_memory-0.11.0 → basic_memory-0.12.0}/tests/schemas/test_schemas.py +0 -0
- {basic_memory-0.11.0 → basic_memory-0.12.0}/tests/services/test_context_service.py +0 -0
- {basic_memory-0.11.0 → basic_memory-0.12.0}/tests/services/test_file_service.py +0 -0
- {basic_memory-0.11.0 → basic_memory-0.12.0}/tests/services/test_link_resolver.py +0 -0
- {basic_memory-0.11.0 → basic_memory-0.12.0}/tests/sync/test_tmp_files.py +0 -0
- {basic_memory-0.11.0 → basic_memory-0.12.0}/tests/sync/test_watch_service_edge_cases.py +0 -0
- {basic_memory-0.11.0 → basic_memory-0.12.0}/tests/test_basic_memory.py +0 -0
- {basic_memory-0.11.0 → basic_memory-0.12.0}/tests/test_config.py +0 -0
- {basic_memory-0.11.0 → basic_memory-0.12.0}/tests/utils/test_file_utils.py +0 -0
- {basic_memory-0.11.0 → basic_memory-0.12.0}/tests/utils/test_permalink_formatting.py +0 -0
- {basic_memory-0.11.0 → basic_memory-0.12.0}/tests/utils/test_utf8_handling.py +0 -0
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
name: Claude Code Integration
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
issue_comment:
|
|
5
|
+
types: [ created ]
|
|
6
|
+
pull_request_review_comment:
|
|
7
|
+
types: [ created ]
|
|
8
|
+
|
|
9
|
+
jobs:
|
|
10
|
+
claude-integration:
|
|
11
|
+
uses: basicmachines-co/claude-code-github-action/.github/workflows/claude-full.yml@v0.11.0
|
|
12
|
+
with:
|
|
13
|
+
issue-label: 'claude-fix' # Optional: customize the trigger label
|
|
14
|
+
secrets:
|
|
15
|
+
ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }}
|
|
16
|
+
PERSONAL_ACCESS_TOKEN: ${{ secrets.CLAUDE_TOKEN }}
|
|
@@ -5,6 +5,12 @@ on:
|
|
|
5
5
|
branches: [ "main" ]
|
|
6
6
|
pull_request:
|
|
7
7
|
branches: [ "main" ]
|
|
8
|
+
# pull_request_target runs on the BASE of the PR, not the merge result.
|
|
9
|
+
# It has write permissions and access to secrets.
|
|
10
|
+
# It's useful for PRs from forks or automated PRs but requires careful use for security reasons.
|
|
11
|
+
# See: https://docs.github.com/en/actions/using-workflows/events-that-trigger-workflows#pull_request_target
|
|
12
|
+
pull_request_target:
|
|
13
|
+
branches: [ "main" ]
|
|
8
14
|
|
|
9
15
|
jobs:
|
|
10
16
|
test:
|
|
@@ -1,6 +1,56 @@
|
|
|
1
1
|
# CHANGELOG
|
|
2
2
|
|
|
3
3
|
|
|
4
|
+
## v0.12.0 (2025-04-06)
|
|
5
|
+
|
|
6
|
+
### Bug Fixes
|
|
7
|
+
|
|
8
|
+
- [bug] `#` character accumulation in markdown frontmatter tags prop
|
|
9
|
+
([#79](https://github.com/basicmachines-co/basic-memory/pull/79),
|
|
10
|
+
[`6c19c9e`](https://github.com/basicmachines-co/basic-memory/commit/6c19c9edf5131054ba201a109b37f15c83ef150c))
|
|
11
|
+
|
|
12
|
+
- [bug] Cursor has errors calling search tool
|
|
13
|
+
([#78](https://github.com/basicmachines-co/basic-memory/pull/78),
|
|
14
|
+
[`9d581ce`](https://github.com/basicmachines-co/basic-memory/commit/9d581cee133f9dde4a0a85118868227390c84161))
|
|
15
|
+
|
|
16
|
+
- [bug] Some notes never exit "modified" status
|
|
17
|
+
([#77](https://github.com/basicmachines-co/basic-memory/pull/77),
|
|
18
|
+
[`7930ddb`](https://github.com/basicmachines-co/basic-memory/commit/7930ddb2919057be30ceac8c4c19da6aaa1d3e92))
|
|
19
|
+
|
|
20
|
+
- [bug] write_note Tool Fails to Update Existing Files in Some Situations.
|
|
21
|
+
([#80](https://github.com/basicmachines-co/basic-memory/pull/80),
|
|
22
|
+
[`9bff1f7`](https://github.com/basicmachines-co/basic-memory/commit/9bff1f732e71bc60f88b5c2ce3db5a2aa60b8e28))
|
|
23
|
+
|
|
24
|
+
- Set default mcp log level to ERROR
|
|
25
|
+
([#81](https://github.com/basicmachines-co/basic-memory/pull/81),
|
|
26
|
+
[`248214c`](https://github.com/basicmachines-co/basic-memory/commit/248214cb114a269ca60ff6398e382f9e2495ad8e))
|
|
27
|
+
|
|
28
|
+
- Write_note preserves frontmatter fields in content
|
|
29
|
+
([#84](https://github.com/basicmachines-co/basic-memory/pull/84),
|
|
30
|
+
[`3f4d9e4`](https://github.com/basicmachines-co/basic-memory/commit/3f4d9e4d872ebc0ed719c61b24d803c14a9db5e6))
|
|
31
|
+
|
|
32
|
+
### Documentation
|
|
33
|
+
|
|
34
|
+
- Add VS Code instructions to README
|
|
35
|
+
([#76](https://github.com/basicmachines-co/basic-memory/pull/76),
|
|
36
|
+
[`43cbb7b`](https://github.com/basicmachines-co/basic-memory/commit/43cbb7b38cc0482ac0a41b6759320e3588186e43))
|
|
37
|
+
|
|
38
|
+
- Updated basicmachines.co links to be https
|
|
39
|
+
([#69](https://github.com/basicmachines-co/basic-memory/pull/69),
|
|
40
|
+
[`40ea28b`](https://github.com/basicmachines-co/basic-memory/commit/40ea28b0bfc60012924a69ecb76511daa4c7d133))
|
|
41
|
+
|
|
42
|
+
### Features
|
|
43
|
+
|
|
44
|
+
- Add watch to mcp process ([#83](https://github.com/basicmachines-co/basic-memory/pull/83),
|
|
45
|
+
[`00c8633`](https://github.com/basicmachines-co/basic-memory/commit/00c8633cfcee75ff640ff8fe81dafeb956281a94))
|
|
46
|
+
|
|
47
|
+
- Permalink enhancements ([#82](https://github.com/basicmachines-co/basic-memory/pull/82),
|
|
48
|
+
[`617e60b`](https://github.com/basicmachines-co/basic-memory/commit/617e60bda4a590678a5f551f10a73e7b47e3b13e))
|
|
49
|
+
|
|
50
|
+
- Avoiding "useless permalink values" for files without metadata - Enable permalinks to be updated
|
|
51
|
+
on move via config setting
|
|
52
|
+
|
|
53
|
+
|
|
4
54
|
## v0.11.0 (2025-03-29)
|
|
5
55
|
|
|
6
56
|
### Bug Fixes
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: basic-memory
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.12.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
|
|
@@ -47,8 +47,8 @@ Basic Memory lets you build persistent knowledge through natural conversations w
|
|
|
47
47
|
Claude, while keeping everything in simple Markdown files on your computer. It uses the Model Context Protocol (MCP) to
|
|
48
48
|
enable any compatible LLM to read and write to your local knowledge base.
|
|
49
49
|
|
|
50
|
-
- Website:
|
|
51
|
-
- Documentation:
|
|
50
|
+
- Website: https://basicmachines.co
|
|
51
|
+
- Documentation: https://memory.basicmachines.co
|
|
52
52
|
|
|
53
53
|
## Pick up your conversation right where you left off
|
|
54
54
|
|
|
@@ -296,6 +296,43 @@ Examples of relations:
|
|
|
296
296
|
- documented_in [[Coffee Journal]]
|
|
297
297
|
```
|
|
298
298
|
|
|
299
|
+
## Using with VS Code
|
|
300
|
+
For one-click installation, click one of the install buttons below...
|
|
301
|
+
|
|
302
|
+
[](https://insiders.vscode.dev/redirect/mcp/install?name=basic-memory&config=%7B%22command%22%3A%22uvx%22%2C%22args%22%3A%5B%22basic-memory%22%2C%22mcp%22%5D%7D) [](https://insiders.vscode.dev/redirect/mcp/install?name=basic-memory&config=%7B%22command%22%3A%22uvx%22%2C%22args%22%3A%5B%22basic-memory%22%2C%22mcp%22%5D%7D&quality=insiders)
|
|
303
|
+
|
|
304
|
+
You can use Basic Memory with VS Code to easily retrieve and store information while coding. Click the installation buttons above for one-click setup, or follow the manual installation instructions below.
|
|
305
|
+
|
|
306
|
+
### Manual Installation
|
|
307
|
+
|
|
308
|
+
Add the following JSON block to your User Settings (JSON) file in VS Code. You can do this by pressing `Ctrl + Shift + P` and typing `Preferences: Open User Settings (JSON)`.
|
|
309
|
+
|
|
310
|
+
```json
|
|
311
|
+
{
|
|
312
|
+
"mcp": {
|
|
313
|
+
"servers": {
|
|
314
|
+
"basic-memory": {
|
|
315
|
+
"command": "uvx",
|
|
316
|
+
"args": ["basic-memory", "mcp"]
|
|
317
|
+
}
|
|
318
|
+
}
|
|
319
|
+
}
|
|
320
|
+
}
|
|
321
|
+
```
|
|
322
|
+
|
|
323
|
+
Optionally, you can add it to a file called `.vscode/mcp.json` in your workspace. This will allow you to share the configuration with others.
|
|
324
|
+
|
|
325
|
+
```json
|
|
326
|
+
{
|
|
327
|
+
"servers": {
|
|
328
|
+
"basic-memory": {
|
|
329
|
+
"command": "uvx",
|
|
330
|
+
"args": ["basic-memory", "mcp"]
|
|
331
|
+
}
|
|
332
|
+
}
|
|
333
|
+
}
|
|
334
|
+
```
|
|
335
|
+
|
|
299
336
|
## Using with Claude Desktop
|
|
300
337
|
|
|
301
338
|
Basic Memory is built using the MCP (Model Context Protocol) and works with the Claude desktop app (https://claude.ai/):
|
|
@@ -13,8 +13,8 @@ Basic Memory lets you build persistent knowledge through natural conversations w
|
|
|
13
13
|
Claude, while keeping everything in simple Markdown files on your computer. It uses the Model Context Protocol (MCP) to
|
|
14
14
|
enable any compatible LLM to read and write to your local knowledge base.
|
|
15
15
|
|
|
16
|
-
- Website:
|
|
17
|
-
- Documentation:
|
|
16
|
+
- Website: https://basicmachines.co
|
|
17
|
+
- Documentation: https://memory.basicmachines.co
|
|
18
18
|
|
|
19
19
|
## Pick up your conversation right where you left off
|
|
20
20
|
|
|
@@ -262,6 +262,43 @@ Examples of relations:
|
|
|
262
262
|
- documented_in [[Coffee Journal]]
|
|
263
263
|
```
|
|
264
264
|
|
|
265
|
+
## Using with VS Code
|
|
266
|
+
For one-click installation, click one of the install buttons below...
|
|
267
|
+
|
|
268
|
+
[](https://insiders.vscode.dev/redirect/mcp/install?name=basic-memory&config=%7B%22command%22%3A%22uvx%22%2C%22args%22%3A%5B%22basic-memory%22%2C%22mcp%22%5D%7D) [](https://insiders.vscode.dev/redirect/mcp/install?name=basic-memory&config=%7B%22command%22%3A%22uvx%22%2C%22args%22%3A%5B%22basic-memory%22%2C%22mcp%22%5D%7D&quality=insiders)
|
|
269
|
+
|
|
270
|
+
You can use Basic Memory with VS Code to easily retrieve and store information while coding. Click the installation buttons above for one-click setup, or follow the manual installation instructions below.
|
|
271
|
+
|
|
272
|
+
### Manual Installation
|
|
273
|
+
|
|
274
|
+
Add the following JSON block to your User Settings (JSON) file in VS Code. You can do this by pressing `Ctrl + Shift + P` and typing `Preferences: Open User Settings (JSON)`.
|
|
275
|
+
|
|
276
|
+
```json
|
|
277
|
+
{
|
|
278
|
+
"mcp": {
|
|
279
|
+
"servers": {
|
|
280
|
+
"basic-memory": {
|
|
281
|
+
"command": "uvx",
|
|
282
|
+
"args": ["basic-memory", "mcp"]
|
|
283
|
+
}
|
|
284
|
+
}
|
|
285
|
+
}
|
|
286
|
+
}
|
|
287
|
+
```
|
|
288
|
+
|
|
289
|
+
Optionally, you can add it to a file called `.vscode/mcp.json` in your workspace. This will allow you to share the configuration with others.
|
|
290
|
+
|
|
291
|
+
```json
|
|
292
|
+
{
|
|
293
|
+
"servers": {
|
|
294
|
+
"basic-memory": {
|
|
295
|
+
"command": "uvx",
|
|
296
|
+
"args": ["basic-memory", "mcp"]
|
|
297
|
+
}
|
|
298
|
+
}
|
|
299
|
+
}
|
|
300
|
+
```
|
|
301
|
+
|
|
265
302
|
## Using with Claude Desktop
|
|
266
303
|
|
|
267
304
|
Basic Memory is built using the MCP (Model Context Protocol) and works with the Claude desktop app (https://claude.ai/):
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
"""FastAPI application for basic-memory knowledge graph API."""
|
|
2
|
+
|
|
3
|
+
import asyncio
|
|
4
|
+
from contextlib import asynccontextmanager
|
|
5
|
+
|
|
6
|
+
from fastapi import FastAPI, HTTPException
|
|
7
|
+
from fastapi.exception_handlers import http_exception_handler
|
|
8
|
+
from loguru import logger
|
|
9
|
+
|
|
10
|
+
from basic_memory import db
|
|
11
|
+
from basic_memory.api.routers import knowledge, memory, project_info, resource, search
|
|
12
|
+
from basic_memory.config import config as project_config
|
|
13
|
+
from basic_memory.config import config_manager
|
|
14
|
+
from basic_memory.sync import SyncService, WatchService
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
async def run_background_sync(sync_service: SyncService, watch_service: WatchService): # pragma: no cover
|
|
18
|
+
logger.info(f"Starting watch service to sync file changes in dir: {project_config.home}")
|
|
19
|
+
# full sync
|
|
20
|
+
await sync_service.sync(project_config.home, show_progress=False)
|
|
21
|
+
|
|
22
|
+
# watch changes
|
|
23
|
+
await watch_service.run()
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
@asynccontextmanager
|
|
27
|
+
async def lifespan(app: FastAPI): # pragma: no cover
|
|
28
|
+
"""Lifecycle manager for the FastAPI app."""
|
|
29
|
+
await db.run_migrations(project_config)
|
|
30
|
+
|
|
31
|
+
# app config
|
|
32
|
+
basic_memory_config = config_manager.load_config()
|
|
33
|
+
logger.info(f"Sync changes enabled: {basic_memory_config.sync_changes}")
|
|
34
|
+
logger.info(f"Update permalinks on move enabled: {basic_memory_config.update_permalinks_on_move}")
|
|
35
|
+
|
|
36
|
+
watch_task = None
|
|
37
|
+
if basic_memory_config.sync_changes:
|
|
38
|
+
# import after migrations have run
|
|
39
|
+
from basic_memory.cli.commands.sync import get_sync_service
|
|
40
|
+
|
|
41
|
+
sync_service = await get_sync_service()
|
|
42
|
+
watch_service = WatchService(
|
|
43
|
+
sync_service=sync_service,
|
|
44
|
+
file_service=sync_service.entity_service.file_service,
|
|
45
|
+
config=project_config,
|
|
46
|
+
)
|
|
47
|
+
watch_task = asyncio.create_task(run_background_sync(sync_service, watch_service))
|
|
48
|
+
else:
|
|
49
|
+
logger.info("Sync changes disabled. Skipping watch service.")
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
# proceed with startup
|
|
53
|
+
yield
|
|
54
|
+
|
|
55
|
+
logger.info("Shutting down Basic Memory API")
|
|
56
|
+
if watch_task:
|
|
57
|
+
watch_task.cancel()
|
|
58
|
+
|
|
59
|
+
await db.shutdown_db()
|
|
60
|
+
|
|
61
|
+
|
|
62
|
+
# Initialize FastAPI app
|
|
63
|
+
app = FastAPI(
|
|
64
|
+
title="Basic Memory API",
|
|
65
|
+
description="Knowledge graph API for basic-memory",
|
|
66
|
+
version="0.1.0",
|
|
67
|
+
lifespan=lifespan,
|
|
68
|
+
)
|
|
69
|
+
|
|
70
|
+
|
|
71
|
+
# Include routers
|
|
72
|
+
app.include_router(knowledge.router)
|
|
73
|
+
app.include_router(search.router)
|
|
74
|
+
app.include_router(memory.router)
|
|
75
|
+
app.include_router(resource.router)
|
|
76
|
+
app.include_router(project_info.router)
|
|
77
|
+
|
|
78
|
+
|
|
79
|
+
@app.exception_handler(Exception)
|
|
80
|
+
async def exception_handler(request, exc): # pragma: no cover
|
|
81
|
+
logger.exception(
|
|
82
|
+
"API unhandled exception",
|
|
83
|
+
url=str(request.url),
|
|
84
|
+
method=request.method,
|
|
85
|
+
client=request.client.host if request.client else None,
|
|
86
|
+
path=request.url.path,
|
|
87
|
+
error_type=type(exc).__name__,
|
|
88
|
+
error=str(exc),
|
|
89
|
+
)
|
|
90
|
+
return await http_exception_handler(request, HTTPException(status_code=500, detail=str(exc)))
|
|
@@ -1,11 +1,7 @@
|
|
|
1
|
-
import asyncio
|
|
2
1
|
from typing import Optional
|
|
3
2
|
|
|
4
3
|
import typer
|
|
5
4
|
|
|
6
|
-
from basic_memory import db
|
|
7
|
-
from basic_memory.config import config
|
|
8
|
-
|
|
9
5
|
|
|
10
6
|
def version_callback(value: bool) -> None:
|
|
11
7
|
"""Show version and exit."""
|
|
@@ -58,9 +54,6 @@ def app_callback(
|
|
|
58
54
|
config = new_config
|
|
59
55
|
|
|
60
56
|
|
|
61
|
-
# Run database migrations
|
|
62
|
-
asyncio.run(db.run_migrations(config))
|
|
63
|
-
|
|
64
57
|
# Register sub-command groups
|
|
65
58
|
import_app = typer.Typer(help="Import data from various sources")
|
|
66
59
|
app.add_typer(import_app, name="import")
|
|
@@ -4,7 +4,7 @@ from loguru import logger
|
|
|
4
4
|
|
|
5
5
|
import basic_memory
|
|
6
6
|
from basic_memory.cli.app import app
|
|
7
|
-
from basic_memory.config import config
|
|
7
|
+
from basic_memory.config import config, config_manager
|
|
8
8
|
|
|
9
9
|
# Import mcp instance
|
|
10
10
|
from basic_memory.mcp.server import mcp as mcp_server # pragma: no cover
|
|
@@ -19,8 +19,15 @@ def mcp(): # pragma: no cover
|
|
|
19
19
|
home_dir = config.home
|
|
20
20
|
project_name = config.project
|
|
21
21
|
|
|
22
|
+
# app config
|
|
23
|
+
basic_memory_config = config_manager.load_config()
|
|
24
|
+
|
|
22
25
|
logger.info(f"Starting Basic Memory MCP server {basic_memory.__version__}")
|
|
23
26
|
logger.info(f"Project: {project_name}")
|
|
24
27
|
logger.info(f"Project directory: {home_dir}")
|
|
28
|
+
logger.info(f"Sync changes enabled: {basic_memory_config.sync_changes}")
|
|
29
|
+
logger.info(
|
|
30
|
+
f"Update permalinks on move enabled: {basic_memory_config.update_permalinks_on_move}"
|
|
31
|
+
)
|
|
25
32
|
|
|
26
33
|
mcp_server.run()
|
|
@@ -2,31 +2,29 @@
|
|
|
2
2
|
|
|
3
3
|
import asyncio
|
|
4
4
|
import sys
|
|
5
|
-
from typing import
|
|
5
|
+
from typing import Annotated, List, Optional
|
|
6
6
|
|
|
7
7
|
import typer
|
|
8
8
|
from loguru import logger
|
|
9
9
|
from rich import print as rprint
|
|
10
10
|
|
|
11
11
|
from basic_memory.cli.app import app
|
|
12
|
-
from basic_memory.mcp.tools import build_context as mcp_build_context
|
|
13
|
-
from basic_memory.mcp.tools import read_note as mcp_read_note
|
|
14
|
-
from basic_memory.mcp.tools import recent_activity as mcp_recent_activity
|
|
15
|
-
from basic_memory.mcp.tools import search_notes as mcp_search
|
|
16
|
-
from basic_memory.mcp.tools import write_note as mcp_write_note
|
|
17
12
|
|
|
18
13
|
# Import prompts
|
|
19
14
|
from basic_memory.mcp.prompts.continue_conversation import (
|
|
20
15
|
continue_conversation as mcp_continue_conversation,
|
|
21
16
|
)
|
|
22
|
-
|
|
23
17
|
from basic_memory.mcp.prompts.recent_activity import (
|
|
24
18
|
recent_activity_prompt as recent_activity_prompt,
|
|
25
19
|
)
|
|
26
|
-
|
|
20
|
+
from basic_memory.mcp.tools import build_context as mcp_build_context
|
|
21
|
+
from basic_memory.mcp.tools import read_note as mcp_read_note
|
|
22
|
+
from basic_memory.mcp.tools import recent_activity as mcp_recent_activity
|
|
23
|
+
from basic_memory.mcp.tools import search_notes as mcp_search
|
|
24
|
+
from basic_memory.mcp.tools import write_note as mcp_write_note
|
|
27
25
|
from basic_memory.schemas.base import TimeFrame
|
|
28
26
|
from basic_memory.schemas.memory import MemoryUrl
|
|
29
|
-
from basic_memory.schemas.search import
|
|
27
|
+
from basic_memory.schemas.search import SearchItemType
|
|
30
28
|
|
|
31
29
|
tool_app = typer.Typer()
|
|
32
30
|
app.add_typer(tool_app, name="tool", help="Access to MCP tools via CLI")
|
|
@@ -198,13 +196,28 @@ def search_notes(
|
|
|
198
196
|
raise typer.Abort()
|
|
199
197
|
|
|
200
198
|
try:
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
199
|
+
if permalink and title: # pragma: no cover
|
|
200
|
+
typer.echo(
|
|
201
|
+
"Use either --permalink or --title, not both. Exiting.",
|
|
202
|
+
err=True,
|
|
203
|
+
)
|
|
204
|
+
raise typer.Exit(1)
|
|
205
|
+
|
|
206
|
+
# set search type
|
|
207
|
+
search_type = ("permalink" if permalink else None,)
|
|
208
|
+
search_type = ("permalink_match" if permalink and "*" in query else None,)
|
|
209
|
+
search_type = ("title" if title else None,)
|
|
210
|
+
search_type = "text" if search_type is None else search_type
|
|
211
|
+
|
|
212
|
+
results = asyncio.run(
|
|
213
|
+
mcp_search(
|
|
214
|
+
query,
|
|
215
|
+
search_type=search_type,
|
|
216
|
+
page=page,
|
|
217
|
+
after_date=after_date,
|
|
218
|
+
page_size=page_size,
|
|
219
|
+
)
|
|
206
220
|
)
|
|
207
|
-
results = asyncio.run(mcp_search(query=search_query, page=page, page_size=page_size))
|
|
208
221
|
# Use json module for more controlled serialization
|
|
209
222
|
import json
|
|
210
223
|
|
|
@@ -1,21 +1,26 @@
|
|
|
1
1
|
"""Main CLI entry point for basic-memory.""" # pragma: no cover
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
import asyncio
|
|
4
|
+
|
|
4
5
|
import typer
|
|
5
6
|
|
|
7
|
+
from basic_memory.cli.app import app # pragma: no cover
|
|
8
|
+
|
|
6
9
|
# Register commands
|
|
7
10
|
from basic_memory.cli.commands import ( # noqa: F401 # pragma: no cover
|
|
8
|
-
status,
|
|
9
|
-
sync,
|
|
10
11
|
db,
|
|
11
|
-
|
|
12
|
-
mcp,
|
|
12
|
+
import_chatgpt,
|
|
13
13
|
import_claude_conversations,
|
|
14
14
|
import_claude_projects,
|
|
15
|
-
|
|
16
|
-
|
|
15
|
+
import_memory_json,
|
|
16
|
+
mcp,
|
|
17
17
|
project,
|
|
18
|
+
status,
|
|
19
|
+
sync,
|
|
20
|
+
tool,
|
|
18
21
|
)
|
|
22
|
+
from basic_memory.config import config
|
|
23
|
+
from basic_memory.db import run_migrations as db_run_migrations
|
|
19
24
|
|
|
20
25
|
|
|
21
26
|
# Version command
|
|
@@ -55,4 +60,8 @@ def main(
|
|
|
55
60
|
|
|
56
61
|
|
|
57
62
|
if __name__ == "__main__": # pragma: no cover
|
|
63
|
+
# Run database migrations
|
|
64
|
+
asyncio.run(db_run_migrations(config))
|
|
65
|
+
|
|
66
|
+
# start the app
|
|
58
67
|
app()
|
|
@@ -38,7 +38,11 @@ class ProjectConfig(BaseSettings):
|
|
|
38
38
|
default=500, description="Milliseconds to wait after changes before syncing", gt=0
|
|
39
39
|
)
|
|
40
40
|
|
|
41
|
-
|
|
41
|
+
# update permalinks on move
|
|
42
|
+
update_permalinks_on_move: bool = Field(
|
|
43
|
+
default=False,
|
|
44
|
+
description="Whether to update permalinks when files are moved or renamed. default (False)",
|
|
45
|
+
)
|
|
42
46
|
|
|
43
47
|
model_config = SettingsConfigDict(
|
|
44
48
|
env_prefix="BASIC_MEMORY_",
|
|
@@ -77,6 +81,18 @@ class BasicMemoryConfig(BaseSettings):
|
|
|
77
81
|
description="Name of the default project to use",
|
|
78
82
|
)
|
|
79
83
|
|
|
84
|
+
log_level: str = "INFO"
|
|
85
|
+
|
|
86
|
+
update_permalinks_on_move: bool = Field(
|
|
87
|
+
default=False,
|
|
88
|
+
description="Whether to update permalinks when files are moved or renamed. default (False)",
|
|
89
|
+
)
|
|
90
|
+
|
|
91
|
+
sync_changes: bool = Field(
|
|
92
|
+
default=True,
|
|
93
|
+
description="Whether to sync changes in real time. default (True)",
|
|
94
|
+
)
|
|
95
|
+
|
|
80
96
|
model_config = SettingsConfigDict(
|
|
81
97
|
env_prefix="BASIC_MEMORY_",
|
|
82
98
|
extra="ignore",
|
|
@@ -194,9 +210,14 @@ def get_project_config(project_name: Optional[str] = None) -> ProjectConfig:
|
|
|
194
210
|
"BASIC_MEMORY_PROJECT", project_name or config_manager.default_project
|
|
195
211
|
)
|
|
196
212
|
|
|
213
|
+
update_permalinks_on_move = config_manager.load_config().update_permalinks_on_move
|
|
197
214
|
try:
|
|
198
215
|
project_path = config_manager.get_project_path(actual_project_name)
|
|
199
|
-
return ProjectConfig(
|
|
216
|
+
return ProjectConfig(
|
|
217
|
+
home=project_path,
|
|
218
|
+
project=actual_project_name,
|
|
219
|
+
update_permalinks_on_move=update_permalinks_on_move,
|
|
220
|
+
)
|
|
200
221
|
except ValueError: # pragma: no cover
|
|
201
222
|
logger.warning(f"Project '{actual_project_name}' not found, using default")
|
|
202
223
|
project_path = config_manager.get_project_path(config_manager.default_project)
|
|
@@ -225,8 +246,10 @@ def get_process_name(): # pragma: no cover
|
|
|
225
246
|
return "sync"
|
|
226
247
|
elif "mcp" in sys.argv:
|
|
227
248
|
return "mcp"
|
|
228
|
-
|
|
249
|
+
elif "cli" in sys.argv:
|
|
229
250
|
return "cli"
|
|
251
|
+
else:
|
|
252
|
+
return "api"
|
|
230
253
|
|
|
231
254
|
|
|
232
255
|
process_name = get_process_name()
|
|
@@ -234,6 +257,7 @@ process_name = get_process_name()
|
|
|
234
257
|
# Global flag to track if logging has been set up
|
|
235
258
|
_LOGGING_SETUP = False
|
|
236
259
|
|
|
260
|
+
|
|
237
261
|
def setup_basic_memory_logging(): # pragma: no cover
|
|
238
262
|
"""Set up logging for basic-memory, ensuring it only happens once."""
|
|
239
263
|
global _LOGGING_SETUP
|
|
@@ -245,7 +269,7 @@ def setup_basic_memory_logging(): # pragma: no cover
|
|
|
245
269
|
setup_logging(
|
|
246
270
|
env=config.env,
|
|
247
271
|
home_dir=user_home, # Use user home for logs
|
|
248
|
-
log_level=
|
|
272
|
+
log_level=config_manager.load_config().log_level,
|
|
249
273
|
log_file=f"{DATA_DIR_NAME}/basic-memory-{process_name}.log",
|
|
250
274
|
console=False,
|
|
251
275
|
)
|
|
@@ -146,7 +146,9 @@ async def engine_session_factory(
|
|
|
146
146
|
_session_maker = None
|
|
147
147
|
|
|
148
148
|
|
|
149
|
-
async def run_migrations(
|
|
149
|
+
async def run_migrations(
|
|
150
|
+
app_config: ProjectConfig, database_type=DatabaseType.FILESYSTEM
|
|
151
|
+
): # pragma: no cover
|
|
150
152
|
"""Run any pending alembic migrations."""
|
|
151
153
|
logger.info("Running database migrations...")
|
|
152
154
|
try:
|
|
@@ -104,6 +104,9 @@ def has_frontmatter(content: str) -> bool:
|
|
|
104
104
|
Returns:
|
|
105
105
|
True if content has valid frontmatter markers (---), False otherwise
|
|
106
106
|
"""
|
|
107
|
+
if not content:
|
|
108
|
+
return False
|
|
109
|
+
|
|
107
110
|
content = content.strip()
|
|
108
111
|
if not content.startswith("---"):
|
|
109
112
|
return False
|
|
@@ -92,27 +92,36 @@ class EntityParser:
|
|
|
92
92
|
async def parse_file(self, path: Path | str) -> EntityMarkdown:
|
|
93
93
|
"""Parse markdown file into EntityMarkdown."""
|
|
94
94
|
|
|
95
|
-
|
|
95
|
+
# TODO move to api endpoint to check if absolute path was requested
|
|
96
|
+
# Check if the path is already absolute
|
|
97
|
+
if (
|
|
98
|
+
isinstance(path, Path)
|
|
99
|
+
and path.is_absolute()
|
|
100
|
+
or (isinstance(path, str) and Path(path).is_absolute())
|
|
101
|
+
):
|
|
102
|
+
absolute_path = Path(path)
|
|
103
|
+
else:
|
|
104
|
+
absolute_path = self.base_path / path
|
|
105
|
+
|
|
96
106
|
# Parse frontmatter and content using python-frontmatter
|
|
97
|
-
|
|
107
|
+
file_content = absolute_path.read_text()
|
|
108
|
+
return await self.parse_file_content(absolute_path, file_content)
|
|
98
109
|
|
|
110
|
+
async def parse_file_content(self, absolute_path, file_content):
|
|
111
|
+
post = frontmatter.loads(file_content)
|
|
99
112
|
# Extract file stat info
|
|
100
113
|
file_stats = absolute_path.stat()
|
|
101
|
-
|
|
102
114
|
metadata = post.metadata
|
|
103
|
-
metadata["title"] = post.metadata.get("title", absolute_path.
|
|
115
|
+
metadata["title"] = post.metadata.get("title", absolute_path.stem)
|
|
104
116
|
metadata["type"] = post.metadata.get("type", "note")
|
|
105
117
|
tags = parse_tags(post.metadata.get("tags", [])) # pyright: ignore
|
|
106
118
|
if tags:
|
|
107
119
|
metadata["tags"] = tags
|
|
108
|
-
|
|
109
120
|
# frontmatter
|
|
110
121
|
entity_frontmatter = EntityFrontmatter(
|
|
111
122
|
metadata=post.metadata,
|
|
112
123
|
)
|
|
113
|
-
|
|
114
124
|
entity_content = parse(post.content)
|
|
115
|
-
|
|
116
125
|
return EntityMarkdown(
|
|
117
126
|
frontmatter=entity_frontmatter,
|
|
118
127
|
content=post.content,
|