The previous backfill trigger relied on Alembic revision tracking, but
alembic_version only stores the head revision — intermediate revisions
(like the backfill trigger) are invisible after a multi-step upgrade or
fresh DB creation.
Three changes fix this:
1. Replace Alembic revision check with a simple "entities exist but
embeddings are empty" check that works regardless of migration path
2. Generate embeddings during sync — after FTS indexing, batch-embed all
synced entities at the end of the sync operation
3. Add background backfill at MCP startup for the upgrade path (entities
already exist, no embeddings) without blocking server readiness
Also adds clear startup logging for semantic embedding status so issues
are easy to spot in the logs.
📋 Covers: fresh DB, upgrade from pre-embedding version, db reset,
interrupted backfill
Signed-off-by: Pedro Hernandez <pedro@basicmachines.co>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Signed-off-by: phernandez <paul@basicmachines.co>
In Postgres test mode, stale dependency_overrides on the module-level
FastAPI app allow _resolve_default_project_from_api() to query a live
database and return 'test-project' even when the test sets
default_project=None. Monkeypatch the async fallback in the three
affected tests to isolate config-based resolution from API leakage.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Signed-off-by: phernandez <paul@basicmachines.co>
Add #634 (stale schema metadata) to bug fixes section.
Apply ruff formatting to schema.py, write_note.py, test files.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Signed-off-by: phernandez <paul@basicmachines.co>
Use config.default_project as single source of truth for the Default
column in `bm project list`, removing checks against local DB and cloud
API is_default fields that could independently mark multiple projects.
Also updates tests that were out of date after get_project_mode changed
to default unknown projects to CLOUD:
- test_get_client_local_project_uses_asgi_transport: register "main" as LOCAL
- test_run_filters_cloud_projects_each_cycle: register local project in config
- test_new_project_addition_scenario: register projects as LOCAL in config
- test_get_project_mode_defaults_to_cloud: assert new CLOUD default
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Signed-off-by: phernandez <paul@basicmachines.co>
Refactor CLI commands to use typed ProjectClient instead of raw HTTP calls,
and add workspace metadata to cloud project listings so users can distinguish
personal vs organization projects.
Key changes:
- 🔧 CLI commands now use ProjectClient typed API clients instead of
call_get/call_post with manual URL construction
- 🏢 Cloud project listings include workspace_name, workspace_type, and
workspace_tenant_id for each cloud-sourced project
- Pass config.default_workspace when fetching cloud projects via
_fetch_cloud_projects() and CLI list_projects
- Add --workspace flag to `bm project list` for explicit workspace override
- Add "Workspace" column to CLI project list table
- Add `bm tool list-projects` and `bm tool list-workspaces` JSON commands
- Comprehensive tests for workspace passthrough, merge behavior, and CLI routing
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Signed-off-by: phernandez <paul@basicmachines.co>
Add `allow_discovery` parameter to `resolve_project_parameter()` that
enables tools like `recent_activity` to work across all projects in
cloud mode without requiring a project parameter.
- Add `allow_discovery: bool = False` param to resolve_project_parameter
- In cloud mode with allow_discovery=True, return None instead of error
- Update recent_activity to use allow_discovery=True
- Fix circular import by deferring call_get import inside functions
- Add comprehensive tests for resolve_project_parameter
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Signed-off-by: phernandez <paul@basicmachines.co>