Refactor hooks codebase: reduce complexity and improve maintainability (#204)
* refactor: Clean up hook-response and new-hook files - Removed 'PreCompact' hook type and associated logic from hook-response.ts for improved type safety. - Deleted extensive architecture comments in new-hook.ts to streamline code readability. - Simplified debug logging in new-hook.ts to reduce verbosity. - Enhanced ensureWorkerRunning function in worker-utils.ts with a final health check before throwing errors. - Added a new documentation file outlining the hooks cleanup process and future improvements. * Refactor cleanup and user message hooks - Updated cleanup-hook.js to improve error handling and remove unnecessary input checks. - Simplified user-message-hook.js by removing time-sensitive announcements and streamlining output. - Enhanced logging functionality in both hooks for better debugging and clarity. * Refactor error handling in hooks to use centralized error handler - Introduced `handleWorkerError` function in `src/shared/hook-error-handler.ts` to manage worker-related errors. - Updated `context-hook.ts`, `new-hook.ts`, `save-hook.ts`, and `summary-hook.ts` to utilize the new error handler, simplifying error management and improving code readability. - Removed repetitive error handling logic from individual hooks, ensuring consistent user-friendly messages for connection issues. * Refactor user-message and summary hooks to utilize shared transcript parser; introduce hook exit codes - Moved user message extraction logic to a new shared module `transcript-parser.ts` for better code reuse. - Updated `summary-hook.ts` to use the new `extractLastMessage` function for retrieving user and assistant messages. - Replaced direct exit code usage in `user-message-hook.ts` with constants from `hook-constants.ts` for improved readability and maintainability. - Added `HOOK_EXIT_CODES` to `hook-constants.ts` to standardize exit codes across hooks. * Refactor hook input interfaces to enforce required fields - Updated `SessionStartInput`, `UserPromptSubmitInput`, `PostToolUseInput`, and `StopInput` interfaces to require `session_id`, `transcript_path`, and `cwd` fields, ensuring better type safety and clarity in hook inputs. - Removed optional index signatures from these interfaces to prevent unintended properties and improve code maintainability. - Adjusted related hook implementations to align with the new interface definitions. * Refactor save-hook to remove tool skipping logic; enhance summary-hook to handle spinner stopping with error logging; update SessionRoutes to load skip tools from settings; add CLAUDE_MEM_SKIP_TOOLS to SettingsDefaultsManager for configurable tool exclusion. * Document CLAUDE_MEM_SKIP_TOOLS setting in public docs Added documentation for the new CLAUDE_MEM_SKIP_TOOLS configuration setting in response to PR review feedback. Users can now discover and customize which tools are excluded from observations. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com> --------- Co-authored-by: Claude Sonnet 4.5 <noreply@anthropic.com>
This commit is contained in:
+5
-57
@@ -1,49 +1,14 @@
|
||||
/**
|
||||
* New Hook - UserPromptSubmit
|
||||
*
|
||||
* DUAL PURPOSE HOOK: Handles BOTH session initialization AND continuation
|
||||
* ==========================================================================
|
||||
*
|
||||
* CRITICAL ARCHITECTURE FACTS (NEVER FORGET):
|
||||
*
|
||||
* 1. SESSION ID THREADING - The Single Source of Truth
|
||||
* - Claude Code assigns ONE session_id per conversation
|
||||
* - ALL hooks in that conversation receive the SAME session_id
|
||||
* - We ALWAYS use this session_id - NEVER generate our own
|
||||
* - This is how NEW hook, SAVE hook, and SUMMARY hook stay connected
|
||||
*
|
||||
* 2. NO EXISTENCE CHECKS NEEDED
|
||||
* - createSDKSession is idempotent (INSERT OR IGNORE)
|
||||
* - Prompt #1: Creates new database row, returns new ID
|
||||
* - Prompt #2+: Row exists, returns existing ID
|
||||
* - We NEVER need to check "does session exist?" - just use the session_id
|
||||
*
|
||||
* 3. CONTINUATION LOGIC LOCATION
|
||||
* - This hook does NOT contain continuation prompt logic
|
||||
* - That lives in SDKAgent.ts (lines 125-127)
|
||||
* - SDKAgent checks promptNumber to choose init vs continuation prompt
|
||||
* - BOTH prompts receive the SAME session_id from this hook
|
||||
*
|
||||
* 4. UNIFIED WITH SAVE HOOK
|
||||
* - SAVE hook uses: db.createSDKSession(session_id, '', '')
|
||||
* - NEW hook uses: db.createSDKSession(session_id, project, prompt)
|
||||
* - Both use session_id from hook context - this keeps everything connected
|
||||
*
|
||||
* This is KISS in action: Use the session_id we're given, trust idempotent
|
||||
* database operations, and let SDKAgent handle init vs continuation logic.
|
||||
*/
|
||||
|
||||
import path from 'path';
|
||||
import { stdin } from 'process';
|
||||
import { createHookResponse } from './hook-response.js';
|
||||
import { ensureWorkerRunning, getWorkerPort } from '../shared/worker-utils.js';
|
||||
import { happy_path_error__with_fallback } from '../utils/silent-debug.js';
|
||||
import { handleWorkerError } from '../shared/hook-error-handler.js';
|
||||
|
||||
export interface UserPromptSubmitInput {
|
||||
session_id: string;
|
||||
cwd: string;
|
||||
prompt: string;
|
||||
[key: string]: any;
|
||||
}
|
||||
|
||||
|
||||
@@ -59,25 +24,12 @@ async function newHook(input?: UserPromptSubmitInput): Promise<void> {
|
||||
}
|
||||
|
||||
const { session_id, cwd, prompt } = input;
|
||||
|
||||
// Debug: Log what we received
|
||||
happy_path_error__with_fallback('[new-hook] Input received', {
|
||||
session_id,
|
||||
cwd,
|
||||
cwd_type: typeof cwd,
|
||||
cwd_length: cwd?.length,
|
||||
has_cwd: !!cwd,
|
||||
prompt_length: prompt?.length
|
||||
});
|
||||
|
||||
const project = path.basename(cwd);
|
||||
|
||||
happy_path_error__with_fallback('[new-hook] Project extracted', {
|
||||
happy_path_error__with_fallback('[new-hook] Input received', {
|
||||
session_id,
|
||||
project,
|
||||
project_type: typeof project,
|
||||
project_length: project?.length,
|
||||
is_empty: project === '',
|
||||
cwd_was: cwd
|
||||
prompt_length: prompt?.length
|
||||
});
|
||||
|
||||
const port = getWorkerPort();
|
||||
@@ -116,11 +68,7 @@ async function newHook(input?: UserPromptSubmitInput): Promise<void> {
|
||||
|
||||
console.error(`[new-hook] Session ${sessionDbId}, prompt #${promptNumber}`);
|
||||
} catch (error: any) {
|
||||
// Only show restart message for connection errors, not HTTP errors
|
||||
if (error.cause?.code === 'ECONNREFUSED' || error.name === 'TimeoutError' || error.message.includes('fetch failed')) {
|
||||
throw new Error("There's a problem with the worker. If you just updated, type `pm2 restart claude-mem-worker` in your terminal to continue");
|
||||
}
|
||||
throw error;
|
||||
handleWorkerError(error);
|
||||
}
|
||||
|
||||
console.log(createHookResponse('UserPromptSubmit', true));
|
||||
|
||||
Reference in New Issue
Block a user