mirror of
https://github.com/basicmachines-co/basic-memory
synced 2026-06-21 13:47:35 +00:00
docs: remove working documentation files
Clean up development docs before v0.13.0 beta release 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
-210
@@ -1,210 +0,0 @@
|
||||
# App-Level Database Refactoring
|
||||
|
||||
This document outlines the plan for migrating Basic Memory from per-project SQLite databases to a single app-level database that manages all knowledge data across projects.
|
||||
|
||||
## Goals
|
||||
|
||||
- Move to a single app-level SQLite database for all knowledge data
|
||||
- Deprecate per-project databases completely
|
||||
- Add project information to entities, observations, and relations
|
||||
- Simplify project switching and management
|
||||
- Enable better multi-project support for the Pro app
|
||||
- Prepare for cloud/GoHighLevel integration
|
||||
|
||||
## Architecture Changes
|
||||
|
||||
We're moving from:
|
||||
```
|
||||
~/.basic-memory/config.json (project list)
|
||||
~/basic-memory/[project-name]/.basic-memory/memory.db (one DB per project)
|
||||
```
|
||||
|
||||
To:
|
||||
```
|
||||
~/.basic-memory/config.json (project list) <- same
|
||||
~/.basic-memory/memory.db (app-level DB with project/entity/observation/search_index tables)
|
||||
~/basic-memory/[project-name]/.basic-memory/memory.db (project DBs deprecated) <- we are removing these
|
||||
```
|
||||
|
||||
## Implementation Tasks
|
||||
|
||||
### 1. Configuration Changes
|
||||
|
||||
- [x] Update config.py to use a single app database for all projects
|
||||
- [x] Add functions to get app database path for all operations
|
||||
- [x] Keep JSON-based config.json for project listing/paths
|
||||
- [x] Update project configuration loading to use app DB for all operations
|
||||
|
||||
|
||||
### 3. Project Model Implementation
|
||||
|
||||
- [x] Create Project SQLAlchemy model in models/project.py
|
||||
- [x] Define attributes: id, name, path, config, etc.
|
||||
- [x] Add proper indexes and constraints
|
||||
- [x] Add project_id foreign key to Entity, Observation, and Relation models
|
||||
- [x] Create migration script for updating schema with project relations
|
||||
- [x] Implement app DB initialization with project table
|
||||
|
||||
### 4. Repository Layer Updates
|
||||
|
||||
- [x] Create ProjectRepository for CRUD operations on Project model
|
||||
- [x] Update base Repository class to filter queries by project_id
|
||||
- [x] Update existing repositories to use project context automatically
|
||||
- [x] Implement query scoping to specific projects
|
||||
- [x] Add functions for project context management
|
||||
|
||||
### 5. Search Functionality Updates
|
||||
|
||||
- [x] Update search_index table to include project_id
|
||||
- [x] Modify search queries to filter by project_id
|
||||
- [x] Update FTS (Full Text Search) to be project-aware
|
||||
- [x] Add appropriate indices for efficient project-scoped searches
|
||||
- [x] Update search repository for project context
|
||||
|
||||
### 6. Service Layer Updates
|
||||
|
||||
- [x] Update ProjectService to manage projects in the database
|
||||
- [x] Add methods for project creation, deletion, updating
|
||||
- [x] Modify existing services to use project context
|
||||
- [x] Update initialization service for app DB setup
|
||||
- [x] ~~Implement project switching logic~~
|
||||
|
||||
### 7. Sync Service Updates
|
||||
|
||||
- [x] Modify background sync service to handle project context
|
||||
- [x] Update file watching to support multiple project directories
|
||||
- [x] Add project context to file sync events
|
||||
- [x] Update file path resolution to respect project boundaries
|
||||
- [x] Handle file change detection with project awareness
|
||||
|
||||
### 8. API Layer Updates
|
||||
|
||||
- [x] Update API endpoints to include project context
|
||||
- [x] Create new endpoints for project management
|
||||
- [x] Modify dependency injection to include project context
|
||||
- [x] Add request/response models for project operations
|
||||
- [x] ~~Implement middleware for project context handling~~
|
||||
- [x] Update error handling to include project information
|
||||
|
||||
### 9. MCP Tools Updates
|
||||
|
||||
- [x] Update MCP tools to include project context
|
||||
- [x] Add project selection capabilities to MCP server
|
||||
- [x] Update context building to respect project boundaries
|
||||
- [x] Update file operations to handle project paths correctly
|
||||
- [x] Add project-aware helper functions for MCP tools
|
||||
|
||||
### 10. CLI Updates
|
||||
|
||||
- [x] Update CLI commands to work with app DB
|
||||
- [x] Add or update project management commands
|
||||
- [x] Implement project switching via app DB
|
||||
- [x] Ensure CLI help text reflects new project structure
|
||||
- [x] ~~Add migration commands for existing projects~~
|
||||
- [x] Update project CLI commands to use the API with direct config fallback
|
||||
- [x] Added tests for CLI project commands
|
||||
|
||||
### 11. Performance Optimizations
|
||||
|
||||
- [x] Add proper indices for efficient project filtering
|
||||
- [x] Optimize queries for multi-project scenarios
|
||||
- [x] ~~Add query caching if needed~~
|
||||
- [x] Monitor and optimize performance bottlenecks
|
||||
|
||||
### 12. Testing Updates
|
||||
|
||||
- [x] Update test fixtures to support project context
|
||||
- [x] Add multi-project testing scenarios
|
||||
- [x] Create tests for migration processes
|
||||
- [ ] Test performance with larger multi-project datasets
|
||||
|
||||
### 13 Migrations
|
||||
|
||||
- [x] project table
|
||||
- [x] search project_id index
|
||||
- [x] project import/sync - during initialization
|
||||
|
||||
## Database Schema Changes
|
||||
|
||||
### New Project Table
|
||||
```sql
|
||||
CREATE TABLE project (
|
||||
id INTEGER PRIMARY KEY,
|
||||
name TEXT NOT NULL UNIQUE,
|
||||
description TEXT,
|
||||
path TEXT NOT NULL,
|
||||
config JSON,
|
||||
is_active BOOLEAN DEFAULT TRUE,
|
||||
is_default BOOLEAN DEFAULT FALSE,
|
||||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
|
||||
);
|
||||
```
|
||||
|
||||
### Modified Entity Table
|
||||
```sql
|
||||
ALTER TABLE entity ADD COLUMN project_id INTEGER REFERENCES project(id);
|
||||
CREATE INDEX ix_entity_project_id ON entity(project_id);
|
||||
```
|
||||
|
||||
### Modified Observation Table
|
||||
```sql
|
||||
-- No direct changes needed as observations are linked to entities which have project_id
|
||||
CREATE INDEX ix_observation_entity_project_id ON observation(entity_id, project_id);
|
||||
```
|
||||
|
||||
### Modified Relation Table
|
||||
```sql
|
||||
-- No direct changes needed as relations are linked to entities which have project_id
|
||||
CREATE INDEX ix_relation_from_project_id ON relation(from_id, project_id);
|
||||
CREATE INDEX ix_relation_to_project_id ON relation(to_id, project_id);
|
||||
```
|
||||
|
||||
## Migration Path
|
||||
|
||||
For existing projects, we'll:
|
||||
1. Create the project table in the app database
|
||||
2. For each project in config.json:
|
||||
a. Register the project in the project table
|
||||
b. Import all entities, observations, and relations from the project's DB
|
||||
c. Set the project_id on all imported records
|
||||
3. Validate that all data has been migrated correctly
|
||||
4. Keep config.json but use the database as the source of truth
|
||||
|
||||
## Testing
|
||||
|
||||
- [x] Test project creation, switching, deletion
|
||||
- [x] Test knowledge operations (entity, observation, relation) with project context
|
||||
- [x] Verify existing projects can be migrated successfully
|
||||
- [x] Test multi-project operations
|
||||
- [x] Test error cases (missing project, etc.)
|
||||
- [x] Test CLI commands with multiple projects
|
||||
- [x] Test CLI error handling for API failures
|
||||
- [x] Test CLI commands use only API, no config fallback
|
||||
|
||||
## Current Status
|
||||
|
||||
The app-level database refactoring is now complete! We have successfully:
|
||||
|
||||
1. Migrated from per-project SQLite databases to a single app-level database
|
||||
2. Added project context to all layers of the application (models, repositories, services, API)
|
||||
3. Implemented bidirectional synchronization between config.json and the database
|
||||
4. Updated all API endpoints to include project context
|
||||
5. Enhanced project management capabilities in both the API and CLI
|
||||
6. Added comprehensive test coverage for project operations
|
||||
7. Modified the directory router and all other routers to respect project boundaries
|
||||
|
||||
The only remaining task is to thoroughly test performance with larger multi-project datasets, which can be done as part of regular usage monitoring.
|
||||
|
||||
## CLI API Integration
|
||||
|
||||
The CLI commands have been updated to use the API endpoints for project management operations. This includes:
|
||||
|
||||
1. The `project list` command now fetches projects from the API
|
||||
2. The `project add` command creates projects through the API
|
||||
3. The `project remove` command removes projects through the API
|
||||
4. The `project default` command sets the default project through the API
|
||||
5. Added a new `project sync` command to synchronize projects between config and database
|
||||
6. The `project current` command now shows detailed project information from the API
|
||||
|
||||
This approach ensures that project operations performed through the CLI are synchronized with the database, maintaining consistency between the configuration file and the app-level database. Failed API requests result in a proper error message instructing the user to ensure the Basic Memory server is running, rather than falling back to direct config updates. This ensures that the database remains the single source of truth for project information.
|
||||
@@ -1,42 +0,0 @@
|
||||
Looking at write_note, I can see it's a complete content replacement tool. An edit_note() tool would be really valuable for incremental changes. Here's my thinking:
|
||||
|
||||
Use Cases for edit_note():
|
||||
|
||||
- Append new sections to existing notes (most common)
|
||||
- Update specific information without rewriting everything
|
||||
- Add observations/relations to existing content
|
||||
- Fix typos or update facts
|
||||
- Prepend updates like meeting notes with timestamps
|
||||
|
||||
Proposed Design:
|
||||
|
||||
@mcp.tool()
|
||||
async def edit_note(
|
||||
identifier: str, # title, permalink, or memory:// URL
|
||||
operation: str, # "append", "prepend", "replace_section", "find_replace"
|
||||
content: str, # content to add/replace
|
||||
section: str = None, # for replace_section - header name like "## Notes"
|
||||
find_text: str = None, # for find_replace
|
||||
) -> str:
|
||||
|
||||
Operations:
|
||||
|
||||
1. append - Add content to end (most useful)
|
||||
edit_note("project-planning", "append", "\n## New Requirements\n- Feature X\n- Feature Y")
|
||||
2. prepend - Add content to beginning
|
||||
edit_note("meeting-notes", "prepend", "## 2025-05-25 Update\n- Progress on feature...")
|
||||
3. replace_section - Replace content under specific header
|
||||
edit_note("specs/api", "replace_section", "New API design...", section="## Implementation")
|
||||
4. find_replace - Simple text replacement
|
||||
edit_note("config", "find_replace", "v0.13.0", find_text="v0.12.0")
|
||||
|
||||
Implementation Flow:
|
||||
|
||||
1. Use read_note() internally to get current content
|
||||
2. Apply the specified operation
|
||||
3. Use existing PUT /knowledge/entities/{permalink} endpoint
|
||||
4. Return similar summary as write_note()
|
||||
|
||||
This would be perfect for AI assistants making targeted updates without having to regenerate entire documents. The append operation alone would handle 80% of use cases.
|
||||
|
||||
Want me to implement this? I'd start with just append and prepend for v0.13.0 to keep it simple.
|
||||
@@ -1,186 +0,0 @@
|
||||
# Frontmatter Tag Search Implementation
|
||||
|
||||
## Overview
|
||||
|
||||
This document outlines the implementation of frontmatter tag search functionality for Basic Memory. The goal is to enable users to search for entities based on their frontmatter tags, improving discoverability of content.
|
||||
|
||||
## Current State
|
||||
|
||||
### What Works
|
||||
- ✅ Tags are parsed from YAML frontmatter and stored in `entity.entity_metadata`
|
||||
- ✅ FTS5 search infrastructure is in place
|
||||
- ✅ Observation tags are already indexed and searchable
|
||||
- ✅ Search metadata structure supports additional fields
|
||||
|
||||
### What's Missing
|
||||
- ✅ Entity frontmatter tags are now included in search indexing (COMPLETED)
|
||||
- ❌ No special tag search syntax (e.g., `tag:foo`) - Future Phase 2
|
||||
|
||||
### Example Data
|
||||
Current entity metadata includes tags:
|
||||
```json
|
||||
{
|
||||
"title": "Business Strategy Index",
|
||||
"type": "note",
|
||||
"permalink": "business/business-strategy-index",
|
||||
"tags": ["business", "strategy", "planning", "organization"]
|
||||
}
|
||||
```
|
||||
|
||||
## Implementation Plan
|
||||
|
||||
### Phase 1: Basic Tag Search (v0.13.0) - LOW RISK ⭐
|
||||
|
||||
**Goal:** Make frontmatter tags searchable via regular text search
|
||||
|
||||
**Approach:** Add entity tags to `content_stems` during search indexing
|
||||
|
||||
**Benefits:**
|
||||
- Users can search for tags as regular text
|
||||
- Zero risk to existing search functionality
|
||||
- Immediate value with minimal code changes
|
||||
|
||||
**Implementation Tasks:**
|
||||
|
||||
1. **Update Search Indexing** (`search_service.py`)
|
||||
- Extract tags from `entity.entity_metadata`
|
||||
- Add tags to `content_stems` for entity indexing
|
||||
- Handle both string and list tag formats
|
||||
|
||||
2. **Add Tests**
|
||||
- Test tag extraction from entity metadata
|
||||
- Test searching for entities by tag content
|
||||
- Test both list and string tag formats
|
||||
|
||||
3. **Verify Existing Tag Data**
|
||||
- Ensure consistent tag format in metadata
|
||||
- Test with real data from existing entities
|
||||
|
||||
### Phase 2: Enhanced Tag Search (Future) - MEDIUM RISK ⭐⭐⭐
|
||||
|
||||
**Goal:** Add dedicated tag search syntax (`tag:foo`)
|
||||
|
||||
**Approach:** Extend search query parsing and repository
|
||||
|
||||
**Benefits:**
|
||||
- More precise tag-only searches
|
||||
- Better search result categorization
|
||||
- Foundation for advanced tag operations
|
||||
|
||||
**Implementation Tasks:**
|
||||
- Update search query parsing to handle `tag:` prefix
|
||||
- Add tag-specific search repository methods
|
||||
- Update search result metadata to highlight tag matches
|
||||
- Comprehensive testing of new search syntax
|
||||
|
||||
## File Changes Required (Phase 1)
|
||||
|
||||
### Primary Changes
|
||||
|
||||
1. **`src/basic_memory/services/search_service.py`**
|
||||
- Update `index_entity_markdown()` method
|
||||
- Add entity tag extraction logic
|
||||
- Include tags in content_stems
|
||||
|
||||
2. **`tests/services/test_search_service.py`**
|
||||
- Add test for entity tag indexing
|
||||
- Add test for searching entities by tags
|
||||
- Test tag format handling
|
||||
|
||||
### Supporting Changes
|
||||
|
||||
3. **`tests/mcp/test_tool_search.py`** (if exists)
|
||||
- Add integration tests for tag search via MCP tools
|
||||
|
||||
## Success Criteria
|
||||
|
||||
### Phase 1 ✅ COMPLETED
|
||||
- [x] Entity frontmatter tags are included in search index
|
||||
- [x] Users can find entities by searching tag text
|
||||
- [x] All existing search functionality continues to work
|
||||
- [x] Test coverage for new functionality
|
||||
- [x] Works with both list and string tag formats
|
||||
|
||||
### Phase 2 (Future)
|
||||
- [ ] `tag:foo` syntax returns only entities with that tag
|
||||
- [ ] Multiple tag search (`tag:foo tag:bar`)
|
||||
- [ ] Tag autocomplete/suggestions
|
||||
- [ ] Search result metadata shows matched tags
|
||||
|
||||
## Risk Assessment
|
||||
|
||||
### Phase 1 Risks: ⭐ VERY LOW
|
||||
- **Code Impact:** ~20 lines in search service
|
||||
- **Search Logic:** No changes to core search functionality
|
||||
- **Backward Compatibility:** 100% - only adds to existing search content
|
||||
- **Testing:** Straightforward unit tests required
|
||||
|
||||
### Phase 2 Risks: ⭐⭐⭐ MEDIUM
|
||||
- **Code Impact:** Query parsing, repository methods, API changes
|
||||
- **Search Logic:** New search syntax parsing required
|
||||
- **Backward Compatibility:** Must maintain existing search behavior
|
||||
- **Testing:** Complex query parsing and edge case testing
|
||||
|
||||
## Implementation Notes
|
||||
|
||||
### Tag Format Handling
|
||||
Entity metadata contains tags in different formats:
|
||||
```python
|
||||
# List format (preferred)
|
||||
"tags": ["business", "strategy", "planning"]
|
||||
|
||||
# String format (legacy)
|
||||
"tags": "['documentation', 'tools', 'best-practices']"
|
||||
|
||||
# Empty
|
||||
"tags": "[]"
|
||||
```
|
||||
|
||||
The implementation must handle all formats gracefully.
|
||||
|
||||
### Search Content Inclusion
|
||||
Tags will be added to `content_stems` which already includes:
|
||||
- Entity title variants
|
||||
- Entity content
|
||||
- Permalink variants
|
||||
- File path variants
|
||||
|
||||
Adding tags to this stream maintains consistency with existing search behavior.
|
||||
|
||||
## Implementation Details (Phase 1 COMPLETED)
|
||||
|
||||
### Changes Made
|
||||
|
||||
1. **`src/basic_memory/services/search_service.py`** ✅
|
||||
- Added `_extract_entity_tags()` helper method to handle multiple tag formats
|
||||
- Modified `index_entity_markdown()` to include entity tags in `content_stems`
|
||||
- Added proper error handling for malformed tag data
|
||||
|
||||
2. **`tests/services/test_search_service.py`** ✅
|
||||
- Added 8 comprehensive tests covering all tag formats and edge cases
|
||||
- Tests verify tag extraction, search indexing, and search functionality
|
||||
- Includes tests for both list and string tag formats
|
||||
|
||||
### Key Implementation Features
|
||||
|
||||
- **Robust Tag Parsing:** Handles list format, string format, and edge cases
|
||||
- **Safe Evaluation:** Uses `ast.literal_eval()` for parsing string representations
|
||||
- **Backward Compatible:** Zero impact on existing search functionality
|
||||
- **Comprehensive Testing:** Full test coverage for all scenarios
|
||||
|
||||
### Tag Format Support
|
||||
```python
|
||||
# All these formats are now properly handled:
|
||||
"tags": ["business", "strategy"] # List format
|
||||
"tags": "['documentation', 'tools']" # String format
|
||||
"tags": "[]" # Empty string
|
||||
"tags": [] # Empty list
|
||||
# Missing tags key or metadata - gracefully handled
|
||||
```
|
||||
|
||||
## Next Steps (Future)
|
||||
|
||||
1. **Consider Phase 2:** Enhanced tag search syntax for future release
|
||||
2. **Monitor Usage:** Track how users search for tags
|
||||
3. **Gather Feedback:** Understand if `tag:foo` syntax would be valuable
|
||||
4. **Performance Monitoring:** Ensure tag indexing doesn't impact performance
|
||||
@@ -1,89 +0,0 @@
|
||||
# v0.13.0 Release Issues
|
||||
|
||||
This document tracks the issues identified for the v0.13.0 release, organized by priority.
|
||||
|
||||
## High Priority Bug Fixes
|
||||
|
||||
These issues address core functionality problems and should be resolved first:
|
||||
|
||||
### ~~#118: [BUG] Non-standard tag markup in YAML frontmatter~~ ✅ COMPLETED
|
||||
- **Impact**: Data quality issue affecting tag formatting
|
||||
- **Description**: Tags are improperly formatted with `#` prefix and incorrect YAML indentation
|
||||
- **Expected**: `tags:\n - basicmemory`
|
||||
- **Actual**: `tags:\n- '#basicmemory'`
|
||||
- **Complexity**: Low - straightforward formatting fix
|
||||
- **User Impact**: High - affects all tag usage
|
||||
- **Resolution**: Fixed in write_note.py by removing `#` prefix from tag formatting
|
||||
|
||||
### ~~#110: [BUG] `--project` flag ignored in some commands~~ ✅ COMPLETED
|
||||
- **Impact**: Breaks multi-project functionality added in v0.12.3
|
||||
- **Description**: Commands like `project info` and `sync` don't respect `--project` flag
|
||||
- **Root Cause**: Inconsistent project parameter handling across CLI commands
|
||||
- **Complexity**: Medium - requires CLI argument parsing review
|
||||
- **User Impact**: High - breaks core multi-project workflow
|
||||
- **Resolution**: Fixed CLI app callback to update global config when --project specified
|
||||
|
||||
### ~~#107: [BUG] Fails to update note ("already exists")~~ ✅ ALREADY RESOLVED
|
||||
- **Impact**: Prevents updating existing notes via write_note tool
|
||||
- **Description**: `write_note` errors when target file exists, breaking daily note workflows
|
||||
- **Root Cause**: EntityParser couldn't handle absolute paths correctly
|
||||
- **Complexity**: Medium - requires write_note behavior enhancement
|
||||
- **User Impact**: High - breaks core knowledge management workflow
|
||||
- **Resolution**: Fixed in commit 9bff1f7 - EntityParser now handles absolute paths correctly
|
||||
|
||||
## Medium Priority Enhancements
|
||||
|
||||
These features would improve user experience and can be added if time permits:
|
||||
|
||||
### ~~#52: Search frontmatter tags~~ ✅ COMPLETED
|
||||
- **Impact**: Enhances search capabilities
|
||||
- **Description**: Include YAML frontmatter tags in search index
|
||||
- **Implementation**: Index tags in search metadata, possibly add "tag:" search prefix
|
||||
- **Complexity**: Medium - requires search index modification
|
||||
- **User Impact**: Medium - improves discoverability
|
||||
- **Resolution**: Implemented Phase 1 - frontmatter tags now included in FTS5 search index
|
||||
|
||||
### ~~#93: Reliable write_note Behavior for Populating Link Placeholders~~ ✅ COMPLETED
|
||||
- **Impact**: Improves WikiLink workflow
|
||||
- **Description**: Handle system-generated placeholder files gracefully in write_note
|
||||
- **Features Needed**:
|
||||
- Detect and populate placeholder files
|
||||
- Respect user-specified permalinks in frontmatter
|
||||
- Consistent file conflict handling
|
||||
- **Complexity**: High - requires significant write_note refactoring
|
||||
- **User Impact**: Medium-High - smooths linking workflow
|
||||
- **Resolution**: Fixed entity_service.py to parse frontmatter before permalink resolution. Both new and existing notes now respect custom permalinks specified in frontmatter.
|
||||
|
||||
## Lower Priority Issues
|
||||
|
||||
These issues are tracked but not planned for v0.13.0:
|
||||
|
||||
### External/Third-party
|
||||
- **#116**: MseeP.ai badge PR (external contribution)
|
||||
|
||||
### Diagnostic/Investigation Needed
|
||||
- **#99**: Timeout logs on Windows
|
||||
- **#108**: Claude connection interruptions
|
||||
- **#111**: Highlight app MCP errors
|
||||
- **#97**: Notes become inaccessible on Windows 11
|
||||
- **#96**: LLM not generating proper knowledge graph format
|
||||
|
||||
## Implementation Strategy
|
||||
|
||||
1. **Start with High Priority bugs** - these fix broken functionality
|
||||
2. **Add Medium Priority enhancements** if time allows
|
||||
3. **Investigate Lower Priority issues** for future releases
|
||||
|
||||
## Success Criteria for v0.13.0
|
||||
|
||||
- [x] YAML tag formatting follows standard specification
|
||||
- [x] `--project` flag works consistently across all commands
|
||||
- [x] `write_note` can update existing notes reliably
|
||||
- [x] Custom permalinks in frontmatter are respected by write_note
|
||||
- [x] Frontmatter tags are included in search index
|
||||
- [x] Comprehensive test coverage for all fixes
|
||||
- [ ] Documentation updates for any behavior changes
|
||||
|
||||
## Notes
|
||||
|
||||
This release focuses on stability and core functionality fixes rather than major new features. The goal is to ensure the multi-project system introduced in v0.12.3 works reliably and that basic knowledge management workflows are robust.
|
||||
@@ -1,168 +0,0 @@
|
||||
# move_note() Implementation Plan
|
||||
|
||||
## Overview
|
||||
Implement `move_note()` MCP tool to move notes to new locations while maintaining database consistency and search indexing. Follows the established MCP → API → Service architecture pattern.
|
||||
|
||||
## Architecture
|
||||
|
||||
```
|
||||
MCP Tool → API Route → Service Logic
|
||||
move_note() → POST /knowledge/move → entity_service.move_entity()
|
||||
```
|
||||
|
||||
## Implementation Tasks
|
||||
|
||||
### Phase 1: Service Layer
|
||||
- [ ] Add `move_entity()` method to `EntityService`
|
||||
- [ ] Handle file path resolution and validation
|
||||
- [ ] Implement physical file move with rollback on failure
|
||||
- [ ] Update database (file_path, permalink if configured, checksum)
|
||||
- [ ] Update search index
|
||||
- [ ] Add comprehensive error handling
|
||||
|
||||
### Phase 2: API Layer
|
||||
- [ ] Create `MoveEntityRequest` schema in `schemas/`
|
||||
- [ ] Add `POST /knowledge/move` route to `knowledge_router.py`
|
||||
- [ ] Handle project parameter and validation
|
||||
- [ ] Return formatted success/error messages
|
||||
|
||||
### Phase 3: MCP Tool
|
||||
- [ ] Create `move_note.py` in `mcp/tools/`
|
||||
- [ ] Implement tool with project parameter support
|
||||
- [ ] Add to tool registry in `mcp/server.py`
|
||||
- [ ] Follow existing tool patterns for httpx client usage
|
||||
|
||||
### Phase 4: Testing
|
||||
- [ ] Unit tests for `EntityService.move_entity()`
|
||||
- [ ] API route tests in `test_knowledge_router.py`
|
||||
- [ ] MCP tool integration tests
|
||||
- [ ] Error case testing (rollback scenarios)
|
||||
- [ ] Cross-project move testing
|
||||
|
||||
## Detailed Implementation
|
||||
|
||||
### Service Method Signature
|
||||
```python
|
||||
# src/basic_memory/services/entity_service.py
|
||||
async def move_entity(
|
||||
self,
|
||||
identifier: str, # title, permalink, or memory:// URL
|
||||
destination_path: str, # new path relative to project root
|
||||
project_config: ProjectConfig
|
||||
) -> str:
|
||||
"""Move entity to new location with database consistency."""
|
||||
```
|
||||
|
||||
### API Schema
|
||||
```python
|
||||
# src/basic_memory/schemas/memory.py
|
||||
class MoveEntityRequest(BaseModel):
|
||||
identifier: str
|
||||
destination_path: str
|
||||
project: str
|
||||
```
|
||||
|
||||
### MCP Tool Signature
|
||||
```python
|
||||
# src/basic_memory/mcp/tools/move_note.py
|
||||
@tool
|
||||
async def move_note(
|
||||
identifier: str,
|
||||
destination_path: str,
|
||||
project: Optional[str] = None
|
||||
) -> str:
|
||||
"""Move a note to a new location, updating database and maintaining links."""
|
||||
```
|
||||
|
||||
## Service Implementation Logic
|
||||
|
||||
### 1. Entity Resolution
|
||||
- Use existing `link_resolver` to find entity by identifier
|
||||
- Validate entity exists and get current file_path
|
||||
- Get current project config for file operations
|
||||
|
||||
### 2. Path Validation
|
||||
- Validate destination_path format
|
||||
- Ensure destination directory can be created
|
||||
- Check destination doesn't already exist
|
||||
- Verify source file exists on filesystem
|
||||
|
||||
### 3. File Operations
|
||||
- Create destination directory if needed
|
||||
- Move physical file with `Path.rename()`
|
||||
- Implement rollback on subsequent failures
|
||||
|
||||
### 4. Database Updates
|
||||
- Update entity file_path
|
||||
- Generate new permalink if `update_permalinks_on_move` is True
|
||||
- Update frontmatter with new permalink if changed
|
||||
- Recalculate and update checksum
|
||||
- Use existing repository methods
|
||||
|
||||
### 5. Search Re-indexing
|
||||
- Call `search_service.index_entity()` with updated entity
|
||||
- Existing search cleanup should be handled automatically
|
||||
|
||||
## Error Handling
|
||||
|
||||
### Validation Errors
|
||||
- Entity not found by identifier
|
||||
- Source file doesn't exist on filesystem
|
||||
- Destination already exists
|
||||
- Invalid destination path format
|
||||
|
||||
### Operation Errors
|
||||
- File system permission errors
|
||||
- Database update failures
|
||||
- Search index update failures
|
||||
|
||||
### Rollback Strategy
|
||||
- On database failure: restore original file location
|
||||
- On search failure: log error but don't rollback (search can be rebuilt)
|
||||
- Clear error messages for each failure type
|
||||
|
||||
## Return Messages
|
||||
|
||||
### Success
|
||||
```
|
||||
✅ Note moved successfully
|
||||
|
||||
📁 **old/path.md** → **new/path.md**
|
||||
🔗 Permalink updated: old-permalink → new-permalink
|
||||
📊 Database and search index updated
|
||||
|
||||
<!-- Project: project-name -->
|
||||
```
|
||||
|
||||
### Failure
|
||||
```
|
||||
❌ Move failed: [specific error message]
|
||||
|
||||
<!-- Project: project-name -->
|
||||
```
|
||||
|
||||
## Testing Strategy
|
||||
|
||||
### Unit Tests
|
||||
- `test_entity_service.py` - Add move_entity tests
|
||||
- Path validation edge cases
|
||||
- Permalink generation scenarios
|
||||
- Error handling and rollback
|
||||
|
||||
### Integration Tests
|
||||
- `test_knowledge_router.py` - API endpoint tests
|
||||
- `test_tool_move_note.py` - MCP tool tests
|
||||
- Cross-project move scenarios
|
||||
- Full workflow from MCP to filesystem
|
||||
|
||||
### Edge Cases
|
||||
- Moving to same location (no-op)
|
||||
- Moving across project boundaries
|
||||
- Moving files with complex wikilink references
|
||||
- Concurrent move operations
|
||||
|
||||
## Future Enhancements (Not v0.13.0)
|
||||
- Update wikilinks in other files that reference moved note
|
||||
- Batch move operations
|
||||
- Move with automatic link fixing
|
||||
- Integration with git for move tracking
|
||||
@@ -1,311 +0,0 @@
|
||||
Current vs. Desired State
|
||||
|
||||
Current: Project context is fixed at startup → Restart required to switch
|
||||
Desired: Fluid project switching during conversation → "Switch to my work-notes project"
|
||||
|
||||
## UX Scenarios to Consider
|
||||
|
||||
### Scenario 1: Project Discovery & Switching
|
||||
|
||||
User: "What projects do I have?"
|
||||
Assistant: [calls list_projects()]
|
||||
• personal-notes (active)
|
||||
• work-project
|
||||
• code-snippets
|
||||
|
||||
User: "Switch to work-project"
|
||||
Assistant: [calls switch_project("work-project")]
|
||||
✓ Switched to work-project
|
||||
|
||||
User: "What did I work on yesterday?"
|
||||
Assistant: [calls recent_activity() in work-project context]
|
||||
|
||||
### Scenario 2: Cross-Project Operations
|
||||
|
||||
User: "Create a note about this meeting in my personal-notes project"
|
||||
Assistant: [calls write_note(..., project="personal-notes")]
|
||||
|
||||
User: "Now search for 'API design' across all my projects"
|
||||
Assistant: [calls search_across_projects("API design")]
|
||||
|
||||
### Scenario 3: Context Awareness
|
||||
|
||||
User: "Edit my todo list"
|
||||
Assistant: [calls read_note("todo-list")]
|
||||
📍 Note from work-project: "Todo List"
|
||||
• Finish API documentation
|
||||
• Review pull requests
|
||||
|
||||
## Design Options
|
||||
|
||||
### Option A: Session-Based Context
|
||||
|
||||
# New MCP tools for project management
|
||||
switch_project("work-project") # Sets session context
|
||||
list_projects() # Shows available projects
|
||||
get_current_project() # Shows active project
|
||||
|
||||
# Existing tools use session context
|
||||
edit_note("my-note", "append", "content") # Uses work-project
|
||||
|
||||
### Option B: Explicit Project Parameters
|
||||
|
||||
# Add optional project param to all tools
|
||||
edit_note("my-note", "append", "content", project="personal-notes")
|
||||
search_notes("query", project="work-project")
|
||||
|
||||
# If no project specified, use session default
|
||||
edit_note("my-note", "append", "content") # Uses current context
|
||||
|
||||
### Option C: Hybrid (Most Flexible)
|
||||
|
||||
# Set default context
|
||||
switch_project("work-project")
|
||||
|
||||
# Use context by default
|
||||
edit_note("my-note", "append", "content")
|
||||
|
||||
# Override when needed
|
||||
search_notes("query", project="personal-notes")
|
||||
|
||||
Technical Implementation Ideas
|
||||
|
||||
Session State Management
|
||||
|
||||
# Simple in-memory session store
|
||||
SESSION_STORE = {
|
||||
"session_123": {
|
||||
"current_project": "work-project",
|
||||
"default_project": "personal-notes"
|
||||
}
|
||||
}
|
||||
|
||||
## New MCP Tools
|
||||
|
||||
@tool
|
||||
async def list_projects() -> str:
|
||||
"""List all available projects."""
|
||||
|
||||
@tool
|
||||
async def switch_project(project_name: str) -> str:
|
||||
"""Switch to a different project context."""
|
||||
|
||||
@tool
|
||||
async def get_current_project() -> str:
|
||||
"""Show the currently active project."""
|
||||
|
||||
@tool
|
||||
async def search_across_projects(query: str) -> str:
|
||||
"""Search across all projects."""
|
||||
|
||||
@tool
|
||||
async def set_default_project(project-name: str) -> str:
|
||||
"""Set default project. Requires restart"""
|
||||
|
||||
## Enhanced Existing Tools
|
||||
|
||||
@tool
|
||||
async def edit_note(
|
||||
identifier: str,
|
||||
operation: str,
|
||||
content: str,
|
||||
project: Optional[str] = None # New optional parameter
|
||||
) -> str:
|
||||
# If project not specified, use session context
|
||||
project_id = project or get_session_project()
|
||||
|
||||
## UX Questions to Consider
|
||||
|
||||
1. Context Visibility: Should every tool response show which project it's operating on?
|
||||
|
||||
- we could add a footer or something to the tool result that the LLM could understand is just metadata, not to display to the user
|
||||
|
||||
2. Error Handling: What happens when you reference a non-existent project?
|
||||
|
||||
- we would need to validate the project as an input and show an error
|
||||
|
||||
3. Default Behavior: Should there be a "global search" that works across all projects?
|
||||
|
||||
- i'm thinking this is a "not now" thing
|
||||
|
||||
4. State Persistence: Should project context persist across MCP reconnections?
|
||||
|
||||
- I think we always startup with the "default" project. If the user wants to change it, they can update the config, or call the new tool.
|
||||
|
||||
5. Conversation Flow: How do we make project switching feel natural in conversation?
|
||||
|
||||
What's your vision for the ideal user experience? Should it feel more like:
|
||||
- A file system: "cd into work-project, then edit my notes"
|
||||
- A workspace switcher: "Switch to work mode" vs "Switch to personal mode"
|
||||
- Context tags: "In work-project, show me recent activity"
|
||||
|
||||
Something like "lets switch to project X", LLM responds "ok we are working in project X, and shows project summary"
|
||||
|
||||
# Implementation Plan - Client-Side Project Management
|
||||
|
||||
## Overview
|
||||
Implement ad-hoc project switching as an MCP-only feature. No API changes needed - just session state management on the MCP side with enhanced tools.
|
||||
|
||||
## Core Components
|
||||
|
||||
### 1. Session State Management
|
||||
```python
|
||||
# src/basic_memory/mcp/project_session.py
|
||||
class ProjectSession:
|
||||
"""Simple in-memory project context for MCP session."""
|
||||
_current_project: Optional[str] = None
|
||||
_default_project: Optional[str] = None
|
||||
|
||||
@classmethod
|
||||
def initialize(cls, default_project: str):
|
||||
"""Set the default project from config on startup."""
|
||||
cls._default_project = default_project
|
||||
cls._current_project = default_project
|
||||
|
||||
@classmethod
|
||||
def get_current_project(cls) -> str:
|
||||
return cls._current_project or cls._default_project or "main"
|
||||
|
||||
@classmethod
|
||||
def set_current_project(cls, project_name: str):
|
||||
cls._current_project = project_name
|
||||
|
||||
@classmethod
|
||||
def get_default_project(cls) -> str:
|
||||
return cls._default_project or "main"
|
||||
```
|
||||
|
||||
### 2. New MCP Tools
|
||||
File: `src/basic_memory/mcp/tools/project_management.py`
|
||||
|
||||
```python
|
||||
@tool
|
||||
async def list_projects() -> str:
|
||||
"""List all available projects with their status."""
|
||||
|
||||
@tool
|
||||
async def switch_project(project_name: str) -> str:
|
||||
"""Switch to a different project context. Shows project summary after switching."""
|
||||
|
||||
@tool
|
||||
async def get_current_project() -> str:
|
||||
"""Show the currently active project and basic stats."""
|
||||
|
||||
@tool
|
||||
async def set_default_project(project_name: str) -> str:
|
||||
"""Set default project in config. Requires restart to take effect."""
|
||||
```
|
||||
|
||||
### 3. Enhanced Existing Tools
|
||||
Add optional `project` parameter to all existing tools:
|
||||
- `edit_note(..., project: Optional[str] = None)`
|
||||
- `write_note(..., project: Optional[str] = None)`
|
||||
- `read_note(..., project: Optional[str] = None)`
|
||||
- `search_notes(..., project: Optional[str] = None)`
|
||||
- `recent_activity(..., project: Optional[str] = None)`
|
||||
|
||||
### 4. Tool Response Metadata
|
||||
Add project context footer to all tool responses:
|
||||
```python
|
||||
def add_project_metadata(result: str, project_name: str) -> str:
|
||||
"""Add project context as metadata footer."""
|
||||
return f"{result}\n\n<!-- Project: {project_name} -->"
|
||||
```
|
||||
|
||||
## Implementation Tasks
|
||||
|
||||
### Phase 1: Core Infrastructure ✅
|
||||
- [x] Create `ProjectSession` class
|
||||
- [x] Create `project_management.py` tools file
|
||||
- [x] Initialize session state in MCP server startup
|
||||
- [x] Add project validation utilities
|
||||
|
||||
### Phase 2: New Tools Implementation ✅
|
||||
- [x] Implement `list_projects()`
|
||||
- [x] Implement `switch_project()`
|
||||
- [x] Implement `get_current_project()`
|
||||
- [x] Implement `set_default_project()`
|
||||
|
||||
### Phase 3: Enhance Existing Tools ✅
|
||||
- [x] Add `project` parameter to all existing tools
|
||||
- [x] Update tools to use session context when project not specified
|
||||
- [x] Add project metadata to tool responses
|
||||
- [x] Update tool documentation
|
||||
|
||||
### Phase 4: Testing & Polish ✅
|
||||
- [x] Add comprehensive tests for project management tools
|
||||
- [x] Test cross-project operations
|
||||
- [x] Test error handling for invalid projects
|
||||
- [x] Update documentation and examples
|
||||
- [x] All tests passing (146/146 MCP, 16/16 CLI)
|
||||
- [x] 100% test coverage achieved
|
||||
|
||||
### Phase 5: v0.13.0 Additional Features
|
||||
- [x] Implement `edit_note()` MCP tool (append/prepend operations)
|
||||
- [ ] Add `move_note()` functionality
|
||||
- [ ] Implement agent mode capabilities
|
||||
- [ ] Update release notes
|
||||
|
||||
### Later
|
||||
- [ ] Add prompt agent functionality
|
||||
|
||||
## Expected UX Flow
|
||||
|
||||
```
|
||||
User: "What projects do I have?"
|
||||
Assistant: [calls list_projects()]
|
||||
|
||||
Available projects:
|
||||
• main (current, default)
|
||||
• work-notes
|
||||
• personal-journal
|
||||
• code-snippets
|
||||
|
||||
---
|
||||
|
||||
User: "Switch to work-notes"
|
||||
Assistant: [calls switch_project("work-notes")]
|
||||
|
||||
✓ Switched to work-notes project
|
||||
|
||||
Project Summary:
|
||||
• 47 notes
|
||||
• Last updated: 2 hours ago
|
||||
• Recent activity: 3 notes modified today
|
||||
|
||||
---
|
||||
|
||||
User: "What did I work on yesterday?"
|
||||
Assistant: [calls recent_activity() - uses work-notes context]
|
||||
|
||||
Recent activity in work-notes:
|
||||
• Updated "API Design Notes"
|
||||
• Created "Meeting with Team Lead"
|
||||
• Modified "Project Timeline"
|
||||
|
||||
---
|
||||
|
||||
User: "Edit my todo list"
|
||||
Assistant: [calls edit_note("todo-list", ...) - uses work-notes context]
|
||||
|
||||
Edited note (append) in work-notes:
|
||||
• file_path: Todo List.md
|
||||
• Added 2 lines to end of note
|
||||
```
|
||||
|
||||
## Technical Details
|
||||
|
||||
### Error Handling
|
||||
- Validate project names against available projects
|
||||
- Show helpful error messages for non-existent projects
|
||||
- Graceful fallback to default project on errors
|
||||
|
||||
### Context Visibility
|
||||
- Add `<!-- Project: project-name -->` footer to all tool responses
|
||||
- LLM can use this metadata but doesn't need to show to user
|
||||
- Clear indication in tool responses which project is active
|
||||
|
||||
### State Management
|
||||
- Session state resets to default project on MCP restart
|
||||
- No persistence across reconnections (keeps it simple)
|
||||
- Config changes require restart (matches current behavior)
|
||||
Reference in New Issue
Block a user