- Add type annotations to all FastAPI endpoints in api/app.py
- Fix bare list/dict generics in sync.py and app.py
- Fix no-any-return in vault_client.py and sync.py
- Remove mypy || true from GitHub Actions CI — mypy is now clean
- Add type annotations to all _sqlite_* private methods
- Type sqlite_conn as sqlite3.Connection | None with assert narrowing
- Fix _api_request return type (dict[str, Any])
- Add return type to _init_sqlite
- Fix tool_name type in handle_tools_call
- Import sqlite3 at module level
- GHA ci.yml: add build + deploy jobs (push to DockerHub, trigger Woodpecker)
- Drop test matrix to single Python 3.12, preserve mypy step
- Build/deploy gated on push to main (PRs still run tests only)
- Woodpecker: deploy.yml (manual event, kubectl set image + slack notify)
- Old pipeline preserved as build-fallback.yml (manual trigger)
The delete endpoint intentionally returns 200 (not 404) when a memory
is already deleted, to prevent retry loops in old clients. Tests were
asserting 404 incorrectly.
- Blend BM25/ts_rank relevance with importance instead of sorting by one
dimension only. Default mode: 40% relevance + 60% importance. Relevance
mode: 70% relevance + 30% importance.
- Try AND-match first for precise results, fall back to OR-match when too
few results are found. Prevents single-word matches from flooding results.
- Applied to both SQLite (local) and PostgreSQL (API) search paths.
- Add MAX_MEMORY_CHARS=800 Pydantic validation on MemoryStore.content
- Update auto-learn judge prompts: "ONE topic per event", 100-500 chars,
include the WHY not just the WHAT
- Split 9 mega-memories (800-2400ch) into 70 focused memories (100-500ch)
via migration script
Before: median 331ch, 11 memories >800ch, recall wastes 84% of returned tokens
After: median 213ch, 2 memories >800ch (dense single-topic refs), recall returns
only the relevant knowledge
Trade-off research: PostgreSQL ts_rank gives the same score regardless of
document size, so a 2400-char memory with 12 topics gets recalled for any
of its 12 topics but wastes context with the other 11. Focused memories
(100-500ch) give higher signal-to-noise per recall.
Old sync clients without 404 handling get stuck in infinite retry
loops when trying to delete an already-deleted memory. Making the
endpoint idempotent (returning success regardless) fixes this for
all existing clients without requiring client upgrades.
Three fixes for high 4xx alert rate:
1. Catch urllib.error.HTTPError (not just RuntimeError) for 404 on
DELETE in pending_ops — was causing infinite retry loop for
already-deleted memories
2. try_sync_delete: treat 404 as success instead of enqueuing
a retry that will also 404 forever
3. URL-encode the `since` query param to prevent `+` in timezone
offset being decoded to a space (the asyncpg-string-timestamp
pattern applied to the sync client)
- claude CLI: run from /tmp to avoid internet-mode-used marker prompts
- ollama: try small local models (qwen2.5:3b, llama3.2:3b, etc.)
- heuristic: pattern matching for corrections, preferences, decisions
- better JSON extraction: handles markdown fences and surrounding text
- Deep extraction every 5 turns: reads last 5 exchanges for debugging
insights, workarounds, architectural patterns, and operational knowledge
- Single-turn extraction on every other turn (cheap, corrections/prefs only)
- State tracking per session: turn counter, content hashes for dedup
- Writes to both memory API/SQLite AND auto-memory markdown files
- Expanded judge prompt: now catches debugging (error→cause→fix),
workarounds, and operational knowledge — not just corrections/facts
- Auto-cleanup of state files older than 24 hours
The '+' in '+00:00' timezone offsets gets URL-decoded to a space,
causing datetime.fromisoformat() to fail with ValueError. Replace
spaces back to '+' before parsing.
Lead with value prop and install command, add conversation example,
restructure around features/hooks/auto-behaviors, consolidate env
vars and API reference into clean tables, move API server docs below
plugin setup since it's optional.
Consolidates plugin components (hooks, commands, skills, MCP config)
into this repo so it can be installed with:
claude plugins install github:ViktorBarzin/claude-memory-mcp
- .claude-plugin/plugin.json: manifest with all hook events
- mcp/memory-mcp.json: MCP server config using existing src/
- hooks/: compaction survival, auto-recall, auto-learn, auto-approve
- commands/: /remember and /recall slash commands
- skills/: memory-management skill
- Bump MCP server to v2.0.0 with metaclaw migration fallback
- Update README with quick install and plugin hooks docs
- Add SyncEngine for background sync between local SQLite cache and
remote API with pending_ops queue for offline resilience
- Refactor MCP server to support three modes: SQLite-only, hybrid
(local cache + sync, new default), and HTTP-only (legacy)
- Add GET /api/memories/sync endpoint for incremental sync
- Change DELETE to soft delete (set deleted_at) for sync support
- Add deleted_at IS NULL filters to all read queries
- Scale API deployment to 2 replicas with pod anti-affinity, PDB,
and startup probe for high availability
- Add migration 003 for deleted_at column and updated_at index
- Add comprehensive tests for sync engine and API sync endpoint
- API recall and list endpoints now return {"memories": [...]} matching
the format expected by the MCP server
- Rewrote README with comprehensive setup instructions for new agents,
accurate API reference, migration docs, and multi-user setup guide
Replace inline migration logic with proper Alembic migrations:
- 001: Initial schema (creates memories table with FTS)
- 002: Add multi-user and secrets columns (user_id, is_sensitive,
vault_path, encrypted_content)
Migrations run automatically on app startup. Existing databases
are handled gracefully with IF NOT EXISTS / column existence checks.