Compare commits
6 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| b446f2630e | |||
| 224567f980 | |||
| 2b31792f06 | |||
| 613f0e9795 | |||
| f1162ed4a4 | |||
| 8039ada222 |
@@ -10,7 +10,7 @@
|
||||
"plugins": [
|
||||
{
|
||||
"name": "claude-mem",
|
||||
"version": "10.2.1",
|
||||
"version": "10.2.3",
|
||||
"source": "./plugin",
|
||||
"description": "Persistent memory system for Claude Code - context compression across sessions"
|
||||
}
|
||||
|
||||
+20
-88
@@ -2,6 +2,26 @@
|
||||
|
||||
All notable changes to claude-mem.
|
||||
|
||||
## [v10.2.2] - 2026-02-17
|
||||
|
||||
## Bug Fixes
|
||||
|
||||
- **Removed `node-addon-api` dev dependency** — was only needed for `sharp`, which was already removed in v10.2.1
|
||||
- **Simplified native module cache clearing** in `smart-install.js` and `sync-marketplace.cjs` — replaced targeted `@img/sharp` directory deletion and lockfile removal with `bun pm cache rm`
|
||||
- Reduced ~30 lines of brittle file system manipulation to a clean Bun CLI command
|
||||
|
||||
## [v10.2.1] - 2026-02-16
|
||||
|
||||
## Bug Fixes
|
||||
|
||||
- **Bun install & sharp native modules**: Fixed stale native module cache issues on Bun updates, added `node-addon-api` as a dev dependency required by sharp (#1140)
|
||||
- **PendingMessageStore consolidation**: Deduplicated PendingMessageStore initialization in worker-service; added session-scoped filtering to `resetStaleProcessingMessages` to prevent cross-session message resets (#1140)
|
||||
- **Gemini empty response handling**: Fixed silent message deletion when Gemini returns empty summary responses — now logs a warning and preserves the original message (#1138)
|
||||
- **Idle timeout session scoping**: Fixed idle timeout handler to only reset messages for the timed-out session instead of globally resetting all sessions (#1138)
|
||||
- **Shell injection in sync-marketplace**: Replaced `execSync` with `spawnSync` for rsync calls to eliminate command injection via gitignore patterns (#1138)
|
||||
- **Sharp cache invalidation**: Added cache clearing for sharp's native bindings when Bun version changes (#1138)
|
||||
- **Marketplace install**: Switched marketplace sync from npm to bun for package installation consistency (#1140)
|
||||
|
||||
## [v10.1.0] - 2026-02-16
|
||||
|
||||
## SessionStart System Message & Cleaner Defaults
|
||||
@@ -1388,91 +1408,3 @@ Patch release v8.2.4
|
||||
- Implement file-based locking mechanism for worker operations to prevent race conditions
|
||||
- Fix restart command references in documentation (changed from `claude-mem restart` to `npm run worker:restart`)
|
||||
|
||||
## [v8.2.2] - 2025-12-27
|
||||
|
||||
## What's Changed
|
||||
|
||||
### Features
|
||||
- Add OpenRouter provider settings and documentation
|
||||
- Add modal footer with save button and status indicators
|
||||
- Implement self-spawn pattern for background worker execution
|
||||
|
||||
### Bug Fixes
|
||||
- Resolve critical error handling issues in worker lifecycle
|
||||
- Handle Windows/Unix kill errors in orphaned process cleanup
|
||||
- Validate spawn pid before writing PID file
|
||||
- Handle process exit in waitForProcessesExit filter
|
||||
- Use readiness endpoint for health checks instead of port check
|
||||
- Add missing OpenRouter and Gemini settings to settingKeys array
|
||||
|
||||
### Other Changes
|
||||
- Enhance error handling and validation in agents and routes
|
||||
- Delete obsolete process management files (ProcessManager, worker-wrapper, worker-cli)
|
||||
- Update hooks.json to use worker-service.cjs CLI
|
||||
- Add comprehensive tests for hook constants and worker spawn functionality
|
||||
|
||||
## [v8.2.1] - 2025-12-27
|
||||
|
||||
## 🔧 Worker Lifecycle Hardening
|
||||
|
||||
This patch release addresses critical bugs discovered during PR review of the self-spawn pattern introduced in 8.2.0. The worker daemon now handles edge cases robustly across both Unix and Windows platforms.
|
||||
|
||||
### 🐛 Critical Bug Fixes
|
||||
|
||||
#### Process Exit Detection Fixed
|
||||
The `waitForProcessesExit` function was crashing when processes exited during monitoring. The `process.kill(pid, 0)` call throws when a process no longer exists, which was not being caught. Now wrapped in try/catch to correctly identify exited processes.
|
||||
|
||||
#### Spawn PID Validation
|
||||
The worker daemon now validates that `spawn()` actually returned a valid PID before writing to the PID file. Previously, spawn failures could leave invalid PID files that broke subsequent lifecycle operations.
|
||||
|
||||
#### Cross-Platform Orphan Cleanup
|
||||
- **Unix**: Replaced single `kill` command with individual `process.kill()` calls wrapped in try/catch, so one already-exited process doesn't abort cleanup of remaining orphans
|
||||
- **Windows**: Wrapped `taskkill` calls in try/catch for the same reason
|
||||
|
||||
#### Health Check Reliability
|
||||
Changed `waitForHealth` to use the `/api/readiness` endpoint (returns 503 until fully initialized) instead of just checking if the port is in use. Callers now wait for *actual* worker readiness, not just network availability.
|
||||
|
||||
### 🔄 Refactoring
|
||||
|
||||
#### Code Consolidation (-580 lines)
|
||||
Deleted obsolete process management infrastructure that was replaced by the self-spawn pattern:
|
||||
- `src/services/process/ProcessManager.ts` (433 lines) - PID management now in worker-service
|
||||
- `src/cli/worker-cli.ts` (81 lines) - CLI handling now in worker-service
|
||||
- `src/services/worker-wrapper.ts` (157 lines) - Replaced by `--daemon` flag
|
||||
|
||||
#### Updated Hook Commands
|
||||
All hooks now use `worker-service.cjs` CLI directly instead of the deleted `worker-cli.js`.
|
||||
|
||||
### ⏱️ Timeout Adjustments
|
||||
|
||||
Increased timeouts throughout for compatibility with slow systems:
|
||||
|
||||
| Component | Before | After |
|
||||
|-----------|--------|-------|
|
||||
| Default hook timeout | 120s | 300s |
|
||||
| Health check timeout | 1s | 30s |
|
||||
| Health check retries | 15 | 300 |
|
||||
| Context initialization | 30s | 300s |
|
||||
| MCP connection | 15s | 300s |
|
||||
| PowerShell commands | 5s | 60s |
|
||||
| Git commands | 30s | 300s |
|
||||
| NPM install | 120s | 600s |
|
||||
| Hook worker commands | 30s | 180s |
|
||||
|
||||
### 🧪 Testing
|
||||
|
||||
Added comprehensive test suites:
|
||||
- `tests/hook-constants.test.ts` - Validates timeout configurations
|
||||
- `tests/worker-spawn.test.ts` - Tests worker CLI and health endpoints
|
||||
|
||||
### 🛡️ Additional Robustness
|
||||
|
||||
- PID validation in restart command (matches start command behavior)
|
||||
- Try/catch around `forceKillProcess()` for graceful shutdown
|
||||
- Try/catch around `getChildProcesses()` for Windows failures
|
||||
- Improved logging for PID file operations and HTTP shutdown
|
||||
|
||||
---
|
||||
|
||||
**Full Changelog**: https://github.com/thedotmack/claude-mem/compare/v8.2.0...v8.2.1
|
||||
|
||||
|
||||
+1
-2
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "claude-mem",
|
||||
"version": "10.2.1",
|
||||
"version": "10.2.3",
|
||||
"description": "Memory compression system for Claude Code - persist context across sessions",
|
||||
"keywords": [
|
||||
"claude",
|
||||
@@ -118,7 +118,6 @@
|
||||
"@types/react": "^18.3.5",
|
||||
"@types/react-dom": "^18.3.0",
|
||||
"esbuild": "^0.27.2",
|
||||
"node-addon-api": "^8.5.0",
|
||||
"np": "^11.0.2",
|
||||
"tsx": "^4.20.6",
|
||||
"typescript": "^5.3.0"
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "claude-mem",
|
||||
"version": "10.2.1",
|
||||
"version": "10.2.3",
|
||||
"description": "Persistent memory system for Claude Code - seamlessly preserve context across sessions",
|
||||
"author": {
|
||||
"name": "Alex Newman"
|
||||
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "claude-mem-plugin",
|
||||
"version": "10.2.1",
|
||||
"version": "10.2.3",
|
||||
"private": true,
|
||||
"description": "Runtime dependencies for claude-mem bundled hooks",
|
||||
"type": "module",
|
||||
|
||||
File diff suppressed because one or more lines are too long
+311
-264
File diff suppressed because one or more lines are too long
@@ -5,7 +5,7 @@
|
||||
* Ensures Bun runtime and uv (Python package manager) are installed
|
||||
* (auto-installs if missing) and handles dependency installation when needed.
|
||||
*/
|
||||
import { existsSync, readFileSync, writeFileSync, rmSync } from 'fs';
|
||||
import { existsSync, readFileSync, writeFileSync } from 'fs';
|
||||
import { execSync, spawnSync } from 'child_process';
|
||||
import { join } from 'path';
|
||||
import { homedir } from 'os';
|
||||
@@ -260,15 +260,6 @@ function installDeps() {
|
||||
|
||||
console.error('📦 Installing dependencies with Bun...');
|
||||
|
||||
// Clear stale native module cache (sharp/libvips) to prevent broken dylib references.
|
||||
// Bun's cache can retain native binaries that reference companion libraries at
|
||||
// broken relative paths after version upgrades.
|
||||
const bunCacheImgDir = join(homedir(), '.bun', 'install', 'cache', '@img');
|
||||
if (existsSync(bunCacheImgDir)) {
|
||||
console.error(' Clearing stale native module cache (@img/sharp)...');
|
||||
rmSync(bunCacheImgDir, { recursive: true, force: true });
|
||||
}
|
||||
|
||||
// Quote path for Windows paths with spaces
|
||||
const bunCmd = IS_WINDOWS && bunPath.includes(' ') ? `"${bunPath}"` : bunPath;
|
||||
|
||||
|
||||
@@ -80,24 +80,6 @@ try {
|
||||
{ stdio: 'inherit' }
|
||||
);
|
||||
|
||||
// Remove stale lockfiles before install — they pin old native dep versions
|
||||
const { unlinkSync, rmSync } = require('fs');
|
||||
for (const lockfile of ['package-lock.json', 'bun.lock']) {
|
||||
const lockpath = path.join(INSTALLED_PATH, lockfile);
|
||||
if (existsSync(lockpath)) {
|
||||
unlinkSync(lockpath);
|
||||
console.log(`Removed stale ${lockfile}`);
|
||||
}
|
||||
}
|
||||
|
||||
// Clear stale native module cache (sharp/libvips) — Bun's cache can retain
|
||||
// native binaries that reference companion libraries at broken relative paths
|
||||
const bunCacheImgDir = path.join(os.homedir(), '.bun', 'install', 'cache', '@img');
|
||||
if (existsSync(bunCacheImgDir)) {
|
||||
rmSync(bunCacheImgDir, { recursive: true, force: true });
|
||||
console.log('Cleared stale native module cache (@img/sharp)');
|
||||
}
|
||||
|
||||
console.log('Running bun install in marketplace...');
|
||||
execSync(
|
||||
'cd ~/.claude/plugins/marketplaces/thedotmack/ && bun install',
|
||||
@@ -117,6 +99,10 @@ try {
|
||||
{ stdio: 'inherit' }
|
||||
);
|
||||
|
||||
// Install dependencies in cache directory so worker can resolve them
|
||||
console.log(`Running bun install in cache folder (version ${version})...`);
|
||||
execSync(`bun install`, { cwd: CACHE_VERSION_PATH, stdio: 'inherit' });
|
||||
|
||||
console.log('\x1b[32m%s\x1b[0m', 'Sync complete!');
|
||||
|
||||
// Trigger worker restart after file sync
|
||||
|
||||
@@ -81,6 +81,7 @@ export class ChromaSync {
|
||||
private collectionName: string;
|
||||
private readonly VECTOR_DB_DIR: string;
|
||||
private readonly BATCH_SIZE = 100;
|
||||
private modelCacheCorruptionRetried = false;
|
||||
|
||||
constructor(project: string) {
|
||||
this.project = project;
|
||||
@@ -189,6 +190,10 @@ export class ChromaSync {
|
||||
}
|
||||
|
||||
try {
|
||||
// Store model cache outside node_modules so reinstalls don't corrupt it
|
||||
const { env } = await import('@huggingface/transformers');
|
||||
env.cacheDir = path.join(os.homedir(), '.claude-mem', 'models');
|
||||
|
||||
// Use WASM backend to avoid native ONNX binary issues (#1104, #1105, #1110).
|
||||
// Same model (all-MiniLM-L6-v2), same embeddings, but runs in WASM —
|
||||
// no native binary loading, no segfaults, no ENOENT errors.
|
||||
@@ -204,8 +209,22 @@ export class ChromaSync {
|
||||
collection: this.collectionName
|
||||
});
|
||||
} catch (error) {
|
||||
const errorMessage = error instanceof Error ? error.message : String(error);
|
||||
|
||||
// Self-heal: corrupted model cache → clear and retry once
|
||||
if (errorMessage.includes('Protobuf parsing failed') && !this.modelCacheCorruptionRetried) {
|
||||
this.modelCacheCorruptionRetried = true;
|
||||
logger.warn('CHROMA_SYNC', 'Corrupted model cache detected, clearing and retrying...');
|
||||
const modelCacheDir = path.join(os.homedir(), '.claude-mem', 'models');
|
||||
const fs = await import('fs');
|
||||
if (fs.existsSync(modelCacheDir)) {
|
||||
fs.rmSync(modelCacheDir, { recursive: true, force: true });
|
||||
}
|
||||
return this.ensureCollection(); // retry once
|
||||
}
|
||||
|
||||
logger.error('CHROMA_SYNC', 'Failed to get/create collection', { collection: this.collectionName }, error as Error);
|
||||
throw new Error(`Collection setup failed: ${error instanceof Error ? error.message : String(error)}`);
|
||||
throw new Error(`Collection setup failed: ${errorMessage}`);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user