PATCH release for the /clear queue-drain fix (PR #2136):
removes the SessionEnd → session-complete shim across all five
integration surfaces so pending observations are no longer abandoned
when users type /clear, logout, or exit.
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* fix: 5 trivial bugs from v12.4.1 issue triage
- #2092: emit CJS-safe banner (no import.meta.url) in worker-service.cjs
- #2100: PreToolUse Read hook timeout 2000s → 60s
- #2131: add "shell": "bash" to every hook for Windows compat
- #2132: Antigravity dir typo .agent → .agents
- #2088: clear inherited MCP servers in worker SDK query() calls
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* fix: stop context overflow loop + block task-notification leak
- SDKAgent: clear memorySessionId on "prompt is too long" so crash-recovery
starts a fresh SDK session instead of resuming the same poisoned context
forever (was producing 68+ failed pending_messages on a single stuck
session in the wild)
- tag-stripping: new isInternalProtocolPayload() predicate; session-init
hook + SessionRoutes both skip storage when entire prompt is one of
Claude Code's autonomous protocol blocks (currently <task-notification>;
conservative deny-list — does NOT touch <command-name>/<command-message>
which wrap real user slash-commands)
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* chore: bump version to 12.4.2
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* docs: update CHANGELOG.md for v12.4.2
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* feat(cleanup): one-time v12.4.3 migration purges observer-sessions and stuck pending_messages
Adds CleanupV12_4_3 module that runs once per data dir on worker startup
(after migrations apply, before Chroma backfill). Drops accumulated pollution
that v12.4.0 (observer-sessions filter) and v12.4.2 (context-overflow guard +
task-notification leak block) prevent from recurring:
- DELETE FROM sdk_sessions WHERE project='observer-sessions' (cascades to
user_prompts, observations, session_summaries via existing FK ON DELETE CASCADE)
- DELETE FROM pending_messages stuck in 'failed'/'processing' for any session
with >=10 such rows (poisoned chains from the pre-v12.4.2 retry loop;
threshold spares legitimate transient failures)
- Wipes ~/.claude-mem/chroma and chroma-sync-state.json so backfillAllProjects
rebuilds the vector store from cleaned SQLite
Pre-flight checks free disk (1.2x DB size + 100MB) via fs.statfsSync; backs up
via VACUUM INTO with copyFileSync fallback; PRAGMA foreign_keys=ON on the
cleanup connection (off by default in bun:sqlite). Marker file
~/.claude-mem/.cleanup-v12.4.3-applied records backup path and counts. Opt-out
via CLAUDE_MEM_SKIP_CLEANUP_V12_4_3=1.
Verified locally: 311MB DB backed up to 277MB in 943ms; 11 observer sessions
+ 3 cascade rows + 141 stuck pending_messages purged; chroma rebuilt via
backfill. Total cleanup time 1.1s.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* fix: address PR #2133 code review
- SessionRoutes: check isInternalProtocolPayload before stripping tags
so internal protocol prompts skip the strip work entirely.
- tag-stripping: bound isInternalProtocolPayload input length to
256KB to prevent ReDoS-class scans on malformed unclosed tags.
- SDKAgent: extract resetSessionForFreshStart helper; both
context-overflow paths now share one nullification routine.
- worker-service: drop the per-startup "Checking for one-time
v12.4.3 cleanup" info log — runs every boot even after marker
exists; the function already logs at debug/warn when relevant.
- tests: add isInternalProtocolPayload edge cases (whitespace,
attributes, partial tags, unrelated tags, oversize input).
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* fix: address Greptile P2 comments on PR #2133
CleanupV12_4_3.ts: derive backup directory and restore-hint path from
effectiveDataDir instead of the module-level BACKUPS_DIR/DB_PATH
constants. The dataDirectory override is meant for test isolation;
the prior version still wrote backups to the production directory.
SessionRoutes.ts: move isInternalProtocolPayload guard to the top of
handleSessionInitByClaudeId, before createSDKSession. The previous
position blocked the user_prompts insert but still created an empty
sdk_sessions row, asymmetric with the hook-layer guard in
session-init.ts.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* fix(cleanup): retry on disk-skip; survive chroma wipe failure
CodeRabbit Major + Claude review:
- Disk pre-flight skip no longer writes the marker. A user temporarily
low on disk would otherwise have the cleanup permanently disabled
even after freeing space. Retry on next startup instead.
- Wrap wipeChromaArtifacts in try/catch and write the marker even on
failure (with chromaWipeError captured). Without this, an rmSync
permission failure on chroma/ left writeMarker unreached, so every
subsequent boot re-ran the SQL purge AND created a fresh backup,
consuming disk indefinitely.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* fix(cleanup): close backup handle before copyFileSync fallback
Claude review:
- backupDb is now closed before falling into the copyFileSync fallback.
On Windows an open SQLite handle holds a file lock that can prevent
the fallback copy from reading the source. The previous version only
closed after both branches completed.
- Add empty-body <task-notification></task-notification> case to the
isInternalProtocolPayload tests for completeness.
Cascade-row count queries already match the actual FK columns
(content_session_id for user_prompts, memory_session_id for
observations / session_summaries) — no fix needed there.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* fix(cleanup): accurate session count + add migration tests
Claude review v3:
session-init.ts: filter on rawPrompt before the [media prompt]
substitution. Functionally equivalent but explicit — the check no
longer depends on the substitution leaving real protocol payloads
untouched.
CleanupV12_4_3.ts: counts.observerSessions now comes from a pre-DELETE
COUNT(*), not from result.changes. bun:sqlite inflates result.changes
with FTS-trigger and cascade row counts (the user_prompts_fts triggers
inflate a 3-session purge to 19 changes). The previous code logged a
misleading total and wrote it to the marker.
tests/infrastructure/cleanup-v12_4_3.test.ts: happy-path coverage of
the migration against a real on-disk SQLite under a tmpdir. Verifies
observer-session purge with cascades, stuck pending_messages purge,
chroma artifact wipe, marker payload shape, idempotency on re-run, and
CLAUDE_MEM_SKIP_CLEANUP_V12_4_3 opt-out.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* fix(protocol-filter): close two-block false positive; address review
CodeRabbit + Claude review v5:
tag-stripping.ts: PROTOCOL_ONLY_REGEX rewritten with a negative-lookahead
body so a prompt like "<task-notification>x</task-notification> hi
<task-notification>y</task-notification>" no longer matches as a single
outer block — the prior greedy [\s\S]* spanned the middle user text and
would have silently dropped a real prompt. Confirmed via probe.
tag-stripping.test.ts: drop the 50ms wall-clock assertion (CI flake);
add the two-block-with-text case as a regression test.
SessionRoutes.ts: filter on req.body.prompt directly, before the
[media prompt] substitution and 256KB truncation. Mirrors the
session-init.ts hook-layer ordering and ensures a protocol payload
that happens to be near the byte limit isn't truncated before the
filter runs.
cleanup-v12_4_3.test.ts: add stuckCount=9 below-threshold case
verifying pending_messages with <10 stuck rows are preserved.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* fix(cleanup): include WAL/SHM in backup fallback; safer rollback
CodeRabbit Major + Claude review v6:
CleanupV12_4_3.ts: when VACUUM INTO fails and copyFileSync runs, also
copy any -wal/-shm sidecars. The DB is configured WAL mode, so recent
committed pages can live in those files; copying only the .db would
miss them. VACUUM INTO already captures everything in one file, so
the happy path is unaffected.
CleanupV12_4_3.ts: wrap ROLLBACK in try/catch so a no-op rollback
(SQLite already rolled back on a constraint failure) cannot shadow
the original purge error.
SDKAgent.ts: align both context-overflow log levels to error. Both
branches are fatal-recovery paths; the previous warn/error split was
inconsistent and made the throw branch easy to miss in logs.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* fix: pre-count stuck pending_messages; document adjacent-block fall-through
Claude review v7:
CleanupV12_4_3.ts: runStuckPendingPurge now uses a SELECT COUNT(*)
before the DELETE, matching the pattern in runObserverSessionsPurge.
result.changes is reliable today (no FTS on pending_messages) but the
explicit count protects against future schema additions, and keeps
the two purges symmetric.
tag-stripping.test.ts: add test documenting that adjacent protocol
blocks (no user text between) deliberately fall through to storage.
The deny-list is per-block; concatenations are out of scope.
Skipped per project rules / Node API constraints:
- frsize fallback in disk check: Node/Bun StatFs doesn't expose frsize
- VACUUM-INTO comment: comment-only suggestion
- Overflow string constant extraction: low value
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Removes the 300 req/min rate limiter from the worker's HTTP middleware.
The worker is localhost-only (enforced via CORS), so rate limiting was
pointless security theater — but it broke the viewer, which polls logs
and stats frequently enough to trip the limit within seconds.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
SessionStart context injection regressed in v12.3.3 — no memory
context is being delivered to new sessions. Rolling back to the
v12.3.2 tree state while the regression is investigated.
Reverts #2080.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Patch release for the MCP server bun:sqlite crash fix landed in
PR #1645 (commit abd55977).
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* feat: add smart-file-read module for token-optimized semantic code search
- Created package.json for the smart-file-read module with dependencies and scripts.
- Implemented parser.ts for code structure parsing using tree-sitter, supporting multiple languages.
- Developed search.ts for searching code files and symbols with grep-style and structural matching.
- Added test-run.mjs for testing search and outline functionalities.
- Configured TypeScript with tsconfig.json for strict type checking and module resolution.
* fix: update .gitignore to include _tree-sitter and remove unused subproject
* feat: add preliminary results and skill recommendation for smart-explore module
* chore: remove outdated plan.md file detailing session start hook issues
* feat: update Smart File Read integration plan and skill documentation for smart-explore
* feat: migrate Smart File Read to web-tree-sitter WASM for cross-platform compatibility
* refactor: switch to tree-sitter CLI for parsing and enhance search functionality
- Updated `parser.ts` to utilize the tree-sitter CLI for AST extraction instead of native bindings, improving compatibility and performance.
- Removed grammar loading logic and replaced it with a path resolution for grammar packages.
- Implemented batch parsing in `parseFilesBatch` to handle multiple files in a single CLI call, enhancing search speed.
- Refactored `searchCodebase` to collect files and parse them in batches, streamlining the search process.
- Adjusted symbol extraction logic to accommodate the new parsing method and ensure accurate symbol matching.
* feat: update Smart File Read integration plan to utilize tree-sitter CLI for improved performance and cross-platform compatibility
* feat: add smart-file-read parser and search to src/services
Copy validated tree-sitter CLI-based parser and search modules from
smart-file-read prototype into the claude-mem source tree for MCP
tool integration.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* feat: register smart_search, smart_unfold, smart_outline MCP tools
Add 3 tree-sitter AST-based code exploration tools to the MCP server.
Direct execution (no HTTP delegation) — they call parser/search
functions directly for sub-second response times.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* feat: add tree-sitter CLI deps to build system and plugin runtime
Externalize tree-sitter packages in esbuild MCP server build. Add
10 grammar packages + CLI to plugin package.json for runtime install.
Remove unused @chroma-core/default-embed from plugin deps.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* feat: create smart-explore skill with 3-layer workflow docs
Progressive disclosure workflow: search -> outline -> unfold.
Documents all 3 MCP tools with parameters and token economics.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* Add comprehensive documentation for the smart-explore feature
- Introduced a detailed technical reference covering the architecture, parser, search engine, and tool registration for the smart-explore feature in claude-mem.
- Documented the three-layer workflow: search, outline, and unfold, along with their respective MCP tools.
- Explained the parsing process using tree-sitter, including language support, query patterns, and symbol extraction.
- Outlined the search module's functionality, including file discovery, batch parsing, and relevance scoring.
- Provided insights into build system integration and token economics for efficient code exploration.
* chore: remove experiment artifacts, prototypes, and plan files
Remove A/B test docs, prototype smart-file-read directory, and
implementation plans. Keep only production code.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* refactor: simplify hooks configuration and remove setup script
* fix: use execFileSync to prevent command injection in tree-sitter parser
Replaces execSync shell string with execFileSync + argument array,
eliminating shell interpretation of file paths. Also corrects
file_pattern description from "Glob pattern" to "Substring filter".
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>