Adds additive, git-style `bm cloud push`/`pull` that are safe on shared Team workspaces (never delete on the destination; conflicts abort by default with `--on-conflict {fail|keep-local|keep-cloud|keep-both}`), and gates the destructive `bm cloud sync`/`bisync` mirrors to Personal workspaces. Closes#858. Longer-term Team-safe reconciler tracked in #862; workspace-scoped mount info (Codex P1) tracked as a follow-up.
L2-normalizes FastEmbed output vectors at the provider boundary so SQLite vector scoring keeps its unit-vector contract for custom FastEmbed models such as multilingual MiniLM variants.
Zero vectors are preserved as-is to avoid division errors, and the provider tests cover both non-unit vectors and zero-vector behavior.
Verification:
- uv run pytest tests/repository/test_fastembed_provider.py -q
- uv run ruff check src/basic_memory/repository/fastembed_provider.py tests/repository/test_fastembed_provider.py
- uv run ruff format --check src/basic_memory/repository/fastembed_provider.py tests/repository/test_fastembed_provider.py
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
Signed-off-by: tk-pkm111 <133480534+tk-pkm111@users.noreply.github.com>
Signed-off-by: phernandez <paul@basicmachines.co>
Adds LiteLLM as a semantic embedding provider, including provider configuration, vector normalization, live-provider evaluation tooling, and documentation for OpenAI, Cohere, Azure Foundry, Azure OpenAI, and NVIDIA NIM-style cases.
Maintainer follow-up on this PR added provider hardening, asymmetric document/query embedding support, dimension-forwarding controls, SQLite/Postgres vector invalidation coverage, and the repeatable live LiteLLM harness.
Verification:
- Full base-repo Tests workflow passed for 3d4e092ceb: https://github.com/basicmachines-co/basic-memory/actions/runs/27072071785
- Live LiteLLM harness passed locally for OpenAI, Cohere, and Azure Foundry.
Co-authored-by: Aarish Alam <arishalam121@gmail.com>
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Signed-off-by: RheagalFire <arishalam121@gmail.com>
Signed-off-by: phernandez <paul@basicmachines.co>
Review feedback on #876:
- Codex (P2): the SessionStart "Where to write" brief said all auto-capture goes to
captureFolder, but captureFolder is only the PreCompact checkpoint folder. Narrowed
it — checkpoints go to captureFolder; decisions/tasks/notes follow
placementConventions (or topic folders when none are set), so proactive captures
aren't dumped into sessions/ alongside checkpoints.
- Claude review: replaced the em dash in the skills-source-guard echo string with a
hyphen so the instruction's console output stays ASCII (CLAUDE.md compatibility).
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Signed-off-by: phernandez <paul@basicmachines.co>
- Project mapping: document local vs cloud project creation — a cloud-workspace
project needs a cloud-connected MCP server and a workspace selector; a purely
local server fails to mkdir the cloud-style path. Pin cloud primaryProject to the
external_id UUID.
- Install shared skills: guard against clobbering a source checkout — if ./skills is
git-tracked and holds memory-* dirs (the skills' own source repo), skip the npx
install instead of overwriting the working copy with published versions.
- Cloud/teams: warn that the SessionStart brief reads only the first 6 shared
projects per session, so order the most relevant first when more are configured.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Signed-off-by: phernandez <paul@basicmachines.co>
- Focus question is now load-bearing: it drives an adaptive light folder-structure
suggestion and is stored. The placement step branches learn (existing project
with notes) vs suggest (new/empty project) instead of only learning.
- Seed schema notes via the write_note `metadata` param instead of content
frontmatter. The cloud write path silently coerces nested YAML to the string
'[object Object]', corrupting schema/settings (basic-memory-cloud#1000); the
metadata param round-trips correctly on both local and cloud.
- Surface placementConventions + captureFolder in the SessionStart brief so the
output style's "follow stored placement conventions" reflex has something to
follow — previously written by setup but never shown to Claude (dead config).
- Add a post-settings smoke test (run the hook's recall query, confirm routing)
and a restart prompt gated on outputStyle in the close.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Signed-off-by: phernandez <paul@basicmachines.co>
Codex flagged (review 4397232451) that the hooks locate the CLI via
`command -v basic-memory || command -v bm`, but our own README recommends
connecting the MCP server as `claude mcp add basic-memory -- uvx basic-memory mcp`
— an ephemeral uv run that leaves NO binary on PATH. In that (recommended) setup
both hooks exited before doing anything, so the bridge silently did nothing even
though the MCP server worked.
Both hooks now resolve the CLI invocation as: prefer a `basic-memory`/`bm` binary
(fast), else fall back to `uvx basic-memory`, else `uv tool run basic-memory`, else
silent no-op. The launcher may be multi-token, so the embedded Python splits it with
shlex and prepends it to each command list. The uv cache is already warm from
running the MCP server, so the fallback is cheap.
Verified: with no binary on PATH but uvx present, SessionStart now produces a brief
(previously a silent no-op). Updated the README requirement to note uvx-only works.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Signed-off-by: phernandez <paul@basicmachines.co>