Refactor: Remove hook-templates and related functionality

- Updated the published package contents to exclude `hook-templates`.
- Removed references to the hooks directory and related scripts in the installation and uninstallation processes.
- Simplified the status command by eliminating checks for runtime hook scripts.
- Adjusted the path discovery service to remove methods related to hook templates.
- Updated the installation logic to directly configure hooks using CLI commands.
- Cleaned up the uninstall process to remove claude-mem hooks from settings.
This commit is contained in:
Alex Newman
2025-10-15 20:38:11 -04:00
parent edeed2ee2c
commit 2608fb180e
7 changed files with 105 additions and 206 deletions
+65 -65
View File
File diff suppressed because one or more lines are too long
+1 -1
View File
@@ -125,4 +125,4 @@ claude-mem/
- The build process embeds the version from `package.json` at build time
- `prepublishOnly` script ensures build runs before npm publish
- Dependencies are bundled except for external packages
- The published package includes: `dist/`, `hook-templates/`, `commands/`, `src/`, `docs/`
- The published package includes: `dist/`, `commands/`, `src/`, `docs/`
-1
View File
@@ -54,7 +54,6 @@
},
"files": [
"dist",
"hook-templates",
"commands",
"src",
"docs",
+11 -14
View File
@@ -86,7 +86,16 @@ function detectClaudePath(): string {
function hasExistingInstallation(): boolean {
const pathDiscovery = PathDiscovery.getInstance();
return existsSync(pathDiscovery.getHooksDirectory());
const settingsPath = pathDiscovery.getClaudeSettingsPath();
if (!existsSync(settingsPath)) return false;
try {
const settings = JSON.parse(readFileSync(settingsPath, 'utf8'));
return !!(settings.hooks?.SessionStart || settings.hooks?.Stop || settings.hooks?.PostToolUse);
} catch {
return false;
}
}
async function runInstallationWizard(existingInstall: boolean): Promise<InstallConfig | null> {
@@ -232,17 +241,6 @@ function copyFileRecursively(src: string, dest: string): void {
}
}
// No longer needed - hooks are now CLI commands
// Kept for backwards compatibility only
function ensureHooksDirectory(): void {
const pathDiscovery = PathDiscovery.getInstance();
const runtimeHooksDir = pathDiscovery.getHooksDirectory();
// Just ensure the directory exists for any legacy references
if (!existsSync(runtimeHooksDir)) {
mkdirSync(runtimeHooksDir, { recursive: true });
}
}
function ensureClaudeMdInstructions(): void {
@@ -366,7 +364,7 @@ function configureHooks(settingsPath: string): void {
}
});
// Configure hooks to use CLI commands directly (new architecture)
// Configure hooks to use CLI commands directly
const cliPath = detectClaudePath() || PACKAGE_NAME;
settings.hooks.SessionStart = [createHookConfig(`${cliPath} context`, 180)];
@@ -494,7 +492,6 @@ export async function install(options: OptionValues = {}): Promise<void> {
{ name: 'Installing Chroma MCP server', fn: () => installChromaMcp(config.forceReinstall) },
{ name: 'Adding CLAUDE.md instructions', fn: () => ensureClaudeMdInstructions() },
{ name: 'Installing Claude commands', fn: () => installClaudeCommands() },
{ name: 'Configuring CLI hook integration', fn: () => ensureHooksDirectory() },
{ name: 'Configuring Claude settings', fn: () => configureHooks(getSettingsPath(config)) },
{ name: 'Configuring user settings', fn: () => configureUserSettings(config) }
];
+10 -39
View File
@@ -12,30 +12,9 @@ const __dirname = dirname(fileURLToPath(import.meta.url));
export async function status(): Promise<void> {
console.log('🔍 Claude Memory System Status Check');
console.log('=====================================\n');
console.log('📂 Runtime Hook Scripts (installed from hook-templates/):');
const pathDiscovery = PathDiscovery.getInstance();
const runtimeHooksDir = pathDiscovery.getHooksDirectory();
const sessionStartScript = join(runtimeHooksDir, 'session-start.js');
const stopScript = join(runtimeHooksDir, 'stop.js');
const userPromptScript = join(runtimeHooksDir, 'user-prompt-submit.js');
const postToolScript = join(runtimeHooksDir, 'post-tool-use.js');
const checkScript = (path: string, name: string) => {
if (existsSync(path)) {
console.log(`${name}: Found at ${path}`);
} else {
console.log(`${name}: Not found at ${path}`);
}
};
checkScript(sessionStartScript, 'session-start.js');
checkScript(stopScript, 'stop.js');
checkScript(userPromptScript, 'user-prompt-submit.js');
checkScript(postToolScript, 'post-tool-use.js');
console.log('');
console.log('⚙️ Settings Configuration:');
const checkSettings = (name: string, path: string) => {
@@ -50,34 +29,26 @@ export async function status(): Promise<void> {
const settings = JSON.parse(readFileSync(path, 'utf8'));
const hasSessionStart = settings.hooks?.SessionStart?.some((matcher: any) =>
matcher.hooks?.some((hook: any) =>
hook.command?.includes('session-start.js') || hook.command?.includes('claude-mem')
)
matcher.hooks?.some((hook: any) => hook.command?.includes('claude-mem'))
);
const hasStop = settings.hooks?.Stop?.some((matcher: any) =>
matcher.hooks?.some((hook: any) =>
hook.command?.includes('stop.js') || hook.command?.includes('claude-mem')
)
matcher.hooks?.some((hook: any) => hook.command?.includes('claude-mem'))
);
const hasUserPrompt = settings.hooks?.UserPromptSubmit?.some((matcher: any) =>
matcher.hooks?.some((hook: any) =>
hook.command?.includes('user-prompt-submit.js') || hook.command?.includes('claude-mem')
)
matcher.hooks?.some((hook: any) => hook.command?.includes('claude-mem'))
);
const hasPostTool = settings.hooks?.PostToolUse?.some((matcher: any) =>
matcher.hooks?.some((hook: any) =>
hook.command?.includes('post-tool-use.js') || hook.command?.includes('claude-mem')
)
matcher.hooks?.some((hook: any) => hook.command?.includes('claude-mem'))
);
console.log(` SessionStart: ${hasSessionStart ? '✅' : '❌'}`);
console.log(` Stop: ${hasStop ? '✅' : '❌'}`);
console.log(` UserPromptSubmit: ${hasUserPrompt ? '✅' : '❌'}`);
console.log(` PostToolUse: ${hasPostTool ? '✅' : '❌'}`);
console.log(` SessionStart (claude-mem context): ${hasSessionStart ? '✅' : '❌'}`);
console.log(` Stop (claude-mem summary): ${hasStop ? '✅' : '❌'}`);
console.log(` UserPromptSubmit (claude-mem new): ${hasUserPrompt ? '✅' : '❌'}`);
console.log(` PostToolUse (claude-mem save): ${hasPostTool ? '✅' : '❌'}`);
} catch (error: any) {
console.log(` ⚠️ Could not parse settings`);
}
+17 -53
View File
@@ -86,12 +86,6 @@ export async function uninstall(options: OptionValues = {}): Promise<void> {
});
}
const pathDiscovery = PathDiscovery.getInstance();
const runtimeHooksDir = pathDiscovery.getHooksDirectory();
const preCompactScript = join(runtimeHooksDir, 'pre-compact.js');
const sessionStartScript = join(runtimeHooksDir, 'session-start.js');
const sessionEndScript = join(runtimeHooksDir, 'session-end.js');
let removedCount = 0;
for (const location of locations) {
@@ -110,57 +104,27 @@ export async function uninstall(options: OptionValues = {}): Promise<void> {
let modified = false;
if (settings.hooks.PreCompact) {
const filteredPreCompact = settings.hooks.PreCompact.filter((matcher: any) =>
!matcher.hooks?.some((hook: any) =>
hook.command === preCompactScript ||
hook.command?.includes('pre-compact.js') ||
hook.command?.includes('claude-mem')
)
);
// Remove claude-mem hooks (CLI commands)
const hookTypes = ['SessionStart', 'Stop', 'UserPromptSubmit', 'PostToolUse'];
if (filteredPreCompact.length !== settings.hooks.PreCompact.length) {
settings.hooks.PreCompact = filteredPreCompact.length ? filteredPreCompact : undefined;
modified = true;
console.log(`✅ Removed PreCompact hook from ${location.name} settings`);
for (const hookType of hookTypes) {
if (settings.hooks[hookType]) {
const filteredHooks = settings.hooks[hookType].filter((matcher: any) =>
!matcher.hooks?.some((hook: any) => hook.command?.includes('claude-mem'))
);
if (filteredHooks.length !== settings.hooks[hookType].length) {
settings.hooks[hookType] = filteredHooks.length ? filteredHooks : undefined;
modified = true;
console.log(`✅ Removed ${hookType} hook from ${location.name} settings`);
}
}
}
if (settings.hooks.SessionStart) {
const filteredSessionStart = settings.hooks.SessionStart.filter((matcher: any) =>
!matcher.hooks?.some((hook: any) =>
hook.command === sessionStartScript ||
hook.command?.includes('session-start.js') ||
hook.command?.includes('claude-mem')
)
);
if (filteredSessionStart.length !== settings.hooks.SessionStart.length) {
settings.hooks.SessionStart = filteredSessionStart.length ? filteredSessionStart : undefined;
modified = true;
console.log(`✅ Removed SessionStart hook from ${location.name} settings`);
}
}
if (settings.hooks.SessionEnd) {
const filteredSessionEnd = settings.hooks.SessionEnd.filter((matcher: any) =>
!matcher.hooks?.some((hook: any) =>
hook.command === sessionEndScript ||
hook.command?.includes('session-end.js') ||
hook.command?.includes('claude-mem')
)
);
if (filteredSessionEnd.length !== settings.hooks.SessionEnd.length) {
settings.hooks.SessionEnd = filteredSessionEnd.length ? filteredSessionEnd : undefined;
modified = true;
console.log(`✅ Removed SessionEnd hook from ${location.name} settings`);
}
}
if (settings.hooks.PreCompact === undefined) delete settings.hooks.PreCompact;
if (settings.hooks.SessionStart === undefined) delete settings.hooks.SessionStart;
if (settings.hooks.SessionEnd === undefined) delete settings.hooks.SessionEnd;
// Clean up undefined hooks
hookTypes.forEach(hookType => {
if (settings.hooks[hookType] === undefined) delete settings.hooks[hookType];
});
if (!Object.keys(settings.hooks).length) delete settings.hooks;
if (modified) {
+1 -33
View File
@@ -53,12 +53,6 @@ export class PathDiscovery {
return join(this.getDataDirectory(), 'archives');
}
/**
* Hooks directory where claude-mem hooks are installed
*/
getHooksDirectory(): string {
return join(this.getDataDirectory(), 'hooks');
}
/**
* Logs directory for claude-mem operation logs
@@ -222,31 +216,6 @@ export class PathDiscovery {
throw new Error('Cannot locate claude-mem package root. Ensure claude-mem is properly installed.');
}
/**
* Find hook templates directory in the installed package
*
* This returns the SOURCE templates directory that gets copied during installation
* to the runtime hooks directory (~/.claude-mem/hooks/)
*/
findPackageHookTemplatesDirectory(): string {
const packageRoot = this.getPackageRoot();
const hookTemplatesDir = join(packageRoot, 'hook-templates');
// Verify it contains expected hook template files
const requiredHookTemplates = [
'session-start.js',
'stop.js',
'user-prompt-submit.js',
'post-tool-use.js'
];
for (const hookTemplateFile of requiredHookTemplates) {
if (!existsSync(join(hookTemplatesDir, hookTemplateFile))) {
throw new Error(`Package hook-templates directory missing required template file: ${hookTemplateFile}`);
}
}
return hookTemplatesDir;
}
/**
* Find commands directory in the installed package
@@ -292,8 +261,7 @@ export class PathDiscovery {
ensureAllDataDirectories(): void {
this.ensureDirectories([
this.getDataDirectory(),
this.getArchivesDirectory(),
this.getHooksDirectory(),
this.getArchivesDirectory(),
this.getLogsDirectory(),
this.getTrashDirectory(),
this.getBackupsDirectory(),