/** * User Message Hook Handler (SessionStart - parallel) * * Displays memory status info to user via stderr. * Runs alongside context hook but only writes to stderr * (visible to user in Claude Code UI) without injecting * into Claude's conversation context. * * @module @agentkits/memory/hooks/user-message */ import { NormalizedHookInput, HookResult, EventHandler, } from './types.js'; import { MemoryHookService } from './service.js'; /** * User Message Hook - SessionStart Event * * Shows memory system status to user in terminal. * Does NOT inject anything into Claude's context. */ export class UserMessageHook implements EventHandler { private service: MemoryHookService; private ownsService: boolean; constructor(service: MemoryHookService, ownsService = false) { this.service = service; this.ownsService = ownsService; } /** * Shutdown the hook (closes database if owned) */ async shutdown(): Promise { if (this.ownsService) { await this.service.shutdown(); } } /** * Execute the user message hook */ async execute(input: NormalizedHookInput): Promise { try { // Initialize service await this.service.initialize(); // Get context to count observations const context = await this.service.getContext(input.project); const obsCount = context.recentObservations.length; const sessionCount = context.sessionSummaries.length || context.previousSessions.length; const promptCount = context.userPrompts.length; // Build status display const parts: string[] = []; parts.push(''); parts.push(' AgentKits Memory Loaded'); if (obsCount > 0 || sessionCount > 0 || promptCount > 0) { const stats: string[] = []; if (sessionCount > 0) stats.push(`${sessionCount} session${sessionCount > 1 ? 's' : ''}`); if (obsCount > 0) stats.push(`${obsCount} observation${obsCount > 1 ? 's' : ''}`); if (promptCount > 0) stats.push(`${promptCount} prompt${promptCount > 1 ? 's' : ''}`); parts.push(` Context: ${stats.join(', ')}`); parts.push(' Use: memory_search → memory_timeline → memory_details'); } else { parts.push(' Fresh memory — use memory_save to start building context'); } parts.push(''); // Write to stderr for user visibility console.error(parts.join('\n')); return { continue: true, suppressOutput: true, }; } catch (error) { // Log error but don't block session console.error('[AgentKits Memory] User message hook error:', error); return { continue: true, suppressOutput: true, error: error instanceof Error ? error.message : 'Unknown error', }; } } } /** * Create user message hook handler */ export function createUserMessageHook(cwd: string): UserMessageHook { const service = new MemoryHookService(cwd); return new UserMessageHook(service, true); } export default UserMessageHook;