claude-mem 3.2.0 â 3.2.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/claude-mem +0 -0
- package/package.json +1 -2
- package/dist/bin/cli.d.ts +0 -2
- package/dist/bin/cli.js +0 -129
- package/dist/commands/compress.d.ts +0 -2
- package/dist/commands/compress.js +0 -27
- package/dist/commands/hooks.d.ts +0 -19
- package/dist/commands/hooks.js +0 -131
- package/dist/commands/install.d.ts +0 -2
- package/dist/commands/install.js +0 -649
- package/dist/commands/load-context.d.ts +0 -2
- package/dist/commands/load-context.js +0 -108
- package/dist/commands/logs.d.ts +0 -2
- package/dist/commands/logs.js +0 -76
- package/dist/commands/migrate-to-jsonl.d.ts +0 -5
- package/dist/commands/migrate-to-jsonl.js +0 -99
- package/dist/commands/status.d.ts +0 -1
- package/dist/commands/status.js +0 -136
- package/dist/commands/uninstall.d.ts +0 -2
- package/dist/commands/uninstall.js +0 -107
- package/dist/constants.d.ts +0 -271
- package/dist/constants.js +0 -199
- package/dist/core/compression/TranscriptCompressor.d.ts +0 -83
- package/dist/core/compression/TranscriptCompressor.js +0 -602
- package/dist/core/orchestration/PromptOrchestrator.d.ts +0 -165
- package/dist/core/orchestration/PromptOrchestrator.js +0 -182
- package/dist/lib/time-utils.d.ts +0 -5
- package/dist/lib/time-utils.js +0 -70
- package/dist/prompts/constants.d.ts +0 -126
- package/dist/prompts/constants.js +0 -161
- package/dist/prompts/index.d.ts +0 -10
- package/dist/prompts/index.js +0 -11
- package/dist/prompts/templates/analysis/AnalysisTemplates.d.ts +0 -13
- package/dist/prompts/templates/analysis/AnalysisTemplates.js +0 -94
- package/dist/prompts/templates/context/ContextTemplates.d.ts +0 -119
- package/dist/prompts/templates/context/ContextTemplates.js +0 -399
- package/dist/prompts/templates/hooks/HookTemplates.d.ts +0 -175
- package/dist/prompts/templates/hooks/HookTemplates.js +0 -394
- package/dist/prompts/templates/hooks/HookTemplates.test.d.ts +0 -7
- package/dist/prompts/templates/hooks/HookTemplates.test.js +0 -127
- package/dist/shared/config.d.ts +0 -4
- package/dist/shared/config.js +0 -41
- package/dist/shared/error-handler.d.ts +0 -22
- package/dist/shared/error-handler.js +0 -142
- package/dist/shared/logger.d.ts +0 -19
- package/dist/shared/logger.js +0 -51
- package/dist/shared/paths.d.ts +0 -28
- package/dist/shared/paths.js +0 -100
- package/dist/shared/types.d.ts +0 -141
- package/dist/shared/types.js +0 -78
|
@@ -1,108 +0,0 @@
|
|
|
1
|
-
import fs from 'fs';
|
|
2
|
-
import { PathResolver } from '../shared/paths.js';
|
|
3
|
-
import { createCompletionMessage, createContextualError, createUserFriendlyError, formatTimeAgo, outputSessionStartContent } from '../prompts/templates/context/ContextTemplates.js';
|
|
4
|
-
export async function loadContext(options = {}) {
|
|
5
|
-
const pathResolver = new PathResolver();
|
|
6
|
-
const indexPath = pathResolver.getIndexPath();
|
|
7
|
-
try {
|
|
8
|
-
// Check if index file exists
|
|
9
|
-
if (!fs.existsSync(indexPath)) {
|
|
10
|
-
if (options.format === 'session-start') {
|
|
11
|
-
console.log(createContextualError('NO_MEMORIES', options.project || 'this project'));
|
|
12
|
-
}
|
|
13
|
-
return;
|
|
14
|
-
}
|
|
15
|
-
const content = fs.readFileSync(indexPath, 'utf-8');
|
|
16
|
-
const lines = content.trim().split('\n').filter(line => line.trim());
|
|
17
|
-
if (lines.length === 0) {
|
|
18
|
-
if (options.format === 'session-start') {
|
|
19
|
-
console.log(createContextualError('NO_MEMORIES', options.project || 'this project'));
|
|
20
|
-
}
|
|
21
|
-
return;
|
|
22
|
-
}
|
|
23
|
-
// Parse JSONL format - each line is a JSON object
|
|
24
|
-
const jsonObjects = [];
|
|
25
|
-
for (const line of lines) {
|
|
26
|
-
try {
|
|
27
|
-
// Skip lines that don't look like JSON (could be legacy format)
|
|
28
|
-
if (!line.trim().startsWith('{')) {
|
|
29
|
-
continue;
|
|
30
|
-
}
|
|
31
|
-
const obj = JSON.parse(line);
|
|
32
|
-
jsonObjects.push(obj);
|
|
33
|
-
}
|
|
34
|
-
catch (e) {
|
|
35
|
-
// Skip malformed JSON lines
|
|
36
|
-
continue;
|
|
37
|
-
}
|
|
38
|
-
}
|
|
39
|
-
if (jsonObjects.length === 0) {
|
|
40
|
-
if (options.format === 'session-start') {
|
|
41
|
-
console.log(createContextualError('NO_MEMORIES', options.project || 'this project'));
|
|
42
|
-
}
|
|
43
|
-
return;
|
|
44
|
-
}
|
|
45
|
-
// Filter by project if specified
|
|
46
|
-
let filteredObjects = jsonObjects;
|
|
47
|
-
if (options.project) {
|
|
48
|
-
// Sanitize project name to match how it's stored (replace hyphens with underscores)
|
|
49
|
-
const sanitizedProject = options.project.replace(/-/g, '_');
|
|
50
|
-
// Filter objects by project field
|
|
51
|
-
filteredObjects = jsonObjects.filter(obj => obj.project === sanitizedProject || obj.project === options.project);
|
|
52
|
-
}
|
|
53
|
-
// Take more entries for session-start to get multiple overviews
|
|
54
|
-
const count = options.format === 'session-start' ? 30 : 10;
|
|
55
|
-
const recentObjects = filteredObjects.slice(-count);
|
|
56
|
-
if (options.format === 'session-start') {
|
|
57
|
-
// Find most recent timestamp for last session info
|
|
58
|
-
let lastSessionTime = 'recently';
|
|
59
|
-
const timestamps = recentObjects
|
|
60
|
-
.map(obj => {
|
|
61
|
-
// Get timestamp from JSON object
|
|
62
|
-
return obj.timestamp ? new Date(obj.timestamp) : null;
|
|
63
|
-
})
|
|
64
|
-
.filter(date => date !== null)
|
|
65
|
-
.sort((a, b) => b.getTime() - a.getTime());
|
|
66
|
-
if (timestamps.length > 0) {
|
|
67
|
-
lastSessionTime = formatTimeAgo(timestamps[0]);
|
|
68
|
-
}
|
|
69
|
-
// Use dual-stream output for session start formatting
|
|
70
|
-
outputSessionStartContent({
|
|
71
|
-
projectName: options.project || 'your project',
|
|
72
|
-
memoryCount: recentObjects.length,
|
|
73
|
-
lastSessionTime,
|
|
74
|
-
recentObjects
|
|
75
|
-
});
|
|
76
|
-
}
|
|
77
|
-
else if (options.format === 'json') {
|
|
78
|
-
console.log(JSON.stringify(recentObjects));
|
|
79
|
-
}
|
|
80
|
-
else {
|
|
81
|
-
// Default format - show completion message and entries
|
|
82
|
-
console.log(createCompletionMessage('Context loading', recentObjects.length, 'recent memories found'));
|
|
83
|
-
recentObjects.forEach((obj) => {
|
|
84
|
-
if (obj.type === 'memory') {
|
|
85
|
-
console.log(`${obj.text} | ${obj.document_id} | ${obj.keywords}`);
|
|
86
|
-
}
|
|
87
|
-
else if (obj.type === 'overview') {
|
|
88
|
-
console.log(`**Overview:** ${obj.content}`);
|
|
89
|
-
}
|
|
90
|
-
else if (obj.type === 'session') {
|
|
91
|
-
console.log(`# Session: ${obj.session_id} [${obj.timestamp}]`);
|
|
92
|
-
}
|
|
93
|
-
else {
|
|
94
|
-
console.log(JSON.stringify(obj));
|
|
95
|
-
}
|
|
96
|
-
});
|
|
97
|
-
}
|
|
98
|
-
}
|
|
99
|
-
catch (error) {
|
|
100
|
-
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
101
|
-
if (options.format === 'session-start') {
|
|
102
|
-
console.log(createContextualError('CONNECTION_FAILED', errorMessage));
|
|
103
|
-
}
|
|
104
|
-
else {
|
|
105
|
-
console.log(createUserFriendlyError('Context loading', errorMessage, 'Check file permissions and try again'));
|
|
106
|
-
}
|
|
107
|
-
}
|
|
108
|
-
}
|
package/dist/commands/logs.d.ts
DELETED
package/dist/commands/logs.js
DELETED
|
@@ -1,76 +0,0 @@
|
|
|
1
|
-
import { readFileSync, readdirSync, statSync } from 'fs';
|
|
2
|
-
import { join } from 'path';
|
|
3
|
-
import { homedir } from 'os';
|
|
4
|
-
// <Block> 1.1 ====================================
|
|
5
|
-
async function showLog(logPath, logType, tail) {
|
|
6
|
-
// <Block> 1.2 ====================================
|
|
7
|
-
try {
|
|
8
|
-
const content = readFileSync(logPath, 'utf8');
|
|
9
|
-
const lines = content.split('\n').filter(line => line.trim());
|
|
10
|
-
const displayLines = lines.slice(-tail);
|
|
11
|
-
console.log(`đ ${logType} Logs (last ${tail} lines):`);
|
|
12
|
-
console.log(` File: ${logPath}`);
|
|
13
|
-
console.log('');
|
|
14
|
-
// <Block> 1.3 ====================================
|
|
15
|
-
if (displayLines.length === 0) {
|
|
16
|
-
console.log(' No log entries found');
|
|
17
|
-
// </Block> =======================================
|
|
18
|
-
}
|
|
19
|
-
else {
|
|
20
|
-
displayLines.forEach(line => {
|
|
21
|
-
console.log(` ${line}`);
|
|
22
|
-
});
|
|
23
|
-
}
|
|
24
|
-
// </Block> =======================================
|
|
25
|
-
console.log('');
|
|
26
|
-
// </Block> =======================================
|
|
27
|
-
}
|
|
28
|
-
catch (error) {
|
|
29
|
-
// <Block> 1.4 ====================================
|
|
30
|
-
console.log(`â Could not read ${logType.toLowerCase()} log: ${logPath}`);
|
|
31
|
-
// </Block> =======================================
|
|
32
|
-
}
|
|
33
|
-
// </Block> =======================================
|
|
34
|
-
}
|
|
35
|
-
// <Block> 2.1 ====================================
|
|
36
|
-
export async function logs(options = {}) {
|
|
37
|
-
// <Block> 2.2 ====================================
|
|
38
|
-
const logsDir = join(homedir(), '.claude-mem', 'logs');
|
|
39
|
-
const tail = parseInt(options.tail) || 20;
|
|
40
|
-
// </Block> =======================================
|
|
41
|
-
// Find most recent log file
|
|
42
|
-
try {
|
|
43
|
-
const files = readdirSync(logsDir);
|
|
44
|
-
const logFiles = files
|
|
45
|
-
.filter(f => f.startsWith('claude-mem-') && f.endsWith('.log'))
|
|
46
|
-
.map(f => ({
|
|
47
|
-
name: f,
|
|
48
|
-
path: join(logsDir, f),
|
|
49
|
-
mtime: statSync(join(logsDir, f)).mtime
|
|
50
|
-
}))
|
|
51
|
-
.sort((a, b) => b.mtime.getTime() - a.mtime.getTime());
|
|
52
|
-
if (logFiles.length === 0) {
|
|
53
|
-
console.log('â No log files found in ~/.claude-mem/logs/');
|
|
54
|
-
return;
|
|
55
|
-
}
|
|
56
|
-
// Show most recent log
|
|
57
|
-
await showLog(logFiles[0].path, 'Most Recent', tail);
|
|
58
|
-
if (options.all && logFiles.length > 1) {
|
|
59
|
-
console.log(`đ Found ${logFiles.length} total log files`);
|
|
60
|
-
}
|
|
61
|
-
}
|
|
62
|
-
catch (error) {
|
|
63
|
-
console.log('â Could not read logs directory: ~/.claude-mem/logs/');
|
|
64
|
-
console.log(' Run a compression first to generate logs');
|
|
65
|
-
}
|
|
66
|
-
// <Block> 2.5 ====================================
|
|
67
|
-
if (options.follow) {
|
|
68
|
-
console.log('Following logs... (Press Ctrl+C to stop)');
|
|
69
|
-
// Basic follow implementation - would need more sophisticated watching in real usage
|
|
70
|
-
setInterval(() => {
|
|
71
|
-
// This would need proper file watching implementation
|
|
72
|
-
}, 1000);
|
|
73
|
-
}
|
|
74
|
-
// </Block> =======================================
|
|
75
|
-
// </Block> =======================================
|
|
76
|
-
}
|
|
@@ -1,99 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
/**
|
|
3
|
-
* One-time migration script to convert claude-mem-index.md to claude-mem-index.jsonl
|
|
4
|
-
*/
|
|
5
|
-
import fs from 'fs';
|
|
6
|
-
import path from 'path';
|
|
7
|
-
import { PathResolver } from '../shared/paths.js';
|
|
8
|
-
export function migrateToJSONL() {
|
|
9
|
-
const pathResolver = new PathResolver();
|
|
10
|
-
const oldIndexPath = path.join(pathResolver.getConfigDir(), 'claude-mem-index.md');
|
|
11
|
-
const newIndexPath = path.join(pathResolver.getConfigDir(), 'claude-mem-index.jsonl');
|
|
12
|
-
// Check if old index exists
|
|
13
|
-
if (!fs.existsSync(oldIndexPath)) {
|
|
14
|
-
console.log('No markdown index found to migrate');
|
|
15
|
-
return;
|
|
16
|
-
}
|
|
17
|
-
// Check if new index already exists
|
|
18
|
-
if (fs.existsSync(newIndexPath)) {
|
|
19
|
-
console.log('JSONL index already exists, skipping migration');
|
|
20
|
-
return;
|
|
21
|
-
}
|
|
22
|
-
console.log('Starting migration from MD to JSONL...');
|
|
23
|
-
const content = fs.readFileSync(oldIndexPath, 'utf-8');
|
|
24
|
-
const lines = content.split('\n').filter(line => line.trim());
|
|
25
|
-
const jsonlLines = [];
|
|
26
|
-
let currentSessionId = '';
|
|
27
|
-
let currentSessionTimestamp = '';
|
|
28
|
-
for (const line of lines) {
|
|
29
|
-
// Parse session headers: # Session: <id> [<timestamp>]
|
|
30
|
-
const sessionMatch = line.match(/^# Session:\s*([^\[]+)(?:\s*\[([^\]]+)\])?/);
|
|
31
|
-
if (sessionMatch) {
|
|
32
|
-
currentSessionId = sessionMatch[1].trim();
|
|
33
|
-
currentSessionTimestamp = sessionMatch[2]?.trim() || new Date().toISOString();
|
|
34
|
-
// Extract project from session ID (assuming format like <project>_<uuid>)
|
|
35
|
-
const projectMatch = currentSessionId.match(/^([^_]+)_/);
|
|
36
|
-
const project = projectMatch ? projectMatch[1] : 'unknown';
|
|
37
|
-
jsonlLines.push(JSON.stringify({
|
|
38
|
-
type: 'session',
|
|
39
|
-
session_id: currentSessionId,
|
|
40
|
-
timestamp: currentSessionTimestamp,
|
|
41
|
-
project
|
|
42
|
-
}));
|
|
43
|
-
continue;
|
|
44
|
-
}
|
|
45
|
-
// Parse overviews: **Overview:** <text>
|
|
46
|
-
const overviewMatch = line.match(/^\*\*Overview:\*\*\s*(.+)/);
|
|
47
|
-
if (overviewMatch) {
|
|
48
|
-
const overviewText = overviewMatch[1].trim();
|
|
49
|
-
// Extract project from current session ID
|
|
50
|
-
const projectMatch = currentSessionId.match(/^([^_]+)_/);
|
|
51
|
-
const project = projectMatch ? projectMatch[1] : 'unknown';
|
|
52
|
-
jsonlLines.push(JSON.stringify({
|
|
53
|
-
type: 'overview',
|
|
54
|
-
content: overviewText,
|
|
55
|
-
session_id: currentSessionId,
|
|
56
|
-
project,
|
|
57
|
-
timestamp: currentSessionTimestamp
|
|
58
|
-
}));
|
|
59
|
-
continue;
|
|
60
|
-
}
|
|
61
|
-
// Skip certain lines
|
|
62
|
-
if (line.startsWith('# NO SUMMARIES EXTRACTED')) {
|
|
63
|
-
continue;
|
|
64
|
-
}
|
|
65
|
-
// Parse memory entries (pipe-separated)
|
|
66
|
-
if (line.includes(' | ')) {
|
|
67
|
-
const parts = line.split(' | ').map(p => p.trim());
|
|
68
|
-
if (parts.length >= 3) {
|
|
69
|
-
const [text, document_id, keywords, timestamp, archive] = parts;
|
|
70
|
-
// Extract project from document_id (format: <project>_<session>_<number>)
|
|
71
|
-
const projectMatch = document_id?.match(/^([^_]+)_/);
|
|
72
|
-
const project = projectMatch ? projectMatch[1] : 'unknown';
|
|
73
|
-
jsonlLines.push(JSON.stringify({
|
|
74
|
-
type: 'memory',
|
|
75
|
-
text,
|
|
76
|
-
document_id: document_id || `${currentSessionId}_${Date.now()}`,
|
|
77
|
-
keywords: keywords || '',
|
|
78
|
-
session_id: currentSessionId,
|
|
79
|
-
project,
|
|
80
|
-
timestamp: timestamp || currentSessionTimestamp,
|
|
81
|
-
archive: archive || `${currentSessionId}.jsonl.archive`
|
|
82
|
-
}));
|
|
83
|
-
}
|
|
84
|
-
}
|
|
85
|
-
}
|
|
86
|
-
// Write JSONL file
|
|
87
|
-
fs.writeFileSync(newIndexPath, jsonlLines.join('\n') + '\n');
|
|
88
|
-
// Backup old index
|
|
89
|
-
const backupPath = oldIndexPath + '.backup';
|
|
90
|
-
fs.renameSync(oldIndexPath, backupPath);
|
|
91
|
-
console.log(`â
Migration complete!`);
|
|
92
|
-
console.log(` - Converted ${jsonlLines.length} entries`);
|
|
93
|
-
console.log(` - New index: ${newIndexPath}`);
|
|
94
|
-
console.log(` - Backup: ${backupPath}`);
|
|
95
|
-
}
|
|
96
|
-
// Run if called directly
|
|
97
|
-
if (import.meta.url === `file://${process.argv[1]}`) {
|
|
98
|
-
migrateToJSONL();
|
|
99
|
-
}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export declare function status(): Promise<void>;
|
package/dist/commands/status.js
DELETED
|
@@ -1,136 +0,0 @@
|
|
|
1
|
-
import { readFileSync, existsSync, readdirSync, statSync } from 'fs';
|
|
2
|
-
import { join, dirname } from 'path';
|
|
3
|
-
import { homedir } from 'os';
|
|
4
|
-
import { execSync } from 'child_process';
|
|
5
|
-
import { fileURLToPath } from 'url';
|
|
6
|
-
const __dirname = dirname(fileURLToPath(import.meta.url));
|
|
7
|
-
export async function status() {
|
|
8
|
-
console.log('đ Claude Memory System Status Check');
|
|
9
|
-
console.log('=====================================\n');
|
|
10
|
-
console.log('đ Installed Hook Scripts:');
|
|
11
|
-
const claudeMemHooksDir = join(homedir(), '.claude-mem', 'hooks');
|
|
12
|
-
const preCompactScript = join(claudeMemHooksDir, 'pre-compact.js');
|
|
13
|
-
const sessionStartScript = join(claudeMemHooksDir, 'session-start.js');
|
|
14
|
-
const sessionEndScript = join(claudeMemHooksDir, 'session-end.js');
|
|
15
|
-
const checkScript = (path, name) => {
|
|
16
|
-
if (existsSync(path)) {
|
|
17
|
-
console.log(` â
${name}: Found at ${path}`);
|
|
18
|
-
}
|
|
19
|
-
else {
|
|
20
|
-
console.log(` â ${name}: Not found at ${path}`);
|
|
21
|
-
}
|
|
22
|
-
};
|
|
23
|
-
checkScript(preCompactScript, 'pre-compact.js');
|
|
24
|
-
checkScript(sessionStartScript, 'session-start.js');
|
|
25
|
-
checkScript(sessionEndScript, 'session-end.js');
|
|
26
|
-
console.log('');
|
|
27
|
-
console.log('âī¸ Settings Configuration:');
|
|
28
|
-
const checkSettings = (name, path) => {
|
|
29
|
-
if (!existsSync(path)) {
|
|
30
|
-
console.log(` âī¸ ${name}: No settings file`);
|
|
31
|
-
return;
|
|
32
|
-
}
|
|
33
|
-
console.log(` đ ${name}: ${path}`);
|
|
34
|
-
try {
|
|
35
|
-
const settings = JSON.parse(readFileSync(path, 'utf8'));
|
|
36
|
-
const hasPreCompact = settings.hooks?.PreCompact?.some((matcher) => matcher.hooks?.some((hook) => hook.command?.includes('pre-compact.js') || hook.command?.includes('claude-mem')));
|
|
37
|
-
const hasSessionStart = settings.hooks?.SessionStart?.some((matcher) => matcher.hooks?.some((hook) => hook.command?.includes('session-start.js') || hook.command?.includes('claude-mem')));
|
|
38
|
-
const hasSessionEnd = settings.hooks?.SessionEnd?.some((matcher) => matcher.hooks?.some((hook) => hook.command?.includes('session-end.js') || hook.command?.includes('claude-mem')));
|
|
39
|
-
console.log(` PreCompact: ${hasPreCompact ? 'â
' : 'â'}`);
|
|
40
|
-
console.log(` SessionStart: ${hasSessionStart ? 'â
' : 'â'}`);
|
|
41
|
-
console.log(` SessionEnd: ${hasSessionEnd ? 'â
' : 'â'}`);
|
|
42
|
-
}
|
|
43
|
-
catch (error) {
|
|
44
|
-
console.log(` â ī¸ Could not parse settings`);
|
|
45
|
-
}
|
|
46
|
-
};
|
|
47
|
-
checkSettings('Global', join(homedir(), '.claude', 'settings.json'));
|
|
48
|
-
checkSettings('Project', join(process.cwd(), '.claude', 'settings.json'));
|
|
49
|
-
console.log('');
|
|
50
|
-
console.log('đĻ Compressed Transcripts:');
|
|
51
|
-
const claudeProjectsDir = join(homedir(), '.claude', 'projects');
|
|
52
|
-
if (existsSync(claudeProjectsDir)) {
|
|
53
|
-
try {
|
|
54
|
-
let compressedCount = 0;
|
|
55
|
-
let archiveCount = 0;
|
|
56
|
-
const searchDir = (dir, depth = 0) => {
|
|
57
|
-
if (depth > 3)
|
|
58
|
-
return;
|
|
59
|
-
const files = readdirSync(dir);
|
|
60
|
-
for (const file of files) {
|
|
61
|
-
const fullPath = join(dir, file);
|
|
62
|
-
const stats = statSync(fullPath);
|
|
63
|
-
if (stats.isDirectory() && !file.startsWith('.')) {
|
|
64
|
-
searchDir(fullPath, depth + 1);
|
|
65
|
-
}
|
|
66
|
-
else if (file.endsWith('.jsonl.compressed')) {
|
|
67
|
-
compressedCount++;
|
|
68
|
-
}
|
|
69
|
-
else if (file.endsWith('.jsonl.archive')) {
|
|
70
|
-
archiveCount++;
|
|
71
|
-
}
|
|
72
|
-
}
|
|
73
|
-
};
|
|
74
|
-
searchDir(claudeProjectsDir);
|
|
75
|
-
console.log(` Compressed files: ${compressedCount}`);
|
|
76
|
-
console.log(` Archive files: ${archiveCount}`);
|
|
77
|
-
}
|
|
78
|
-
catch (error) {
|
|
79
|
-
console.log(` â ī¸ Could not scan projects directory`);
|
|
80
|
-
}
|
|
81
|
-
}
|
|
82
|
-
else {
|
|
83
|
-
console.log(` âšī¸ No Claude projects directory found`);
|
|
84
|
-
}
|
|
85
|
-
console.log('');
|
|
86
|
-
console.log('đ§ Runtime Environment:');
|
|
87
|
-
const checkCommand = (cmd, name) => {
|
|
88
|
-
try {
|
|
89
|
-
const version = execSync(`${cmd} --version`, { encoding: 'utf8' }).trim();
|
|
90
|
-
console.log(` â
${name}: ${version}`);
|
|
91
|
-
}
|
|
92
|
-
catch {
|
|
93
|
-
console.log(` â ${name}: Not found`);
|
|
94
|
-
}
|
|
95
|
-
};
|
|
96
|
-
checkCommand('node', 'Node.js');
|
|
97
|
-
checkCommand('bun', 'Bun');
|
|
98
|
-
console.log('');
|
|
99
|
-
console.log('đ§ Chroma Storage Status:');
|
|
100
|
-
console.log(' â
Storage backend: Chroma MCP');
|
|
101
|
-
console.log(' đ Data location: ~/.claude-mem/chroma');
|
|
102
|
-
console.log(' đ Features: Vector search, semantic similarity, document storage');
|
|
103
|
-
console.log('');
|
|
104
|
-
console.log('đ Summary:');
|
|
105
|
-
const globalPath = join(homedir(), '.claude', 'settings.json');
|
|
106
|
-
const projectPath = join(process.cwd(), '.claude', 'settings.json');
|
|
107
|
-
let isInstalled = false;
|
|
108
|
-
let installLocation = 'Not installed';
|
|
109
|
-
try {
|
|
110
|
-
if (existsSync(globalPath)) {
|
|
111
|
-
const settings = JSON.parse(readFileSync(globalPath, 'utf8'));
|
|
112
|
-
if (settings.hooks?.PreCompact || settings.hooks?.SessionStart || settings.hooks?.SessionEnd) {
|
|
113
|
-
isInstalled = true;
|
|
114
|
-
installLocation = 'Global';
|
|
115
|
-
}
|
|
116
|
-
}
|
|
117
|
-
if (existsSync(projectPath)) {
|
|
118
|
-
const settings = JSON.parse(readFileSync(projectPath, 'utf8'));
|
|
119
|
-
if (settings.hooks?.PreCompact || settings.hooks?.SessionStart || settings.hooks?.SessionEnd) {
|
|
120
|
-
isInstalled = true;
|
|
121
|
-
installLocation = installLocation === 'Global' ? 'Global + Project' : 'Project';
|
|
122
|
-
}
|
|
123
|
-
}
|
|
124
|
-
}
|
|
125
|
-
catch { }
|
|
126
|
-
if (isInstalled) {
|
|
127
|
-
console.log(` â
Claude Memory System is installed (${installLocation})`);
|
|
128
|
-
console.log('');
|
|
129
|
-
console.log('đĄ To test: Use /compact in Claude Code');
|
|
130
|
-
}
|
|
131
|
-
else {
|
|
132
|
-
console.log(` â Claude Memory System is not installed`);
|
|
133
|
-
console.log('');
|
|
134
|
-
console.log('đĄ To install: claude-mem install');
|
|
135
|
-
}
|
|
136
|
-
}
|
|
@@ -1,107 +0,0 @@
|
|
|
1
|
-
import { readFileSync, writeFileSync, existsSync } from 'fs';
|
|
2
|
-
import { join } from 'path';
|
|
3
|
-
import { homedir } from 'os';
|
|
4
|
-
export async function uninstall(options = {}) {
|
|
5
|
-
console.log('đ Uninstalling Claude Memory System hooks...');
|
|
6
|
-
const locations = [];
|
|
7
|
-
if (options.all) {
|
|
8
|
-
locations.push({
|
|
9
|
-
name: 'User',
|
|
10
|
-
path: join(homedir(), '.claude', 'settings.json')
|
|
11
|
-
});
|
|
12
|
-
locations.push({
|
|
13
|
-
name: 'Project',
|
|
14
|
-
path: join(process.cwd(), '.claude', 'settings.json')
|
|
15
|
-
});
|
|
16
|
-
}
|
|
17
|
-
else {
|
|
18
|
-
const isProject = options.project;
|
|
19
|
-
locations.push({
|
|
20
|
-
name: isProject ? 'Project' : 'User',
|
|
21
|
-
path: join(isProject ? process.cwd() : homedir(), '.claude', 'settings.json')
|
|
22
|
-
});
|
|
23
|
-
}
|
|
24
|
-
const claudeMemHooksDir = join(homedir(), '.claude-mem', 'hooks');
|
|
25
|
-
const preCompactScript = join(claudeMemHooksDir, 'pre-compact.js');
|
|
26
|
-
const sessionStartScript = join(claudeMemHooksDir, 'session-start.js');
|
|
27
|
-
const sessionEndScript = join(claudeMemHooksDir, 'session-end.js');
|
|
28
|
-
let removedCount = 0;
|
|
29
|
-
for (const location of locations) {
|
|
30
|
-
if (!existsSync(location.path)) {
|
|
31
|
-
console.log(`âī¸ No settings found at ${location.name} location`);
|
|
32
|
-
continue;
|
|
33
|
-
}
|
|
34
|
-
try {
|
|
35
|
-
const content = readFileSync(location.path, 'utf8');
|
|
36
|
-
const settings = JSON.parse(content);
|
|
37
|
-
if (!settings.hooks) {
|
|
38
|
-
console.log(`âī¸ No hooks configured in ${location.name} settings`);
|
|
39
|
-
continue;
|
|
40
|
-
}
|
|
41
|
-
let modified = false;
|
|
42
|
-
if (settings.hooks.PreCompact) {
|
|
43
|
-
const filteredPreCompact = settings.hooks.PreCompact.filter((matcher) => !matcher.hooks?.some((hook) => hook.command === preCompactScript ||
|
|
44
|
-
hook.command?.includes('pre-compact.js') ||
|
|
45
|
-
hook.command?.includes('claude-mem')));
|
|
46
|
-
if (filteredPreCompact.length !== settings.hooks.PreCompact.length) {
|
|
47
|
-
settings.hooks.PreCompact = filteredPreCompact.length ? filteredPreCompact : undefined;
|
|
48
|
-
modified = true;
|
|
49
|
-
console.log(`â
Removed PreCompact hook from ${location.name} settings`);
|
|
50
|
-
}
|
|
51
|
-
}
|
|
52
|
-
if (settings.hooks.SessionStart) {
|
|
53
|
-
const filteredSessionStart = settings.hooks.SessionStart.filter((matcher) => !matcher.hooks?.some((hook) => hook.command === sessionStartScript ||
|
|
54
|
-
hook.command?.includes('session-start.js') ||
|
|
55
|
-
hook.command?.includes('claude-mem')));
|
|
56
|
-
if (filteredSessionStart.length !== settings.hooks.SessionStart.length) {
|
|
57
|
-
settings.hooks.SessionStart = filteredSessionStart.length ? filteredSessionStart : undefined;
|
|
58
|
-
modified = true;
|
|
59
|
-
console.log(`â
Removed SessionStart hook from ${location.name} settings`);
|
|
60
|
-
}
|
|
61
|
-
}
|
|
62
|
-
if (settings.hooks.SessionEnd) {
|
|
63
|
-
const filteredSessionEnd = settings.hooks.SessionEnd.filter((matcher) => !matcher.hooks?.some((hook) => hook.command === sessionEndScript ||
|
|
64
|
-
hook.command?.includes('session-end.js') ||
|
|
65
|
-
hook.command?.includes('claude-mem')));
|
|
66
|
-
if (filteredSessionEnd.length !== settings.hooks.SessionEnd.length) {
|
|
67
|
-
settings.hooks.SessionEnd = filteredSessionEnd.length ? filteredSessionEnd : undefined;
|
|
68
|
-
modified = true;
|
|
69
|
-
console.log(`â
Removed SessionEnd hook from ${location.name} settings`);
|
|
70
|
-
}
|
|
71
|
-
}
|
|
72
|
-
if (settings.hooks.PreCompact === undefined)
|
|
73
|
-
delete settings.hooks.PreCompact;
|
|
74
|
-
if (settings.hooks.SessionStart === undefined)
|
|
75
|
-
delete settings.hooks.SessionStart;
|
|
76
|
-
if (settings.hooks.SessionEnd === undefined)
|
|
77
|
-
delete settings.hooks.SessionEnd;
|
|
78
|
-
if (!Object.keys(settings.hooks).length)
|
|
79
|
-
delete settings.hooks;
|
|
80
|
-
if (modified) {
|
|
81
|
-
const backupPath = location.path + '.backup.' + Date.now();
|
|
82
|
-
writeFileSync(backupPath, content);
|
|
83
|
-
console.log(`đ Created backup: ${backupPath}`);
|
|
84
|
-
writeFileSync(location.path, JSON.stringify(settings, null, 2));
|
|
85
|
-
removedCount++;
|
|
86
|
-
console.log(`â
Updated ${location.name} settings: ${location.path}`);
|
|
87
|
-
}
|
|
88
|
-
else {
|
|
89
|
-
console.log(`âšī¸ No Claude Memory System hooks found in ${location.name} settings`);
|
|
90
|
-
}
|
|
91
|
-
}
|
|
92
|
-
catch (error) {
|
|
93
|
-
console.log(`â ī¸ Could not process ${location.name} settings: ${error.message}`);
|
|
94
|
-
}
|
|
95
|
-
}
|
|
96
|
-
console.log('');
|
|
97
|
-
if (removedCount > 0) {
|
|
98
|
-
console.log('⨠Uninstallation complete!');
|
|
99
|
-
console.log('The Claude Memory System hooks have been removed from your settings.');
|
|
100
|
-
console.log('');
|
|
101
|
-
console.log('Note: Your compressed transcripts and archives are preserved.');
|
|
102
|
-
console.log('To reinstall: claude-mem install');
|
|
103
|
-
}
|
|
104
|
-
else {
|
|
105
|
-
console.log('âšī¸ No Claude Memory System hooks were found to remove.');
|
|
106
|
-
}
|
|
107
|
-
}
|