Compare commits

...

3 Commits

Author SHA1 Message Date
Alex Newman da01e4bba0 chore: bump version to 9.0.9 2026-01-25 23:59:26 -05:00
Max Millien 7c3bfadd5e fix: Prevent creation of new CLAUDE.md files if no activity is present. (#809) 2026-01-25 23:57:55 -05:00
Alex Newman a8bb625513 docs: update CHANGELOG.md for v9.0.8 2026-01-25 20:13:04 -05:00
8 changed files with 79 additions and 44 deletions
+1 -1
View File
@@ -10,7 +10,7 @@
"plugins": [
{
"name": "claude-mem",
"version": "9.0.8",
"version": "9.0.9",
"source": "./plugin",
"description": "Persistent memory system for Claude Code - context compression across sessions"
}
+31 -8
View File
@@ -2,6 +2,37 @@
All notable changes to claude-mem.
## [v9.0.8] - 2026-01-26
## Fix: Prevent Zombie Process Accumulation (Issue #737)
This release fixes a critical issue where Claude haiku subprocesses spawned by the SDK weren't terminating properly, causing zombie process accumulation. One user reported 155 processes consuming 51GB RAM.
### Root Causes Addressed
- SDK's SpawnedProcess interface hides subprocess PIDs
- `deleteSession()` didn't verify subprocess exit
- `abort()` was fire-and-forget with no confirmation
- No mechanism to track or clean up orphaned processes
### Solution
- **ProcessRegistry module**: Tracks spawned Claude subprocesses via PID
- **Custom spawn**: Uses SDK's `spawnClaudeCodeProcess` option to capture PIDs
- **Signal propagation**: Passes signal parameter to enable AbortController integration
- **Graceful shutdown**: Waits for subprocess exit in `deleteSession()` with 5s timeout
- **SIGKILL escalation**: Force-kills processes that don't exit gracefully
- **Orphan reaper**: Safety net running every 5 minutes to clean up any missed processes
- **Race detection**: Warns about multiple processes per session (race condition indicator)
### Files Changed
- `src/services/worker/ProcessRegistry.ts` (new): PID registry and reaper
- `src/services/worker/SDKAgent.ts`: Use custom spawn to capture PIDs
- `src/services/worker/SessionManager.ts`: Verify subprocess exit on delete
- `src/services/worker-service.ts`: Start/stop orphan reaper
**Full Changelog**: https://github.com/thedotmack/claude-mem/compare/v9.0.7...v9.0.8
Fixes #737
## [v9.0.6] - 2026-01-22
## Windows Console Popup Fix
@@ -1265,11 +1296,3 @@ This represents a major reliability improvement for Windows users, eliminating c
Patch release for bug fixes and minor improvements
## [v7.3.3] - 2025-12-16
## What's Changed
- Remove all better-sqlite3 references from codebase (#357)
**Full Changelog**: https://github.com/thedotmack/claude-mem/compare/v7.3.2...v7.3.3
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "claude-mem",
"version": "9.0.8",
"version": "9.0.9",
"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": "9.0.8",
"version": "9.0.9",
"description": "Persistent memory system for Claude Code - seamlessly preserve context across sessions",
"author": {
"name": "Alex Newman"
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "claude-mem-plugin",
"version": "9.0.8",
"version": "9.0.9",
"private": true,
"description": "Runtime dependencies for claude-mem bundled hooks",
"type": "module",
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
+14 -2
View File
@@ -76,8 +76,8 @@ export function replaceTaggedContent(existingContent: string, newContent: string
if (startIdx !== -1 && endIdx !== -1) {
return existingContent.substring(0, startIdx) +
`${startTag}\n${newContent}\n${endTag}` +
existingContent.substring(endIdx + endTag.length);
`${startTag}\n${newContent}\n${endTag}` +
existingContent.substring(endIdx + endTag.length);
}
// If no tags exist, append tagged content at end
@@ -320,6 +320,18 @@ export async function updateFolderClaudeMdFiles(
}
const formatted = formatTimelineForClaudeMd(result.content[0].text);
// Fix for #758: Don't create new CLAUDE.md files if there's no activity
// But update existing ones to show "No recent activity" if they already exist
const claudeMdPath = path.join(folderPath, 'CLAUDE.md');
const hasNoActivity = formatted.includes('*No recent activity*');
const fileExists = existsSync(claudeMdPath);
if (hasNoActivity && !fileExists) {
logger.debug('FOLDER_INDEX', 'Skipping empty CLAUDE.md creation', { folderPath });
continue;
}
writeClaudeMdToFolder(folderPath, formatted);
logger.debug('FOLDER_INDEX', 'Updated CLAUDE.md', { folderPath });