Release history
claude-mem releases
A Claude Code plugin that automatically captures everything Claude does during your coding sessions, compresses it with AI (using Claude's agent-sdk), and injects relevant context back into future sessions.
All releases
118 shown
- Full Postgres + BullMQ event-to-observation pipeline with idempotent enqueue, request‑id propagation, and structured audit log.
- New API surface: POST /v1/events, POST /v1/sessions/start, GET/POST generation‑job controls, MCP routes, scoped reads.
- Legacy compat shims for `/api/sessions/observations` and `/api/sessions/summarize` mapping old payloads to the new model with improved error handling.
Full changelog
Server-beta event pipeline (phases 4–13)
This release lands the full server-beta track developed on server-beta-phase-4-event-pipeline — a self-contained Postgres + BullMQ event-to-observation pipeline with API-key auth, team/project scope, audit log, three AI providers (Anthropic, OpenAI, Google), a dedicated MCP server, legacy compat adapters for existing worker clients, a Docker/Compose stack, and a generation-job retry/cancel surface.
Highlights
- Event pipeline:
agent_event→observation_generation_jobs(outbox) → BullMQ worker →observationrow. Idempotent enqueue, request-id propagation end-to-end, structured audit log. - API surface:
POST /v1/events,POST /v1/sessions/start,POST /v1/sessions/:id/end, generation-job list/retry/cancel, MCP routes, scoped reads. - Legacy compat:
/api/sessions/observationsand/api/sessions/summarizeshims map legacy worker payloads into the new event/job model without touching worker code. Both shims now wrap session lookup in their try/catch so Postgres failures return structured JSON, andresolveServerSessionsurvives TOCTOU races via 23505 catch-and-refetch. - POST /v1/sessions/start also catches 23505 on concurrent start with the same
externalSessionIdand refetches the winning row instead of returning 500. - Generation providers: Anthropic, OpenAI, and Google with per-team-project scope enforcement and error classification.
- Docker / Compose stack and
bin/server-beta-clifor local operator workflows.
Bug fixes
resolveServerSessionPostgres errors no longer escapeasyncHandler.catch(next)and return HTML 500s to legacy clients.POST /v1/sessions/startno longer returns 500 to the loser of a concurrent same-externalSessionIdrace.
Full PR thread: #2383.
Fixed crash in `onclose` handler by background tree‑kill on unexpected subprocess exit.
Full changelog
Bug fixes
MCP server
- #2371 — drop
${_R%/}parameter-expansion trim in.mcp.jsonthat tripped Claude Code's MCP validator
Environment isolation
- #2357 — block
ANTHROPIC_BASE_URLleak; use a three-branch OAuth-skip predicate - Add
CLAUDE_MEM_ENV_FILElazy resolver so tests (and multi-profile users) can redirect the env-file path without module-load-order constraints
Worker lifecycle
- Classify Claude SDK HTTP 400 as unrecoverable so the worker stops retrying a doomed request
- Stop hook crash hardened:
onclosehandler now performs background tree-kill on unexpected subprocess exit
Chroma
- #2313 — enforce a single
chroma-mcpsubprocess per worker (singleton viadisposeCurrentSubprocess()on every code path; tree-kill of orphans on dispose) - Pin
onnxruntime>=1.20andprotobuf<7to fixINVALID_PROTOBUFon macOS arm64
Build
- Polyfill
import.meta.urltopathToFileURL(__filename)in the CJS worker bundle so ESM-style code resolves correctly (CodeRabbit-driven follow-up)
Tests / review
tests/env-isolation.test.tsno longer mutates the real~/.claude-mem/.env; OAuth spy wrapped in try/finally to avoid leaks across runs- 3 new chroma-mcp regression tests for #2313 (singleton enforcement)
Misc
- Daily dependency bump per CLAUDE.md maintenance policy
Full diff: https://github.com/thedotmack/claude-mem/pull/2394
- Server Beta requires PostgreSQL and Redis when enabled.
- Node version must be ≥ 20 or Bun ≥ 1.0 for the new runtime.
- Repository license changed from AGPL‑3.0 to Apache-2.0.
- Server Beta runtime (opt-in) with Postgres-backed storage, BullMQ + Redis queue engine, new /v1 REST API surface, API‑key auth, outbox pattern, generation-job primitives
- Installer now offers Server Beta as an optional component
Full changelog
Highlights
This is the claude-mem 13 major release, landing the Server Beta runtime and the project's relicense.
Server Beta runtime (opt-in)
- Independent server-beta service with its own lifecycle (
claude-mem server start/status/stop) - Postgres-backed observation storage
- BullMQ + Redis observation queue engine (gated behind
CLAUDE_MEM_QUEUE_ENGINE=bullmq, fail-fast) - New
/v1REST API surface (events, sessions, memories, search, context, audit, jobs) - API-key auth + Better-Auth proxy
- Outbox pattern for transactional event-to-job pipelines
- Generation-job primitives (
ServerJobQueue,ActiveServerBetaQueueManager, deterministic colon-free SHA-256 job IDs) - Docker Compose + E2E harness for the new stack
Licensing
- Repository relicensed from AGPL-3.0 to Apache-2.0
NOTICEfile addeddocs/license.mdanddocs/ip-boundary.mdclarify the OSS / commercial boundaryragtime/subproject also relicensed to Apache-2.0
Installer
- Server Beta is exposed as an installer option (default off — open-source core is unaffected)
Migration notes
- Existing users on the worker-era plugin keep working — no breaking changes for the default install
- Server Beta is opt-in. Worker continues to run on its existing port and SQLite store.
- See
docs/migration-worker-to-server.mdfor forward-looking migration guidance
Compatibility
- Node ≥ 20, Bun ≥ 1.0
- Server Beta requires Postgres + Redis (only when enabled)
Full diff: https://github.com/thedotmack/claude-mem/compare/v12.7.5...v13.0.0
- Run `npm run build-and-sync` instead of `npm run build` to ensure the local marketplace and worker are synchronized during releases.
Full changelog
Patch release for npx installs that hit an existing Codex marketplace registration.
Fixes:
- If Codex already has claude-mem-local registered from a different source, the installer now removes that stale registration and re-adds the local npx marketplace instead of failing.
- Keeps Codex plugin_hooks enablement and legacy AGENTS cleanup after the marketplace registration succeeds.
- Updates the release workflow instructions to use npm run build-and-sync instead of plain npm run build so the local marketplace and worker are synced during releases.
Validation:
- npm run build-and-sync
- bun test tests/install-non-tty.test.ts tests/infrastructure/plugin-distribution.test.ts tests/servers/mcp-tool-schemas.test.ts tests/setup-runtime.test.ts tests/hook-command.test.ts
- Docker smoke with codex-cli 0.128.0 reproducing the remote-to-local marketplace source conflict and verifying install completion.
- npx --yes [email protected] --version
- Resilient MCP launcher fallbacks for local installs, Codex plugin cache installs, Claude plugin cache installs, and remote marketplace clones
- Registers Codex plugin marketplaces during install, enables plugin_hooks, and cleans up legacy AGENTS-based context injection
- Adds Codex session-start hook migration and version‑mismatch investigation plan
Full changelog
Patch release for the Codex mem-search marketplace fix.
Highlights:
- Restores Codex access to the claude-mem MCP/search plugin by pointing the Codex marketplace at the bundled plugin root.
- Adds resilient MCP launcher fallbacks for local installs, Codex plugin cache installs, Claude plugin cache installs, and remote marketplace clones.
- Registers Codex plugin marketplaces during install, enables plugin_hooks, and cleans up legacy AGENTS-based Codex context injection.
- Includes the Codex session-start hook migration and Codex version-mismatch investigation plan.
Validation:
- npm run build
- bun test tests/install-non-tty.test.ts tests/infrastructure/plugin-distribution.test.ts tests/servers/mcp-tool-schemas.test.ts tests/setup-runtime.test.ts tests/hook-command.test.ts
- Docker smoke with codex-cli 0.128.0 for local install, remote marketplace add/upgrade, and MCP initialize.
Fixed observer generator restarts on context‑overflow/quota hard stops, made Stop hook transcript failures non‑blocking, hardened MCP startup resolution, and repaired pending_messages handling.
Full changelog
Patch release for the reliability fixes merged in PR #2344.
- Stops context-overflow and quota hard-stop failures from restarting observer generators and burning subscription quota.
- Makes Stop hook transcript lookup failures non-blocking, so missing worktree transcript paths do not re-wake Claude Code in a loop.
- Hardens MCP/plugin startup path resolution when host plugin-root environment variables are absent.
- Accepts legacy install markers while keeping new marker writes on the JSON format.
- Fixes export-memories to honor isolated data dirs, validate worker ports, and send the worker route's canonical session-id field.
- Makes pending_messages repair safer and removes stale worker_pid assumptions from the current queue/schema path.
- Adds a focused PR babysit status helper for low-noise review/check monitoring.
Fixed JSON config write durability and added safety tests.
Full changelog
v12.7.2
Fixed
- Disable Claude Code built-in auto-memory during claude-code installs by setting
CLAUDE_CODE_DISABLE_AUTO_MEMORY=1in Claude settings. - Make JSON config writes crash-safe, durable, symlink-safe, and safe for dangling symlink destinations.
- Add regression coverage for atomic JSON writes through symlinked and dangling-symlink settings paths.
- "babysit" skill for monitoring PR checks, review comments, and unresolved threads
Full changelog
Added
- Package the new
babysitskill for monitoring PR checks, review comments, and unresolved review threads until a PR is merge-ready.
Verification
npm run buildnpm publishcompleted for[email protected]
- Native Codex hooks via the Codex plugin marketplace
- Payload normalization, file‑context extraction, and Stop hook observation support in Codex
- Codex installer `npx claude-mem@latest install` with CLI version guidance
Full changelog
Added
- Add native Codex hooks integration through the Codex plugin marketplace.
- Add Codex hook payload normalization, file-context extraction, and Stop hook observation support.
- Add Codex installer support for
npx claude-mem@latest installwith Codex CLI version guidance.
Fixed
- Avoid slow observation flow retries by replacing the worker-side initialization wait with hook-side readiness polling.
- Keep Codex file-context extraction from consuming boolean flags like
cat -n. - Include
bun-runner.jsin hook distribution verification.
- Installer supports subscription auth, direct Anthropic API keys, and LiteLLM/custom gateway setup with `ANTHROPIC_AUTH_TOKEN` env var
- Added `ANTHROPIC_AUTH_TOKEN` gateway environment support alongside `ANTHROPIC_BASE_URL`
Full changelog
[12.6.5] - 2026-05-05
Added
- Installer now keeps the Claude Agent SDK as the single memory-agent path while supporting subscription auth, direct Anthropic API keys, and LiteLLM/custom gateway setup.
- Added gateway env support for
ANTHROPIC_AUTH_TOKENalongsideANTHROPIC_BASE_URL.
Fixed
- Removed the fixed agent-pool slot timeout so queued memory-agent work waits for process availability instead of dropping pending messages under load.
- Reset generator failures back to pending messages instead of clearing queued work.
Fixed infinite retries for invalid observer responses and aligned all plugin manifest versions to 12.6.4.
Full changelog
Fixed
- Drain invalid/non-XML observer responses so pending agent observations are cleared instead of retrying forever (PR #2316 / issue #2315).
- Correct all plugin manifest versions so Claude, Codex, OpenClaw, bundled plugin, and npm metadata agree on 12.6.4.
Fixed hanging installs caused by tree‑sitter grammar postinstall scripts.
Full changelog
Fix: npx claude-mem@latest install no longer hangs on tree-sitter-swift
What broke in 12.6.1
PR #2300 moved 21 tree-sitter grammar packages from root devDependencies → root dependencies. As a result, npx [email protected] install started fetching all 21 grammars at npx time. tree-sitter-swift's postinstall pulled a nested tree-sitter-cli that downloads a Rust binary from GitHub and SIGINT'd the install:
npm error path .../node_modules/claude-mem/node_modules/tree-sitter-swift/node_modules/tree-sitter-cli
npm error command failed
npm error signal SIGINT
npm error Downloading https://github.com/tree-sitter/tree-sitter/releases/download/v0.23.2/tree-sitter-macos-arm64.gz
npm doesn't honor the bun-only trustedDependencies allowlist, so postinstalls always run on a bare npx fetch.
Fix (PR #2305)
Move the 21 grammar packages back to root devDependencies. The marketplace plugin install path is untouched — plugin/package.json keeps them as runtime deps and bun install (in installPluginDependencies) honors trustedDependencies: ["tree-sitter-cli"] to skip the harmful postinstalls on every other grammar. Smart-search/smart-outline/smart-unfold continue to work end-to-end.
PR #2300's --legacy-peer-deps and --omit=dev install.ts changes are kept — they fix a separate, valid marketplace ERESOLVE.
- Use `--omit=dev --legacy-peer-deps` when running `npm install` in the marketplace to avoid ERESOLVE errors with tree‑sitter peer dependencies.
Full changelog
Patch release
Fixed
- install: marketplace
npm installno longer fails on tree-sitter peer-dep ERESOLVE. Tree-sitter grammar packages moved fromdevDependenciestodependenciesand the install command updated to--omit=dev --legacy-peer-deps(#2300). - chroma-mcp: removed ONNX/OpenBLAS thread cap from spawn env to restore performance on multi-core systems.
Docs
- Documented the
--legacy-peer-depsrationale inrunNpmInstallInMarketplace.
- OAuth keychain reader (`readClaudeOAuthToken()`) accesses platform-native credential stores and validates JWT expiration at worker spawn-time
- Quota‑aware wall‑clock guard adds per‑window rate limits, grace buffer, and exposes `rateLimits` on `/api/health`
- Network retry helper `withRetry` supports exponential backoff with jitter and request‑ID capture for dedup logging
Full changelog
Highlights
17 issues fixed and 4 new foundations introduced via PR #2282 — a 24-cycle review-loop landed across 33 commits.
New capabilities
- OAuth keychain reader (#2215) —
readClaudeOAuthToken()reads from platform-native credential stores (macOS keychain, Windows DPAPI, Linux libsecret) at worker spawn-time. JWT exp / sidecarexpiresAtvalidation refuses stale tokens. Re-login hint surfaced via SessionStartadditionalContext. - Quota-aware wall-clock guard (#2234) — new
RateLimitStorewith auth-type gate:api_keynever aborts; cli/oauth aborts at per-window thresholds (5h:0.95, 7d_opus:0.93, 7d_sonnet:0.92). 15min reset-grace buffer with 0.85 utilization floor.rateLimitsexposed on/api/health. - Network retry helper (#2254) —
withRetryhonorsClassifiedProviderError.kind, exponential backoff with jitter, request-id capture for dedup logging.
Foundations (new public modules)
- F1
spawnHidden(src/shared/spawn.ts) —windowsHide: truedefault; 8 spawn sites adopted. - F2
paths(src/shared/paths.ts) — 24 hardcodedhomedir() + '.claude-mem'sites collapsed into 18 named accessors.CLAUDE_MEM_DATA_DIRflows through 100% of runtime. Self-extending invariant test. - F3
getUptimeSeconds(src/shared/uptime.ts) — fixes ms-bug atServer.ts:165. - F4
ClassifiedProviderError(src/services/worker/provider-errors.ts) —kindunion (transient | unrecoverable | rate_limit | quota_exhausted | auth_invalid); per-provider classifiers;unrecoverablePatternsallowlist deleted.
Bug fixes
- #2188 — empty stdin no longer falls back to
'{}'; diagnostic log +CAPTURE_BROKENmarker - #2196 —
ANTHROPIC_BASE_URLdocumentation added - #2220 / #2253 — chroma-mcp CPU storm (Windows + macOS): thread caps, per-batch watermarks, telemetry off,
killProcessTreeon shutdown - #2225 — opencode
_zod.defcrash: Zod schemas replace plain JSON-schema arg shapes - #2231 —
SECURITY.mdat repo root populates GitHub Security tab - #2233 — Part A:
stripCodeFences()+ fence example removed from prompt (Part B deferred) - #2236 — observer agent visible windows on Windows (consumed F1)
- #2237 / #2238 — hardcoded paths (consumed F2)
- #2240 — dedupe
observationIdsbefore Chroma sync - #2242 —
check-pending-queue.tspoints at/api/processing-status+/api/processing; honorsCLAUDE_MEM_WORKER_PORT - #2243 —
scripts/sync-marketplace.cjsrsync excludes stalescripts/package.json+scripts/node_modules - #2244 —
unrecoverablePatternsallowlist deleted; worker dispatches onerror.kind - #2247 — Codex
task_completeevent added to session-end matched types - #2248 — Cursor sessions never summarized: 3 bugs in stop→summarize path fixed (transcriptPath, type-only match, empty-text first-match) — 10-case regression test added
- #2250 — health endpoint uptime returns seconds (consumed F3)
- #2222 —
CLAUDE_CODE_PATHdesktop-app silent fail: rejectsClaude.exepaths, falls back to real CLI binary
Tests / CI
- 1454 pass / 77 fail — matches main baseline, zero net regressions
- All CI green: build, CodeRabbit (17 rounds resolved), Greptile (clean)
Out of scope (deferred)
#2213 dual-queue avalanche, #2256 unbounded transcript retention, #2217 observation chunking, #2202 codex compression provider, #2249 Codex hook lifecycle migration, #2218 installer cache cleanup, #2167 parallel-agent throughput, #2191 Kiro IDE, #2212 Windows PTY, #2166 stable/beta channels.
Full diff: d384d3c5 → a3b161f8
Fixed install failures on Node 25+ by skipping unused tree‑sitter native compilation.
Full changelog
Fixed
- Install failure on Node 25+ —
bun installno longer fails when trying to compile the unusedtree-sitterruntime against Node 25's V8 headers (which require C++20). AddedtrustedDependencies: ["tree-sitter-cli"]to the plugin manifest so bun runs only the CLI's prebuilt-binary download script and skips all other lifecycle scripts — including the failing native compile and the unused.nodebindings of all 24+ grammar packages. claude-mem only ever shells out to the prebuilttree-sitter-cliRust binary; the runtime native module was never imported. (#2278)
Internal
- Sync the OpenClaw plugin manifest version (10.4.1 → 12.5.1) so it tracks with the rest of the package going forward; the version-bump skill already lists it but past releases skipped it.
- Existing databases auto-migrate on worker startup; no user action required.
- Providers (Claude, Gemini, OpenRouter) no longer track `processingMessageIds`; session‑scoped clear handles success path.
- Removed `markFailed` method and associated per-message retry counter logic from PendingMessageStore, eliminating silent data loss after three attempts.
- Dropped columns `retry_count`, `failed_at_epoch`, `completed_at_epoch`, `worker_pid` from the `pending_messages` table in schema migrations v31‑v32.
- Reduced status enum for `pending_messages` to `'pending' | 'processing'`, removing unreachable states `'processed'` and `'failed'`.
Full changelog
Highlights
Observation pipeline cleanup — kill the per-message retry counter. The AI's parseable response is the only success signal; any other response (unparseable, empty, transport error) is a no-op. No more silent data loss after 3 retries.
What changed
- Parser: collapsed to binary
{ valid: true, observations, summary } | { valid: false }. No morekind/skippedenum dispatch in callers. - ResponseProcessor: two branches only — parseable → store + clear pending → broadcast; not parseable → reset claimed-but-unprocessed messages to pending. Removed per-message FIFO popping and the summarize-special-case best-effort confirm.
- PendingMessageStore: 226 → 165 lines. Removed
markFailed(the retry counter that silently dropped data after 3 attempts),transitionMessagesTo,confirmProcessed,clearFailedOlderThan, plus four other dead methods. - Provider cleanup: removed
processingMessageIdstracking from Claude, Gemini, OpenRouter providers. The session-scoped clear handles the success path; no per-message in-flight tracking needed. - GeneratorExitHandler: drain-in-flight loop deleted; hard-stop / restart-guard paths now just clear pending for the session.
- Schema migration v31 + v32: dropped four dead columns from
pending_messages—retry_count,failed_at_epoch,completed_at_epoch,worker_pid. Status enum reduced to'pending' | 'processing'(the unreachable'processed'and'failed'are gone).
Bug fixes / polish
SessionQueueProcessor: removed two arbitrary 1-second recovery sleeps after error inclaimNextMessage/waitForMessage; let the iterator end cleanly soGeneratorExitHandlercan restart it.Server.ts+SettingsRoutes.ts: unified four magic-numbersetTimeoutexit-flush patterns (100ms × 2, 1000ms × 2) into oneflushResponseThenhelper usingres.on('finish', ...).- PR review feedback (21+ threads): install.ts argument fixes, settings cache TTL, Dockerfile login-banner sourcing, docs port-model + Node version updates, regex whitespace fix, Date.UTC for year-mismatch test, sync-marketplace port range guard, banner inflate fail-open, version-bump arg validation.
Net diff
-181 lines (worker-service.cjs unaffected; total source lines down).
Migration
Existing databases auto-migrate on worker startup (schema v31 + v32 drop the dead columns). No user action needed.
Fixed six critical bugs affecting macOS binary drift, privacy tag handling, semantic search ordering, Windows spawn, Codex transcript ingestion deadlocks, SDK boundary isolation, and batch operations.
Full changelog
Patches in 7 critical fixes from PR #2219 (integration/critical-fixes-april):
- #2211 build/bundle drift — remove stale macOS binary + regen artifacts (closes #2158, #2200, #2154)
- #2204 strip privacy tags before summarization (closes #2149)
- #2205 preserve relevance order in semantic search (closes #2153)
- #2208 restore Windows spawn (PR #751 re-apply) + Windows CI
- #2209 Codex transcript ingestion + queue self-deadlock on Windows (closes #2192)
- #2206 isolate SDK boundary — close 6 issues at 3 call sites
- #2210 standalone batch — npm peer deps, marketplace self-heal, cache prune
Fixed timeline tool to correctly handle stringified numeric anchors in MCP and HTTP requests.
Full changelog
Bug Fixes
- timeline tool: Coerce stringified numeric anchors (e.g.
"123") into the observation-ID dispatch path so they no longer fall through to ISO-timestamp parsing and return wrong-epoch windows. The HTTP layer always sends anchor as a string, so this fixes anchor lookups via MCP and HTTP across the board. (#2176)
Tests
- Added a 7-case regression suite covering JS-number anchors, stringified-number anchors (incl. whitespace-padded), session-ID anchors (
S<n>), ISO-timestamp anchors, garbage anchors, and explicit numeric-not-found behavior. The suite runs against a real in-memory SQLiteSessionStoreto exercise the full dispatch path.
Refactors
- Extracted
parseNumericAnchorhelper inSearchManagerto centralize anchor coercion across timeline handlers.
- Strips proxy environment variables from subprocesses to prevent leaking to AI API calls
- Multi-account isolation via CLAUDE_MEM_DATA_DIR and per-UID worker ports
- CLAUDE_MEM_INTERNAL trust boundary replaces cwd-based detection
- Shared shouldEmitProjectRow predicate for SSE and pagination filter sync
Full changelog
Cynical deletion + review fixes
This release wraps up the cynical-deletion sweep (PR #2141) — closing 27 issues by removing two anti-patterns that were breeding bugs:
- Defenders (orphan cleanup, duplicate liveness probes, restart-port-steal logic) replaced with fail-fast or single-source paths.
- Tolerators (silent JSON drops, drifted SSE/SQL filters, passthrough Zod schemas) replaced with strict boundaries.
Highlights
- Multi-account isolation via
CLAUDE_MEM_DATA_DIR+ per-UID worker port (37700 + uid % 100), withCLAUDE_MEM_WORKER_PORToverride (#2101) - New
CLAUDE_MEM_INTERNAL=1trust boundary replaces cwd-based observer-session detection - Shared
shouldEmitProjectRowpredicate keeps SSE broadcast and pagination filters in sync - Pinned
chroma-mcpto 0.2.6 for reproducible installs - Install/uninstall: shared
shutdown-helperreleases file locks before overwrite/delete (#2106) - Migration 30:
observations.metadatacolumn added (#2116) - Proxy env vars stripped from spawned subprocesses to prevent user proxy config leaking into AI API calls
Review-comment fixes (post-PR)
worker-servicerestart now exits 1 with error ifspawnDaemonfails (Greptile P1)shutdown-helperdistinguishesAbortError(slow worker) from connection-refused (gone) (Greptile P2)hooks.json$HOMEcache lookup quoted to support paths with spacestimeline-reportSKILL works on Windows (noprocess.getuid()requirement)opencode-pluginvalidatesCLAUDE_MEM_WORKER_PORTbefore useuninstallonly strips alias lines, not function declarationsMemoryRoutestrims whitespace-onlyprojectbefore precedence resolution- Migration 21 preserves
metadatacolumn when rebuilding observations table
Closes
#2087, #2089, #2094, #2099, #2101, #2103, #2106, #2116, #2139, #2140, and 17 more (see PR #2141).
Fixes silent observation persistence failures in fresh installs caused by missing SessionStore migration 28 columns.
Full changelog
Bug Fixes
- Fix observation persistence on fresh installs (#2139):
SessionStorewas missing migration 28's column additions, so freshly createdpending_messagestables had notool_use_idorworker_pidcolumns. Every queue claim and observation insert failed silently with "no such column" errors and nothing reached memory. AddedaddPendingMessagesToolUseIdAndWorkerPidColumnsmirror inSessionStore.ts(matches the existingaddObservationSubagentColumns/addObservationsUniqueContentHashIndexmirror pattern). Already-broken DBs at "v29 with no v28 columns" self-heal on next worker boot via column-existence guards. Dedup DELETE + UNIQUE index creation are now wrapped in a transaction matching the v29 mirror precedent.
Thanks to @drdah123 for the precise diagnosis and reproduction in the issue report.
Fixed observation queue being drained on session end.
Full changelog
Bug fix: stop draining the observation queue on /clear
When users typed /clear in Claude Code (or logged out, exited, or hit prompt_input_exit), every still-pending observation in the worker queue was being marked abandoned and never processed. The same shim was wired across Claude Code, Gemini CLI, the transcripts processor, OpenCode plugin, and OpenClaw — five surfaces, all draining the queue on what should be benign session-end signals.
This release removes the SessionEnd → session-complete hook entirely. The worker self-completes via its SDK-agent generator's finally-block, so no external completion call is needed. Pending observations now finish processing naturally instead of being abandoned.
Explicit user-initiated session deletion (via the viewer UI's DELETE /api/sessions/:id) still drains the queue — that's the only path that should.
What changed
- Removed
SessionEndhook block fromplugin/hooks/hooks.json - Removed
POST /api/sessions/completeroute + Zod schema inSessionRoutes.ts - Deleted
src/cli/handlers/session-complete.tsand its registry entry - Removed the call from
src/services/transcripts/processor.ts - Removed the call from the OpenCode plugin's
session.deletedhandler - Removed the Gemini CLI installer's
SessionEnd → session-completemapping - Removed
scheduleSessionComplete,pendingCompletionTimers, andcompletionDelayMsfrom OpenClaw
Background
This bug had been quietly draining queues since November 7, 2025 (~6 months). The wiring crept in as a "cleanup hook stops the spinner" side effect (#4416), got rationalized as canonical architecture (#6682, #14793), and survived multiple refactors that preserved it instead of questioning it. Full timeline in PR #2136.
- Fixed storage leak and ReDoS vulnerability in protocol tag filtering
- Automatic cleanup removes observer-session pollution and stuck pending_messages chains
- Fixed context-overflow infinite retry loop with resetSessionForFreshStart helper
Full changelog
One-time pollution cleanup migration plus the v12.4.1 / v12.4.2 ship-blocker fixes folded into a single release.
Headline
One-shot DB cleanup migration (CleanupV12_4_3.ts) — runs once per data directory at worker startup, marker-file gated, opt-out via CLAUDE_MEM_SKIP_CLEANUP_V12_4_3=1. Cleans:
observer-sessionsrows that polluted user-facing search/timeline before the observer-sessions filter shipped (cascades touser_prompts,observations,session_summaries).- Stuck
pending_messageschains (≥10 rows per session infailed/processing) left over from the pre-v12.4.2 context-overflow loop. ~/.claude-mem/chroma/andchroma-sync-state.jsonsobackfillAllProjectsrebuilds vectors from the cleaned SQLite.
Backups before any delete: VACUUM INTO first, with a copyFileSync fallback that also mirrors -wal / -shm sidecars so a WAL-mode restore is complete. Pre-flight statfsSync disk check before backup. The marker is only written after SQLite purges succeed; Chroma-wipe failures record the error on the marker rather than re-running the backup on every boot.
v12.4.2 ship-blockers
- Context-overflow loop fix (
SDKAgent.ts): both overflow detection paths ('prompt is too long'/'Prompt is too long') now clearmemorySessionIdand force a fresh session via the newresetSessionForFreshStarthelper before aborting/throwing. Stops the infinite retry seen in pre-v12.4.2 logs. <task-notification>storage leak (tag-stripping.ts+session-init.ts+SessionRoutes.ts): dual-layer filter at the hook and at the worker HTTP boundary.isInternalProtocolPayloaduses a tempered greedy body with negative lookahead so adjacent and surrounded protocol tags can't span across user text. 256 KB size guard before the regex prevents ReDoS on malformed payloads.
v12.4.1 trivial fixes
mcpServers: {}onSDKAgentandKnowledgeAgentspawns prevents host MCP server inheritance.McpIntegrations.ts:.agent→.agentspath correction.hooks.json:file-contexttimeout2000→60(was 33 minutes); explicitshell: bashon hooks that use bash-only syntax.
Cleanup-migration counts (sample run)
11 sessions + 3 cascade rows + 141 pending_messages purged in 1.1s; 277 MB pre-cleanup backup written.
Tests
New: tests/infrastructure/cleanup-v12_4_3.test.ts — real on-disk SQLite under a tmpdir, exercises the happy path, idempotency, opt-out env var, no-DB marker, threshold-boundary preservation. Writing these tests caught a real counting bug (bun:sqlite result.changes inflates with FTS triggers) and the regex false positive (greedy [\s\S]* spanning two protocol blocks).
Notes
- The migration is intentionally NOT atomic across the two transactions: if
runStuckPendingPurgefails afterrunObserverSessionsPurgecommits, the observer rows stay deleted and the cleanup retries on next boot. Both purges are idempotent. - A user low on disk at first post-upgrade boot will retry on the next boot with adequate space (the marker is not written on disk-skip).
Fixed context overflow infinite loops and protocol payload pollution.
Full changelog
Two ship-blockers from yesterday's triage + 5 trivial fixes
Worker reliability
- Context overflow no longer loops forever. When the Claude SDK throws
Prompt is too long,SDKAgentnow clearssession.memorySessionIdand setssession.forceInit = truebefore throwing — so the immediately-following crash-recovery spawn starts a fresh SDK session instead of resuming the same overflowed context. In the wild this had stranded 68+ pending messages on a single poisoned session before the windowed RestartGuard finally abandoned the queue. <task-notification>payloads no longer polluteuser_prompts. Claude Code's autonomous protocol blocks (emitted on backgroundAgentcompletion) were being captured as if they were user prompts — 471 such rows in one local DB. NewisInternalProtocolPayload()predicate insrc/utils/tag-stripping.tsblocks them at both the hook layer (session-init.ts) and the worker boundary (SessionRoutes.ts). Conservative deny-list — does NOT touch<command-name>/<command-message>which wrap real user slash-commands.
Triage cleanup (from yesterday's open-issue review)
- #2092:
worker-service.cjsbuild banner now CJS-safe (noimport.meta.url);node -cpasses for the first time in several releases. - #2100: PreToolUse Read hook timeout reduced from
2000(s, plainly a typo) to60. - #2131:
"shell": "bash"added to every hook inplugin/hooks/hooks.jsonso Claude Code on Windows routes through Git Bash instead of cmd.exe. - #2132: Antigravity context file path corrected from
.agent/rulesto.agents/rules. - #2088: Worker SDK
query()calls now passmcpServers: {}to suppress inheritance of the user's global MCP servers (Serena, etc.) into observer/knowledge sessions.
Notes
- Cleanup of polluted rows is included in the worker — fresh installs are clean. To clean an existing DB:
sqlite3 ~/.claude-mem/claude-mem.db "DELETE FROM user_prompts WHERE prompt_text LIKE '<task-notification>%';"(the AFTER-DELETE trigger handles FTS). - The 5 triage fixes were authored from a multi-agent review of 38 open issues against the v12.3.0–v12.4.1 cleanup arc.
🤖 Generated with Claude Code
Eliminated redundant Chroma scans via watermark caching.
Full changelog
perf(chroma): Cache backfill watermarks to skip per-restart Chroma scans
Worker restarts were re-scanning Chroma's full metadata for every project on every boot to determine which sqlite ids were already embedded. With ~253 projects and ~92k embeddings, this pegged chroma-mcp at 100–422% CPU on each spawn.
What changed
- New
~/.claude-mem/chroma-sync-state.jsonwatermark cache — per-project highest synced sqlite_id for observations, summaries, and prompts. - Backfill SQL changed from
id NOT IN (huge list)toid > watermark. - Live
syncObservation/syncSummary/syncUserPromptbump the watermark on success. - One-time bootstrap derives initial watermarks from a single Chroma scan if the state file is missing — after that, Chroma metadata is never scanned again on startup.
- Watermark advances per batch, so partial-failure runs resume cleanly.
Result
- Chroma CPU on worker restart: 422% → 0%.
- State file size for 253 projects: ~3.7 KB.
- Backfill startup time: seconds → near-instant after bootstrap.
- Security observation types with Telegram notifier
- Stop hook fire-and-forget summarize
- Worker-port precedence and Windows support
Full changelog
Highlights
🔐 Security observation types + Telegram notifier
- New observation types:
security_alert🚨 (high-priority, triggers notifications) andsecurity_note🔐 (low-priority). - Fire-and-forget Telegram notifier — MarkdownV2 formatting, per-observation error isolation, no token logging.
- Five env vars control behavior.
CLAUDE_MEM_TELEGRAM_ENABLEDmaster toggle defaults on (no-op without bot token + chat ID).
⚡ Stop hook: fire-and-forget summarize
- Eliminated the ~110s terminal block when a session ended. Summarize handler now enqueues and returns immediately.
- Server-side
SessionCompletionHandlerfinalizes off the hook's critical path (generator + HTTP fallback), with singleton sharing across the worker.
🐛 Hooks: worker-port precedence + Windows (#2086 / PR #2084)
- Hooks now resolve endpoint with the same precedence as the worker: env (
CLAUDE_MEM_WORKER_PORT,CLAUDE_MEM_WORKER_HOST) > settings.json > defaults. - Looser sed regex handles both quoted and unquoted JSON port values.
- Windows fallback to 37777 when per-uid formula doesn't apply.
🔧 Bug fixes (reviewer rounds on PR #2084)
- Don't remove in-memory session after a failed finalize; preserve crash-recovery state at 3 sites.
- Eliminate double-broadcast of
session_completedon fallback path. - Sync
DatabaseManager.getSessionByIdreturn type. TelegramNotifiernow respectssettings.json(not just env).- Hardcoded 🚨 emoji replaced with per-type mapping.
📝 Docs
version-bumpskill now coversnpm publish+ all 6 manifest paths sonpx claude-mem@<version>always resolves. Addsgit greppre-flight for new manifests.
⚙️ Chores
- 🤖 Generated with Claude Code
Full Changelog: https://github.com/thedotmack/claude-mem/compare/v12.3.8...v12.3.9
Fixed PID reuse detection in worker start-guard enabling clean container restarts.
Full changelog
🔧 Fix
Detect PID reuse in the worker start-guard so containers can restart cleanly. (#2082)
The kill(pid, 0) liveness check false-positived when the worker's PID file outlived its PID namespace — most commonly after docker stop / docker start with a bind-mounted ~/.claude-mem. The new worker would boot as the same low PID (often 11) as the old one, kill(0) would report "alive," and the worker would refuse to start against its own prior incarnation. Symptom: container appeared to start, immediately exited cleanly with no user-visible error, worker never came up.
What changed
- Capture an opaque process-start identity token alongside the PID and verify identity, not just liveness:
- Linux:
/proc/<pid>/statfield 22 (starttime in jiffies) — cheap, no exec, same signalpgrep/systemduse. - macOS / POSIX:
ps -p <pid> -o lstart=withLC_ALL=Cpinned so the emitted timestamp is locale-independent across environments. - Windows: unchanged — falls back to liveness-only. The PID-reuse scenario doesn't affect Windows deployments the way containers do.
- Linux:
verifyPidFileOwnershipemits a DEBUG log when liveness passes but the token mismatches, so the "PID reused" case is distinguishable from "process dead" in production logs.- PID files written by older versions are token-less;
verifyPidFileOwnershipfalls back to the existing liveness-only behavior for backwards compatibility. No migration required.
Surface
Shared helpers (PidInfo, captureProcessStartToken, verifyPidFileOwnership) live in src/supervisor/process-registry.ts and are re-exported from ProcessManager.ts to preserve the existing public surface. Both entry points updated: worker-service.ts GUARD 1 and supervisor/index.ts validateWorkerPidFile.
Tests
+14 new tests covering token capture, ownership verification, backwards compatibility for tokenless PID files, and the container-restart regression scenario. Zero regressions.
- Bearer token auth removed from worker API
- platform_source query-time filter removed from context pipeline
- In-memory rate limiter (300 req/min) with IPv4 normalization and Retry-After responses
Full changelog
What's Changed
Refactor: remove bearer auth and platform_source context filter (#2081)
- Drop bearer-token auth from the worker API. Worker binds localhost-only and CORS restricts origins to localhost — the token added friction for every internal client (hooks, CLI, viewer, sync script) with no real security benefit for single-user local deployments.
- Drop the unused
platform_sourcequery-time filter from the/api/context/injectpipeline (ContextBuilder, ObservationCompiler, SearchRoutes, context handler, transcripts processor). The DB column stays — only the WHERE-clause filter and its plumbing are removed. - Replace the removed auth with a simple in-memory rate limiter (300 req/min) as a lightweight compensating control. Limiter normalises IPv4-mapped IPv6, emits
Retry-Afteron 429, and has a size-guarded prune that never runs on localhost.
Cleanup
- Deleted
src/shared/auth-token.tsand all its dependents (worker-utils.tsAuthorization header,ViewerRoutes.tstoken injection, CORSallowedHeaders: ['Authorization'],sync-marketplace.cjsadmin restart header). - Stopped tracking
.docker-blowout-data/claude-mem.dband added the directory to.gitignore.
Full Changelog
https://github.com/thedotmack/claude-mem/compare/v12.3.6...v12.3.7
Removed rate limiter causing viewer errors.
Full changelog
Viewer fix: drop the rate limiter
v12.3.5 kept the 300 req/min rate limiter from v12.3.3's "security hardening" bundle. That tripped the live viewer within seconds (it polls logs and stats) and served it "Rate limit exceeded" errors.
Fix: remove the rate limiter entirely. The worker is localhost-only (enforced via CORS), so there's no abuse surface to protect. Rate-limiting a single-user local process is security theater.
Still kept from v12.3.3 hardening
- 5 MB JSON body limit
- Path traversal protection
- Localhost-only CORS
- Everything else from v12.3.5
No upgrade action required.
- In-memory rate limiter (300 req/min/IP)
- Path traversal protection on watch.context.path
- 5 MB JSON body limit
- In-memory rate limiter (300 req/min/IP)
- Path traversal protection on watch.context.path
- Idle session eviction on pool slot allocation
Full changelog
Restored v12.3.3 fixes minus bearer auth
v12.3.3 shipped 25 bug fixes under "Issue Blowout 2026" but also introduced bearer-token auth that broke SessionStart context injection for everyone. v12.3.4 rolled everything back to v12.3.2 to unblock users.
v12.3.5 restores all 25 fixes, with the bearer-auth mechanism surgically removed.
Kept hardening from v12.3.3
- 5 MB JSON body limit
- In-memory rate limiter (300 req/min/IP)
- Path traversal protection on
watch.context.path RestartGuard(time-windowed restart counter)- Idle session eviction on pool slot allocation
- WAL checkpoint +
journal_size_limit - Periodic
clearFailed()for pending_messages - FTS5 keyword-search fallback when ChromaDB is unavailable
ResponseProcessormarks non-XML responses as failed (with retry) instead of confirming/healthreportsactiveSessions- Summarize hook wraps
workerHttpRequestin try/catch (no more blocking exit code 2) - UserPromptSubmit session-init waits for worker health on Linux/WSL
- MCP loopback self-check uses
process.execPathinstead of barenode - Nounset-safe
TTY_ARGSindocker/claude-mem/run.sh
Removed from v12.3.3
src/shared/auth-token.ts(deleted)requireAuthmiddleware and its wiring inServer.ts/Middleware.tsAuthorization: Bearerinjection inworker-utils.ts(hook client),ViewerRoutes.ts(browser token injection), viewerauthFetch, and the OpenCode plugin
Upgrade notes
~/.claude-mem/worker-auth-tokenfrom a previous 12.3.3 install is harmless and can be deleted.- If your Claude Code session kept the 12.3.3 daemon alive, restart Claude Code once so the fresh 12.3.5 daemon takes over.
Rolled back to v12.3.2 to fix SessionStart context injection regression introduced in v12.3.3.
Full changelog
Rollback of v12.3.3
v12.3.3 (Issue Blowout 2026, PR #2080) broke SessionStart context injection — new sessions received no memory context from claude-mem. This release reverts to the v12.3.2 tree state while the regression is investigated.
Reverted
- #2080 — Issue Blowout 2026 (25 bugs across worker, hooks, security, and search)
Notes
No functional changes from v12.3.2. A follow-up release will re-land the v12.3.3 fixes individually once the context regression is identified and resolved.
- Session-init hook now requires successful worker health check before execution — will not run when worker is unreachable
- Bearer token authentication required for all worker API endpoints
- JSON body limit reduced from 50MB to 5MB
- Caller headers can no longer override bearer authentication token
- Path traversal protection on context write paths
- Per-user worker port derivation (37700 + uid%100) prevents cross-user data leakage
- Time-windowed RestartGuard prevents message strand on long sessions
- Idle session eviction prevents worker pool deadlock
- FTS5 keyword fallback for search when ChromaDB is unavailable
Full changelog
Issue Blowout 2026 — 25 bugs across worker, hooks, security, and search
Security Hardening
- Bearer token authentication for all worker API endpoints with auto-generated tokens
- Path traversal protection on context write paths
- Per-user worker port derivation (37700 + uid%100) to prevent cross-user data leakage
- Rate limiting (300 req/min/IP) and reduced JSON body limit (50MB → 5MB)
- Caller headers can no longer override the bearer auth token
Worker Stability
- Time-windowed RestartGuard replaces flat counter — prevents stranding pending messages on long sessions
- Idle session eviction prevents pool slot deadlock when all slots are full
- MCP loopback self-check uses process.execPath instead of bare 'node'
- Age-scoped failed message purge (1h retention) instead of clearing all
- RestartGuard decay anchored to real successes, not object creation time
Search & Chroma
- FTS5 keyword fallback when ChromaDB is unavailable for all search handlers
- doc_type:'observation' filter on Chroma queries feeding observation hydration
- Project filtering passed to Chroma queries and SQLite hydration in all endpoints
- Bounded post-import Chroma sync with concurrency limit of 8
- FTS5 MATCH input escaped as quoted literal phrases to prevent syntax errors
- LIKE metacharacters escaped in prompt text search
- date_desc ordering respected in FTS session search
Hooks Reliability
- Summarize hook wrapped in try/catch to prevent exit code 2 on network failures
- Session-init gated on health check success — no longer runs when worker unreachable
- Health-check wait loop added to UserPromptSubmit for Linux/WSL startup race
Database & Performance
- Periodic WAL checkpoint and journal_size_limit to prevent unbounded WAL growth
- FTS5 availability cached at construction time (no DDL probe per query)
- _fts5Available downgraded when FTS table creation fails
Viewer UI
- response.ok check added to settings save and initial load flows
- Auth failure handling in saveSettings
Minor fixes and improvements.
Full changelog
Bug Fixes
- Search: Fix
concept/conceptsparameter mismatch in/api/search/by-concept(#1916) - Search: Add FTS5 keyword fallback when ChromaDB is unavailable (#1913, #2048)
- Database: Add periodic
clearFailed()to purge stale pending messages (#1957) - Database: Add WAL checkpoint schedule and
journal_size_limitto prevent unbounded growth (#1956) - Worker: Mark messages as failed (with retry) instead of confirming on non-XML responses (#1874)
- Worker: Include
activeSessionsin/healthendpoint for queue liveness monitoring (#1867) - Docker: Fix nounset-safe
TTY_ARGSexpansion inrun.sh - Search: Cache
isFts5Available()at construction time (Greptile review)
Closed Issues
#1908, #1953, #1916, #1913, #2048, #1957, #1956, #1874, #1867
- Fixed multi-turn context loss in OpenRouterAgent conversationHistory
- Fixed ChromaSync cross-type dedup collisions preventing silent result drops
- Improved error handling across 91 files with structured error boundaries and instanceof checks
Full changelog
Error Handling & Code Quality
This patch release resolves error handling anti-patterns across the entire codebase (91 files), improving resilience and correctness.
Bug Fixes
- OpenRouterAgent: Restored assistant replies to
conversationHistory— multi-turn context was lost after method extraction (#2078) - ChromaSync: Fixed cross-type dedup collision where
observation#N,session_summary#N, anduser_prompt#Ncould silently drop results - Timeline queries: Fixed logger calls wrapping Error inside an object instead of passing directly
- FTS migrations: Preserved non-Error failure details instead of silently dropping them
Error Handling Improvements
- Replaced 301 error handling anti-patterns across 91 files:
- Narrowed overly broad try-catch blocks into focused error boundaries
- Replaced unsafe
error as Errorcasts withinstanceofchecks - Added structured error logging where catches were previously empty
- Extracted large try blocks into dedicated helper methods
- Installer resilience: Moved filesystem operations (
mkdirSync) inside try/catch in Cursor, Gemini CLI, Goose MCP, and OpenClaw installers to maintain numeric return-code contracts - GeminiCliHooksInstaller: Install/uninstall paths now catch
readGeminiSettings()failures instead of throwing past the0/1return contract - OpenClawInstaller: Malformed
openclaw.jsonnow throws instead of silently returning{}and potentially wiping user config - WindsurfHooksInstaller: Added null-safe parsing of
hooks.jsonwith optional chaining - McpIntegrations: Goose YAML updater now throws when claude-mem markers exist but regex replacement fails
- EnvManager: Directory setup and existing-file reads are now wrapped in structured error logging
- WorktreeAdoption:
adoptedSqliteIdsmutation delayed until SQL update succeeds - Import script: Guard against malformed timestamps before
toISOString() - Runtime CLI: Guard
response.json()parsing with controlled error output
Documentation
- Added README for Docker claude-mem harness
- Secured extracted OAuth credentials with restrictive file permissions (chmod 600)
- Docker container with automatic OAuth extraction for ad-hoc testing
- SWE-bench evaluation harness with two-container orchestration and parallel testing
Full changelog
New features
Basic claude-mem Docker container (docker/claude-mem/)
A ready-to-run container for ad-hoc claude-mem testing with zero local setup beyond Docker.
FROM node:20; layers pinned Bun (1.3.12) + uv (0.11.7) + the built plugin- Non-root
nodeuser so--permission-mode bypassPermissionsworks headlessly build.sh,run.sh(auto-extracts OAuth from macOS Keychain or~/.claude/.credentials.json, falls back toANTHROPIC_API_KEY),entrypoint.sh- Persistent
.claude-mem/mount so the observations DB survives container exit
Validated end-to-end: PostToolUse hook → queue → worker SDK call under subscription OAuth → <observation> XML → observations table → Chroma sync.
SWE-bench evaluation harness (evals/swebench/)
Two-container split (our agent image + the upstream SWE-bench harness) for measuring claude-mem's effect on resolve rate.
Dockerfile.agent→claude-mem/swebench-agent:latest(same non-root, version-pinned approach)run-instance.sh— two-turn ingest/fix protocol per instance; shallow clone atbase_commitwith full-clone fallbackrun-batch.py— parallel orchestrator with OAuth extraction, per-container naming, timeout enforcement + force-cleanup,--overwriteguard against silent truncation of partial resultseval.sh— wrapspython -m swebench.harness.run_evaluationsummarize.py— aggregates per-instance reportssmoke-test.sh— one-instance smoke test
Fixes / hardening (from PR review)
chmod 600on extracted OAuth creds files- Grouped
{ chmod || true; }so bash precedence can't mask failedcurl|shinstalls - macOS creds: Keychain-first with file fallback for migrated / older setups
smoke-test.shTIMEOUTnow actually enforced viatimeout/gtimeoutplusdocker rm -fon exit 124- Container naming + force-cleanup in
run-batch.pytimeout handler prevents orphan containers - Fixed stdin-redirection collision in the consolidated
smoke-test.shJSON parser - Drop
execinrun.shso the EXIT trap fires and cleans the temp creds file
PR: https://github.com/thedotmack/claude-mem/pull/2076
Eliminated spurious parser warning on observation responses.
Full changelog
Fixed
- Parser: stop warning on normal observation responses (#2074). Eliminated the
PARSER Summary response contained <observation> tags instead of <summary> — prompt conditioning may need strengtheningwarning that fired on every normal observation turn. The warning was inherited from #1345 whenparseSummarywas only called after summary prompts; after #1633's refactor it runs on every response, so the observation-only fallthrough always tripped. Gated the entire observation-on-summary path oncoerceFromObservationso only genuine summary-turn coercion failures log.
Full diff: https://github.com/thedotmack/claude-mem/compare/v12.2.2...v12.2.3
- Subagent Stop hooks skip session summarization; only main assistant owns summary
- Observations table gains agent_type and agent_id columns for subagent labeling
- Defense-in-depth guard prevents direct API callers from bypassing hook-layer short-circuit
Full changelog
Subagent summary disable + labeling
Claude Code subagents (the Task tool and built-in agents like Explore/Plan/Bash) no longer trigger a session summary on Stop, and every observation row now carries the originating subagent's identity.
Features
- Subagent Stop hooks skip summarization. When a hook fires inside a subagent (identified by
agent_idon stdin), the handler short-circuits before bootstrapping the worker. Only the main assistant owns the session summary. Sessions started with--agent(which setagent_typebut notagent_id) still own their summary. - Observations are labeled by subagent. The
observationstable gains two new nullable columns —agent_typeandagent_id— populated end-to-end from the hook stdin through the pending queue into storage. Main-session rows remainNULL. Labels survive worker restarts via matching columns onpending_messages.
Safety
- Defense-in-depth guard on the worker
/api/sessions/summarizeroute so direct API callers can't bypass the hook-layer short-circuit. pickAgentFieldtype guard at the adapter edge validates the hook input: must be a non-empty string ≤128 characters, otherwise dropped.- Content-hash dedup intentionally excludes
agent_type/agent_idso the same semantic observation from a subagent and its parent merges to a single row.
Schema
- Migration 010 (version 27) adds the two columns to
observationsandpending_messages, plus indexes onobservations.agent_typeandobservations.agent_id. Idempotent, state-aware logging.
Tests
- 17 new unit tests: adapter extraction (length cap boundary, empty-string rejection, type guards), handler short-circuit behavior, DB-level labeling and dedup invariants.
PR: #2073
Fixed infinite summary-retry loop causing unbounded context growth in sessions.
Full changelog
What's Fixed
Break infinite summary-retry loop (#1633)
When the summary agent returned <observation> tags instead of <summary> tags, the parser rejected the response, no summary was stored, the session completed without a summary, and a new session was spawned with ~5–6 KB of extra prompt context — repeating indefinitely.
Three layers of defense (PR #2072):
- Parser coercion — when a summary is expected, observation fields are mapped to summary fields (title → request/completed, narrative → investigated, facts → learned) instead of discarding the response.
- Stronger prompt — summary prompts now include an explicit tag-requirement block and a closing reminder so the LLM is much less likely to emit observation tags in the first place.
- Circuit breaker — per-session counter caps consecutive summary failures at 3; further summarize requests are skipped until a success resets it. Explicit
<skip_summary/>responses are treated as neutral, not failures.
Edge cases handled:
- Empty leading
<observation>blocks fall through to the first populated one. - Empty
<summary></summary>wrappers fall back to observation coercion. - Multiple observation blocks are iterated via a global regex.
Full details: #2072
- Worktree adoption engine consolidates observations into parent project when merged
- `npx claude-mem adopt` command with --dry-run and --branch flags for manual adoption control
- Auto-adoption on worker startup for merged worktrees
Full changelog
Highlights
Worktree Adoption — When a git worktree is merged back into its parent branch, its observations are now consolidated into the parent project's view, so memory follows the code after a merge.
Features
- Worktree adoption engine — consolidates merged-worktree observations under the parent project (#2052)
npx claude-mem adopt— new CLI command with--dry-runand--branch Xflags for manual adoption- Auto-adoption on worker startup — merged worktrees are adopted automatically when the worker service starts
- CWD-based project remap — project identity derived from
pending_messages.cwd, applied on worker startup - Parent + worktree read scope — worktree sessions now include parent repo observations in their read scope
- Composite project names — parent/worktree naming prevents observations from crossing worktrees
- Merged-into-parent badge — UI now flags observations that have been adopted from a merged worktree
- Observer-sessions project hidden — internal bookkeeping project no longer appears in UI lists
Fixes
- Drop orphan flag when filtering empty-string spawn args (#2049)
- Self-heal Chroma metadata on re-run
- Schema guard, startup adoption path, and query parity hardening
- Git operation timeouts + dry-run sentinel fixes
- Context derivation uses explicit
projectsarray rather than cwd
Chores
- Removed auto-generated per-directory
CLAUDE.mdfiles across the tree
Full Changelog: https://github.com/thedotmack/claude-mem/compare/v12.1.6...v12.2.0
Fixes critical regression where observations failed to save on Claude Code 2.1.109+.
Full changelog
Fix
Critical regression fix (#2049): observations no longer save on Claude Code 2.1.109+
Resolves 100% observation/summary failure on Claude Code 2.1.109+ caused by a latent bug in how the bundled Agent SDK emits the --setting-sources flag.
Root cause
The Agent SDK emits ["--setting-sources", ""] whenever settingSources defaults to []. Our existing Bun-compat filter stripped the empty string but left an orphan --setting-sources flag, which then consumed the following --permission-mode as its value. Claude Code 2.1.109+ rejects this with:
Error processing --setting-sources:
Invalid setting source: --permission-mode.
Every observation SDK spawn crashed with exit code 1 before any data could be written.
Fix
ProcessRegistry.createPidCapturingSpawn now uses a pair-aware filter: when an empty-string arg follows a --flag, both are dropped together. The SDK default (no setting sources) is preserved by omission.
Credits
Thanks to @GigiTiti-Kai for the detailed root-cause report in #2049.
Forced update to fix critical observation failure from empty-string arg filtering
Removes synthetic summary generation that fabricated summaries with poorly-mapped fields.
- Restrict ~/.claude-mem/.env permissions to 0600 to prevent unauthorized credential access
- Session lifecycle guards to prevent runaway API spend
- Circuit breaker on OpenClaw worker client
- Login-shell PATH resolution for cross-platform compatibility
- Glob CVE fix
- MCP CallToolResult compliance
- Data integrity filtering
- 6 MCP tools: build_corpus, list_corpora, prime_corpus, query_corpus, rebuild_corpus, reprime_corpus
- 8 HTTP API endpoints on worker service
- CorpusBuilder, CorpusRenderer, KnowledgeAgent system with auto-reprime on expired sessions
- Build-time guardrails: regex check preventing require('bun:*') in bundle, 600KB size budget
- Memoized resolveWorkerRuntimePath() with recovery path for mid-session Bun install
- Prevent shell injection in summary workflow
- Sanitize observation titles in file-context deny reason
- Normalize platformSource at route boundary to prevent filter inconsistencies
- File-read decision gate blocks redundant file reads with observation timeline injection
- Smart-explore supports 24 programming languages via tree-sitter AST parsing
- Platform source isolation for Claude/Codex sessions with database migration
- CLAUDE_MEM_SEMANTIC_INJECT default changed from true to false
Full changelog
v11.0.1 — Disable Semantic Inject by Default
Patch release — Changes CLAUDE_MEM_SEMANTIC_INJECT default from true to false.
What changed
- Per-prompt Chroma vector search on
UserPromptSubmitis now opt-in rather than opt-out - Reduces latency and context noise for users who haven't explicitly enabled it
- Users can re-enable via
CLAUDE_MEM_SEMANTIC_INJECT=truein~/.claude-mem/settings.json
Why
The semantic inject fires on every prompt and often surfaces tangentially related observations. A more precise file-context approach (PreToolUse timeline gate) is in development as a replacement.
- Semantic context injection using ChromaDB relevance search on UserPromptSubmit
- Observation timeline caching survives /clear command
- Multi-machine sync support with tiered routing
Interactive IDE installer restored; --ide flag and multi-select functionality now working again.
- Installation delegates to native Claude Code plugin system
- Multi-IDE support for Gemini, Windsurf, OpenCode, OpenClaw, Codex, Copilot
- Worker shutdown improved with proper process exit handling before cleanup
- Fixed MCP server import.meta.url ESM-compat crash
- Hardened worker spawn handling for Windows
- Scoped HTTP logging to DEBUG level
Full changelog
v10.6.3 — Critical Patch Release
Bug Fixes
- Fix MCP server crash: Removed erroneous
import.meta.urlESM-compat banner from CJS files that caused Node.js startup failures - Fix 7 critical bugs affecting all non-dev-machine users and Windows:
- Hook registration paths corrected for plugin distribution
- Worker service spawn handling hardened for Windows
- Environment sanitization for cross-platform compatibility
- ProcessManager Windows spawn catch block improvements
- SessionEnd inline hook exemption in regression tests
summarize.tswarning log now includessessionIdfor triage
- CodeRabbit review feedback addressed from PR #1518
Improvements
- Gemini CLI integration: Strip ANSI color codes from timeline display, provide markdown fallback
Files Changed
plugin/hooks/hooks.jsonplugin/scripts/mcp-server.cjsplugin/scripts/worker-service.cjsscripts/build-hooks.jssrc/cli/handlers/summarize.tssrc/services/infrastructure/ProcessManager.tssrc/services/worker-service.tssrc/supervisor/env-sanitizer.tstests/infrastructure/plugin-distribution.test.tstests/supervisor/env-sanitizer.test.ts
- Scoped isAnySessionProcessing to active in-memory sessions
- Added terminateSession restart-or-terminate invariant
- Fixed idle-timeout race condition for message arrivals
Full changelog
fix: Activity spinner stuck spinning forever
The viewer UI activity spinner would spin indefinitely because isAnySessionProcessing() queried all pending/processing messages in the database globally — including orphaned messages from dead sessions that no generator would ever process. These orphans caused isProcessing=true forever.
Changes
- Scoped
isAnySessionProcessing()andhasPendingMessages()to only check sessions in the active in-memory Map, so orphaned DB messages no longer affect the spinner - Added
terminateSession()method enforcing a restart-or-terminate invariant — every generator exit must either restart or fully clean up - Fixed 3 zombie paths in the
.finally()handler that previously left sessions alive in memory with no generator running - Fixed idle-timeout race condition where fresh messages arriving between idle abort and cleanup could be silently dropped
- Removed redundant bare
isProcessing: truebroadcast and eliminated double-iteration inbroadcastProcessingStatus() - Replaced inline
require()with proper accessor viasessionManager.getPendingMessageStore() - Added 8 regression tests for session termination invariant
- dump_to_file parameter removed
- Removed arbitrary file write vulnerability (dump_to_file parameter)
- Timeline Report skill generates narrative journey reports from development history
- Git worktree detection for timeline reports
- Compressed context output reduced ~53% via compact formatting
- OpenClaw stops writing to MEMORY.md, injects context via system prompt instead
- OpenClaw system prompt context injection via before_prompt_build hook
- New syncMemoryFileExclude config for excluding agents from injection
- Context caching for 60 seconds per project
- Fixed isPidAlive(0) kernel scheduler check
- Fixed signal handler race condition with shutdownInitiated flag
- Downgraded HTTP logging to DEBUG level
Full changelog
Patch: Process Supervisor Hardening & Logging Cleanup
Fixes
- Downgrade HTTP request/response logging from INFO to DEBUG — eliminates noisy per-request log spam from the viewer UI polling
- Fix
isPidAlive(0)returning true — PID 0 is the kernel scheduler, not a valid child process - Fix signal handler race condition — added
shutdownInitiatedflag to prevent duplicate shutdown cascades when signals arrive beforestopPromiseis set - Remove unused
dataDirparameter fromShutdownCascadeOptions - Export and reuse env sanitizer constants —
Server.tsnow importsENV_PREFIXES/ENV_EXACT_MATCHESfromenv-sanitizer.tsinstead of duplicating them - Rename
zombiePidFilestodeadProcessPids— now returns actual PID array instead of a boolean - Use
buildWorkerUrlhelper inworkerHttpRequestinstead of inline URL construction - Remove unused
getWorkerPortimports from observation and session-init handlers - Upgrade
reapSessionfailure log from debug to warn level - Clean up
.gitignore— remove stale~*/,http*/,https*/patterns and duplicatedatasets/entry
Tests
- Rewrote supervisor index tests to use temp directories instead of relying on real
~/.claude-mem/worker.pid - Added deterministic test cases for missing, invalid, stale, and alive PID file states
- Removed unused
dataDirfrom shutdown test fixtures
- Unified observation type/concept filter reading from mode JSON
- Removed dead CLAUDE_MEM_CONTEXT filter settings
Full changelog
Bug Fix
- Fixed empty context queries after mode switching: Switching from a non-code mode (e.g., law-study) back to code mode left stale observation type/concept filters in
settings.json, causing all context queries to return empty results. All modes now read types/concepts from their mode JSON definition uniformly.
Cleanup
- Removed dead
CLAUDE_MEM_CONTEXT_OBSERVATION_TYPESandCLAUDE_MEM_CONTEXT_OBSERVATION_CONCEPTSsettings constants - Deleted
src/constants/observation-metadata.ts(no longer needed) - Removed observation type/concept filter UI controls from the viewer's Context Settings modal
Restores modes to correct location, fixing broken mode loading.
- Law-study mode with 6 observation types (Case Holding, Issue Pattern, etc.)
- Chill variant for high-signal items only
- CLAUDE.md template for Socratic legal study partnership
Full changelog
What's New
Law Study Mode
Adds law-study — a purpose-built claude-mem mode for law students.
Observation Types:
- Case Holding — 2-3 sentence brief with extracted legal rule
- Issue Pattern — exam trigger or fact pattern that signals a legal issue
- Prof Framework — professor's analytical lens and emphasis for a topic
- Doctrine / Rule — legal test or standard synthesized from cases/statutes
- Argument Structure — legal argument or counter-argument worked through analytically
- Cross-Case Connection — insight linking cases or doctrines to reveal a deeper principle
Concepts (cross-cutting tags):
exam-relevant · minority-position · gotcha · unsettled-law · policy-rationale · course-theme
Chill Variant — law-study--chill records only high-signal items: issue patterns, gotchas, and professor frameworks. Skips routine case holdings unless the result is counterintuitive.
CLAUDE.md Template — law-study-CLAUDE.md is a drop-in template for any law study project directory. It configures Claude as a Socratic legal study partner: precise case briefs, critical document analysis, issue spotting, and doctrine synthesis — without writing exam answers for the student.
Activate with: /mode law-study or /mode law-study--chill
Published Smart Explore benchmark report with updated token economics.
Restored hooks.json configuration with Setup hook, worker start command, and PostToolUse matcher.
- Replaced execSync with execFileSync to prevent command injection in file path handling
- Smart explore with smart_search, smart_outline, smart_unfold MCP tools
- 10-language tree-sitter support for AST-based code navigation
- 6-12x token cost reduction for code exploration vs full file reads
Removed `save_observation` from MCP tool surface to prevent unintended invocation.
- Added missing break statements in worker-service switch cases
- CLAUDE_PLUGIN_ROOT fallback for Stop hooks
- Removed redundant start commands triggering collectStdin timeout
Full changelog
Bug Fixes
- Fix PostToolUse hook crashes and 5-second latency (#1220): Added missing
breakstatements to all 7 switch cases inworker-service.tspreventing fall-through execution, added.catch()onmain()to handle unhandled promise rejections, and removed redundantstartcommands from hook groups that triggered the 5-secondcollectStdin()timeout - Fix CLAUDE_PLUGIN_ROOT fallback for Stop hooks (#1215): Added POSIX shell-level
CLAUDE_PLUGIN_ROOTfallback inhooks.jsonfor environments where the variable isn't injected, added script-level self-resolution viaimport.meta.urlinbun-runner.js, and regression test added inplugin-distribution.test.ts
Maintenance
- Synced all version files (plugin.json was stuck at 10.4.0)
Minor fixes and improvements.
Full changelog
Bug Fixes
- Fix PostToolUse hook crashes and 5-second latency (#1220): Added missing
breakstatements to all 7 switch cases inworker-service.tspreventing fall-through execution, added.catch()onmain()to handle unhandled promise rejections, and removed redundantstartcommands from hook groups that triggered the 5-secondcollectStdin()timeout - Fix CLAUDE_PLUGIN_ROOT fallback for Stop hooks (#1215): Added POSIX shell-level
CLAUDE_PLUGIN_ROOTfallback inhooks.jsonfor environments where the variable isn't injected, added script-level self-resolution viaimport.meta.urlinbun-runner.js, and regression test added inplugin-distribution.test.ts - Sync plugin.json version: Fixed
plugin.jsonbeing stuck at 10.4.0 while other version files were at 10.4.1
- Session custom titles for agent attribution
- Chroma toggle for SQLite-only fallback mode
- Context re-injection guard prevents duplicate context
### Bug Fixes - Fixed session context footer to reference the claude-mem skill instead of MCP search tools for accessing memories
- MCP tool renamed from save_memory to save_observation
- Worker startup readiness race condition fix
- MCP search instruction accuracy updates
- Installer hosting and routing improvements
Full changelog
Bug Fixes
- Worker startup readiness: Worker startup hook now waits for full DB/search readiness before proceeding, fixing the race condition where hooks would fire before the worker was initialized on first start (#1210)
- MCP tool naming: Renamed
save_memorytosave_observationfor consistency with the observation-based data model (#1210) - MCP search instructions: Updated MCP server tool descriptions to accurately reflect the 3-layer search workflow (#1210)
- Installer hosting: Serve installer JS from install.cmem.ai instead of GitHub raw URLs for reliability
- Installer routing: Added rewrite rule so install.cmem.ai root path correctly serves the install script
- Installer build: Added compiled installer dist so CLI installation works out of the box
Fixed duplicate worker daemon and zombie process issues causing chroma-mcp timeouts.
- SQL injection guards added to ChromaSync ID exclusion queries
- ChromaMcpManager singleton via uvx
- Graceful subprocess lifecycle with GracefulShutdown integration
- 10-second reconnect backoff preventing spawn storms
- reapStaleSessions() background interval for orphan cleanup
- ensureProcessExit() in finally blocks across SessionRoutes and worker-service
- Atomic self-healing in claimNextMessage
- Auto-reset stale processing messages (>60s)
- Removed redundant idle-timeout reset
Full changelog
Bug Fixes
- Self-healing message queue: Renamed
claimAndDelete→claimNextMessagewith atomic self-healing — automatically resets stale processing messages (>60s) back to pending before claiming, eliminating stuck messages from generator crashes without external timers - Removed redundant idle-timeout reset: The
resetStaleProcessingMessages()call during idle timeout in worker-service was removed (startup reset kept), since the atomic self-healing inclaimNextMessagenow handles recovery inline - TypeScript diagnostic fix: Added
QUEUEto loggerComponenttype
Tests
- 5 new tests for self-healing behavior (stuck recovery, active protection, atomicity, empty queue, session isolation)
- 1 new integration test for stuck recovery in zombie-prevention suite
- All existing queue tests updated for renamed method
Fixes critical bug where Chroma backfill never ran on startup, leaving vector database with incomplete data.
- Moved HuggingFace model cache to ~/.claude-mem/models/
- Self-healing retry for Protobuf parsing failures with cache clear and re-download
- Replaced file system manipulation with bun pm cache rm command
- Shell injection in sync-marketplace: replaced execSync with spawnSync to eliminate command injection via gitignore patterns
- systemMessage field on HookResult for ANSI-colored timeline display
- Promise.all for parallel context fetching
- Streamlined defaults hiding tokens and savings columns
Fixes cross-platform compatibility by removing native binary dependencies from Chroma embeddings.
- Persistent ChromaServerManager via HTTP
- DefaultEmbeddingFunction for local vector embeddings
- Pinned chromadb v3.2.2
Fixed MEMORY.md project query mismatch and added Telegram botToken support for feeds.
- OpenClaw one-liner installer (curl | bash)
- Platform detection and automatic dependency management
- Distribution readiness test suite
Full changelog
OpenClaw Installer & Distribution
This release introduces the OpenClaw one-liner installer and fixes several OpenClaw plugin issues.
New Features
- OpenClaw Installer (
openclaw/install.sh): Full cross-platform installer script withcurl | bashsupport- Platform detection (macOS, Linux, WSL)
- Automatic dependency management (Bun, uv, Node.js)
- Interactive AI provider setup with settings writer
- OpenClaw gateway detection, plugin install, and memory slot configuration
- Worker startup and health verification with rich diagnostics
- TTY detection,
--provider/--api-keyCLI flags - Error recovery and upgrade handling for existing installations
- jq/python3/node fallback chain for JSON config writing
- Distribution readiness tests (
openclaw/test-install.sh): Comprehensive test suite for the installer - Enhanced
/api/healthendpoint: Now returns version, uptime, workerPath, and AI status
Bug Fixes
- Fix: use
event.promptinstead ofctx.sessionKeyfor prompt storage in OpenClaw plugin - Fix: detect both
openclawandopenclaw.mjsbinary names in gateway discovery - Fix: pass file paths via env vars instead of bash interpolation in
node -ecalls - Fix: handle stale plugin config that blocks OpenClaw CLI during reinstall
- Fix: remove stale memory slot reference during reinstall cleanup
- Fix: remove opinionated filters from OpenClaw plugin
Reverts v10.0.3 due to regressions; restores v10.0.2 codebase.
- 5-layer defense: connection mutex, process count guard, hardened close, orphan reaper, circuit breaker
- etime-based process age sorting for reliable age determination
- Project-scoped statusline counter utility for observation tracking
- SSE observation feed for OpenClaw agent sessions
- Fixed ObservationSSEPayload.project nullability
- Added EnvManager support for OpenClaw configuration
Full changelog
What's Changed
OpenClaw Observation Feed
- Enabled SSE observation feed for OpenClaw agent sessions, allowing real-time streaming of observations to connected OpenClaw clients
- Fixed
ObservationSSEPayload.projecttype to be nullable, preventing type errors when project context is unavailable - Added
EnvManagersupport for OpenClaw environment configuration
Build Artifacts
- Rebuilt worker service and MCP server with latest changes
- Official OpenClaw plugin for persistent agent memory
- MEMORY.md live sync to agent workspaces
- Real-time observation feed to Telegram, Discord, Slack, Signal, WhatsApp, LINE
- Restored mem-search skill with updated MCP tool workflow
- CORS restricted to localhost/127.0.0.1 origins only
- XSS defense-in-depth via DOMPurify in TerminalPreview.tsx
- Manual memory storage via save_memory MCP tool
- Project exclusion setting with glob patterns
- Folder exclude setting for CLAUDE.md generation
Fixes fresh installation PATH resolution for Bun via smart discovery wrapper.
- Prevents API key hijacking from random project .env files
- Credentials now sourced exclusively from ~/.claude-mem/.env
- In-process worker architecture when port 37777 available
- Chained hook configuration support in hooks.json
- 3-minute idle timeout for SessionQueueProcessor to terminate inactive processes
Fixes authentication failure caused by observer session isolation override.
Fixes crash when resuming SDK conversations after worker restart.
- Shared path-utils.ts module with path normalization utilities
- 61 new tests for path matching edge cases
Prevents creation of empty context files in project directories, keeping them clean.
- ProcessRegistry module for PID tracking
- Orphan reaper running every 5 minutes
- 5-second graceful timeout with SIGKILL escalation
- Chroma vector search disabled on Windows pending architecture migration
- WMIC-based detached process spawning on Windows
- Removed hidden fallback behavior: users selecting Gemini/OpenRouter now get those providers directly without Claude fallback
- Removed dangerous ANTHROPIC_API_KEY check that could use user's API key (20x more expensive than Claude Code pricing)
- Dynamic MCP version management via build-time injection from package.json
- /do command for task execution
- /make-plan command for implementation planning
- buildStatusOutput() function generating structured JSON with status, message, continue fields
- Graceful exit strategy for terminal (exit code 0)
- Replaced WMIC with PowerShell Get-Process for Windows 11
- Cleaned obsolete CLAUDE.md files
Full changelog
Bug Fixes
- Windows Terminal Tab Accumulation (#625, #628): Fixed terminal tab accumulation on Windows by implementing graceful exit strategy. All expected failure scenarios (port conflicts, version mismatches, health check timeouts) now exit with code 0 instead of code 1.
- Windows 11 Compatibility (#625): Replaced deprecated WMIC commands with PowerShell
Get-ProcessandGet-CimInstancefor process enumeration. WMIC is being removed from Windows 11.
Maintenance
- Removed Obsolete CLAUDE.md Files: Cleaned up auto-generated CLAUDE.md files from
~/.claude/plans/and~/.claude/plugins/marketplaces/directories.
Full Changelog: https://github.com/thedotmack/claude-mem/compare/v9.0.1...v9.0.2
- isValidPathForClaudeMd() rejecting tilde, URLs, spaces, GitHub references, relative paths
- Promoted 38+ WARN messages to ERROR for debugging visibility
- Auto-generated folder CLAUDE.md with chronological activity timelines
- Worktree support with project-aware filtering
- Modular service layer decomposition
- Context injection header shows current date and time
- Gemini-3-flash model support with proper rate limits
- Windows process management fixes for Git Bash/WSL compatibility
- Apple Silicon Homebrew paths for bun and uv detection
- SQLite Repositories modularization
- Worker Agents extraction
- Comprehensive 595-test suite with 1120 assertions
Full changelog
Modular Architecture Refactor
This release refactors the monolithic service architecture into focused, single-responsibility modules with comprehensive test coverage.
Architecture Improvements
- SQLite Repositories (
src/services/sqlite/) - Modular repositories for sessions, observations, prompts, summaries, and timeline - Worker Agents (
src/services/worker/agents/) - Extracted response processing, error handling, and session cleanup - Search Strategies (
src/services/worker/search/) - Modular search with Chroma, SQLite, and Hybrid strategies plus orchestrator - Context Generation (
src/services/context/) - Separated context building, token calculation, formatters, and renderers - Infrastructure (
src/services/infrastructure/) - Graceful shutdown, health monitoring, and process management - Server (
src/services/server/) - Express server setup, middleware, and error handling
Test Coverage
- 595 tests across 36 test files
- 1,120 expect() assertions
- Coverage for SQLite repos, worker agents, search, context, infrastructure, and server modules
Session ID Refactor
- Aligned tests with NULL-based memory session initialization pattern
- Updated
SESSION_ID_ARCHITECTURE.mddocumentation
Other Improvements
- Added missing logger imports to 34 files for better observability
- Updated esbuild and MCP SDK to latest versions
- Removed
bun.lockfrom version control
Full Changelog: https://github.com/thedotmack/claude-mem/compare/v8.5.6...v8.5.7
Refactors monolithic services into modular, maintainable components.
Critical bug fix for memory_session_id incorrectly equaling content_session_id.
- Console filter bar with structured log parsing
- Distinguished Chroma connection errors from missing collections
- Error handling baseline documentation and tooling
Full changelog
Bug Fixes
Chroma Connection Error Handling
Fixed a critical bug in ChromaSync where connection-related errors were misinterpreted as missing collections. The ensureCollection() method previously caught ALL errors and assumed they meant the collection doesn't exist, which caused connection errors to trigger unnecessary collection creation attempts. Now connection-related errors like "Not connected" are properly distinguished and re-thrown immediately, preventing false error handling paths and inappropriate fallback behavior.
Removed Dead last_user_message Code
Cleaned up dead code related to last_user_message handling in the summary flow. This field was being extracted from transcripts but never used anywhere - in Claude Code transcripts, "user" type messages are mostly tool_results rather than actual user input, and the user's original request is already stored in the user_prompts table. Removing this unused field eliminates confusing warnings like "Missing last_user_message when queueing summary". Changes span summary-hook, SessionRoutes, SessionManager, interface definitions, and all agent implementations.
Improvements
Enhanced Error Handling Across Services
Comprehensive improvement to error handling across 8 core services:
- BranchManager - Now logs recovery checkout failures
- PaginationHelper - Logs when file paths are plain strings instead of valid JSON
- SDKAgent - Enhanced logging for Claude executable detection failures
- SearchManager - Logs plain string handling for files read and edited
- paths.ts - Improved logging for git root detection failures
- timeline-formatting - Enhanced JSON parsing errors with input previews
- transcript-parser - Logs summary of parse errors after processing
- ChromaSync - Logs full error context before attempting collection creation
Error Handling Documentation & Tooling
- Created
error-handling-baseline.txtestablishing baseline error handling practices - Documented error handling anti-pattern rules in CLAUDE.md
- Added
detect-error-handling-antipatterns.tsscript to identify empty catch blocks, improper logging practices, and oversized try-catch blocks
New Features
Console Filter Bar with Log Parsing
Implemented interactive log filtering in the viewer UI:
- Structured Log Parsing - Extracts timestamp, level, component, correlation ID, and message content using regex pattern matching
- Level Filtering - Toggle visibility for DEBUG, INFO, WARN, ERROR log levels
- Component Filtering - Filter by 9 component types: HOOK, WORKER, SDK, PARSER, DB, SYSTEM, HTTP, SESSION, CHROMA
- Color-Coded Rendering - Visual distinction with component-specific icons and log level colors
- Special Message Detection - Recognizes markers like → (dataIn), ← (dataOut), ✓ (success), ✗ (failure), ⏱ (timing), [HAPPY-PATH]
- Smart Auto-Scroll - Maintains scroll position when reviewing older logs
- Responsive Design - Filter bar adapts to smaller screens
- detect-error-handling-antipatterns.ts: detects 7 categories with zero-tolerance empty catch policy
- npm run queue:clear and DELETE /api/pending-queue endpoints for queue maintenance
- Developer console with draggable UI, auto-refresh, log viewer