claude-recall 0.9.1 โ 0.9.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/cli/claude-recall-cli.js +67 -57
- package/package.json +1 -1
- package/scripts/postinstall.js +80 -51
|
@@ -565,73 +565,82 @@ async function main() {
|
|
|
565
565
|
}
|
|
566
566
|
}
|
|
567
567
|
}
|
|
568
|
-
// Install
|
|
569
|
-
function
|
|
568
|
+
// Install skills and clean up old hooks (v0.9.0+ uses Skills, not hooks)
|
|
569
|
+
function installSkillsAndCleanupHooks(force = false) {
|
|
570
570
|
const cwd = process.cwd();
|
|
571
571
|
const projectName = path.basename(cwd);
|
|
572
|
-
console.log('\n๐ฆ
|
|
572
|
+
console.log('\n๐ฆ Claude Recall v0.9.x Setup\n');
|
|
573
573
|
console.log(`๐ Project: ${projectName}`);
|
|
574
574
|
console.log(`๐ Directory: ${cwd}\n`);
|
|
575
575
|
// Find the package directory (where claude-recall is installed)
|
|
576
|
-
// When run via npx, __dirname points to dist/cli, so we go up to find .claude
|
|
577
576
|
const packageDir = path.resolve(__dirname, '../..');
|
|
578
|
-
const packageHooksDir = path.join(packageDir, '.claude/hooks');
|
|
579
577
|
const packageSkillsDir = path.join(packageDir, '.claude/skills');
|
|
580
578
|
const claudeDir = path.join(cwd, '.claude');
|
|
581
579
|
const hooksDir = path.join(claudeDir, 'hooks');
|
|
582
|
-
// Create .claude/hooks directory
|
|
583
|
-
if (!fs.existsSync(hooksDir)) {
|
|
584
|
-
fs.mkdirSync(hooksDir, { recursive: true });
|
|
585
|
-
}
|
|
586
|
-
// Copy single enforcement hook
|
|
587
|
-
const hookSource = path.join(packageHooksDir, 'memory_enforcer.py');
|
|
588
|
-
const hookDest = path.join(hooksDir, 'memory_enforcer.py');
|
|
589
|
-
if (fs.existsSync(hookSource)) {
|
|
590
|
-
fs.copyFileSync(hookSource, hookDest);
|
|
591
|
-
fs.chmodSync(hookDest, 0o755);
|
|
592
|
-
console.log('โ
Installed memory_enforcer.py to .claude/hooks/');
|
|
593
|
-
}
|
|
594
|
-
else {
|
|
595
|
-
console.log(`โ ๏ธ Hook not found at: ${packageHooksDir}`);
|
|
596
|
-
}
|
|
597
|
-
// Create or update .claude/settings.json with hook configuration
|
|
598
580
|
const settingsPath = path.join(claudeDir, 'settings.json');
|
|
581
|
+
// === CLEANUP: Remove old hooks (v0.9.0+ doesn't use hooks) ===
|
|
582
|
+
if (fs.existsSync(hooksDir)) {
|
|
583
|
+
const oldHooks = [
|
|
584
|
+
'memory_enforcer.py',
|
|
585
|
+
'pre_tool_search_enforcer.py',
|
|
586
|
+
'mcp_tool_tracker.py',
|
|
587
|
+
'pubnub_pre_tool_hook.py',
|
|
588
|
+
'pubnub_prompt_hook.py',
|
|
589
|
+
'user_prompt_capture.py',
|
|
590
|
+
'user_prompt_reminder.py'
|
|
591
|
+
];
|
|
592
|
+
let removedCount = 0;
|
|
593
|
+
for (const hook of oldHooks) {
|
|
594
|
+
const hookPath = path.join(hooksDir, hook);
|
|
595
|
+
if (fs.existsSync(hookPath)) {
|
|
596
|
+
fs.unlinkSync(hookPath);
|
|
597
|
+
removedCount++;
|
|
598
|
+
}
|
|
599
|
+
}
|
|
600
|
+
// Remove hooks directory if empty
|
|
601
|
+
try {
|
|
602
|
+
const remaining = fs.readdirSync(hooksDir);
|
|
603
|
+
if (remaining.length === 0) {
|
|
604
|
+
fs.rmdirSync(hooksDir);
|
|
605
|
+
}
|
|
606
|
+
}
|
|
607
|
+
catch (e) {
|
|
608
|
+
// Ignore
|
|
609
|
+
}
|
|
610
|
+
if (removedCount > 0) {
|
|
611
|
+
console.log(`๐งน Removed ${removedCount} old hook file(s) from .claude/hooks/`);
|
|
612
|
+
}
|
|
613
|
+
}
|
|
614
|
+
// === CLEANUP: Clear hook configuration from settings.json ===
|
|
599
615
|
let settings = {};
|
|
600
616
|
if (fs.existsSync(settingsPath)) {
|
|
601
617
|
try {
|
|
602
618
|
settings = JSON.parse(fs.readFileSync(settingsPath, 'utf8'));
|
|
619
|
+
const hadHooks = settings.hooks && Object.keys(settings.hooks).length > 0;
|
|
620
|
+
// Clear hooks - v0.9.0+ uses Skills instead
|
|
621
|
+
settings.hooks = {};
|
|
622
|
+
settings.hooksVersion = '2.0.0';
|
|
623
|
+
fs.writeFileSync(settingsPath, JSON.stringify(settings, null, 2));
|
|
624
|
+
if (hadHooks) {
|
|
625
|
+
console.log('๐งน Cleared old hook configuration from .claude/settings.json');
|
|
626
|
+
}
|
|
603
627
|
}
|
|
604
628
|
catch (e) {
|
|
605
|
-
settings
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
if (needsUpdate) {
|
|
611
|
-
settings.hooksVersion = CURRENT_HOOKS_VERSION;
|
|
612
|
-
settings.hooks = {
|
|
613
|
-
PreToolUse: [
|
|
614
|
-
{
|
|
615
|
-
matcher: "mcp__claude-recall__.*|Write|Edit|Bash|Task",
|
|
616
|
-
hooks: [
|
|
617
|
-
{
|
|
618
|
-
type: "command",
|
|
619
|
-
command: `python3 ${path.join(hooksDir, 'memory_enforcer.py')}`,
|
|
620
|
-
}
|
|
621
|
-
]
|
|
622
|
-
}
|
|
623
|
-
]
|
|
624
|
-
};
|
|
625
|
-
fs.writeFileSync(settingsPath, JSON.stringify(settings, null, 2));
|
|
626
|
-
console.log('โ
Configured hook in .claude/settings.json');
|
|
627
|
-
if (force) {
|
|
628
|
-
console.log(' โ Force flag: overwrote existing configuration');
|
|
629
|
+
// If settings.json is invalid, create fresh one
|
|
630
|
+
if (!fs.existsSync(claudeDir)) {
|
|
631
|
+
fs.mkdirSync(claudeDir, { recursive: true });
|
|
632
|
+
}
|
|
633
|
+
fs.writeFileSync(settingsPath, JSON.stringify({ hooks: {}, hooksVersion: '2.0.0' }, null, 2));
|
|
629
634
|
}
|
|
630
635
|
}
|
|
631
636
|
else {
|
|
632
|
-
|
|
637
|
+
// Create new settings.json without hooks
|
|
638
|
+
if (!fs.existsSync(claudeDir)) {
|
|
639
|
+
fs.mkdirSync(claudeDir, { recursive: true });
|
|
640
|
+
}
|
|
641
|
+
fs.writeFileSync(settingsPath, JSON.stringify({ hooks: {}, hooksVersion: '2.0.0' }, null, 2));
|
|
633
642
|
}
|
|
634
|
-
// Copy skills directory
|
|
643
|
+
// === INSTALL: Copy skills directory ===
|
|
635
644
|
if (fs.existsSync(packageSkillsDir)) {
|
|
636
645
|
const skillsDir = path.join(claudeDir, 'skills');
|
|
637
646
|
copyDirRecursive(packageSkillsDir, skillsDir);
|
|
@@ -640,18 +649,19 @@ async function main() {
|
|
|
640
649
|
else {
|
|
641
650
|
console.log(`โ ๏ธ Skills not found at: ${packageSkillsDir}`);
|
|
642
651
|
}
|
|
643
|
-
console.log('\nโ
|
|
652
|
+
console.log('\nโ
Setup complete!\n');
|
|
653
|
+
console.log('โน๏ธ v0.9.0+ uses native Claude Skills instead of hooks.');
|
|
644
654
|
console.log('Restart Claude Code to activate.\n');
|
|
645
655
|
}
|
|
646
|
-
// Setup command - shows activation instructions or installs
|
|
656
|
+
// Setup command - shows activation instructions or installs skills
|
|
647
657
|
program
|
|
648
658
|
.command('setup')
|
|
649
|
-
.description('Show activation instructions or install
|
|
650
|
-
.option('--install', 'Install
|
|
659
|
+
.description('Show activation instructions or install skills')
|
|
660
|
+
.option('--install', 'Install skills and clean up old hooks')
|
|
651
661
|
.action((options) => {
|
|
652
662
|
if (options.install) {
|
|
653
|
-
// Install
|
|
654
|
-
|
|
663
|
+
// Install skills and clean up old hooks
|
|
664
|
+
installSkillsAndCleanupHooks();
|
|
655
665
|
}
|
|
656
666
|
else {
|
|
657
667
|
// Show activation instructions
|
|
@@ -676,13 +686,13 @@ async function main() {
|
|
|
676
686
|
}
|
|
677
687
|
process.exit(0);
|
|
678
688
|
});
|
|
679
|
-
// Repair command -
|
|
689
|
+
// Repair command - cleans up old hooks and installs skills
|
|
680
690
|
program
|
|
681
691
|
.command('repair')
|
|
682
|
-
.description('
|
|
683
|
-
.option('--force', 'Force overwrite existing
|
|
692
|
+
.description('Clean up old hooks and install skills (v0.9.0+ migration)')
|
|
693
|
+
.option('--force', 'Force overwrite existing configuration')
|
|
684
694
|
.action((options) => {
|
|
685
|
-
|
|
695
|
+
installSkillsAndCleanupHooks(options.force || false);
|
|
686
696
|
process.exit(0);
|
|
687
697
|
});
|
|
688
698
|
// Check hooks function
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "claude-recall",
|
|
3
|
-
"version": "0.9.
|
|
3
|
+
"version": "0.9.2",
|
|
4
4
|
"description": "Persistent memory for Claude Code with native Skills integration, automatic capture, failure learning, and project scoping via MCP server",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"bin": {
|
package/scripts/postinstall.js
CHANGED
|
@@ -4,7 +4,7 @@ const fs = require('fs');
|
|
|
4
4
|
const path = require('path');
|
|
5
5
|
const os = require('os');
|
|
6
6
|
|
|
7
|
-
console.log('\n๐ Setting up Claude Recall...\n');
|
|
7
|
+
console.log('\n๐ Setting up Claude Recall v0.9.x...\n');
|
|
8
8
|
|
|
9
9
|
const { execSync } = require('child_process');
|
|
10
10
|
|
|
@@ -28,6 +28,22 @@ function copyDirRecursive(src, dest) {
|
|
|
28
28
|
}
|
|
29
29
|
}
|
|
30
30
|
|
|
31
|
+
// Helper function to remove directory recursively
|
|
32
|
+
function rmDirRecursive(dir) {
|
|
33
|
+
if (fs.existsSync(dir)) {
|
|
34
|
+
const entries = fs.readdirSync(dir, { withFileTypes: true });
|
|
35
|
+
for (const entry of entries) {
|
|
36
|
+
const fullPath = path.join(dir, entry.name);
|
|
37
|
+
if (entry.isDirectory()) {
|
|
38
|
+
rmDirRecursive(fullPath);
|
|
39
|
+
} else {
|
|
40
|
+
fs.unlinkSync(fullPath);
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
fs.rmdirSync(dir);
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
|
|
31
47
|
try {
|
|
32
48
|
// Set up database location in user's home directory
|
|
33
49
|
const dbDir = path.join(os.homedir(), '.claude-recall');
|
|
@@ -88,78 +104,90 @@ try {
|
|
|
88
104
|
console.log('โ ๏ธ Failed to register project (non-fatal):', error.message);
|
|
89
105
|
}
|
|
90
106
|
|
|
91
|
-
// Install
|
|
107
|
+
// Install skills and clean up old hooks (v0.9.0+ uses Skills, not hooks)
|
|
92
108
|
try {
|
|
93
109
|
const cwd = process.cwd();
|
|
94
110
|
const projectName = path.basename(cwd);
|
|
95
|
-
const packageHooksDir = path.join(__dirname, '../.claude/hooks');
|
|
96
111
|
const packageSkillsDir = path.join(__dirname, '../.claude/skills');
|
|
97
112
|
|
|
98
113
|
if (projectName !== 'claude-recall' && !cwd.includes('node_modules/.pnpm') && !cwd.includes('node_modules/claude-recall')) {
|
|
99
114
|
const claudeDir = path.join(cwd, '.claude');
|
|
100
115
|
const hooksDir = path.join(claudeDir, 'hooks');
|
|
116
|
+
const settingsPath = path.join(claudeDir, 'settings.json');
|
|
101
117
|
|
|
102
|
-
//
|
|
103
|
-
if (
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
118
|
+
// === CLEANUP: Remove old hooks (v0.9.0+ doesn't use hooks) ===
|
|
119
|
+
if (fs.existsSync(hooksDir)) {
|
|
120
|
+
// Remove known hook files from previous versions
|
|
121
|
+
const oldHooks = [
|
|
122
|
+
'memory_enforcer.py',
|
|
123
|
+
'pre_tool_search_enforcer.py',
|
|
124
|
+
'mcp_tool_tracker.py',
|
|
125
|
+
'pubnub_pre_tool_hook.py',
|
|
126
|
+
'pubnub_prompt_hook.py',
|
|
127
|
+
'user_prompt_capture.py',
|
|
128
|
+
'user_prompt_reminder.py'
|
|
129
|
+
];
|
|
130
|
+
|
|
131
|
+
let removedCount = 0;
|
|
132
|
+
for (const hook of oldHooks) {
|
|
133
|
+
const hookPath = path.join(hooksDir, hook);
|
|
134
|
+
if (fs.existsSync(hookPath)) {
|
|
135
|
+
fs.unlinkSync(hookPath);
|
|
136
|
+
removedCount++;
|
|
137
|
+
}
|
|
138
|
+
}
|
|
110
139
|
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
140
|
+
// Remove hooks directory if empty
|
|
141
|
+
try {
|
|
142
|
+
const remaining = fs.readdirSync(hooksDir);
|
|
143
|
+
if (remaining.length === 0) {
|
|
144
|
+
fs.rmdirSync(hooksDir);
|
|
145
|
+
}
|
|
146
|
+
} catch (e) {
|
|
147
|
+
// Ignore
|
|
148
|
+
}
|
|
116
149
|
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
copyDirRecursive(packageSkillsDir, skillsDir);
|
|
121
|
-
console.log('โ
Installed SKILL.md to .claude/skills/');
|
|
150
|
+
if (removedCount > 0) {
|
|
151
|
+
console.log(`๐งน Removed ${removedCount} old hook file(s) from .claude/hooks/`);
|
|
152
|
+
}
|
|
122
153
|
}
|
|
123
154
|
|
|
124
|
-
//
|
|
125
|
-
const settingsPath = path.join(claudeDir, 'settings.json');
|
|
126
|
-
let settings = {};
|
|
127
|
-
|
|
155
|
+
// === CLEANUP: Clear hook configuration from settings.json ===
|
|
128
156
|
if (fs.existsSync(settingsPath)) {
|
|
129
157
|
try {
|
|
130
|
-
settings = JSON.parse(fs.readFileSync(settingsPath, 'utf8'));
|
|
158
|
+
let settings = JSON.parse(fs.readFileSync(settingsPath, 'utf8'));
|
|
159
|
+
const hadHooks = settings.hooks && Object.keys(settings.hooks).length > 0;
|
|
160
|
+
|
|
161
|
+
// Clear hooks - v0.9.0+ uses Skills instead
|
|
162
|
+
settings.hooks = {};
|
|
163
|
+
settings.hooksVersion = '2.0.0'; // Bump version to indicate skills-based
|
|
164
|
+
|
|
165
|
+
fs.writeFileSync(settingsPath, JSON.stringify(settings, null, 2));
|
|
166
|
+
|
|
167
|
+
if (hadHooks) {
|
|
168
|
+
console.log('๐งน Cleared old hook configuration from .claude/settings.json');
|
|
169
|
+
}
|
|
131
170
|
} catch (e) {
|
|
132
|
-
settings
|
|
171
|
+
// If settings.json is invalid, create fresh one
|
|
172
|
+
fs.writeFileSync(settingsPath, JSON.stringify({ hooks: {}, hooksVersion: '2.0.0' }, null, 2));
|
|
133
173
|
}
|
|
174
|
+
} else {
|
|
175
|
+
// Create new settings.json without hooks
|
|
176
|
+
if (!fs.existsSync(claudeDir)) {
|
|
177
|
+
fs.mkdirSync(claudeDir, { recursive: true });
|
|
178
|
+
}
|
|
179
|
+
fs.writeFileSync(settingsPath, JSON.stringify({ hooks: {}, hooksVersion: '2.0.0' }, null, 2));
|
|
134
180
|
}
|
|
135
181
|
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
settings.hooks = {
|
|
142
|
-
PreToolUse: [
|
|
143
|
-
{
|
|
144
|
-
matcher: "mcp__claude-recall__.*|Write|Edit|Bash|Task",
|
|
145
|
-
hooks: [
|
|
146
|
-
{
|
|
147
|
-
type: "command",
|
|
148
|
-
command: `python3 ${path.join(hooksDir, 'memory_enforcer.py')}`
|
|
149
|
-
}
|
|
150
|
-
]
|
|
151
|
-
}
|
|
152
|
-
]
|
|
153
|
-
};
|
|
154
|
-
|
|
155
|
-
fs.writeFileSync(settingsPath, JSON.stringify(settings, null, 2));
|
|
156
|
-
console.log('โ
Configured hook in .claude/settings.json');
|
|
157
|
-
} else {
|
|
158
|
-
console.log(`โน๏ธ Hooks already at version ${CURRENT_HOOKS_VERSION}`);
|
|
182
|
+
// === INSTALL: Copy skills directory ===
|
|
183
|
+
if (fs.existsSync(packageSkillsDir)) {
|
|
184
|
+
const skillsDir = path.join(claudeDir, 'skills');
|
|
185
|
+
copyDirRecursive(packageSkillsDir, skillsDir);
|
|
186
|
+
console.log('โ
Installed SKILL.md to .claude/skills/');
|
|
159
187
|
}
|
|
160
188
|
}
|
|
161
189
|
} catch (error) {
|
|
162
|
-
console.log('โ ๏ธ Failed to install
|
|
190
|
+
console.log('โ ๏ธ Failed to install skills (non-fatal):', error.message);
|
|
163
191
|
}
|
|
164
192
|
|
|
165
193
|
console.log('\nโ
Installation complete!\n');
|
|
@@ -173,6 +201,7 @@ try {
|
|
|
173
201
|
console.log('');
|
|
174
202
|
console.log('โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ');
|
|
175
203
|
console.log('');
|
|
204
|
+
console.log('โน๏ธ v0.9.0+ uses native Claude Skills instead of hooks.');
|
|
176
205
|
console.log('๐ก Your memories persist across conversations and restarts.\n');
|
|
177
206
|
|
|
178
207
|
} catch (error) {
|