Add new configure_rclone_remote() that uses single remote name:
- Single remote: "basic-memory-cloud" (not tenant-specific)
- Simplifies from per-tenant remotes to one credential set per user
- Maintains backup_rclone_config() for safety
- Add comprehensive functional tests for rclone config
- Test remote configuration, updates, save/load operations
Old add_tenant_to_rclone_config() kept for backward compatibility
but will be removed in Phase 5.
Part of SPEC-20 Simplified Project-Scoped Rclone Sync.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Signed-off-by: phernandez <paul@basicmachines.co>
Add CloudProjectConfig model and cloud_projects dict to BasicMemoryConfig:
- CloudProjectConfig tracks local_path, last_sync, bisync_initialized
- cloud_projects: dict[str, CloudProjectConfig] in config
- Fix datetime serialization with mode='json' in model_dump()
- Add comprehensive tests for cloud_projects functionality
- Backward compatible: old configs without cloud_projects load correctly
This enables project-scoped sync configuration tracked in config file
rather than filesystem discovery, preventing phantom projects.
Part of SPEC-20 Simplified Project-Scoped Rclone Sync.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Signed-off-by: phernandez <paul@basicmachines.co>
Added a section announcing the launch of Basic Memory Cloud with details on cross-device support and early supporter pricing.
Signed-off-by: Paul Hernandez <60959+phernandez@users.noreply.github.com>
- Moved config evaluation from module load time to runtime
- Unified add_project command to handle both cloud and local modes
- Commands (default, sync-config, move) now check cloud_mode at runtime
- Fixes test failures where monkeypatch wasn't applied before command registration
The /proxy/projects/projects POST endpoint returns a ProjectStatusResponse
with fields: message, status, default, old_project, new_project.
Updated CloudProjectCreateResponse schema to match this format instead of
expecting name, path, message fields.
Also updated all related tests to use the correct response format:
- tests/cli/test_cloud_utils.py (3 tests)
- tests/cli/test_bisync_commands.py (1 test)
Fixes the validation error when creating cloud projects via upload command:
"bm cloud upload --project test --create-project specs"
Signed-off-by: Pablo Hernandez <pablo@basicmachines.co>
Signed-off-by: phernandez <paul@basicmachines.co>
Reduces JSON payload size by 50-70% for directory-heavy responses by omitting
null fields from serialization.
Changes:
- Added response_model_exclude_none=True to all directory endpoints:
- GET /directory/tree
- GET /directory/structure
- GET /directory/list
Impact:
- Directory nodes no longer serialize 7 null fields (title, permalink,
entity_id, entity_type, content_type, updated_at, file_path)
- For 50+ directories: eliminates 350+ null fields from response
- Payload reduction: ~2.3kb → ~1kb for typical directory trees
- File nodes still include all metadata when present
Example directory node output:
{
"name": "Tools",
"directory_path": "/Tools",
"type": "directory",
"children": []
}
Testing:
- All 29 directory tests passing
- Type checking passing (0 errors)
- Backward compatible (clients just see missing keys vs null)
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Signed-off-by: phernandez <paul@basicmachines.co>
The lifespan-based instrumentation only runs when FastAPI app starts.
In MCP context, the app never starts but the httpx client is still used.
Solution: Instrument the client immediately after creation at module level.
This works in both contexts:
- MCP: client is instrumented when module is imported
- API: client is instrumented before lifespan runs (lifespan still safe)
This enables distributed tracing from MCP -> Cloud -> API.
Signed-off-by: phernandez <paul@basicmachines.co>