@alucardeht/claude-memory 1.0.3 → 2.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md ADDED
@@ -0,0 +1,205 @@
1
+ # claude-memory
2
+
3
+ Automatic, invisible memory for Claude Code. Never lose context after `/compact` again.
4
+
5
+ ## What it does
6
+
7
+ claude-memory automatically:
8
+ 1. **Saves conversations** before `/compact` clears context
9
+ 2. **Injects relevant context** into every prompt based on what you're working on
10
+ 3. **Works invisibly** - install once, forget about it
11
+
12
+ ## Installation
13
+
14
+ ```bash
15
+ npm install -g @alucardeht/claude-memory
16
+ ```
17
+
18
+ > **Note**: The `claude-memory install` command runs automatically after npm install.
19
+
20
+ That's it. The installer automatically:
21
+ - Downloads the correct binary for your platform
22
+ - Configures Claude Code hooks
23
+ - Creates the memory database
24
+
25
+ ## How it works
26
+
27
+ ```
28
+ ┌─ Session Start ─────────────────────────────────┐
29
+ │ Loads project core memory │
30
+ │ → "You're working on X, preferences are Y..." │
31
+ └─────────────────────────────────────────────────┘
32
+
33
+ ┌─ Every Prompt ──────────────────────────────────┐
34
+ │ 1. Extracts entities (files, functions, errors) │
35
+ │ 2. Searches for relevant past context │
36
+ │ 3. Injects as system message (~4000 tokens) │
37
+ │ Performance: <5ms total │
38
+ └─────────────────────────────────────────────────┘
39
+
40
+ ┌─ Before /compact ───────────────────────────────┐
41
+ │ Saves entire conversation with importance scores│
42
+ │ → Context preserved for future sessions │
43
+ └─────────────────────────────────────────────────┘
44
+ ```
45
+
46
+ ### What gets saved
47
+
48
+ Both your messages AND Claude's responses are saved, including:
49
+ - Files and functions mentioned
50
+ - Errors discussed
51
+ - Decisions made
52
+
53
+ ### What gets injected
54
+
55
+ On each prompt, the system searches your past conversations and injects relevant context. Example of what Claude sees:
56
+
57
+ ```
58
+ ## Relevant History
59
+ [user, 3 days ago]
60
+ How do I fix the auth bug?
61
+ Files: auth/login.go
62
+
63
+ [assistant, 3 days ago]
64
+ The issue is in line 45, the token wasn't being validated...
65
+ Decisions: Use JWT instead of sessions
66
+ ```
67
+
68
+ ### In practice
69
+
70
+ - You mention `auth/login.go` → System finds past discussions about that file
71
+ - You ask "what was that bug?" → System finds error-related conversations
72
+ - You start fresh session → Claude already has context from days ago
73
+
74
+ ### Context Budget
75
+
76
+ Claude-memory automatically manages context size to prevent token overflow:
77
+
78
+ | Component | Token Budget | Max Size |
79
+ |-----------|--------------|----------|
80
+ | Core Memory | 500 tokens | ~2KB |
81
+ | Retrieved Context | 3500 tokens | ~14KB |
82
+ | **Total** | **4000 tokens** | **~16KB** |
83
+
84
+ **Safety features:**
85
+ - Automatic truncation when limits are exceeded
86
+ - Warning logs via `slog` when approaching limits
87
+ - Hard safety net at 20KB (user prompts) / 10KB (session start)
88
+
89
+ This is transparent and requires no configuration.
90
+
91
+ ### Privacy
92
+
93
+ All data stays local in `~/.claude-memory/`. No cloud, no sync, no network calls.
94
+
95
+ ## Commands
96
+
97
+ ```bash
98
+ # Install hooks (done automatically on npm install)
99
+ claude-memory install
100
+
101
+ # Uninstall hooks
102
+ claude-memory install --uninstall
103
+
104
+ # Search your memory manually
105
+ claude-memory search "auth bug"
106
+ claude-memory search "database migration" --project /path/to/project
107
+
108
+ # Show version
109
+ claude-memory --version
110
+ ```
111
+
112
+ ## Search options
113
+
114
+ ```bash
115
+ claude-memory search [query] [flags]
116
+
117
+ Flags:
118
+ -n, --limit int Maximum results (default 10)
119
+ -p, --project path Search specific project
120
+ -s, --scores Show relevance scores
121
+ ```
122
+
123
+ ## How scoring works
124
+
125
+ | Content Type | Score Boost |
126
+ |--------------|-------------|
127
+ | File mentions (src/auth.go) | +3 |
128
+ | Function mentions (validateToken) | +2 |
129
+ | Error patterns | +3 |
130
+ | Decision phrases ("vamos usar", "let's use") | +2 |
131
+ | Short/filler messages ("ok", "got it") | -2 |
132
+
133
+ Recency also matters:
134
+ - Last hour: 2x boost
135
+ - Last day: 1.5x boost
136
+ - Last week: 1.2x boost
137
+ - Older than month: 0.8x penalty
138
+
139
+ ## Storage
140
+
141
+ Memory is stored in `~/.claude-memory/memory.db` (SQLite with FTS5).
142
+
143
+ Each project has isolated memory based on its absolute path.
144
+
145
+ ## Performance
146
+
147
+ | Operation | Target | Actual |
148
+ |-----------|--------|--------|
149
+ | Entity extraction | <1ms | ~170µs |
150
+ | FTS search | <1ms | ~200µs |
151
+ | Context injection | <5ms | ~160µs |
152
+ | Session start | <1ms | ~30µs |
153
+
154
+ ## Requirements
155
+
156
+ - Claude Code CLI
157
+ - Node.js 16+ (for npm installation)
158
+ - macOS, Linux, or Windows
159
+
160
+ ## Windows Support
161
+
162
+ claude-memory has full support for Windows 10 and Windows 11.
163
+
164
+ ### Installation (same as other platforms)
165
+
166
+ ```powershell
167
+ npm install -g @alucardeht/claude-memory
168
+ claude-memory install
169
+ ```
170
+
171
+ ### Windows-specific paths
172
+
173
+ | Data | Location |
174
+ |------|----------|
175
+ | Claude settings | `%APPDATA%\Claude\settings.json` |
176
+ | claude-memory database | `%APPDATA%\claude-memory\memory.db` |
177
+ | claude-memory config | `%APPDATA%\claude-memory\config.json` |
178
+
179
+ > **Note**: On Windows, `%APPDATA%` typically resolves to `C:\Users\YourUsername\AppData\Roaming\`
180
+
181
+ ### Requirements for Windows
182
+
183
+ - Node.js 16+ (download from [nodejs.org](https://nodejs.org))
184
+ - Git for Windows (recommended, includes Git Bash)
185
+ - Claude Code CLI installed and configured
186
+
187
+ ### Troubleshooting
188
+
189
+ If you encounter issues:
190
+
191
+ 1. **Binary not found**: Try reinstalling with `npm install -g @alucardeht/claude-memory`
192
+ 2. **Permission errors**: Run PowerShell/CMD as Administrator
193
+ 3. **Path issues**: Ensure `%APPDATA%\npm` is in your system PATH
194
+
195
+ ## Uninstall
196
+
197
+ ```bash
198
+ npm uninstall -g @alucardeht/claude-memory
199
+ ```
200
+
201
+ This removes the CLI and hooks. Memory database remains in `~/.claude-memory/`.
202
+
203
+ ## License
204
+
205
+ MIT
@@ -0,0 +1,25 @@
1
+ @echo off
2
+ setlocal EnableDelayedExpansion
3
+
4
+ REM Claude Memory - Windows Wrapper
5
+ REM Executes the claude-memory binary with all arguments
6
+
7
+ set "SCRIPT_DIR=%~dp0"
8
+
9
+ REM Remove trailing backslash
10
+ if "%SCRIPT_DIR:~-1%"=="\" set "SCRIPT_DIR=%SCRIPT_DIR:~0,-1%"
11
+
12
+ REM Check if Windows binary exists
13
+ if exist "%SCRIPT_DIR%\claude-memory.exe" (
14
+ "%SCRIPT_DIR%\claude-memory.exe" %*
15
+ exit /b %ERRORLEVEL%
16
+ )
17
+
18
+ REM Binary not found - show error
19
+ echo Error: claude-memory.exe binary not found in %SCRIPT_DIR% >&2
20
+ echo. >&2
21
+ echo Try reinstalling: npm install -g @alucardeht/claude-memory >&2
22
+ echo. >&2
23
+ echo If the problem persists, please report at: >&2
24
+ echo https://github.com/alucardeht/claude-memory/issues >&2
25
+ exit /b 1
package/install.js CHANGED
@@ -1,127 +1,211 @@
1
1
  #!/usr/bin/env node
2
2
 
3
- const { execSync, spawn } = require('child_process');
3
+ const https = require('https');
4
4
  const fs = require('fs');
5
5
  const path = require('path');
6
- const https = require('https');
6
+ const { spawnSync } = require('child_process');
7
7
  const os = require('os');
8
8
 
9
9
  const VERSION = require('./package.json').version;
10
- const REPO = 'alucardeht/claude-memory';
11
-
12
- function getPlatform() {
13
- const platform = os.platform();
14
- const arch = os.arch();
15
-
16
- const platformMap = {
17
- darwin: 'darwin',
18
- linux: 'linux',
19
- win32: 'windows',
20
- };
21
-
22
- const archMap = {
23
- x64: 'amd64',
24
- arm64: 'arm64',
25
- };
26
-
27
- const p = platformMap[platform];
28
- const a = archMap[arch];
29
-
30
- if (!p || !a) {
31
- throw new Error(`Unsupported platform: ${platform}-${arch}`);
10
+ const BIN_DIR = path.join(__dirname, 'bin');
11
+ const HOME_DIR = os.homedir();
12
+ const OLD_HOOKS_DIR = path.join(HOME_DIR, '.claude', 'hooks');
13
+ const OLD_DB_DIR = path.join(HOME_DIR, '.claude-memory');
14
+
15
+ const PLATFORM_MAP = {
16
+ darwin: 'darwin',
17
+ linux: 'linux',
18
+ win32: 'windows'
19
+ };
20
+
21
+ const ARCH_MAP = {
22
+ x64: 'amd64',
23
+ arm64: 'arm64'
24
+ };
25
+
26
+ function getPlatformArch() {
27
+ const platform = PLATFORM_MAP[process.platform];
28
+ const arch = ARCH_MAP[process.arch];
29
+
30
+ if (!platform || !arch) {
31
+ return null;
32
32
  }
33
33
 
34
- return { platform: p, arch: a };
35
- }
36
-
37
- function getBinaryName() {
38
- const { platform, arch } = getPlatform();
39
- const ext = platform === 'windows' ? '.exe' : '';
40
- return `claude-memory-${platform}-${arch}${ext}`;
41
- }
42
-
43
- function getDownloadUrl() {
44
- const binaryName = getBinaryName();
45
- return `https://github.com/${REPO}/releases/download/v${VERSION}/${binaryName}`;
34
+ return { platform, arch };
46
35
  }
