119 Commits

Author SHA1 Message Date
Drew Cain b997d858cd fix(sync): also exclude orphan DB projects absent from config (#949)
Address Codex review feedback. The previous path-only filter dropped an
implicit protection: get_project_mode() defaults projects missing from
config to CLOUD, so the old mode-based guard skipped stale DB rows that
had been removed from config. With a path-only check, an orphan row with
an absolute path would pass and background sync/watch could still mutate
a directory the user already removed from config (config is the source of
truth) if reconciliation was skipped or failed.

Introduce BasicMemoryConfig.is_locally_syncable(name, path), which
requires both config membership and an absolute path, and use it from
both the background sync selection and the watch cycle so the two paths
cannot diverge. Add direct unit tests for the helper plus an orphan-row
regression test for the watch selection.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Signed-off-by: Drew Cain <groksrc@gmail.com>
2026-06-12 18:02:18 -05:00
Drew Cain 598965c389 test(sync): use OS-absolute paths in watch selection tests
The absolute-path sync guard from the previous commit now checks every
project's path, not just cloud-mode ones. Three existing watch-selection
tests hardcoded POSIX paths like "/tmp/alpha", which are absolute on
Linux/macOS but not on Windows (no drive letter), so the guard filtered
them out and the tests failed on windows-latest.

Build the project paths from the tmp_path fixture so they are absolute on
every platform. Production paths are unaffected: real local projects are
always resolved to OS-absolute paths at creation.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Signed-off-by: Drew Cain <groksrc@gmail.com>
2026-06-12 18:02:18 -05:00
Drew Cain 8dd6451dfe fix(sync): skip projects without an absolute local path (#949)
A project entry in config.json with an empty path (e.g. `{"path": ""}`)
caused background sync and the watch service to adopt the process cwd as
the project root, injecting Basic Memory frontmatter into unrelated
markdown files.

The existing guards only skipped a project when get_project_mode()
returned CLOUD. But ProjectEntry.mode defaults to LOCAL, so an empty- or
relative-path entry without an explicit mode slipped through, and
Path("") resolves against the current working directory.

Gate local sync and watching on the path itself: any project whose path
is not absolute is excluded, regardless of mode. Legitimate local
projects are always resolved to absolute paths at creation, and cloud
projects with a real local bisync copy keep their absolute path and are
still synced/watched.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Signed-off-by: Drew Cain <groksrc@gmail.com>
2026-06-12 18:02:18 -05:00
Paul Hernandez 2f7ef136de perf(ci): lean CI — testmon-select branches, shard postgres, drop depot, remove bossbot (#945)
Branch builds testmon-select against cached baselines; 3-shard Postgres on 3.14 only; free runners; 120s hang ceiling; non-code changes skip the matrix; BM Bossbot and infographic machinery removed.

Signed-off-by: phernandez <paul@basicmemory.com>
2026-06-10 14:21:57 -05:00
DoubleDeeRuffy 0c9800cd3b fix(sync): use strict deferred relation resolution 2026-06-06 21:43:09 -05:00
Paul Hernandez 4aa0cbdd62 fix(sync): ignore hidden paths relative to watched project (#815)
Signed-off-by: phernandez <paul@basicmachines.co>
2026-05-11 11:14:03 -05:00
Paul Hernandez 55f314237d fix(sync): avoid shell for scan subprocesses (#814)
Signed-off-by: phernandez <paul@basicmachines.co>
2026-05-11 09:20:11 -05:00
Paul Hernandez 2fe4488eda fix(sync): constrain watch service to --project scope (#759)
Signed-off-by: phernandez <paul@basicmachines.co>
2026-04-20 13:46:13 -05:00
Paul Hernandez 1b39062ecd refactor(core): rip telemetry wrappers, use logfire directly (#754)
Signed-off-by: phernandez <paul@basicmachines.co>
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-17 13:58:19 -05:00
Paul Hernandez c4cf0aff1e perf(sync): speed up single markdown file indexing (#751)
Signed-off-by: phernandez <paul@basicmachines.co>
2026-04-17 07:08:21 -05:00
phernandez 1c343bed66 perf(sync): skip unchanged markdown indexing
Signed-off-by: phernandez <paul@basicmachines.co>
2026-04-16 18:27:52 -05:00
phernandez c50d97e548 fix(sync): instrument single markdown indexing
Signed-off-by: phernandez <paul@basicmachines.co>
2026-04-16 18:04:17 -05:00
Drew Cain e2e65575d6 fix(core): honor BASIC_MEMORY_CONFIG_DIR across remaining call sites (#744)
Signed-off-by: Drew Cain <groksrc@gmail.com>
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-15 22:55:25 -05:00
Paul Hernandez 474100efef ci(core): reduce duplicate CI and normalize Windows assertions (#749)
Signed-off-by: phernandez <paul@basicmachines.co>
2026-04-15 22:53:33 -05:00
Paul Hernandez b3d5448355 fix(sync): preserve canonical markdown in single-file sync (#746)
Signed-off-by: phernandez <paul@basicmachines.co>
2026-04-15 20:04:28 -05:00
Paul Hernandez 052545b661 chore(core): make ty the default typechecker (#736)
Signed-off-by: phernandez <paul@basicmachines.co>
2026-04-13 10:34:01 -05:00
Paul Hernandez 7945c1e2f7 perf(core): speed up vector sync and tune fastembed defaults (#731)
Signed-off-by: phernandez <paul@basicmachines.co>
2026-04-09 00:20:12 -05:00
Paul Hernandez 540da418b3 perf(sync): batch file indexing in core (#726)
Signed-off-by: phernandez <paul@basicmachines.co>
2026-04-08 01:21:49 -05:00
Paul Hernandez 4791e19685 feat: add Logfire phased instrumentation (#692)
Signed-off-by: phernandez <paul@basicmachines.co>
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-24 20:39:42 -05:00
phernandez 0130573342 fix: prompts call MCP tools directly, sync handles semantic errors, status uses local routing
- Prompts (search, continue_conversation) now call MCP tools directly
  instead of going through API endpoints, matching the recent_activity
  pattern and fixing #526 where prompts returned empty results
- sync_file catches SemanticDependenciesMissingError separately so
  entities are still returned successfully when vector embedding fails,
  with a clear warning instead of silent failure (#578)
- `bm status` and `bm doctor` default to local routing since they scan
  the local filesystem — cloud routing returned Docker-internal paths

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Signed-off-by: phernandez <paul@basicmachines.co>
2026-02-24 19:36:11 -06:00
phernandez c372dfb09f fix: use LinkResolver fallback in build_context for flexible identifier matching (#582)
build_context now falls back to LinkResolver when an exact permalink lookup
returns empty results. This reuses the same resolution pipeline as read_note
(permalink candidates, title match, file path, FTS) so callers no longer
get empty results for valid note identifiers.

Also changes ensure_frontmatter_on_sync default to True — frontmatter is
now added during sync by default. Tests updated accordingly.

🔧 ContextService accepts optional LinkResolver, wired via DI in all 3 factory variants
 2027 unit + 278 integration tests passing

Closes #582

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Signed-off-by: phernandez <paul@basicmachines.co>
2026-02-24 18:58:19 -06:00
phernandez d763d86798 fix: unify project path so path is always the local filesystem path
Cloud projects with bisync had a split-brain problem: `path` held a cloud
slug while the actual local directory lived in `local_sync_path`. This caused
`bm status` and file sync to fail for bisync'd cloud projects.

Changes:
- Config migration promotes `local_sync_path` → `path` for entries where
  `path` is a non-absolute cloud slug
- `ensure_project_paths_exists` skips cloud-only projects with slug paths
- `initialize_file_sync` and watch service now keep cloud projects that have
  an absolute local path (bisync copy) instead of skipping all cloud projects
- `sync-setup` and `project add --cloud --local-path` set both `path` and
  `local_sync_path` to the local directory
- `sync-setup` creates the project in the local DB for immediate MCP use
- `_get_sync_project` falls back from `local_sync_path` to `path`
- Config load errors now show user-friendly messages instead of stack traces

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Signed-off-by: phernandez <paul@basicmachines.co>
2026-02-24 15:08:09 -06:00
Paul Hernandez c44291830c chore: rename entity_type to note_type (#600)
Signed-off-by: phernandez <paul@basicmachines.co>
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-22 20:28:57 -06:00
phernandez 6ff39076a0 fix: double-default display in project list + stale test updates
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>
2026-02-22 00:33:25 -06:00
phernandez a6d8d4c0f6 Add ensure_frontmatter_on_sync with precedence warning
Add a new config option to enforce frontmatter on markdown sync when missing, writing derived title/type/permalink and updating in-memory metadata before upsert. Add startup warning when this option is combined with disable_permalinks to make precedence explicit. Add config/sync/initialization tests for the new behavior, and stabilize project list CLI integration assertions by forcing a wide terminal in tests to avoid Rich truncation.

Signed-off-by: phernandez <paul@basicmachines.co>
2026-02-16 22:08:09 -06:00
Paul Hernandez 55d675e278 feat: min_similarity override, cloud promo improvements (#570)
Signed-off-by: phernandez <paul@basicmachines.co>
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-16 16:44:02 -06:00
Paul Hernandez 545804f194 feat: Add project-prefixed permalinks and memory URL routing (#544)
Signed-off-by: phernandez <paul@basicmachines.co>
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-13 17:45:50 -06:00
Paul Hernandez d84708ca7f feat: add per-project local/cloud routing with API key auth (#555)
Signed-off-by: phernandez <paul@basicmachines.co>
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-13 09:52:50 -06:00
Paul Hernandez 8df88e4d02 feat: add basic-memory watch CLI command (#559)
Signed-off-by: phernandez <paul@basicmachines.co>
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-12 20:10:09 -06:00
Paul Hernandez 530cbac73f feat: fast edit entities, refactors for webui, enhance search (#532)
Signed-off-by: phernandez <paul@basicmachines.co>
2026-01-31 15:16:52 -06:00
Paul Hernandez 8730067f3a feat: Feature/517 local mcp cloud mode (#522)
Signed-off-by: phernandez <paul@basicmachines.co>
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-26 19:51:49 -06:00
Paul Hernandez 863e0a4e24 fix: prevent CLI commands from hanging on exit (Python 3.14) (#505)
Signed-off-by: phernandez <paul@basicmachines.co>
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-11 16:47:35 -06:00
Paul Hernandez 5947f04bd3 refactor: composition roots, deps split, and typed API clients (#490 roadmap) (#502)
Signed-off-by: phernandez <paul@basicmachines.co>
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-04 11:05:58 -06:00
Paul Hernandez b4486d20bd test: remove stdlib mocks, strengthen integration coverage (#489)
Signed-off-by: phernandez <paul@basicmachines.co>
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-02 14:22:01 -06:00
Paul Hernandez 1fd680c3f1 feat: add auto-format files on save with built-in Python formatter (#474)
Signed-off-by: Cedric Hurst <cedric@spantree.net>
Signed-off-by: phernandez <paul@basicmachines.co>
Co-authored-by: Cedric Hurst <cedric@spantree.net>
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
Co-authored-by: Sebastian B Otaegui <feniix@users.noreply.github.com>
Co-authored-by: Cedric Hurst <cedric@divideby0.io>
2025-12-24 15:39:22 -06:00
phernandez 1652f862dd fix: handle FileNotFoundError gracefully during sync
When a file exists in the database but is missing from the filesystem,
the sync worker now treats this as a deletion instead of crashing.

The sync_file() method catches FileNotFoundError specifically and calls
handle_delete() to clean up the orphaned database record. This prevents
the sync from failing on database/filesystem inconsistencies that can
occur due to race conditions, manual file deletions, or cloud storage
caching issues.

Includes a test to verify the graceful handling behavior.

Fixes #386

🤖 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>
2025-12-24 13:34:59 -06:00
Paul Hernandez 897b1edaa4 fix: Reduce watch service CPU usage by increasing reload interval (#458)
Signed-off-by: claude[bot] <41898282+claude[bot]@users.noreply.github.com>
Co-authored-by: claude[bot] <41898282+claude[bot]@users.noreply.github.com>
Co-authored-by: Paul Hernandez <phernandez@users.noreply.github.com>
2025-12-17 11:37:01 -06:00
Paul Hernandez 4a43d7df4a remove logfire instrumentation
Signed-off-by: phernandez <paul@basicmachines.co>
2025-12-13 15:22:14 -06:00
phernandez 203d684c24 fix integrity error handling when setting forward relation refs
Signed-off-by: phernandez <paul@basicmachines.co>
2025-11-29 19:03:12 -06:00
Paul Hernandez fb5e9e1d77 feat: Add PostgreSQL database backend support (#439)
Signed-off-by: phernandez <paul@basicmachines.co>
Co-authored-by: Claude <noreply@anthropic.com>
2025-11-20 11:20:29 -06:00
Paul Hernandez f0d7398815 fix: Quote string values in YAML frontmatter to handle special characters (#418)
Signed-off-by: phernandez <paul@basicmachines.co>
Signed-off-by: Paul Hernandez <60959+phernandez@users.noreply.github.com>
Co-authored-by: claude[bot] <41898282+claude[bot]@users.noreply.github.com>
Co-authored-by: Paul Hernandez <phernandez@users.noreply.github.com>
2025-11-10 18:13:48 -06:00
Drew Cain 0ba6f219f1 fix: Windows CLI Unicode encoding errors (#411)
Signed-off-by: phernandez <paul@basicmachines.co>
Signed-off-by: Claude <noreply@anthropic.com>
Signed-off-by: Paul Hernandez <60959+phernandez@users.noreply.github.com>
Co-authored-by: phernandez <paul@basicmachines.co>
Co-authored-by: Claude <noreply@anthropic.com>
Co-authored-by: Paul Hernandez <60959+phernandez@users.noreply.github.com>
2025-11-02 10:20:48 -06:00
Paul Hernandez 0b3272ae6e feat: SPEC-20 Simplified Project-Scoped Rclone Sync (#405)
Signed-off-by: phernandez <paul@basicmachines.co>
Signed-off-by: Claude <noreply@anthropic.com>
Co-authored-by: Claude <noreply@anthropic.com>
2025-11-02 09:35:26 -06:00
Paul Hernandez e78345ff25 feat: Streaming Foundation & Async I/O Consolidation (SPEC-19) (#384)
Signed-off-by: phernandez <paul@basicmachines.co>
Co-authored-by: Claude <noreply@anthropic.com>
2025-10-21 09:03:59 -05:00
Paul Hernandez 449b62d947 fix: Prevent deleted projects from being recreated by background sync (#193) (#370)
Signed-off-by: Claude <noreply@anthropic.com>
Signed-off-by: phernandez <paul@basicmachines.co>
2025-10-16 15:16:24 -05:00
Paul Hernandez b7497d7484 fix: Use filesystem timestamps for entity sync instead of database operation time (#138) (#369)
Signed-off-by: Claude <noreply@anthropic.com>
Signed-off-by: phernandez <paul@basicmachines.co>
2025-10-16 14:21:27 -05:00
Paul Hernandez 171bef717f fix: Resolve UNIQUE constraint violation in entity upsert with observations (#187) (#367)
Signed-off-by: phernandez <paul@basicmachines.co>
Co-authored-by: Claude <noreply@anthropic.com>
2025-10-16 12:30:56 -05:00
Paul Hernandez 729a5a3b8d fix: Terminate sync immediately when project is deleted (#366)
Signed-off-by: phernandez <paul@basicmachines.co>
Co-authored-by: Claude <noreply@anthropic.com>
2025-10-16 11:07:12 -05:00
Paul Hernandez 434cdf24dd feat: Add circuit breaker for file sync failures (#364)
Signed-off-by: phernandez <paul@basicmachines.co>
Co-authored-by: Claude <noreply@anthropic.com>
2025-10-16 09:47:48 -05:00
Paul Hernandez 5da97e4820 feat: implement SPEC-11 API performance optimizations (#315)
Signed-off-by: phernandez <paul@basicmachines.co>
Co-authored-by: Claude <noreply@anthropic.com>
2025-09-26 14:34:46 -05:00