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>
This commit is contained in:
@@ -10,7 +10,7 @@
|
|||||||
"plugins": [
|
"plugins": [
|
||||||
{
|
{
|
||||||
"name": "claude-mem",
|
"name": "claude-mem",
|
||||||
"version": "7.1.1",
|
"version": "7.1.2",
|
||||||
"source": "./plugin",
|
"source": "./plugin",
|
||||||
"description": "Persistent memory system for Claude Code - context compression across sessions"
|
"description": "Persistent memory system for Claude Code - context compression across sessions"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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.
|
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
|
## Architecture
|
||||||
|
|
||||||
|
|||||||
+1
-1
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "claude-mem",
|
"name": "claude-mem",
|
||||||
"version": "7.1.1",
|
"version": "7.1.2",
|
||||||
"description": "Memory compression system for Claude Code - persist context across sessions",
|
"description": "Memory compression system for Claude Code - persist context across sessions",
|
||||||
"keywords": [
|
"keywords": [
|
||||||
"claude",
|
"claude",
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "claude-mem",
|
"name": "claude-mem",
|
||||||
"version": "7.1.1",
|
"version": "7.1.2",
|
||||||
"description": "Persistent memory system for Claude Code - seamlessly preserve context across sessions",
|
"description": "Persistent memory system for Claude Code - seamlessly preserve context across sessions",
|
||||||
"author": {
|
"author": {
|
||||||
"name": "Alex Newman"
|
"name": "Alex Newman"
|
||||||
|
|||||||
@@ -24,18 +24,56 @@ function isBunInstalled() {
|
|||||||
stdio: ['pipe', 'pipe', 'pipe'],
|
stdio: ['pipe', 'pipe', 'pipe'],
|
||||||
shell: IS_WINDOWS
|
shell: IS_WINDOWS
|
||||||
});
|
});
|
||||||
return result.status === 0;
|
if (result.status === 0) return true;
|
||||||
} catch {
|
} 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
|
* Get Bun version if installed
|
||||||
*/
|
*/
|
||||||
function getBunVersion() {
|
function getBunVersion() {
|
||||||
|
const bunPath = getBunPath();
|
||||||
|
if (!bunPath) return null;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const result = spawnSync('bun', ['--version'], {
|
const result = spawnSync(bunPath, ['--version'], {
|
||||||
encoding: 'utf-8',
|
encoding: 'utf-8',
|
||||||
stdio: ['pipe', 'pipe', 'pipe'],
|
stdio: ['pipe', 'pipe', 'pipe'],
|
||||||
shell: IS_WINDOWS
|
shell: IS_WINDOWS
|
||||||
@@ -56,10 +94,17 @@ function isUvInstalled() {
|
|||||||
stdio: ['pipe', 'pipe', 'pipe'],
|
stdio: ['pipe', 'pipe', 'pipe'],
|
||||||
shell: IS_WINDOWS
|
shell: IS_WINDOWS
|
||||||
});
|
});
|
||||||
return result.status === 0;
|
if (result.status === 0) return true;
|
||||||
} catch {
|
} 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
|
* Install dependencies using Bun
|
||||||
*/
|
*/
|
||||||
function installDeps() {
|
function installDeps() {
|
||||||
|
const bunPath = getBunPath();
|
||||||
|
if (!bunPath) {
|
||||||
|
throw new Error('Bun executable not found');
|
||||||
|
}
|
||||||
|
|
||||||
console.error('📦 Installing dependencies with Bun...');
|
console.error('📦 Installing dependencies with Bun...');
|
||||||
|
|
||||||
|
// Quote path for Windows paths with spaces
|
||||||
|
const bunCmd = IS_WINDOWS && bunPath.includes(' ') ? `"${bunPath}"` : bunPath;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
execSync('bun install', { cwd: ROOT, stdio: 'inherit', shell: IS_WINDOWS });
|
execSync(`${bunCmd} install`, { cwd: ROOT, stdio: 'inherit', shell: IS_WINDOWS });
|
||||||
} catch {
|
} catch {
|
||||||
// Retry with force flag
|
// 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
|
// Write version marker
|
||||||
|
|||||||
@@ -4,8 +4,10 @@
|
|||||||
*/
|
*/
|
||||||
export function handleWorkerError(error: any): never {
|
export function handleWorkerError(error: any): never {
|
||||||
if (error.cause?.code === 'ECONNREFUSED' ||
|
if (error.cause?.code === 'ECONNREFUSED' ||
|
||||||
|
error.code === 'ConnectionRefused' || // Bun-specific error format
|
||||||
error.name === 'TimeoutError' ||
|
error.name === 'TimeoutError' ||
|
||||||
error.message?.includes('fetch failed')) {
|
error.message?.includes('fetch failed') ||
|
||||||
|
error.message?.includes('Unable to connect')) {
|
||||||
throw new Error(
|
throw new Error(
|
||||||
"There's a problem with the worker. Try: npm run worker:restart"
|
"There's a problem with the worker. Try: npm run worker:restart"
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -194,13 +194,6 @@ export async function ensureWorkerRunning(): Promise<void> {
|
|||||||
// Try to start the worker
|
// Try to start the worker
|
||||||
const started = await startWorker();
|
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) {
|
if (!started) {
|
||||||
const port = getWorkerPort();
|
const port = getWorkerPort();
|
||||||
throw new Error(
|
throw new Error(
|
||||||
@@ -209,4 +202,22 @@ export async function ensureWorkerRunning(): Promise<void> {
|
|||||||
`If already running, try: npm run worker:restart`
|
`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`
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user