Compare commits

...

2 Commits

Author SHA1 Message Date
Alex Newman 19af455c57 chore: bump version to 7.1.2
🐛 Bug Fixes

**Windows Installation**
- Fixed Bun PATH detection on Windows after fresh install
- Added fallback to check common install paths before PATH reload
- Improved smart-install.js to use full Bun path when not in PATH
- Added proper path quoting for Windows usernames with spaces

**Worker Startup**
- Fixed worker connection failures in Stop hook
- Added health check retry loop (5 attempts, 500ms intervals)
- Worker now waits up to 2.5s for responsiveness before returning
- Improved error detection for Bun's ConnectionRefused error format

🎯 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2025-12-12 22:50:53 -05:00
Alex Newman b5807aed2e docs: regenerate CHANGELOG from GitHub releases 2025-12-12 22:41:39 -05:00
8 changed files with 113 additions and 100 deletions
+1 -1
View File
@@ -10,7 +10,7 @@
"plugins": [
{
"name": "claude-mem",
"version": "7.1.1",
"version": "7.1.2",
"source": "./plugin",
"description": "Persistent memory system for Claude Code - context compression across sessions"
}
+27 -81
View File
@@ -4,93 +4,39 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
## [7.1.1] - 2025-12-12
## [7.1.1] - 2025-12-13
### Fixed
## 🚨 Critical Fixes
**CRITICAL: Windows 11 Bun Auto-Install Broken**
### Windows 11 Bun Auto-Install Fixed
- **Problem**: v7.1.0 had a chicken-and-egg bug where `bun smart-install.js` failed if Bun wasn't installed
- **Solution**: SessionStart hook now uses `node` (always available) for smart-install.js
- **Impact**: Fresh Windows installations now work out-of-box
- **Chicken-and-Egg Problem**: v7.1.0 hooks called `bun smart-install.js`, but if Bun wasn't installed, the command failed with "bun is not recognized" before smart-install.js could run to install Bun
- **Root Cause**: v7.1.0 migration removed Bun/uv auto-installation logic from smart-install.js
- **Solution**:
- Changed SessionStart hook to use `node` (always available) for smart-install.js
- Restored Bun auto-installation logic: isBunInstalled(), installBun()
- Restored uv auto-installation for Chroma support
- Fresh Windows installations now work correctly
### Path Quoting for Windows
- Fixed `hooks.json` to quote all paths
- Prevents SyntaxError for usernames with spaces (e.g., "C:\Users\John Doe\")
**Path Quoting for Windows Usernames with Spaces**
## ✨ New Feature
- Fixed `hooks.json` to quote all `${CLAUDE_PLUGIN_ROOT}` paths
- Prevents SyntaxError for Windows users with spaces in usernames (e.g., "C:\Users\John Doe\...")
### Automatic Worker Restart on Version Updates
- Worker now automatically restarts when plugin version changes
- No more manual `npm run worker:restart` needed after upgrades
- Eliminates connection errors from running old worker code
### Added
## 📝 Notes
**Automatic Worker Restart on Version Updates**
- **No manual actions required** - worker auto-restarts on next session start
- All future upgrades will automatically restart the worker
- Fresh installs on Windows 11 work correctly
- Added `/api/version` endpoint to worker service
- Added version checking in `ensureWorkerRunning()`:
- Compares plugin version with running worker version
- Automatically restarts worker when version mismatch detected
- Logs version mismatch for debugging
- **Impact**: Users no longer need to manually restart worker after upgrades
- **Critical for**: All future releases - eliminates connection errors from running old worker code
## 🔗 Links
### Notes
- No manual actions required - worker auto-restarts on next session start
- Fresh installs on Windows 11 now work out-of-box
- All hooks now run with correct runtime (node for install, bun for execution)
- [Full Changelog](https://github.com/thedotmack/claude-mem/blob/main/CHANGELOG.md#711---2025-12-12)
- [Documentation](https://docs.claude-mem.ai)
## [7.1.0] - 2025-12-13
## Security Fix: Localhost-Only Binding
**BREAKING CHANGE**: Worker service now binds to `127.0.0.1` (localhost) by default instead of `0.0.0.0` (all interfaces).
### Security Issue Fixed
The worker service was previously binding to `0.0.0.0:37777` by default, exposing all API endpoints to the network without authentication. This posed security risks:
- Unauthorized access to memory data from any network device
- Potential data injection into the database
- Settings modification from remote devices
- Full access to Web Viewer UI from the network
### Solution
Default worker binding changed to `127.0.0.1` (localhost-only), with a new configurable setting `CLAUDE_MEM_WORKER_HOST` for users who need remote access.
### Changes
- **Core**: Added `CLAUDE_MEM_WORKER_HOST` setting with default value `127.0.0.1`
- **Worker**: Modified `worker-service.ts` to bind to configured host address
- **API**: Added host validation in `SettingsRoutes.ts` (IP address format check)
- **UI**: Added host configuration field in Settings panel
- **Docs**: Updated README.md and CLAUDE.md with new setting
### Configuration
**Default (secure):** localhost only
```bash
CLAUDE_MEM_WORKER_HOST=127.0.0.1
```
**Remote access (server deployments):**
```bash
CLAUDE_MEM_WORKER_HOST=0.0.0.0
```
Can be configured via:
- `~/.claude-mem/settings.json`
- Web Viewer UI Settings panel
### Migration
**Automatic**: Existing installations will use `127.0.0.1` on next worker restart. If you need remote access, set `CLAUDE_MEM_WORKER_HOST=0.0.0.0` in `~/.claude-mem/settings.json`.
### Contributors
Thanks to @7Sageer for identifying and fixing this security issue!
## Major Architectural Migration
This release completely replaces PM2 with native Bun-based process management and migrates from better-sqlite3 to bun:sqlite.
@@ -1991,12 +1937,12 @@ None (patch version)
## [4.3.0] - 2025-10-25
## What's Changed
* feat: Enhanced context hook with session observations and cross-platform improvements by @thedotmack in https://github.com/thedotmack/claude-mem/pull/25
## New Contributors
* @thedotmack made their first contribution in https://github.com/thedotmack/claude-mem/pull/25
## What's Changed
* feat: Enhanced context hook with session observations and cross-platform improvements by @thedotmack in https://github.com/thedotmack/claude-mem/pull/25
## New Contributors
* @thedotmack made their first contribution in https://github.com/thedotmack/claude-mem/pull/25
**Full Changelog**: https://github.com/thedotmack/claude-mem/compare/v4.2.11...v4.3.0
## [4.2.10] - 2025-10-25
+1 -1
View File
@@ -6,7 +6,7 @@
Claude-mem is a Claude Code plugin providing persistent memory across sessions. It captures tool usage, compresses observations using the Claude Agent SDK, and injects relevant context into future sessions.
**Current Version**: 7.1.1
**Current Version**: 7.1.2
## Architecture
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "claude-mem",
"version": "7.1.1",
"version": "7.1.2",
"description": "Memory compression system for Claude Code - persist context across sessions",
"keywords": [
"claude",
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "claude-mem",
"version": "7.1.1",
"version": "7.1.2",
"description": "Persistent memory system for Claude Code - seamlessly preserve context across sessions",
"author": {
"name": "Alex Newman"
+61 -7
View File
@@ -24,18 +24,56 @@ function isBunInstalled() {
stdio: ['pipe', 'pipe', 'pipe'],
shell: IS_WINDOWS
});
return result.status === 0;
if (result.status === 0) return true;
} catch {
return false;
// PATH check failed, try common installation paths
}
// Check common installation paths (handles fresh installs before PATH reload)
const bunPaths = IS_WINDOWS
? [join(homedir(), '.bun', 'bin', 'bun.exe')]
: [join(homedir(), '.bun', 'bin', 'bun'), '/usr/local/bin/bun'];
return bunPaths.some(existsSync);
}
/**
* Get the Bun executable path (from PATH or common install locations)
*/
function getBunPath() {
// Try PATH first
try {
const result = spawnSync('bun', ['--version'], {
encoding: 'utf-8',
stdio: ['pipe', 'pipe', 'pipe'],
shell: IS_WINDOWS
});
if (result.status === 0) return 'bun';
} catch {
// Not in PATH
}
// Check common installation paths
const bunPaths = IS_WINDOWS
? [join(homedir(), '.bun', 'bin', 'bun.exe')]
: [join(homedir(), '.bun', 'bin', 'bun'), '/usr/local/bin/bun'];
for (const bunPath of bunPaths) {
if (existsSync(bunPath)) return bunPath;
}
return null;
}
/**
* Get Bun version if installed
*/
function getBunVersion() {
const bunPath = getBunPath();
if (!bunPath) return null;
try {
const result = spawnSync('bun', ['--version'], {
const result = spawnSync(bunPath, ['--version'], {
encoding: 'utf-8',
stdio: ['pipe', 'pipe', 'pipe'],
shell: IS_WINDOWS
@@ -56,10 +94,17 @@ function isUvInstalled() {
stdio: ['pipe', 'pipe', 'pipe'],
shell: IS_WINDOWS
});
return result.status === 0;
if (result.status === 0) return true;
} catch {
return false;
// PATH check failed, try common installation paths
}
// Check common installation paths (handles fresh installs before PATH reload)
const uvPaths = IS_WINDOWS
? [join(homedir(), '.local', 'bin', 'uv.exe'), join(homedir(), '.cargo', 'bin', 'uv.exe')]
: [join(homedir(), '.local', 'bin', 'uv'), join(homedir(), '.cargo', 'bin', 'uv'), '/usr/local/bin/uv'];
return uvPaths.some(existsSync);
}
/**
@@ -226,12 +271,21 @@ function needsInstall() {
* Install dependencies using Bun
*/
function installDeps() {
const bunPath = getBunPath();
if (!bunPath) {
throw new Error('Bun executable not found');
}
console.error('📦 Installing dependencies with Bun...');
// Quote path for Windows paths with spaces
const bunCmd = IS_WINDOWS && bunPath.includes(' ') ? `"${bunPath}"` : bunPath;
try {
execSync('bun install', { cwd: ROOT, stdio: 'inherit', shell: IS_WINDOWS });
execSync(`${bunCmd} install`, { cwd: ROOT, stdio: 'inherit', shell: IS_WINDOWS });
} catch {
// Retry with force flag
execSync('bun install --force', { cwd: ROOT, stdio: 'inherit', shell: IS_WINDOWS });
execSync(`${bunCmd} install --force`, { cwd: ROOT, stdio: 'inherit', shell: IS_WINDOWS });
}
// Write version marker
+3 -1
View File
@@ -4,8 +4,10 @@
*/
export function handleWorkerError(error: any): never {
if (error.cause?.code === 'ECONNREFUSED' ||
error.code === 'ConnectionRefused' || // Bun-specific error format
error.name === 'TimeoutError' ||
error.message?.includes('fetch failed')) {
error.message?.includes('fetch failed') ||
error.message?.includes('Unable to connect')) {
throw new Error(
"There's a problem with the worker. Try: npm run worker:restart"
);
+18 -7
View File
@@ -194,13 +194,6 @@ export async function ensureWorkerRunning(): Promise<void> {
// Try to start the worker
const started = await startWorker();
// Final health check before throwing error
// Worker might be already running but was temporarily unresponsive
if (!started && await isWorkerHealthy()) {
await ensureWorkerVersionMatches();
return;
}
if (!started) {
const port = getWorkerPort();
throw new Error(
@@ -209,4 +202,22 @@ export async function ensureWorkerRunning(): Promise<void> {
`If already running, try: npm run worker:restart`
);
}
// Wait for worker to become responsive after starting
// Try up to 5 times with 500ms delays (2.5 seconds total)
for (let i = 0; i < 5; i++) {
await new Promise(resolve => setTimeout(resolve, 500));
if (await isWorkerHealthy()) {
await ensureWorkerVersionMatches();
return;
}
}
// Worker started but isn't responding
const port = getWorkerPort();
logger.error('SYSTEM', 'Worker started but not responding to health checks');
throw new Error(
`Worker service started but is not responding on port ${port}.\n\n` +
`Try: npm run worker:restart`
);
}