Release v3.5.4

- Updated to match npm package structure
- Includes minified dist/claude-mem.min.js
- Added commands directory
- Updated hooks with latest fixes
- Synced with npm package claude-mem@3.5.4
This commit is contained in:
Alex Newman
2025-09-09 02:10:00 -04:00
parent 4da61a77c7
commit aae7de8e05
15 changed files with 625 additions and 231 deletions
-13
View File
@@ -1,13 +0,0 @@
# Binaries (distributed via GitHub releases)
*.exe
*.app
claude-mem
claude-mem-*
# Temporary files
*.tmp
*.log
.DS_Store
# Node modules (if any)
node_modules/
-58
View File
@@ -1,58 +0,0 @@
# Installation Guide
## Quick Install (Recommended)
### Via NPM
```bash
npm install -g claude-mem
```
### Via curl
```bash
curl -fsSL https://raw.githubusercontent.com/thedotmack/claude-mem/main/install.sh | bash
```
## Manual Installation
1. Download the appropriate binary for your platform from [Releases](https://github.com/thedotmack/claude-mem/releases/latest):
- **Windows**: `claude-mem.exe`
- **Linux x64**: `claude-mem-linux`
- **Linux ARM64**: `claude-mem-linux-arm64`
- **macOS Intel**: `claude-mem-macos-x64`
- **macOS Apple Silicon**: `claude-mem-macos-arm64`
2. Make it executable (Unix-based systems):
```bash
chmod +x claude-mem-*
```
3. Move to your PATH:
```bash
sudo mv claude-mem-* /usr/local/bin/claude-mem
```
## After Installation
Once the binary is installed, set up Claude Code integration:
```bash
claude-mem install
```
This will:
- Install the Chroma MCP server
- Configure Claude Code hooks
- Set up the memory system
## Platform Detection
The `claude-mem` command automatically detects your platform and runs the correct binary. No manual selection needed!
## Troubleshooting
If you get a "command not found" error:
1. Ensure the binary is in your PATH
2. Try running with full path: `./claude-mem`
3. Check binary permissions: `ls -la claude-mem*`
For other issues, please check our [Issues](https://github.com/thedotmack/claude-mem/issues) page.
+22 -34
View File
@@ -1,43 +1,31 @@
# Claude Mem License
CLAUDE-MEM SOFTWARE LICENSE
Copyright (c) 2024 Alex Newman (@thedotmack)
## Binary Distribution License
The compiled binaries (claude-mem, claude-mem.exe, etc.) are provided free of charge for personal and commercial use under the following terms:
1. **USE**: You may use the binaries for any purpose.
2. **DISTRIBUTION**: You may redistribute the unmodified binaries.
3. **NO REVERSE ENGINEERING**: You may not decompile, disassemble, or reverse engineer the binaries.
4. **NO MODIFICATION**: You may not modify the binary files.
5. **NO WARRANTY**: The software is provided "as is" without warranty of any kind.
## Hook Files License (MIT)
The hook files in the `/hooks` directory are licensed under the MIT License:
Copyright (c) 2024 Alex Newman (@thedotmack). All rights reserved.
Permission is hereby granted, free of charge, to any person obtaining a copy
of these hook files and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
of this software in its compiled/distributed form via npm, to use the software
for any purpose, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
1. USE RIGHTS: You may use the claude-mem CLI tool for personal or commercial
purposes without restriction.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
2. NO SOURCE CODE RIGHTS: This license does NOT grant access to source code,
modification rights, or redistribution rights. The software is provided
as-is in its compiled form only.
## Contributions
3. NO REVERSE ENGINEERING: You may not reverse engineer, decompile, or
disassemble the software.
By submitting pull requests for hook files or documentation, you agree to license your contributions under the MIT License.
4. NO REDISTRIBUTION: You may not redistribute, repackage, or resell this
software. Users must install it from the official npm registry.
## Trademark
5. NO WARRANTY: THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
"Claude Mem" is a trademark of Alex Newman. You may use the name when referring to this software, but not in a way that implies endorsement or affiliation.
6. LIMITATION OF LIABILITY: IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT
OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR
THE USE OR OTHER DEALINGS IN THE SOFTWARE.
For questions about this license, contact: thedotmack@gmail.com
+8 -1
View File
@@ -50,12 +50,17 @@ Transform your Claude Code experience from forgetful to persistent, from isolate
## 🛠 Installation & Setup
### Prerequisites
- Node.js 18+
- Claude Code CLI installed
- uv (Python package manager) - automatically installed if missing
### Quick Install
```bash
# Install globally
npm install -g claude-mem
# Set up Claude Code integration
# Set up Claude Code integration (installs uv if needed)
claude-mem install
# Restart Claude Code to activate
@@ -67,6 +72,8 @@ claude-mem install
npx claude-mem install
```
The `claude-mem install` command will automatically install [uv](https://docs.astral.sh/uv/) if it's not already present on your system. uv is required for the Chroma MCP server that powers the memory system.
### Verification
```bash
# Check installation status
-40
View File
@@ -1,40 +0,0 @@
# Claude Mem v3.3.8
## 🚀 Installation
### Quick Install (Recommended)
```bash
curl -fsSL https://raw.githubusercontent.com/thedotmack/claude-mem/main/install.sh | bash
```
### Manual Download
Download the appropriate binary for your platform from the [releases page](https://github.com/thedotmack/claude-mem/releases/latest):
- **Windows x64**: `claude-mem.exe`
- **Linux x64**: `claude-mem-linux`
- **Linux ARM64**: `claude-mem-linux-arm64`
- **macOS ARM64** (Apple Silicon): `claude-mem-macos-arm64`
- **macOS x64** (Intel): `claude-mem-macos-x64`
## 📦 What's Included
- Multi-platform binaries for Windows, Linux, and macOS
- Hook system for customization
- Full documentation
- MCP server integration for Claude Code
## 🔧 Supported Platforms
| Platform | Architecture | Binary Name |
|----------|--------------|-------------|
| Windows | x64 | claude-mem.exe |
| Linux | x64 | claude-mem-linux |
| Linux | ARM64 | claude-mem-linux-arm64 |
| macOS | ARM64 (Apple Silicon) | claude-mem-macos-arm64 |
| macOS | x64 (Intel) | claude-mem-macos-x64 |
## 📝 License
Binary distribution under proprietary license (free to use).
Hook files under MIT license (open source).
See LICENSE file for details.
+1
View File
@@ -0,0 +1 @@
Search claude-mem for #$ARGUMENTS and look up relevant context to help clarify what we are working on.
+3
View File
@@ -0,0 +1,3 @@
Write an overview of the current conversation context and:
1. Add it to claude-mem using the chroma MCP tools
2. Save the overview using the claude-mem CLI tool: `claude-mem save "your overview message"`
Vendored Executable
+444
View File
File diff suppressed because one or more lines are too long
+17 -12
View File
@@ -9,6 +9,7 @@
*/
import { loadCliCommand } from './shared/config-loader.js';
import { getLogsDir } from './shared/path-resolver.js';
import {
createHookResponse,
executeCliCommand,
@@ -16,7 +17,9 @@ import {
debugLog
} from './shared/hook-helpers.js';
const cliCommand = loadCliCommand();
// Set up stdin immediately before any async operations
process.stdin.setEncoding('utf8');
process.stdin.resume(); // Explicitly enter flowing mode to prevent data loss
// Read input from stdin
let input = '';
@@ -26,6 +29,9 @@ process.stdin.on('data', chunk => {
process.stdin.on('end', async () => {
try {
// Load CLI command inside try-catch to handle config errors properly
const cliCommand = loadCliCommand();
const payload = JSON.parse(input);
debugLog('Pre-compact hook started', { payload });
@@ -33,17 +39,18 @@ process.stdin.on('end', async () => {
const validation = validateHookPayload(payload, 'PreCompact');
if (!validation.valid) {
const response = createHookResponse('PreCompact', false, { reason: validation.error });
console.log(JSON.stringify(response));
debugLog('Validation failed', { response });
// Exit silently - validation failure is expected flow control
process.exit(0);
}
// Check for environment-based blocking conditions
if (payload.trigger === 'auto' && process.env.DISABLE_AUTO_COMPRESSION === 'true') {
debugLog('Auto-compression disabled by configuration');
const response = createHookResponse('PreCompact', false, {
reason: 'Auto-compression disabled by configuration'
});
console.log(JSON.stringify(response));
debugLog('Auto-compression disabled', { response });
// Exit silently - disabled compression is expected flow control
process.exit(0);
}
@@ -56,26 +63,24 @@ process.stdin.on('end', async () => {
const result = await executeCliCommand(cliCommand, ['compress', payload.transcript_path]);
if (!result.success) {
debugLog('Compression command failed', { stderr: result.stderr });
const response = createHookResponse('PreCompact', false, {
reason: `Compression failed: ${result.stderr || 'Unknown error'}`
});
console.log(JSON.stringify(response));
process.exit(0);
debugLog('Compression command failed', { stderr: result.stderr, response });
console.log(`claude-mem error: compression failed, see logs at ${getLogsDir()}`);
process.exit(1); // Exit with error code for actual compression failure
}
// Success - create standardized approval response using HookTemplates
// Success - exit silently (suppressOutput is true)
debugLog('Compression completed successfully');
const response = createHookResponse('PreCompact', true);
console.log(JSON.stringify(response));
process.exit(0);
} catch (error) {
debugLog('Pre-compact hook error', { error: error.message });
const response = createHookResponse('PreCompact', false, {
reason: `Hook execution error: ${error.message}`
});
console.log(JSON.stringify(response));
debugLog('Pre-compact hook error', { error: error.message, response });
console.log(`claude-mem error: hook failed, see logs at ${getLogsDir()}`);
process.exit(1);
}
});
+7 -4
View File
@@ -5,16 +5,15 @@
*/
import { loadCliCommand } from './shared/config-loader.js';
import { getSettingsPath, getArchivesDir } from './shared/path-resolver.js';
import { execSync } from 'child_process';
import { join } from 'path';
import { homedir } from 'os';
import { existsSync, readFileSync } from 'fs';
const cliCommand = loadCliCommand();
// Check if save-on-clear is enabled
function isSaveOnClearEnabled() {
const settingsPath = join(homedir(), '.claude-mem', 'settings.json');
const settingsPath = getSettingsPath();
if (existsSync(settingsPath)) {
try {
const settings = JSON.parse(readFileSync(settingsPath, 'utf8'));
@@ -26,6 +25,10 @@ function isSaveOnClearEnabled() {
return false;
}
// Set up stdin immediately before any async operations
process.stdin.setEncoding('utf8');
process.stdin.resume(); // Explicitly enter flowing mode to prevent data loss
// Read input
let input = '';
process.stdin.on('data', chunk => {
@@ -41,7 +44,7 @@ process.stdin.on('end', async () => {
try {
// Use the CLI to compress current transcript
execSync(`${cliCommand} compress --output ${homedir()}/.claude-mem/archives`, {
execSync(`${cliCommand} compress --output ${getArchivesDir()}`, {
stdio: 'inherit',
env: { ...process.env, CLAUDE_MEM_SILENT: 'true' }
});
+10 -6
View File
@@ -21,6 +21,10 @@ import {
const cliCommand = loadCliCommand();
// Set up stdin immediately before any async operations
process.stdin.setEncoding('utf8');
process.stdin.resume(); // Explicitly enter flowing mode to prevent data loss
// Read input from stdin
let input = '';
process.stdin.on('data', chunk => {
@@ -47,14 +51,14 @@ process.stdin.on('end', async () => {
// Skip load-context when source is "resume" to avoid duplicate context
if (payload.source === 'resume') {
debugLog('Skipping load-context for resume source');
// Output nothing at all for resume - no message, no context
// Output valid JSON response with suppressOutput for resume
const response = createHookResponse('SessionStart', true);
console.log(JSON.stringify(response));
process.exit(0);
}
// Extract project name from current working directory and sanitize
const rawProjectName = path.basename(process.cwd());
const projectName = rawProjectName.replace(/-/g, '_');
debugLog('Extracted project name', { rawProjectName, projectName });
// Extract project name from current working directory
const projectName = path.basename(process.cwd());
// Load context using standardized CLI execution helper
const contextResult = await executeCliCommand(cliCommand, [
@@ -152,7 +156,7 @@ function extractProjectName(transcriptPath) {
// Look for project pattern: /path/to/PROJECT_NAME/.claude/
// Need to get PROJECT_NAME, not the parent directory
const parts = transcriptPath.split('/');
const parts = transcriptPath.split(path.sep);
const claudeIndex = parts.indexOf('.claude');
if (claudeIndex > 0) {
+2 -5
View File
@@ -47,13 +47,10 @@ export function createHookResponse(hookType, success, options = {}) {
}
};
} else if (success) {
// No context - just suppress output without any message
return {
continue: true,
suppressOutput: true,
hookSpecificOutput: {
hookEventName: 'SessionStart',
additionalContext: 'Starting fresh session - no previous context available'
}
suppressOutput: true
};
} else {
return {
+54
View File
@@ -0,0 +1,54 @@
#!/usr/bin/env node
/**
* Path resolver utility for Claude Memory hooks
* Provides proper path handling using environment variables
*/
import { join } from 'path';
import { homedir } from 'os';
/**
* Gets the base data directory for claude-mem
* @returns {string} Data directory path
*/
export function getDataDir() {
return process.env.CLAUDE_MEM_DATA_DIR || join(homedir(), '.claude-mem');
}
/**
* Gets the settings file path
* @returns {string} Settings file path
*/
export function getSettingsPath() {
return join(getDataDir(), 'settings.json');
}
/**
* Gets the archives directory path
* @returns {string} Archives directory path
*/
export function getArchivesDir() {
return process.env.CLAUDE_MEM_ARCHIVES_DIR || join(getDataDir(), 'archives');
}
/**
* Gets the logs directory path
* @returns {string} Logs directory path
*/
export function getLogsDir() {
return process.env.CLAUDE_MEM_LOGS_DIR || join(getDataDir(), 'logs');
}
/**
* Gets all common paths used by hooks
* @returns {Object} Object containing all common paths
*/
export function getPaths() {
return {
dataDir: getDataDir(),
settingsPath: getSettingsPath(),
archivesDir: getArchivesDir(),
logsDir: getLogsDir()
};
}
-58
View File
@@ -1,58 +0,0 @@
#!/bin/bash
# Claude Mem Installation Script
set -e
VERSION="${1:-latest}"
PLATFORM=""
ARCH=$(uname -m)
OS=$(uname -s)
# Detect platform
case "$OS" in
Darwin)
if [ "$ARCH" = "arm64" ]; then
PLATFORM="macos-arm64"
BINARY="claude-mem-macos-arm64"
else
PLATFORM="macos-x64"
BINARY="claude-mem-macos-x64"
fi
;;
Linux)
if [ "$ARCH" = "aarch64" ]; then
PLATFORM="linux-arm64"
BINARY="claude-mem-linux-arm64"
else
PLATFORM="linux-x64"
BINARY="claude-mem-linux"
fi
;;
MINGW*|MSYS*|CYGWIN*)
PLATFORM="windows-x64"
BINARY="claude-mem.exe"
;;
*)
echo "Unsupported platform: $OS $ARCH"
exit 1
;;
esac
echo "📥 Downloading Claude Mem for $PLATFORM..."
# Download binary from GitHub releases
if [ "$VERSION" = "latest" ]; then
DOWNLOAD_URL="https://github.com/thedotmack/claude-mem/releases/latest/download/${BINARY}"
else
DOWNLOAD_URL="https://github.com/thedotmack/claude-mem/releases/download/${VERSION}/${BINARY}"
fi
curl -L -o claude-mem "$DOWNLOAD_URL"
# Make executable (non-Windows)
if [ "$OS" != "MINGW" ] && [ "$OS" != "MSYS" ] && [ "$OS" != "CYGWIN" ]; then
chmod +x claude-mem
fi
echo "✅ Claude Mem installed successfully!"
echo "Run ./claude-mem --help to get started"
+57
View File
@@ -0,0 +1,57 @@
{
"name": "claude-mem",
"version": "3.5.4",
"description": "Memory compression system for Claude Code - persist context across sessions",
"keywords": [
"claude",
"claude-code",
"mcp",
"memory",
"compression",
"knowledge-graph",
"transcript",
"cli",
"typescript",
"bun"
],
"author": "Alex Newman",
"license": "SEE LICENSE IN LICENSE",
"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"
},
"publishConfig": {
"access": "public",
"registry": "https://registry.npmjs.org/"
},
"type": "module",
"engines": {
"node": ">=18.0.0"
},
"bin": {
"claude-mem": "./dist/claude-mem.min.js"
},
"dependencies": {
"@anthropic-ai/claude-code": "^1.0.88",
"@clack/prompts": "^0.11.0",
"@modelcontextprotocol/sdk": "^0.5.0",
"boxen": "^8.0.1",
"chalk": "^5.6.0",
"chromadb": "^3.0.14",
"commander": "^14.0.0",
"glob": "^11.0.3",
"gradient-string": "^3.0.0",
"handlebars": "^4.7.8",
"oh-my-logo": "^0.3.2"
},
"files": [
"dist",
"hooks",
"commands",
".mcp.json"
]
}