universal-memory-mcp 0.2.3 → 0.3.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/dist/consolidate.d.ts +6 -0
- package/dist/consolidate.d.ts.map +1 -0
- package/dist/consolidate.js +291 -0
- package/dist/consolidate.js.map +1 -0
- package/dist/consolidation/deduplicator.d.ts +17 -0
- package/dist/consolidation/deduplicator.d.ts.map +1 -0
- package/dist/consolidation/deduplicator.js +158 -0
- package/dist/consolidation/deduplicator.js.map +1 -0
- package/dist/consolidation/extractor.d.ts +36 -0
- package/dist/consolidation/extractor.d.ts.map +1 -0
- package/dist/consolidation/extractor.js +310 -0
- package/dist/consolidation/extractor.js.map +1 -0
- package/dist/consolidation/index.d.ts +14 -0
- package/dist/consolidation/index.d.ts.map +1 -0
- package/dist/consolidation/index.js +14 -0
- package/dist/consolidation/index.js.map +1 -0
- package/dist/consolidation/scanner.d.ts +27 -0
- package/dist/consolidation/scanner.d.ts.map +1 -0
- package/dist/consolidation/scanner.js +122 -0
- package/dist/consolidation/scanner.js.map +1 -0
- package/dist/consolidation/summary-consolidator.d.ts +40 -0
- package/dist/consolidation/summary-consolidator.d.ts.map +1 -0
- package/dist/consolidation/summary-consolidator.js +342 -0
- package/dist/consolidation/summary-consolidator.js.map +1 -0
- package/dist/consolidation/updater.d.ts +9 -0
- package/dist/consolidation/updater.d.ts.map +1 -0
- package/dist/consolidation/updater.js +179 -0
- package/dist/consolidation/updater.js.map +1 -0
- package/dist/cron.d.ts +6 -0
- package/dist/cron.d.ts.map +1 -0
- package/dist/cron.js +200 -0
- package/dist/cron.js.map +1 -0
- package/package.json +5 -3
- package/scripts/postinstall.js +231 -6
- package/scripts/universal-memory-start-hook.mjs +136 -0
- package/scripts/universal-memory-stop-hook.mjs +261 -0
package/dist/cron.js
ADDED
|
@@ -0,0 +1,200 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* universal-memory-cron - 定时任务管理 CLI
|
|
4
|
+
*/
|
|
5
|
+
import { execSync, spawnSync } from 'node:child_process';
|
|
6
|
+
import { platform } from 'node:os';
|
|
7
|
+
function printHelp() {
|
|
8
|
+
console.log(`
|
|
9
|
+
universal-memory-cron - 管理长期记忆整理定时任务
|
|
10
|
+
|
|
11
|
+
使用方法:
|
|
12
|
+
universal-memory-cron <command>
|
|
13
|
+
|
|
14
|
+
命令:
|
|
15
|
+
install 安装定时任务(每天凌晨 2:00 运行)
|
|
16
|
+
uninstall 卸载定时任务
|
|
17
|
+
status 查看定时任务状态
|
|
18
|
+
|
|
19
|
+
示例:
|
|
20
|
+
universal-memory-cron install
|
|
21
|
+
universal-memory-cron uninstall
|
|
22
|
+
universal-memory-cron status
|
|
23
|
+
|
|
24
|
+
说明:
|
|
25
|
+
此命令用于管理 universal-memory-consolidate 的定时任务。
|
|
26
|
+
安装后,系统会每天凌晨 2:00 自动运行记忆整理。
|
|
27
|
+
|
|
28
|
+
支持的系统:macOS, Linux
|
|
29
|
+
Windows 用户请使用 Task Scheduler 手动配置。
|
|
30
|
+
`);
|
|
31
|
+
}
|
|
32
|
+
function getCronJobLine() {
|
|
33
|
+
// 每天凌晨 2:00 运行,整理前一天的对话
|
|
34
|
+
return `0 2 * * * $(which universal-memory-consolidate) --days 1 >> ~/.ai_memory/consolidate.log 2>&1`;
|
|
35
|
+
}
|
|
36
|
+
function getCronMarker() {
|
|
37
|
+
return '# universal-memory-consolidate';
|
|
38
|
+
}
|
|
39
|
+
function installCron() {
|
|
40
|
+
const os = platform();
|
|
41
|
+
if (os === 'win32') {
|
|
42
|
+
console.log('❌ Windows 不支持自动安装 cron 任务');
|
|
43
|
+
console.log('\n请使用 Task Scheduler 手动配置:');
|
|
44
|
+
console.log(' 1. 打开 Task Scheduler');
|
|
45
|
+
console.log(' 2. 创建基本任务');
|
|
46
|
+
console.log(' 3. 触发器:每天 2:00');
|
|
47
|
+
console.log(' 4. 操作:运行 universal-memory-consolidate --days 1');
|
|
48
|
+
return;
|
|
49
|
+
}
|
|
50
|
+
// 检查是否已安装
|
|
51
|
+
try {
|
|
52
|
+
const currentCrontab = execSync('crontab -l 2>/dev/null', { encoding: 'utf-8' });
|
|
53
|
+
if (currentCrontab.includes(getCronMarker())) {
|
|
54
|
+
console.log('ℹ️ 定时任务已存在');
|
|
55
|
+
console.log('\n当前配置:');
|
|
56
|
+
const lines = currentCrontab.split('\n').filter(l => l.includes('universal-memory'));
|
|
57
|
+
lines.forEach(l => console.log(` ${l}`));
|
|
58
|
+
return;
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
catch {
|
|
62
|
+
// crontab 为空或不存在
|
|
63
|
+
}
|
|
64
|
+
// 安装新的 cron 任务
|
|
65
|
+
const marker = getCronMarker();
|
|
66
|
+
const cronJob = getCronJobLine();
|
|
67
|
+
const newEntry = `${marker}\n${cronJob}`;
|
|
68
|
+
try {
|
|
69
|
+
// 获取现有 crontab
|
|
70
|
+
let currentCrontab = '';
|
|
71
|
+
try {
|
|
72
|
+
currentCrontab = execSync('crontab -l 2>/dev/null', { encoding: 'utf-8' });
|
|
73
|
+
}
|
|
74
|
+
catch {
|
|
75
|
+
// crontab 为空
|
|
76
|
+
}
|
|
77
|
+
// 添加新任务
|
|
78
|
+
const newCrontab = currentCrontab.trim() + '\n' + newEntry + '\n';
|
|
79
|
+
// 写入 crontab
|
|
80
|
+
const result = spawnSync('crontab', ['-'], {
|
|
81
|
+
input: newCrontab,
|
|
82
|
+
encoding: 'utf-8',
|
|
83
|
+
});
|
|
84
|
+
if (result.status !== 0) {
|
|
85
|
+
throw new Error(result.stderr || 'Unknown error');
|
|
86
|
+
}
|
|
87
|
+
console.log('✅ 定时任务已安装');
|
|
88
|
+
console.log('\n配置详情:');
|
|
89
|
+
console.log(' 时间:每天凌晨 2:00');
|
|
90
|
+
console.log(' 命令:universal-memory-consolidate --days 1');
|
|
91
|
+
console.log(' 日志:~/.ai_memory/consolidate.log');
|
|
92
|
+
console.log('\n查看:crontab -l | grep universal-memory');
|
|
93
|
+
}
|
|
94
|
+
catch (error) {
|
|
95
|
+
console.error('❌ 安装失败:', error.message);
|
|
96
|
+
console.log('\n请尝试手动安装:');
|
|
97
|
+
console.log(' crontab -e');
|
|
98
|
+
console.log(` # 添加以下行:`);
|
|
99
|
+
console.log(` ${cronJob}`);
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
function uninstallCron() {
|
|
103
|
+
const os = platform();
|
|
104
|
+
if (os === 'win32') {
|
|
105
|
+
console.log('❌ Windows 请使用 Task Scheduler 手动删除任务');
|
|
106
|
+
return;
|
|
107
|
+
}
|
|
108
|
+
try {
|
|
109
|
+
const currentCrontab = execSync('crontab -l 2>/dev/null', { encoding: 'utf-8' });
|
|
110
|
+
if (!currentCrontab.includes('universal-memory')) {
|
|
111
|
+
console.log('ℹ️ 没有找到相关的定时任务');
|
|
112
|
+
return;
|
|
113
|
+
}
|
|
114
|
+
// 移除相关行
|
|
115
|
+
const newCrontab = currentCrontab
|
|
116
|
+
.split('\n')
|
|
117
|
+
.filter(line => !line.includes('universal-memory'))
|
|
118
|
+
.join('\n');
|
|
119
|
+
// 写入 crontab
|
|
120
|
+
const result = spawnSync('crontab', ['-'], {
|
|
121
|
+
input: newCrontab,
|
|
122
|
+
encoding: 'utf-8',
|
|
123
|
+
});
|
|
124
|
+
if (result.status !== 0) {
|
|
125
|
+
throw new Error(result.stderr || 'Unknown error');
|
|
126
|
+
}
|
|
127
|
+
console.log('✅ 定时任务已卸载');
|
|
128
|
+
}
|
|
129
|
+
catch (error) {
|
|
130
|
+
if (error.message.includes('no crontab')) {
|
|
131
|
+
console.log('ℹ️ 没有找到相关的定时任务');
|
|
132
|
+
}
|
|
133
|
+
else {
|
|
134
|
+
console.error('❌ 卸载失败:', error.message);
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
function showStatus() {
|
|
139
|
+
const os = platform();
|
|
140
|
+
if (os === 'win32') {
|
|
141
|
+
console.log('ℹ️ Windows 请使用 Task Scheduler 查看任务状态');
|
|
142
|
+
return;
|
|
143
|
+
}
|
|
144
|
+
try {
|
|
145
|
+
const currentCrontab = execSync('crontab -l 2>/dev/null', { encoding: 'utf-8' });
|
|
146
|
+
const lines = currentCrontab.split('\n').filter(l => l.includes('universal-memory') && !l.startsWith('#'));
|
|
147
|
+
if (lines.length === 0) {
|
|
148
|
+
console.log('ℹ️ 未安装定时任务');
|
|
149
|
+
console.log('\n运行以下命令安装:');
|
|
150
|
+
console.log(' universal-memory-cron install');
|
|
151
|
+
}
|
|
152
|
+
else {
|
|
153
|
+
console.log('✅ 定时任务已安装\n');
|
|
154
|
+
console.log('当前配置:');
|
|
155
|
+
lines.forEach(l => console.log(` ${l}`));
|
|
156
|
+
// 检查日志文件
|
|
157
|
+
try {
|
|
158
|
+
const logTail = execSync('tail -5 ~/.ai_memory/consolidate.log 2>/dev/null', { encoding: 'utf-8' });
|
|
159
|
+
if (logTail.trim()) {
|
|
160
|
+
console.log('\n最近日志:');
|
|
161
|
+
console.log(logTail);
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
catch {
|
|
165
|
+
console.log('\n暂无运行日志');
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
catch {
|
|
170
|
+
console.log('ℹ️ 未安装定时任务');
|
|
171
|
+
console.log('\n运行以下命令安装:');
|
|
172
|
+
console.log(' universal-memory-cron install');
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
function main() {
|
|
176
|
+
const args = process.argv.slice(2);
|
|
177
|
+
const command = args[0];
|
|
178
|
+
switch (command) {
|
|
179
|
+
case 'install':
|
|
180
|
+
installCron();
|
|
181
|
+
break;
|
|
182
|
+
case 'uninstall':
|
|
183
|
+
uninstallCron();
|
|
184
|
+
break;
|
|
185
|
+
case 'status':
|
|
186
|
+
showStatus();
|
|
187
|
+
break;
|
|
188
|
+
case '--help':
|
|
189
|
+
case '-h':
|
|
190
|
+
case undefined:
|
|
191
|
+
printHelp();
|
|
192
|
+
break;
|
|
193
|
+
default:
|
|
194
|
+
console.error(`未知命令: ${command}`);
|
|
195
|
+
console.log('运行 universal-memory-cron --help 查看帮助');
|
|
196
|
+
process.exit(1);
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
main();
|
|
200
|
+
//# sourceMappingURL=cron.js.map
|
package/dist/cron.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cron.js","sourceRoot":"","sources":["../src/cron.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,13 +1,15 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "universal-memory-mcp",
|
|
3
|
-
"version": "0.2
|
|
3
|
+
"version": "0.3.2",
|
|
4
4
|
"description": "MCP Server for persistent AI memory across sessions",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
7
7
|
"types": "./dist/index.d.ts",
|
|
8
8
|
"bin": {
|
|
9
9
|
"universal-memory-mcp": "./dist/index.js",
|
|
10
|
-
"universal-memory-record": "./dist/record.js"
|
|
10
|
+
"universal-memory-record": "./dist/record.js",
|
|
11
|
+
"universal-memory-consolidate": "./dist/consolidate.js",
|
|
12
|
+
"universal-memory-cron": "./dist/cron.js"
|
|
11
13
|
},
|
|
12
14
|
"exports": {
|
|
13
15
|
".": {
|
|
@@ -25,7 +27,7 @@
|
|
|
25
27
|
},
|
|
26
28
|
"dependencies": {
|
|
27
29
|
"@modelcontextprotocol/sdk": "^1.0.0",
|
|
28
|
-
"universal-memory-core": "^0.1.
|
|
30
|
+
"universal-memory-core": "^0.1.4"
|
|
29
31
|
},
|
|
30
32
|
"devDependencies": {
|
|
31
33
|
"@types/node": "^20.11.0",
|
package/scripts/postinstall.js
CHANGED
|
@@ -12,8 +12,10 @@ import fs from 'fs';
|
|
|
12
12
|
import path from 'path';
|
|
13
13
|
import os from 'os';
|
|
14
14
|
|
|
15
|
-
const
|
|
16
|
-
const
|
|
15
|
+
const CLAUDE_DIR = path.join(os.homedir(), '.claude');
|
|
16
|
+
const CLAUDE_SETTINGS_PATH = path.join(CLAUDE_DIR, 'settings.json');
|
|
17
|
+
const CLAUDE_SKILLS_PATH = path.join(CLAUDE_DIR, 'skills');
|
|
18
|
+
const CLAUDE_HOOKS_PATH = path.join(CLAUDE_DIR, 'hooks');
|
|
17
19
|
|
|
18
20
|
// MCP server configuration
|
|
19
21
|
const MCP_CONFIG = {
|
|
@@ -155,6 +157,21 @@ memory_update_long_term({
|
|
|
155
157
|
- Use project name when in project context
|
|
156
158
|
`;
|
|
157
159
|
|
|
160
|
+
/**
|
|
161
|
+
* Check if Claude Code is installed
|
|
162
|
+
*/
|
|
163
|
+
function checkClaudeCodeInstalled() {
|
|
164
|
+
if (!fs.existsSync(CLAUDE_DIR)) {
|
|
165
|
+
console.log('\n⚠️ Claude Code not detected!\n');
|
|
166
|
+
console.log('Please install Claude Code first:');
|
|
167
|
+
console.log(' https://code.claude.com/\n');
|
|
168
|
+
console.log('After installing Claude Code, run:');
|
|
169
|
+
console.log(' npm install -g universal-memory-mcp\n');
|
|
170
|
+
return false;
|
|
171
|
+
}
|
|
172
|
+
return true;
|
|
173
|
+
}
|
|
174
|
+
|
|
158
175
|
/**
|
|
159
176
|
* Read JSON file safely
|
|
160
177
|
*/
|
|
@@ -253,6 +270,184 @@ function installSkill() {
|
|
|
253
270
|
return true;
|
|
254
271
|
}
|
|
255
272
|
|
|
273
|
+
/**
|
|
274
|
+
* Install Stop hook script
|
|
275
|
+
*/
|
|
276
|
+
function installStopHook() {
|
|
277
|
+
console.log('\n🪝 Installing Stop hook...');
|
|
278
|
+
|
|
279
|
+
const hookScriptPath = path.join(CLAUDE_HOOKS_PATH, 'universal-memory-stop-hook.mjs');
|
|
280
|
+
|
|
281
|
+
// Create hooks directory if not exists
|
|
282
|
+
if (!fs.existsSync(CLAUDE_HOOKS_PATH)) {
|
|
283
|
+
fs.mkdirSync(CLAUDE_HOOKS_PATH, { recursive: true });
|
|
284
|
+
console.log(' Created hooks directory');
|
|
285
|
+
}
|
|
286
|
+
|
|
287
|
+
// Get source script path (in the same directory as this postinstall script)
|
|
288
|
+
const sourceScript = new URL('universal-memory-stop-hook.mjs', import.meta.url).pathname;
|
|
289
|
+
|
|
290
|
+
// Check if hook already exists
|
|
291
|
+
if (fs.existsSync(hookScriptPath)) {
|
|
292
|
+
const existingContent = fs.readFileSync(hookScriptPath, 'utf-8');
|
|
293
|
+
const newContent = fs.readFileSync(sourceScript, 'utf-8');
|
|
294
|
+
|
|
295
|
+
if (existingContent === newContent) {
|
|
296
|
+
console.log(' Stop hook already installed (same version)');
|
|
297
|
+
return false;
|
|
298
|
+
}
|
|
299
|
+
|
|
300
|
+
// Backup existing hook
|
|
301
|
+
const backupPath = `${hookScriptPath}.backup.${Date.now()}`;
|
|
302
|
+
fs.copyFileSync(hookScriptPath, backupPath);
|
|
303
|
+
console.log(` Backed up existing hook to: ${backupPath}`);
|
|
304
|
+
}
|
|
305
|
+
|
|
306
|
+
fs.copyFileSync(sourceScript, hookScriptPath);
|
|
307
|
+
fs.chmodSync(hookScriptPath, 0o755); // Make executable
|
|
308
|
+
console.log(' Stop hook installed successfully');
|
|
309
|
+
return true;
|
|
310
|
+
}
|
|
311
|
+
|
|
312
|
+
/**
|
|
313
|
+
* Install SessionStart hook script
|
|
314
|
+
*/
|
|
315
|
+
function installStartHook() {
|
|
316
|
+
console.log('\n🚀 Installing SessionStart hook...');
|
|
317
|
+
|
|
318
|
+
const hookScriptPath = path.join(CLAUDE_HOOKS_PATH, 'universal-memory-start-hook.mjs');
|
|
319
|
+
|
|
320
|
+
// Create hooks directory if not exists
|
|
321
|
+
if (!fs.existsSync(CLAUDE_HOOKS_PATH)) {
|
|
322
|
+
fs.mkdirSync(CLAUDE_HOOKS_PATH, { recursive: true });
|
|
323
|
+
console.log(' Created hooks directory');
|
|
324
|
+
}
|
|
325
|
+
|
|
326
|
+
// Get source script path (in the same directory as this postinstall script)
|
|
327
|
+
const sourceScript = new URL('universal-memory-start-hook.mjs', import.meta.url).pathname;
|
|
328
|
+
|
|
329
|
+
// Check if source exists
|
|
330
|
+
if (!fs.existsSync(sourceScript)) {
|
|
331
|
+
console.log(' Start hook source not found, skipping');
|
|
332
|
+
return false;
|
|
333
|
+
}
|
|
334
|
+
|
|
335
|
+
// Check if hook already exists
|
|
336
|
+
if (fs.existsSync(hookScriptPath)) {
|
|
337
|
+
const existingContent = fs.readFileSync(hookScriptPath, 'utf-8');
|
|
338
|
+
const newContent = fs.readFileSync(sourceScript, 'utf-8');
|
|
339
|
+
|
|
340
|
+
if (existingContent === newContent) {
|
|
341
|
+
console.log(' Start hook already installed (same version)');
|
|
342
|
+
return false;
|
|
343
|
+
}
|
|
344
|
+
|
|
345
|
+
// Backup existing hook
|
|
346
|
+
const backupPath = `${hookScriptPath}.backup.${Date.now()}`;
|
|
347
|
+
fs.copyFileSync(hookScriptPath, backupPath);
|
|
348
|
+
console.log(` Backed up existing hook to: ${backupPath}`);
|
|
349
|
+
}
|
|
350
|
+
|
|
351
|
+
fs.copyFileSync(sourceScript, hookScriptPath);
|
|
352
|
+
fs.chmodSync(hookScriptPath, 0o755); // Make executable
|
|
353
|
+
console.log(' Start hook installed successfully');
|
|
354
|
+
return true;
|
|
355
|
+
}
|
|
356
|
+
|
|
357
|
+
/**
|
|
358
|
+
* Configure Stop hook in Claude settings
|
|
359
|
+
*/
|
|
360
|
+
function configureStopHook() {
|
|
361
|
+
console.log('\n⚙️ Configuring Stop hook...');
|
|
362
|
+
|
|
363
|
+
let settings = readJsonFile(CLAUDE_SETTINGS_PATH) || {};
|
|
364
|
+
|
|
365
|
+
// Initialize hooks if not exists
|
|
366
|
+
if (!settings.hooks) {
|
|
367
|
+
settings.hooks = {};
|
|
368
|
+
}
|
|
369
|
+
|
|
370
|
+
// Initialize Stop hook array if not exists
|
|
371
|
+
if (!settings.hooks.Stop) {
|
|
372
|
+
settings.hooks.Stop = [];
|
|
373
|
+
}
|
|
374
|
+
|
|
375
|
+
// Check if our hook is already configured
|
|
376
|
+
const hookScriptPath = path.join(os.homedir(), '.claude', 'hooks', 'universal-memory-stop-hook.mjs');
|
|
377
|
+
const hookCommand = `node ${hookScriptPath}`;
|
|
378
|
+
const alreadyConfigured = settings.hooks.Stop.some(entry =>
|
|
379
|
+
entry.hooks?.some(hook =>
|
|
380
|
+
hook.type === 'command' && hook.command.includes('universal-memory-stop-hook')
|
|
381
|
+
)
|
|
382
|
+
);
|
|
383
|
+
|
|
384
|
+
if (alreadyConfigured) {
|
|
385
|
+
console.log(' Stop hook already configured');
|
|
386
|
+
return false;
|
|
387
|
+
}
|
|
388
|
+
|
|
389
|
+
// Add Stop hook configuration
|
|
390
|
+
settings.hooks.Stop.push({
|
|
391
|
+
hooks: [
|
|
392
|
+
{
|
|
393
|
+
type: 'command',
|
|
394
|
+
command: hookCommand
|
|
395
|
+
}
|
|
396
|
+
]
|
|
397
|
+
});
|
|
398
|
+
|
|
399
|
+
writeJsonFile(CLAUDE_SETTINGS_PATH, settings);
|
|
400
|
+
console.log(' Stop hook configured successfully');
|
|
401
|
+
return true;
|
|
402
|
+
}
|
|
403
|
+
|
|
404
|
+
/**
|
|
405
|
+
* Configure SessionStart hook in Claude settings
|
|
406
|
+
*/
|
|
407
|
+
function configureStartHook() {
|
|
408
|
+
console.log('\n⚙️ Configuring SessionStart hook...');
|
|
409
|
+
|
|
410
|
+
let settings = readJsonFile(CLAUDE_SETTINGS_PATH) || {};
|
|
411
|
+
|
|
412
|
+
// Initialize hooks if not exists
|
|
413
|
+
if (!settings.hooks) {
|
|
414
|
+
settings.hooks = {};
|
|
415
|
+
}
|
|
416
|
+
|
|
417
|
+
// Initialize SessionStart hook array if not exists
|
|
418
|
+
if (!settings.hooks.SessionStart) {
|
|
419
|
+
settings.hooks.SessionStart = [];
|
|
420
|
+
}
|
|
421
|
+
|
|
422
|
+
// Check if our hook is already configured
|
|
423
|
+
const hookScriptPath = path.join(os.homedir(), '.claude', 'hooks', 'universal-memory-start-hook.mjs');
|
|
424
|
+
const hookCommand = `node ${hookScriptPath}`;
|
|
425
|
+
const alreadyConfigured = settings.hooks.SessionStart.some(entry =>
|
|
426
|
+
entry.hooks?.some(hook =>
|
|
427
|
+
hook.type === 'command' && hook.command.includes('universal-memory-start-hook')
|
|
428
|
+
)
|
|
429
|
+
);
|
|
430
|
+
|
|
431
|
+
if (alreadyConfigured) {
|
|
432
|
+
console.log(' SessionStart hook already configured');
|
|
433
|
+
return false;
|
|
434
|
+
}
|
|
435
|
+
|
|
436
|
+
// Add SessionStart hook configuration
|
|
437
|
+
settings.hooks.SessionStart.push({
|
|
438
|
+
hooks: [
|
|
439
|
+
{
|
|
440
|
+
type: 'command',
|
|
441
|
+
command: hookCommand
|
|
442
|
+
}
|
|
443
|
+
]
|
|
444
|
+
});
|
|
445
|
+
|
|
446
|
+
writeJsonFile(CLAUDE_SETTINGS_PATH, settings);
|
|
447
|
+
console.log(' SessionStart hook configured successfully');
|
|
448
|
+
return true;
|
|
449
|
+
}
|
|
450
|
+
|
|
256
451
|
/**
|
|
257
452
|
* Main installation
|
|
258
453
|
*/
|
|
@@ -261,26 +456,48 @@ function main() {
|
|
|
261
456
|
console.log('║ Universal Memory MCP - Setup ║');
|
|
262
457
|
console.log('╚════════════════════════════════════════════════════════════╝');
|
|
263
458
|
|
|
459
|
+
// Check Claude Code installation
|
|
460
|
+
if (!checkClaudeCodeInstalled()) {
|
|
461
|
+
process.exit(0);
|
|
462
|
+
}
|
|
463
|
+
|
|
264
464
|
let needsRestart = false;
|
|
265
465
|
|
|
266
466
|
try {
|
|
267
|
-
// Configure MCP server
|
|
467
|
+
// 1. Configure MCP server
|
|
268
468
|
const mcpConfigured = configureMcpServer();
|
|
269
469
|
if (mcpConfigured) needsRestart = true;
|
|
270
470
|
|
|
271
|
-
// Install skill
|
|
471
|
+
// 2. Install skill
|
|
272
472
|
const skillInstalled = installSkill();
|
|
273
473
|
if (skillInstalled) needsRestart = true;
|
|
274
474
|
|
|
475
|
+
// 3. Install Stop hook script
|
|
476
|
+
const stopHookInstalled = installStopHook();
|
|
477
|
+
if (stopHookInstalled) needsRestart = true;
|
|
478
|
+
|
|
479
|
+
// 4. Configure Stop hook
|
|
480
|
+
const stopHookConfigured = configureStopHook();
|
|
481
|
+
if (stopHookConfigured) needsRestart = true;
|
|
482
|
+
|
|
483
|
+
// 5. Install SessionStart hook script
|
|
484
|
+
const startHookInstalled = installStartHook();
|
|
485
|
+
if (startHookInstalled) needsRestart = true;
|
|
486
|
+
|
|
487
|
+
// 6. Configure SessionStart hook
|
|
488
|
+
const startHookConfigured = configureStartHook();
|
|
489
|
+
if (startHookConfigured) needsRestart = true;
|
|
490
|
+
|
|
275
491
|
// Summary
|
|
276
492
|
console.log('\n' + '═'.repeat(60));
|
|
277
493
|
|
|
278
494
|
if (needsRestart) {
|
|
279
495
|
console.log('\n✅ Setup complete!\n');
|
|
280
|
-
console.log('⚠️ IMPORTANT: Please restart Claude Code to enable
|
|
496
|
+
console.log('⚠️ IMPORTANT: Please restart Claude Code to enable all features.\n');
|
|
281
497
|
console.log('After restart, Claude will automatically:');
|
|
498
|
+
console.log(' • Recall your profile at session start (via SessionStart hook)');
|
|
282
499
|
console.log(' • Search past conversations when you reference them');
|
|
283
|
-
console.log(' • Record
|
|
500
|
+
console.log(' • Record EVERY conversation automatically (via Stop hook)');
|
|
284
501
|
console.log(' • Remember your preferences and decisions\n');
|
|
285
502
|
} else {
|
|
286
503
|
console.log('\n✅ Already configured! No changes needed.\n');
|
|
@@ -289,8 +506,16 @@ function main() {
|
|
|
289
506
|
console.log('📁 Configuration locations:');
|
|
290
507
|
console.log(` MCP config: ${CLAUDE_SETTINGS_PATH}`);
|
|
291
508
|
console.log(` Skill: ${path.join(CLAUDE_SKILLS_PATH, 'memory-assistant', 'SKILL.md')}`);
|
|
509
|
+
console.log(` Stop hook: ${path.join(CLAUDE_HOOKS_PATH, 'universal-memory-stop-hook.mjs')}`);
|
|
510
|
+
console.log(` Start hook: ${path.join(CLAUDE_HOOKS_PATH, 'universal-memory-start-hook.mjs')}`);
|
|
292
511
|
console.log(` Memory storage: ${path.join(os.homedir(), '.ai_memory')}\n`);
|
|
293
512
|
|
|
513
|
+
console.log('💡 可选:设置自动整理长期记忆');
|
|
514
|
+
console.log(' # 手动整理最近 7 天的对话');
|
|
515
|
+
console.log(' universal-memory-consolidate --days 7\n');
|
|
516
|
+
console.log(' # 完整整理(包含二次整合)');
|
|
517
|
+
console.log(' universal-memory-consolidate --days 7 --consolidate-summary\n');
|
|
518
|
+
|
|
294
519
|
} catch (error) {
|
|
295
520
|
console.error('\n❌ Setup failed:', error.message);
|
|
296
521
|
console.error('\nPlease configure manually. See README for instructions.');
|
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Universal Memory - SessionStart Hook
|
|
5
|
+
*
|
|
6
|
+
* 在会话开始时召回用户画像,注入到会话上下文中。
|
|
7
|
+
*
|
|
8
|
+
* 功能:
|
|
9
|
+
* 1. 读取 profile-summary.md(Level 2 整合摘要)
|
|
10
|
+
* 2. 如果不存在,回退到 profile.md(Level 1 原始条目)
|
|
11
|
+
* 3. 输出用户画像到 stdout,Claude Code 会将其作为系统上下文
|
|
12
|
+
*/
|
|
13
|
+
|
|
14
|
+
import fs from 'node:fs';
|
|
15
|
+
import path from 'node:path';
|
|
16
|
+
import os from 'node:os';
|
|
17
|
+
|
|
18
|
+
// Enable debug logging via environment variable
|
|
19
|
+
const DEBUG = process.env.UNIVERSAL_MEMORY_DEBUG === '1';
|
|
20
|
+
|
|
21
|
+
function debugLog(message) {
|
|
22
|
+
if (DEBUG) {
|
|
23
|
+
fs.appendFileSync('/tmp/universal-memory-start-hook.log', `[${new Date().toISOString()}] ${message}\n`);
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
function getMemoryPath() {
|
|
28
|
+
return process.env.MEMORY_PATH || path.join(os.homedir(), '.ai_memory');
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
function readProfileSummary() {
|
|
32
|
+
const memoryPath = getMemoryPath();
|
|
33
|
+
const longTermDir = path.join(memoryPath, 'long_term');
|
|
34
|
+
|
|
35
|
+
// 优先读取 Level 2 整合摘要
|
|
36
|
+
const summaryPath = path.join(longTermDir, 'profile-summary.md');
|
|
37
|
+
if (fs.existsSync(summaryPath)) {
|
|
38
|
+
debugLog(`Reading profile summary from: ${summaryPath}`);
|
|
39
|
+
const content = fs.readFileSync(summaryPath, 'utf-8');
|
|
40
|
+
return { source: 'profile-summary.md', content };
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
// 回退到 Level 1 原始条目
|
|
44
|
+
const profilePath = path.join(longTermDir, 'profile.md');
|
|
45
|
+
if (fs.existsSync(profilePath)) {
|
|
46
|
+
debugLog(`Reading profile from: ${profilePath}`);
|
|
47
|
+
const content = fs.readFileSync(profilePath, 'utf-8');
|
|
48
|
+
return { source: 'profile.md', content };
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
debugLog('No profile found');
|
|
52
|
+
return null;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
function readKnowledgeSummary() {
|
|
56
|
+
const memoryPath = getMemoryPath();
|
|
57
|
+
const longTermDir = path.join(memoryPath, 'long_term');
|
|
58
|
+
|
|
59
|
+
const summaryPath = path.join(longTermDir, 'knowledge-summary.md');
|
|
60
|
+
if (fs.existsSync(summaryPath)) {
|
|
61
|
+
debugLog(`Reading knowledge summary from: ${summaryPath}`);
|
|
62
|
+
const content = fs.readFileSync(summaryPath, 'utf-8');
|
|
63
|
+
return { source: 'knowledge-summary.md', content };
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
return null;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
function formatOutput(profile, knowledge) {
|
|
70
|
+
const parts = [];
|
|
71
|
+
|
|
72
|
+
parts.push('<user-memory>');
|
|
73
|
+
parts.push('以下是从长期记忆中召回的用户信息,请在对话中参考:');
|
|
74
|
+
parts.push('');
|
|
75
|
+
|
|
76
|
+
if (profile) {
|
|
77
|
+
parts.push(`<!-- Source: ${profile.source} -->`);
|
|
78
|
+
parts.push(profile.content);
|
|
79
|
+
parts.push('');
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
// 知识库摘要可能太长,只包含前 2000 字符
|
|
83
|
+
if (knowledge) {
|
|
84
|
+
const truncated = knowledge.content.length > 2000
|
|
85
|
+
? knowledge.content.substring(0, 2000) + '\n\n[... 更多内容请使用 memory_search 查询]'
|
|
86
|
+
: knowledge.content;
|
|
87
|
+
parts.push(`<!-- Source: ${knowledge.source} -->`);
|
|
88
|
+
parts.push(truncated);
|
|
89
|
+
parts.push('');
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
parts.push('</user-memory>');
|
|
93
|
+
|
|
94
|
+
return parts.join('\n');
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
function main() {
|
|
98
|
+
debugLog('Start hook triggered');
|
|
99
|
+
|
|
100
|
+
// 读取 stdin(Claude Code 会传入 hook 输入)
|
|
101
|
+
let hookInput = {};
|
|
102
|
+
try {
|
|
103
|
+
const raw = fs.readFileSync(0, 'utf8');
|
|
104
|
+
if (raw.trim()) {
|
|
105
|
+
hookInput = JSON.parse(raw);
|
|
106
|
+
debugLog(`Hook input: ${JSON.stringify(hookInput).substring(0, 200)}`);
|
|
107
|
+
}
|
|
108
|
+
} catch (err) {
|
|
109
|
+
debugLog(`Failed to parse hook input: ${err.message}`);
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
// 读取用户画像
|
|
113
|
+
const profile = readProfileSummary();
|
|
114
|
+
|
|
115
|
+
// 可选:读取知识库摘要(如果需要的话)
|
|
116
|
+
// const knowledge = readKnowledgeSummary();
|
|
117
|
+
const knowledge = null; // 暂时不包含知识库,避免上下文过长
|
|
118
|
+
|
|
119
|
+
if (!profile && !knowledge) {
|
|
120
|
+
debugLog('No memory to recall, exiting');
|
|
121
|
+
process.exit(0);
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
// 输出到 stdout
|
|
125
|
+
const output = formatOutput(profile, knowledge);
|
|
126
|
+
debugLog(`Output length: ${output.length} chars`);
|
|
127
|
+
|
|
128
|
+
// 输出 JSON 格式,包含要注入的内容
|
|
129
|
+
const result = {
|
|
130
|
+
result: output,
|
|
131
|
+
};
|
|
132
|
+
|
|
133
|
+
console.log(JSON.stringify(result));
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
main();
|