claude-mem 3.0.4 → 3.1.2
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/.mcp.json +0 -11
- package/claude-mem +0 -0
- package/dist/cli.js +48 -0
- package/dist/commands/compress.js +10 -56
- package/dist/commands/install.js +167 -100
- package/dist/commands/load-context.js +21 -322
- package/dist/commands/logs.js +41 -6
- package/dist/commands/migrate.js +153 -62
- package/dist/commands/status.js +8 -25
- package/dist/commands/uninstall.js +1 -1
- package/dist/config.js +10 -0
- package/dist/constants.d.ts +1 -7
- package/dist/constants.js +25 -37
- package/dist/error-handler.js +29 -0
- package/dist/mcp-server-cli.js +0 -0
- package/dist/mcp-server.d.ts +8 -51
- package/dist/mcp-server.js +112 -156
- package/dist/scripts/migrate-to-simple-format.d.ts +14 -0
- package/dist/scripts/migrate-to-simple-format.js +140 -0
- package/dist/scripts/validate-migration.d.ts +17 -0
- package/dist/scripts/validate-migration.js +141 -0
- package/dist/utils/PathResolver.d.ts +12 -0
- package/dist/utils/PathResolver.js +46 -1
- package/dist/utils/TranscriptCompressor.d.ts +51 -4
- package/dist/utils/TranscriptCompressor.js +304 -214
- package/dist/utils/index.d.ts +5 -0
- package/dist/utils/index.js +9 -0
- package/dist/utils/logger.js +9 -0
- package/dist/utils/mcp-client.js +14 -0
- package/dist/utils/weaviate-mcp-adapter.d.ts +38 -10
- package/dist/utils/weaviate-mcp-adapter.js +250 -372
- package/hooks/pre-compact.js +23 -197
- package/hooks/session-end.js +14 -148
- package/hooks/session-start.js +36 -178
- package/hooks/shared/config-loader.js +26 -0
- package/package.json +1 -1
- package/dist/utils/HookDetector.d.ts +0 -64
- package/dist/utils/HookDetector.js +0 -213
- package/dist/utils/SettingsManager.d.ts +0 -63
- package/dist/utils/SettingsManager.js +0 -133
- package/dist/utils/common.d.ts +0 -29
- package/dist/utils/common.js +0 -14
- package/dist/utils/error-utils.d.ts +0 -93
- package/dist/utils/error-utils.js +0 -238
- package/dist/utils/mcp-client-factory.d.ts +0 -51
- package/dist/utils/mcp-client-factory.js +0 -115
- package/dist/utils/memory-mcp-client.d.ts +0 -135
- package/dist/utils/memory-mcp-client.js +0 -490
package/.mcp.json
CHANGED
package/claude-mem
CHANGED
|
Binary file
|
package/dist/cli.js
CHANGED
|
@@ -1,4 +1,7 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
+
// <Block> 1.1 ====================================
|
|
3
|
+
// CLI Dependencies and Imports Setup
|
|
4
|
+
// Natural pattern: Import what you need before using it
|
|
2
5
|
import { Command } from 'commander';
|
|
3
6
|
import { PACKAGE_NAME, PACKAGE_VERSION, PACKAGE_DESCRIPTION } from './config.js';
|
|
4
7
|
// Import command handlers
|
|
@@ -8,11 +11,20 @@ import { uninstall } from './commands/uninstall.js';
|
|
|
8
11
|
import { status } from './commands/status.js';
|
|
9
12
|
import { logs } from './commands/logs.js';
|
|
10
13
|
import { loadContext } from './commands/load-context.js';
|
|
14
|
+
import { migrate } from './commands/migrate.js';
|
|
11
15
|
const program = new Command();
|
|
16
|
+
// </Block> =======================================
|
|
17
|
+
// <Block> 1.2 ====================================
|
|
18
|
+
// Program Configuration
|
|
19
|
+
// Natural pattern: Configure program metadata first
|
|
12
20
|
program
|
|
13
21
|
.name(PACKAGE_NAME)
|
|
14
22
|
.description(PACKAGE_DESCRIPTION)
|
|
15
23
|
.version(PACKAGE_VERSION);
|
|
24
|
+
// </Block> =======================================
|
|
25
|
+
// <Block> 1.3 ====================================
|
|
26
|
+
// Compress Command Definition
|
|
27
|
+
// Natural pattern: Define command with its options and handler
|
|
16
28
|
// Compress command
|
|
17
29
|
program
|
|
18
30
|
.command('compress [transcript]')
|
|
@@ -21,6 +33,10 @@ program
|
|
|
21
33
|
.option('--dry-run', 'Show what would be compressed without doing it')
|
|
22
34
|
.option('-v, --verbose', 'Show detailed output')
|
|
23
35
|
.action(compress);
|
|
36
|
+
// </Block> =======================================
|
|
37
|
+
// <Block> 1.4 ====================================
|
|
38
|
+
// Install Command Definition
|
|
39
|
+
// Natural pattern: Define command with its options and handler
|
|
24
40
|
// Install command
|
|
25
41
|
program
|
|
26
42
|
.command('install')
|
|
@@ -29,6 +45,10 @@ program
|
|
|
29
45
|
.option('--project', 'Install for current project only')
|
|
30
46
|
.option('--force', 'Force installation even if already installed')
|
|
31
47
|
.action(install);
|
|
48
|
+
// </Block> =======================================
|
|
49
|
+
// <Block> 1.5 ====================================
|
|
50
|
+
// Uninstall Command Definition
|
|
51
|
+
// Natural pattern: Define command with its options and handler
|
|
32
52
|
// Uninstall command
|
|
33
53
|
program
|
|
34
54
|
.command('uninstall')
|
|
@@ -37,11 +57,19 @@ program
|
|
|
37
57
|
.option('--project', 'Remove from project settings')
|
|
38
58
|
.option('--all', 'Remove from both global and project settings')
|
|
39
59
|
.action(uninstall);
|
|
60
|
+
// </Block> =======================================
|
|
61
|
+
// <Block> 1.6 ====================================
|
|
62
|
+
// Status Command Definition
|
|
63
|
+
// Natural pattern: Define command with its handler
|
|
40
64
|
// Status command
|
|
41
65
|
program
|
|
42
66
|
.command('status')
|
|
43
67
|
.description('Check installation status of Claude Memory System')
|
|
44
68
|
.action(status);
|
|
69
|
+
// </Block> =======================================
|
|
70
|
+
// <Block> 1.7 ====================================
|
|
71
|
+
// Logs Command Definition
|
|
72
|
+
// Natural pattern: Define command with its options and handler
|
|
45
73
|
// Logs command
|
|
46
74
|
program
|
|
47
75
|
.command('logs')
|
|
@@ -51,6 +79,10 @@ program
|
|
|
51
79
|
.option('--tail [n]', 'Show last n lines', '50')
|
|
52
80
|
.option('--follow', 'Follow log output')
|
|
53
81
|
.action(logs);
|
|
82
|
+
// </Block> =======================================
|
|
83
|
+
// <Block> 1.8 ====================================
|
|
84
|
+
// Load-Context Command Definition
|
|
85
|
+
// Natural pattern: Define command with its options and handler
|
|
54
86
|
// Load-context command
|
|
55
87
|
program
|
|
56
88
|
.command('load-context')
|
|
@@ -60,5 +92,21 @@ program
|
|
|
60
92
|
.option('--raw', 'Output raw JSON instead of formatted text')
|
|
61
93
|
.option('--format <type>', 'Output format: json, session-start, or default')
|
|
62
94
|
.action(loadContext);
|
|
95
|
+
// </Block> =======================================
|
|
96
|
+
// <Block> 1.9 ====================================
|
|
97
|
+
// Migrate Command Definition
|
|
98
|
+
// Natural pattern: Define command with its options and handler
|
|
99
|
+
// Migrate command
|
|
100
|
+
program
|
|
101
|
+
.command('migrate')
|
|
102
|
+
.description('Migrate index to Weaviate format and extract entities')
|
|
103
|
+
.option('--dry-run', 'Show migration preview without performing it')
|
|
104
|
+
.option('--force', 'Force migration even if data exists')
|
|
105
|
+
.action(migrate);
|
|
106
|
+
// </Block> =======================================
|
|
107
|
+
// <Block> 1.10 ===================================
|
|
108
|
+
// CLI Execution
|
|
109
|
+
// Natural pattern: After defining all commands, parse and execute
|
|
63
110
|
// Parse arguments and execute
|
|
64
111
|
program.parse();
|
|
112
|
+
// </Block> =======================================
|
|
@@ -1,59 +1,13 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { dirname, basename } from 'path';
|
|
3
|
-
import { fileURLToPath } from 'url';
|
|
4
|
-
const __filename = fileURLToPath(import.meta.url);
|
|
5
|
-
const __dirname = dirname(__filename);
|
|
1
|
+
import { basename } from 'path';
|
|
6
2
|
export async function compress(transcript, options = {}) {
|
|
7
|
-
if (!transcript) {
|
|
8
|
-
console.error('❌ Transcript file path is required');
|
|
9
|
-
process.exit(1);
|
|
10
|
-
}
|
|
11
|
-
if (!existsSync(transcript)) {
|
|
12
|
-
console.error(`❌ Transcript file not found: ${transcript}`);
|
|
13
|
-
process.exit(1);
|
|
14
|
-
}
|
|
15
3
|
console.log(`🗜️ Compressing transcript: ${transcript}`);
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
debug: options.verbose || false
|
|
26
|
-
});
|
|
27
|
-
// Extract session ID from transcript filename if not provided
|
|
28
|
-
const sessionId = options.sessionId || basename(transcript, '.jsonl');
|
|
29
|
-
if (options.verbose) {
|
|
30
|
-
console.log(`📊 Starting compression with session ID: ${sessionId}`);
|
|
31
|
-
}
|
|
32
|
-
// Perform compression
|
|
33
|
-
const archivePath = await compressor.compress(transcript, sessionId);
|
|
34
|
-
console.log('✅ Compression completed successfully');
|
|
35
|
-
console.log(`📦 Archive created: ${archivePath}`);
|
|
36
|
-
if (options.output && options.output !== dirname(archivePath)) {
|
|
37
|
-
console.log(`📂 Output directory: ${options.output} (archive location may differ)`);
|
|
38
|
-
}
|
|
39
|
-
}
|
|
40
|
-
catch (error) {
|
|
41
|
-
const err = error;
|
|
42
|
-
console.error('❌ Compression failed:', err.message);
|
|
43
|
-
if (options.verbose) {
|
|
44
|
-
console.error('Stack trace:', err.stack);
|
|
45
|
-
}
|
|
46
|
-
// Provide helpful error messages for common issues
|
|
47
|
-
if (err.message.includes('Claude Code executable not found')) {
|
|
48
|
-
console.error('💡 Hint: Make sure Claude Code is installed and accessible in your PATH');
|
|
49
|
-
console.error(' Or set CLAUDE_CODE_PATH environment variable');
|
|
50
|
-
}
|
|
51
|
-
else if (err.message.includes('JWT_SECRET')) {
|
|
52
|
-
console.error('💡 Hint: Make sure JWT_SECRET is set in your MCP configuration');
|
|
53
|
-
}
|
|
54
|
-
else if (err.message.includes('No summaries extracted')) {
|
|
55
|
-
console.error('💡 Hint: The transcript may be too short or not contain analyzable content');
|
|
56
|
-
}
|
|
57
|
-
process.exit(1);
|
|
58
|
-
}
|
|
4
|
+
// Import and run compression
|
|
5
|
+
const { TranscriptCompressor } = await import('../utils/TranscriptCompressor.js');
|
|
6
|
+
const compressor = new TranscriptCompressor({
|
|
7
|
+
verbose: options.verbose || false
|
|
8
|
+
});
|
|
9
|
+
const sessionId = options.sessionId || basename(transcript || '', '.jsonl');
|
|
10
|
+
const archivePath = await compressor.compress(transcript || '', sessionId);
|
|
11
|
+
console.log('✅ Compression completed successfully');
|
|
12
|
+
console.log(`📦 Archive created: ${archivePath}`);
|
|
59
13
|
}
|
package/dist/commands/install.js
CHANGED
|
@@ -1,10 +1,13 @@
|
|
|
1
|
-
import { readFileSync, writeFileSync, existsSync, chmodSync, mkdirSync, copyFileSync, statSync } from 'fs';
|
|
1
|
+
import { readFileSync, writeFileSync, existsSync, chmodSync, mkdirSync, copyFileSync, statSync, readdirSync } from 'fs';
|
|
2
2
|
import { join, resolve, dirname } from 'path';
|
|
3
3
|
import { homedir } from 'os';
|
|
4
|
+
import { execSync } from 'child_process';
|
|
4
5
|
import { fileURLToPath } from 'url';
|
|
5
6
|
import { PACKAGE_NAME, MCP_SERVER_SCRIPT } from '../config.js';
|
|
6
7
|
import { CLI_MESSAGES } from '../constants.js';
|
|
7
8
|
const __dirname = dirname(fileURLToPath(import.meta.url));
|
|
9
|
+
// <Block> 2.1 ====================================
|
|
10
|
+
// Directory structure creation - natural setup flow
|
|
8
11
|
function ensureDirectoryStructure() {
|
|
9
12
|
const claudeMemDir = join(homedir(), '.claude-mem');
|
|
10
13
|
const hooksDir = join(claudeMemDir, 'hooks');
|
|
@@ -17,12 +20,128 @@ function ensureDirectoryStructure() {
|
|
|
17
20
|
}
|
|
18
21
|
});
|
|
19
22
|
}
|
|
23
|
+
// </Block> =======================================
|
|
24
|
+
function copyFileRecursively(src, dest) {
|
|
25
|
+
const stat = statSync(src);
|
|
26
|
+
if (stat.isDirectory()) {
|
|
27
|
+
if (!existsSync(dest)) {
|
|
28
|
+
mkdirSync(dest, { recursive: true });
|
|
29
|
+
}
|
|
30
|
+
const files = readdirSync(src);
|
|
31
|
+
files.forEach((file) => {
|
|
32
|
+
copyFileRecursively(join(src, file), join(dest, file));
|
|
33
|
+
});
|
|
34
|
+
}
|
|
35
|
+
else {
|
|
36
|
+
copyFileSync(src, dest);
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
function createMcpPackageJson(destDir) {
|
|
40
|
+
const packageJsonPath = join(destDir, 'package.json');
|
|
41
|
+
const mcpPackageJson = {
|
|
42
|
+
"name": "claude-mem-mcp-server",
|
|
43
|
+
"version": "1.0.0",
|
|
44
|
+
"description": "MCP server for claude-mem embedded Weaviate instance",
|
|
45
|
+
"type": "module",
|
|
46
|
+
"main": "mcp-server-cli.js",
|
|
47
|
+
"dependencies": {
|
|
48
|
+
"@anthropic-ai/claude-code": "^1.0.88",
|
|
49
|
+
"@modelcontextprotocol/sdk": "^0.5.0",
|
|
50
|
+
"commander": "^14.0.0",
|
|
51
|
+
"weaviate-ts-embedded": "^1.2.0"
|
|
52
|
+
},
|
|
53
|
+
"engines": {
|
|
54
|
+
"node": ">=18.0.0"
|
|
55
|
+
}
|
|
56
|
+
};
|
|
57
|
+
writeFileSync(packageJsonPath, JSON.stringify(mcpPackageJson, null, 2));
|
|
58
|
+
console.log('✅ Created package.json for MCP server');
|
|
59
|
+
}
|
|
60
|
+
function installMcpServerFiles() {
|
|
61
|
+
const claudeMemDir = join(homedir(), '.claude-mem');
|
|
62
|
+
// Find the dist directory with all compiled files
|
|
63
|
+
const possibleDistPaths = [
|
|
64
|
+
resolve(join(__dirname, '..', '..')), // Development mode - look in project root dist/
|
|
65
|
+
resolve(join(__dirname, '..')), // Development mode - already in dist/
|
|
66
|
+
resolve(join(dirname(process.execPath), '..', 'lib', 'node_modules', 'claude-mem')), // npm global install
|
|
67
|
+
resolve(join(dirname(process.execPath), '..', '..', 'lib', 'node_modules', 'claude-mem')), // npm global install (alternative path)
|
|
68
|
+
];
|
|
69
|
+
let distPath = null;
|
|
70
|
+
for (const candidatePath of possibleDistPaths) {
|
|
71
|
+
const possibleDist = join(candidatePath, 'dist');
|
|
72
|
+
const mcpServerCliPath = join(possibleDist, MCP_SERVER_SCRIPT);
|
|
73
|
+
const mcpServerPath = join(possibleDist, 'mcp-server.js');
|
|
74
|
+
const constantsPath = join(possibleDist, 'constants.js');
|
|
75
|
+
const utilsPath = join(possibleDist, 'utils');
|
|
76
|
+
if (existsSync(mcpServerCliPath) && existsSync(mcpServerPath) && existsSync(constantsPath) && existsSync(utilsPath)) {
|
|
77
|
+
distPath = possibleDist;
|
|
78
|
+
break;
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
if (!distPath) {
|
|
82
|
+
console.log('⚠️ MCP server files not found in dist directory, MCP features will be unavailable');
|
|
83
|
+
return false;
|
|
84
|
+
}
|
|
85
|
+
console.log(`📁 Found MCP server files in: ${distPath}`);
|
|
86
|
+
// Copy all required MCP server files
|
|
87
|
+
const filesToCopy = [
|
|
88
|
+
MCP_SERVER_SCRIPT, // mcp-server-cli.js (entry point)
|
|
89
|
+
'mcp-server.js', // Main server logic
|
|
90
|
+
'constants.js', // Constants and messages
|
|
91
|
+
'config.js', // Configuration
|
|
92
|
+
'types.js', // Type definitions
|
|
93
|
+
'error-handler.js' // Error handling
|
|
94
|
+
];
|
|
95
|
+
// Copy individual files
|
|
96
|
+
for (const file of filesToCopy) {
|
|
97
|
+
const srcPath = join(distPath, file);
|
|
98
|
+
const destPath = join(claudeMemDir, file);
|
|
99
|
+
if (existsSync(srcPath)) {
|
|
100
|
+
copyFileSync(srcPath, destPath);
|
|
101
|
+
if (file === MCP_SERVER_SCRIPT) {
|
|
102
|
+
chmodSync(destPath, 0o755); // Make CLI executable
|
|
103
|
+
}
|
|
104
|
+
console.log(`✅ Copied ${file}`);
|
|
105
|
+
}
|
|
106
|
+
else {
|
|
107
|
+
console.log(`⚠️ Missing required file: ${file}`);
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
// Copy utils directory recursively
|
|
111
|
+
const utilsSrc = join(distPath, 'utils');
|
|
112
|
+
const utilsDest = join(claudeMemDir, 'utils');
|
|
113
|
+
if (existsSync(utilsSrc)) {
|
|
114
|
+
copyFileRecursively(utilsSrc, utilsDest);
|
|
115
|
+
console.log('✅ Copied utils/ directory');
|
|
116
|
+
}
|
|
117
|
+
else {
|
|
118
|
+
console.log('⚠️ Missing required utils/ directory');
|
|
119
|
+
return false;
|
|
120
|
+
}
|
|
121
|
+
// Create package.json with dependencies
|
|
122
|
+
createMcpPackageJson(claudeMemDir);
|
|
123
|
+
// Install dependencies
|
|
124
|
+
try {
|
|
125
|
+
console.log('📦 Installing MCP server dependencies...');
|
|
126
|
+
execSync('npm install', {
|
|
127
|
+
cwd: claudeMemDir,
|
|
128
|
+
stdio: ['ignore', 'pipe', 'pipe'],
|
|
129
|
+
timeout: 120000 // 2 minute timeout
|
|
130
|
+
});
|
|
131
|
+
console.log('✅ Dependencies installed successfully');
|
|
132
|
+
}
|
|
133
|
+
catch (error) {
|
|
134
|
+
console.log(`⚠️ Failed to install dependencies: ${error.message}`);
|
|
135
|
+
console.log(' You may need to run "npm install" manually in ~/.claude-mem/');
|
|
136
|
+
return false;
|
|
137
|
+
}
|
|
138
|
+
return true;
|
|
139
|
+
}
|
|
20
140
|
function writeHookFiles() {
|
|
21
141
|
const hooksDir = join(homedir(), '.claude-mem', 'hooks');
|
|
22
142
|
const preCompactDest = join(hooksDir, 'pre-compact.js');
|
|
23
143
|
const sessionStartDest = join(hooksDir, 'session-start.js');
|
|
24
144
|
const sessionEndDest = join(hooksDir, 'session-end.js');
|
|
25
|
-
const mcpServerDest = join(homedir(), '.claude-mem', MCP_SERVER_SCRIPT);
|
|
26
145
|
// Find hooks directory relative to the package location
|
|
27
146
|
const possibleHooksPaths = [
|
|
28
147
|
resolve(join(__dirname, '..', '..', 'hooks')), // Development mode
|
|
@@ -30,18 +149,9 @@ function writeHookFiles() {
|
|
|
30
149
|
resolve(join(dirname(process.execPath), '..', 'lib', 'node_modules', 'claude-mem', 'hooks')), // npm global install
|
|
31
150
|
resolve(join(dirname(process.execPath), '..', '..', 'lib', 'node_modules', 'claude-mem', 'hooks')), // npm global install (alternative path)
|
|
32
151
|
];
|
|
33
|
-
// Find MCP server script in dist directory
|
|
34
|
-
const possibleMcpServerPaths = [
|
|
35
|
-
resolve(join(__dirname, '..', '..', 'dist', MCP_SERVER_SCRIPT)), // Development mode - look in project dist/
|
|
36
|
-
resolve(join(__dirname, '..', MCP_SERVER_SCRIPT)), // Development mode - compiled to same dist/
|
|
37
|
-
resolve(join(dirname(process.execPath), '..', 'lib', 'node_modules', 'claude-mem', 'dist', MCP_SERVER_SCRIPT)), // npm global install
|
|
38
|
-
resolve(join(dirname(process.execPath), '..', '..', 'lib', 'node_modules', 'claude-mem', 'dist', MCP_SERVER_SCRIPT)), // npm global install (alternative path)
|
|
39
|
-
resolve(join(dirname(process.execPath), MCP_SERVER_SCRIPT)), // Standalone executable with script alongside
|
|
40
|
-
];
|
|
41
152
|
let preCompactSource = null;
|
|
42
153
|
let sessionStartSource = null;
|
|
43
154
|
let sessionEndSource = null;
|
|
44
|
-
let mcpServerSource = null;
|
|
45
155
|
for (const hooksPath of possibleHooksPaths) {
|
|
46
156
|
const preCompactCandidate = join(hooksPath, 'pre-compact.js');
|
|
47
157
|
const sessionStartCandidate = join(hooksPath, 'session-start.js');
|
|
@@ -56,71 +166,37 @@ function writeHookFiles() {
|
|
|
56
166
|
break;
|
|
57
167
|
}
|
|
58
168
|
}
|
|
59
|
-
//
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
169
|
+
// Proceed with whatever files we found
|
|
170
|
+
if (!preCompactSource || !sessionStartSource) {
|
|
171
|
+
console.log('⚠️ Some hook files not found, continuing with available files');
|
|
172
|
+
if (!preCompactSource)
|
|
173
|
+
console.log(' - pre-compact.js not found');
|
|
174
|
+
if (!sessionStartSource)
|
|
175
|
+
console.log(' - session-start.js not found');
|
|
65
176
|
}
|
|
66
|
-
|
|
177
|
+
// Install available files
|
|
178
|
+
if (preCompactSource) {
|
|
67
179
|
copyFileSync(preCompactSource, preCompactDest);
|
|
68
|
-
copyFileSync(sessionStartSource, sessionStartDest);
|
|
69
|
-
// Copy session-end.js if it exists
|
|
70
|
-
if (sessionEndSource) {
|
|
71
|
-
copyFileSync(sessionEndSource, sessionEndDest);
|
|
72
|
-
chmodSync(sessionEndDest, 0o755);
|
|
73
|
-
}
|
|
74
180
|
chmodSync(preCompactDest, 0o755);
|
|
181
|
+
}
|
|
182
|
+
if (sessionStartSource) {
|
|
183
|
+
copyFileSync(sessionStartSource, sessionStartDest);
|
|
75
184
|
chmodSync(sessionStartDest, 0o755);
|
|
76
|
-
// Copy MCP server script
|
|
77
|
-
if (mcpServerSource) {
|
|
78
|
-
copyFileSync(mcpServerSource, mcpServerDest);
|
|
79
|
-
chmodSync(mcpServerDest, 0o755);
|
|
80
|
-
console.log('✅ MCP server script installed');
|
|
81
|
-
}
|
|
82
|
-
else {
|
|
83
|
-
console.error('❌ MCP server script not found');
|
|
84
|
-
console.error('Searched in:');
|
|
85
|
-
possibleMcpServerPaths.forEach(path => console.error(` - ${path}`));
|
|
86
|
-
process.exit(1);
|
|
87
|
-
}
|
|
88
|
-
// Write a configuration file for hooks to know the package name
|
|
89
|
-
const hookConfigPath = join(hooksDir, 'config.json');
|
|
90
|
-
const hookConfig = {
|
|
91
|
-
packageName: PACKAGE_NAME,
|
|
92
|
-
cliCommand: PACKAGE_NAME, // The command to call (claude-mem)
|
|
93
|
-
backend: 'weaviate' // Always use embedded Weaviate
|
|
94
|
-
};
|
|
95
|
-
writeFileSync(hookConfigPath, JSON.stringify(hookConfig, null, 2));
|
|
96
|
-
console.log(CLI_MESSAGES.INSTALLATION.HOOKS_INSTALLED);
|
|
97
|
-
// Validate MCP server script installation
|
|
98
|
-
if (existsSync(mcpServerDest)) {
|
|
99
|
-
try {
|
|
100
|
-
// Test script has execute permissions by checking file stats
|
|
101
|
-
const stats = statSync(mcpServerDest);
|
|
102
|
-
if (stats.mode & parseInt('100', 8)) {
|
|
103
|
-
console.log('✅ MCP server script validated');
|
|
104
|
-
}
|
|
105
|
-
else {
|
|
106
|
-
console.warn('⚠️ MCP server script may not be executable');
|
|
107
|
-
}
|
|
108
|
-
}
|
|
109
|
-
catch (error) {
|
|
110
|
-
console.warn(`⚠️ MCP server script validation failed: ${error.message}`);
|
|
111
|
-
}
|
|
112
|
-
}
|
|
113
|
-
else {
|
|
114
|
-
console.error('❌ MCP server script validation failed - file not found');
|
|
115
|
-
process.exit(1);
|
|
116
|
-
}
|
|
117
185
|
}
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
process.exit(1);
|
|
186
|
+
// Copy session-end.js if it exists
|
|
187
|
+
if (sessionEndSource) {
|
|
188
|
+
copyFileSync(sessionEndSource, sessionEndDest);
|
|
189
|
+
chmodSync(sessionEndDest, 0o755);
|
|
123
190
|
}
|
|
191
|
+
// Write a configuration file for hooks to know the package name
|
|
192
|
+
const hookConfigPath = join(hooksDir, 'config.json');
|
|
193
|
+
const hookConfig = {
|
|
194
|
+
packageName: PACKAGE_NAME,
|
|
195
|
+
cliCommand: PACKAGE_NAME, // The command to call (claude-mem)
|
|
196
|
+
backend: 'weaviate' // Always use embedded Weaviate
|
|
197
|
+
};
|
|
198
|
+
writeFileSync(hookConfigPath, JSON.stringify(hookConfig, null, 2));
|
|
199
|
+
console.log(CLI_MESSAGES.INSTALLATION.HOOKS_INSTALLED);
|
|
124
200
|
}
|
|
125
201
|
/**
|
|
126
202
|
* 🔒 LOCKED by @docs-agent | Change to 🔑 to allow @docs-agent edits
|
|
@@ -211,6 +287,8 @@ export async function install(options = {}) {
|
|
|
211
287
|
'user';
|
|
212
288
|
// Configure MCP server with the appropriate scope
|
|
213
289
|
configureMcpServer(settingsDir, scope);
|
|
290
|
+
// Install MCP server files to ~/.claude-mem/
|
|
291
|
+
const mcpServerInstalled = installMcpServerFiles();
|
|
214
292
|
// Write hook files to ~/.claude-mem/hooks/
|
|
215
293
|
writeHookFiles();
|
|
216
294
|
// Point settings to the installed hooks
|
|
@@ -226,6 +304,7 @@ export async function install(options = {}) {
|
|
|
226
304
|
}
|
|
227
305
|
catch (error) {
|
|
228
306
|
console.log(`⚠️ Creating new settings file (could not parse existing): ${error.message}`);
|
|
307
|
+
settings = {}; // Continue with fresh settings
|
|
229
308
|
}
|
|
230
309
|
}
|
|
231
310
|
// Ensure settings directory exists
|
|
@@ -236,36 +315,24 @@ export async function install(options = {}) {
|
|
|
236
315
|
if (!settings.hooks) {
|
|
237
316
|
settings.hooks = {};
|
|
238
317
|
}
|
|
239
|
-
//
|
|
240
|
-
// Non-tool hooks
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
console.log(CLI_MESSAGES.INSTALLATION.ALREADY_INSTALLED);
|
|
246
|
-
console.log(CLI_MESSAGES.INSTALLATION.USE_FORCE);
|
|
247
|
-
return;
|
|
248
|
-
}
|
|
249
|
-
// Remove existing claude-mem hooks if forcing
|
|
250
|
-
if (options.force) {
|
|
251
|
-
// Non-tool hooks: filter out configs where hooks contain our commands
|
|
252
|
-
if (settings.hooks.PreCompact) {
|
|
253
|
-
settings.hooks.PreCompact = settings.hooks.PreCompact.filter((config) => !config.hooks?.some((hook) => hook.command?.includes(PACKAGE_NAME) || hook.command?.includes('pre-compact.js')));
|
|
254
|
-
if (settings.hooks.PreCompact.length === 0) {
|
|
255
|
-
delete settings.hooks.PreCompact;
|
|
256
|
-
}
|
|
318
|
+
// Remove existing claude-mem hooks to ensure clean installation/update
|
|
319
|
+
// Non-tool hooks: filter out configs where hooks contain our commands
|
|
320
|
+
if (settings.hooks.PreCompact) {
|
|
321
|
+
settings.hooks.PreCompact = settings.hooks.PreCompact.filter((config) => !config.hooks?.some((hook) => hook.command?.includes(PACKAGE_NAME) || hook.command?.includes('pre-compact.js')));
|
|
322
|
+
if (settings.hooks.PreCompact.length === 0) {
|
|
323
|
+
delete settings.hooks.PreCompact;
|
|
257
324
|
}
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
325
|
+
}
|
|
326
|
+
if (settings.hooks.SessionStart) {
|
|
327
|
+
settings.hooks.SessionStart = settings.hooks.SessionStart.filter((config) => !config.hooks?.some((hook) => hook.command?.includes(PACKAGE_NAME) || hook.command?.includes('session-start.js')));
|
|
328
|
+
if (settings.hooks.SessionStart.length === 0) {
|
|
329
|
+
delete settings.hooks.SessionStart;
|
|
263
330
|
}
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
331
|
+
}
|
|
332
|
+
if (settings.hooks.SessionEnd) {
|
|
333
|
+
settings.hooks.SessionEnd = settings.hooks.SessionEnd.filter((config) => !config.hooks?.some((hook) => hook.command?.includes(PACKAGE_NAME) || hook.command?.includes('session-end.js')));
|
|
334
|
+
if (settings.hooks.SessionEnd.length === 0) {
|
|
335
|
+
delete settings.hooks.SessionEnd;
|
|
269
336
|
}
|
|
270
337
|
}
|
|
271
338
|
/**
|
|
@@ -366,7 +433,7 @@ export async function install(options = {}) {
|
|
|
366
433
|
});
|
|
367
434
|
}
|
|
368
435
|
catch (error) {
|
|
369
|
-
console.
|
|
370
|
-
|
|
436
|
+
console.log(CLI_MESSAGES.ERRORS.SETTINGS_WRITE_FAILED(settingsPath, error.message));
|
|
437
|
+
console.log('⚠️ Installation completed but settings file could not be written');
|
|
371
438
|
}
|
|
372
439
|
}
|