703c64c756
* 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>
186 lines
6.4 KiB
JSON
186 lines
6.4 KiB
JSON
{
|
|
"name": "claude-mem",
|
|
"version": "12.4.3",
|
|
"description": "Memory compression system for Claude Code - persist context across sessions",
|
|
"keywords": [
|
|
"claude",
|
|
"claude-code",
|
|
"claude-agent-sdk",
|
|
"mcp",
|
|
"plugin",
|
|
"memory",
|
|
"compression",
|
|
"knowledge-graph",
|
|
"transcript",
|
|
"typescript",
|
|
"nodejs"
|
|
],
|
|
"author": "Alex Newman",
|
|
"license": "AGPL-3.0",
|
|
"repository": {
|
|
"type": "git",
|
|
"url": "https://github.com/thedotmack/claude-mem.git"
|
|
},
|
|
"homepage": "https://github.com/thedotmack/claude-mem#readme",
|
|
"bugs": {
|
|
"url": "https://github.com/thedotmack/claude-mem/issues"
|
|
},
|
|
"type": "module",
|
|
"bin": {
|
|
"claude-mem": "./dist/npx-cli/index.js"
|
|
},
|
|
"exports": {
|
|
".": {
|
|
"types": "./dist/index.d.ts",
|
|
"import": "./dist/index.js"
|
|
},
|
|
"./sdk": {
|
|
"types": "./dist/sdk/index.d.ts",
|
|
"import": "./dist/sdk/index.js"
|
|
},
|
|
"./modes/*": "./plugin/modes/*"
|
|
},
|
|
"files": [
|
|
"dist",
|
|
"plugin/.claude-plugin",
|
|
"plugin/CLAUDE.md",
|
|
"plugin/package.json",
|
|
"plugin/hooks",
|
|
"plugin/modes",
|
|
"plugin/scripts/*.js",
|
|
"plugin/scripts/*.cjs",
|
|
"plugin/scripts/CLAUDE.md",
|
|
"plugin/skills",
|
|
"plugin/ui",
|
|
"openclaw"
|
|
],
|
|
"engines": {
|
|
"node": ">=20.0.0",
|
|
"bun": ">=1.0.0"
|
|
},
|
|
"scripts": {
|
|
"dev": "npm run build-and-sync",
|
|
"build": "node scripts/sync-plugin-manifests.js && node scripts/build-hooks.js",
|
|
"build-and-sync": "npm run build && npm run sync-marketplace && sleep 1 && cd ~/.claude/plugins/marketplaces/thedotmack && npm run worker:restart",
|
|
"sync-marketplace": "node scripts/sync-marketplace.cjs",
|
|
"sync-marketplace:force": "node scripts/sync-marketplace.cjs --force",
|
|
"build:binaries": "node scripts/build-worker-binary.js",
|
|
"worker:logs": "tail -n 50 ~/.claude-mem/logs/worker-$(date +%Y-%m-%d).log",
|
|
"worker:tail": "tail -f 50 ~/.claude-mem/logs/worker-$(date +%Y-%m-%d).log",
|
|
"changelog:generate": "node scripts/generate-changelog.js",
|
|
"discord:notify": "node scripts/discord-release-notify.js",
|
|
"worker:start": "bun plugin/scripts/worker-service.cjs start",
|
|
"worker:stop": "bun plugin/scripts/worker-service.cjs stop",
|
|
"worker:restart": "bun plugin/scripts/worker-service.cjs restart",
|
|
"worker:status": "bun plugin/scripts/worker-service.cjs status",
|
|
"queue": "bun scripts/check-pending-queue.ts",
|
|
"queue:process": "bun scripts/check-pending-queue.ts --process",
|
|
"queue:clear": "bun scripts/clear-failed-queue.ts --all --force",
|
|
"claude-md:regenerate": "bun scripts/regenerate-claude-md.ts",
|
|
"claude-md:dry-run": "bun scripts/regenerate-claude-md.ts --dry-run",
|
|
"translate-readme": "bun scripts/translate-readme/cli.ts -v -o docs/i18n README.md",
|
|
"translate:tier1": "npm run translate-readme -- zh zh-tw ja pt-br ko es de fr",
|
|
"translate:tier2": "npm run translate-readme -- he ar ru pl cs nl tr uk",
|
|
"translate:tier3": "npm run translate-readme -- vi id th hi bn ro sv",
|
|
"translate:tier4": "npm run translate-readme -- it el hu fi da no",
|
|
"translate:all": "npm run translate:tier1 & npm run translate:tier2 & npm run translate:tier3 & npm run translate:tier4 & wait",
|
|
"bug-report": "npx tsx scripts/bug-report/cli.ts",
|
|
"cursor:install": "bun plugin/scripts/worker-service.cjs cursor install",
|
|
"cursor:uninstall": "bun plugin/scripts/worker-service.cjs cursor uninstall",
|
|
"cursor:status": "bun plugin/scripts/worker-service.cjs cursor status",
|
|
"cursor:setup": "bun plugin/scripts/worker-service.cjs cursor setup",
|
|
"typecheck": "tsc --noEmit && tsc --noEmit -p src/ui/viewer/tsconfig.json",
|
|
"typecheck:root": "tsc --noEmit",
|
|
"typecheck:viewer": "tsc --noEmit -p src/ui/viewer/tsconfig.json",
|
|
"test": "bun test",
|
|
"test:sqlite": "bun test tests/sqlite/",
|
|
"test:agents": "bun test tests/worker/agents/",
|
|
"test:search": "bun test tests/worker/search/",
|
|
"test:context": "bun test tests/context/",
|
|
"test:infra": "bun test tests/infrastructure/",
|
|
"test:server": "bun test tests/server/",
|
|
"prepublishOnly": "npm run build",
|
|
"release": "np",
|
|
"release:patch": "np patch --no-cleanup",
|
|
"release:minor": "np minor --no-cleanup",
|
|
"release:major": "np major --no-cleanup"
|
|
},
|
|
"np": {
|
|
"yarn": false,
|
|
"contents": ".",
|
|
"testScript": "test",
|
|
"2fa": false
|
|
},
|
|
"dependencies": {
|
|
"@anthropic-ai/claude-agent-sdk": "^0.2.119",
|
|
"@clack/prompts": "^1.2.0",
|
|
"@modelcontextprotocol/sdk": "^1.29.0",
|
|
"ansi-to-html": "^0.7.2",
|
|
"dompurify": "^3.4.1",
|
|
"express": "^5.2.1",
|
|
"glob": "^13.0.6",
|
|
"handlebars": "^4.7.9",
|
|
"picocolors": "^1.1.1",
|
|
"react": "^19.2.5",
|
|
"react-dom": "^19.2.5",
|
|
"yaml": "^2.8.3",
|
|
"zod": "^4.3.6",
|
|
"zod-to-json-schema": "^3.25.2"
|
|
},
|
|
"devDependencies": {
|
|
"@derekstride/tree-sitter-sql": "^0.3.11",
|
|
"@tree-sitter-grammars/tree-sitter-lua": "^0.4.1",
|
|
"@tree-sitter-grammars/tree-sitter-markdown": "^0.3.2",
|
|
"@tree-sitter-grammars/tree-sitter-toml": "^0.7.0",
|
|
"@tree-sitter-grammars/tree-sitter-yaml": "^0.7.1",
|
|
"@tree-sitter-grammars/tree-sitter-zig": "^1.1.2",
|
|
"@types/bun": "^1.3.13",
|
|
"@types/cors": "^2.8.19",
|
|
"@types/dompurify": "^3.2.0",
|
|
"@types/express": "^5.0.6",
|
|
"@types/node": "^25.6.0",
|
|
"@types/react": "^19.2.14",
|
|
"@types/react-dom": "^19.2.3",
|
|
"esbuild": "^0.28.0",
|
|
"np": "^11.2.0",
|
|
"tree-sitter-bash": "^0.25.1",
|
|
"tree-sitter-c": "^0.24.1",
|
|
"tree-sitter-cli": "^0.26.8",
|
|
"tree-sitter-cpp": "^0.23.4",
|
|
"tree-sitter-css": "^0.25.0",
|
|
"tree-sitter-elixir": "^0.3.5",
|
|
"tree-sitter-go": "^0.25.0",
|
|
"tree-sitter-haskell": "^0.23.1",
|
|
"tree-sitter-java": "^0.23.5",
|
|
"tree-sitter-javascript": "^0.25.0",
|
|
"tree-sitter-kotlin": "^0.3.8",
|
|
"tree-sitter-php": "^0.24.2",
|
|
"tree-sitter-python": "^0.25.0",
|
|
"tree-sitter-ruby": "^0.23.1",
|
|
"tree-sitter-rust": "^0.24.0",
|
|
"tree-sitter-scala": "^0.24.0",
|
|
"tree-sitter-scss": "^1.0.0",
|
|
"tree-sitter-swift": "^0.7.1",
|
|
"tree-sitter-typescript": "^0.23.2",
|
|
"ts-prune": "^0.10.3",
|
|
"tsx": "^4.21.0",
|
|
"typescript": "^6.0.3"
|
|
},
|
|
"optionalDependencies": {
|
|
"tree-kill": "^1.2.2"
|
|
},
|
|
"trustedDependencies": [
|
|
"esbuild",
|
|
"tree-sitter-c",
|
|
"tree-sitter-cli",
|
|
"tree-sitter-cpp",
|
|
"tree-sitter-go",
|
|
"tree-sitter-java",
|
|
"tree-sitter-javascript",
|
|
"tree-sitter-python",
|
|
"tree-sitter-ruby",
|
|
"tree-sitter-rust",
|
|
"tree-sitter-typescript"
|
|
]
|
|
}
|