47
36
 
48
- function download(url, dest) {
37
+ function downloadBinary(url, destPath) {
49
38
  return new Promise((resolve, reject) => {
50
- const file = fs.createWriteStream(dest);
39
+ const file = fs.createWriteStream(destPath);
51
40
 
52
- const request = (url) => {
53
- https.get(url, (response) => {
54
- if (response.statusCode === 302 || response.statusCode === 301) {
55
- request(response.headers.location);
41
+ https
42
+ .get(url, (response) => {
43
+ if (response.statusCode === 404) {
44
+ reject(new Error('Binary not found. Platform or architecture may not be supported.'));
56
45
  return;
57
46
  }
58
47
 
59
48
  if (response.statusCode !== 200) {
60
- reject(new Error(`Failed to download: ${response.statusCode}`));
49
+ reject(new Error(`Download failed with status ${response.statusCode}`));
61
50
  return;
62
51
  }
63
52
 
64
53
  response.pipe(file);
65
- file.on('finish', () => {
66
- file.close();
67
- resolve();
68
- });
69
- }).on('error', (err) => {
70
- fs.unlink(dest, () => {});
54
+ })
55
+ .on('error', (err) => {
56
+ fs.unlink(destPath, () => {});
71
57
  reject(err);
72
58
  });
73
- };
74
59
 
75
- request(url);
60
+ file.on('finish', () => {
61
+ file.close();
62
+ resolve();
63
+ });
64
+
65
+ file.on('error', (err) => {
66
+ fs.unlink(destPath, () => {});
67
+ reject(err);
68
+ });
76
69
  });
77
70
  }
78
71
 
79
- async function main() {
80
- const binDir = path.join(__dirname, 'bin');
81
- const { platform } = getPlatform();
82
- const binaryName = platform === 'windows' ? 'claude-memory.exe' : 'claude-memory';
83
- const binaryPath = path.join(binDir, binaryName);
72
+ function makeExecutable(filePath) {
73
+ if (process.platform !== 'win32') {
74
+ fs.chmodSync(filePath, '0755');
75
+ }
76
+ }
77
+
78
+ function runCommand(command, args, description) {
79
+ console.log(`\n→ ${description}`);
80
+
81
+ const result = spawnSync(command, args, {
82
+ stdio: 'inherit',
83
+ shell: process.platform === 'win32'
84
+ });
84
85
 
85
- if (!fs.existsSync(binDir)) {
86
- fs.mkdirSync(binDir, { recursive: true });
86
+ if (result.error) {
87
+ throw new Error(`${description} failed: ${result.error.message}`);
87
88
  }
88
89
 
89
- const url = getDownloadUrl();
90
- console.log(`Downloading claude-memory from ${url}...`);
90
+ if (result.status !== 0) {
91
+ throw new Error(`${description} failed with exit code ${result.status}`);
92
+ }
93
+ }
94
+
95
+ function isOldInstallationPresent() {
96
+ const hasOldHooks = fs.existsSync(OLD_HOOKS_DIR);
97
+ const hasOldDb = fs.existsSync(OLD_DB_DIR);
98
+ return hasOldHooks || hasOldDb;
99
+ }
100
+
101
+ function removeOldHooks() {
102
+ if (!fs.existsSync(OLD_HOOKS_DIR)) {
103
+ return;
104
+ }
105
+
106
+ const hookFiles = ['user-prompt-submit.sh', 'pre-compact.sh', 'session-end.sh'];
107
+
108
+ for (const hookFile of hookFiles) {
109
+ const hookPath = path.join(OLD_HOOKS_DIR, hookFile);
110
+ if (fs.existsSync(hookPath)) {
111
+ fs.unlinkSync(hookPath);
112
+ }
113
+ }
91
114
 
92
115
  try {
93
- await download(url, binaryPath);
116
+ if (fs.readdirSync(OLD_HOOKS_DIR).length === 0) {
117
+ fs.rmdirSync(OLD_HOOKS_DIR);
118
+ }
94
119
  } catch (err) {
95
- console.error(`Failed to download binary: ${err.message}`);
96
- console.error('');
97
- console.error('You can manually install by:');
98
- console.error('1. Download from: https://github.com/' + REPO + '/releases');
99
- console.error('2. Place the binary in your PATH');
100
- process.exit(1);
120
+ // Directory might not be empty, that's okay
101
121
  }
122
+ }
102
123
 
103
- if (platform !== 'windows') {
104
- fs.chmodSync(binaryPath, 0o755);
124
+ function migrateDatabase(binaryWrapper) {
125
+ if (!fs.existsSync(OLD_DB_DIR)) {
126
+ return;
105
127
  }
106
128
 
107
- console.log('Binary installed successfully!');
108
- console.log('');
109
-
110
- console.log('Configuring Claude Code hooks...');
111
129
  try {
112
- const result = spawn(binaryPath, ['install'], { stdio: 'inherit' });
113
- result.on('close', (code) => {
114
- if (code !== 0) {
115
- console.error('Failed to configure hooks. Run "claude-memory install" manually.');
116
- }
130
+ const result = spawnSync(binaryWrapper, ['migrate'], {
131
+ stdio: 'inherit',
132
+ shell: process.platform === 'win32'
117
133
  });
134
+
135
+ if (result.error) {
136
+ console.log('⚠️ Database migration skipped (binary not yet available)');
137
+ }
118
138
  } catch (err) {
119
- console.error('Failed to run install command:', err.message);
120
- console.error('Run "claude-memory install" manually after installation.');
139
+ console.log('⚠️ Database migration skipped');
140
+ }
141
+ }
142
+
143
+ async function main() {
144
+ try {
145
+ const isUpgrade = isOldInstallationPresent();
146
+
147
+ if (isUpgrade) {
148
+ console.log('⚠️ Upgrading from hook-based version...\n');
149
+ } else {
150
+ console.log('Installing claude-memory...\n');
151
+ }
152
+
153
+ const platformArch = getPlatformArch();
154
+ if (!platformArch) {
155
+ console.error(
156
+ 'Error: Unsupported platform or architecture.\n' +
157
+ 'Supported combinations:\n' +
158
+ ' - darwin (x64, arm64)\n' +
159
+ ' - linux (x64, arm64)\n' +
160
+ ' - win32 (x64, arm64)'
161
+ );
162
+ process.exit(1);
163
+ }
164
+
165
+ const { platform, arch } = platformArch;
166
+ const isWindows = process.platform === 'win32';
167
+ const binaryName = isWindows ? 'claude-memory.exe' : 'claude-memory';
168
+ const binaryPath = path.join(BIN_DIR, binaryName);
169
+ const downloadUrl = `https://github.com/alucardeht/claude-memory/releases/download/v${VERSION}/claude-memory-${platform}-${arch}${isWindows ? '.exe' : ''}`;
170
+
171
+ fs.mkdirSync(BIN_DIR, { recursive: true });
172
+
173
+ console.log(`Downloading claude-memory for ${platform}-${arch}...`);
174
+ await downloadBinary(downloadUrl, binaryPath);
175
+ makeExecutable(binaryPath);
176
+ console.log('✓ Binary downloaded');
177
+
178
+ const binaryWrapper = isWindows ? path.join(BIN_DIR, 'claude-memory.cmd') : path.join(BIN_DIR, 'claude-memory');
179
+
180
+ if (isUpgrade) {
181
+ console.log('\n→ Removing old hooks...');
182
+ removeOldHooks();
183
+ console.log('✓ Old hooks removed');
184
+
185
+ console.log('\n→ Migrating database...');
186
+ migrateDatabase(binaryWrapper);
187
+ console.log('✓ Database migrated');
188
+ }
189
+
190
+ runCommand(binaryWrapper, ['install'], 'Installing Claude Code hooks');
191
+ console.log('✓ Hooks installed');
192
+
193
+ runCommand(binaryWrapper, ['daemon:install'], 'Starting memory daemon');
194
+ console.log('✓ Daemon registered');
195
+
196
+ if (isUpgrade) {
197
+ console.log('\n✅ Upgrade complete!');
198
+ } else {
199
+ console.log('\n✅ claude-memory installed successfully!');
200
+ }
201
+ console.log('The daemon will start automatically on login.\n');
202
+ } catch (error) {
203
+ console.error('\n❌ Installation failed:', error.message);
204
+ console.log('\nYou can try to manually install by running:');
205
+ console.log(' claude-memory install');
206
+ console.log(' claude-memory daemon:install\n');
207
+ process.exit(1);
121
208
  }
122
209
  }
123
210
 
124
- main().catch((err) => {
125
- console.error('Installation failed:', err.message);
126
- process.exit(1);
127
- });
211
+ main();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@alucardeht/claude-memory",
3
- "version": "1.0.3",
3
+ "version": "2.0.1",
4
4
  "description": "Automatic context persistence for Claude Code",
5
5
  "keywords": [
6
6
  "claude",
@@ -20,7 +20,7 @@
20
20
  "claude-memory": "./bin/claude-memory"
21
21
  },
22
22
  "scripts": {
23
- "postinstall": "node install.js"
23
+ "postinstall": "node install.js || true"
24
24
  },
25
25
  "os": [
26
26
  "darwin",
@@ -35,7 +35,10 @@
35
35
  "node": ">=14"
36
36
  },
37
37
  "files": [
38
+ "README.md",
38
39
  "bin",
40
+ "bin/claude-memory",
41
+ "bin/claude-memory.cmd",
39
42
  "install.js"
40
43
  ]
41
44
  }