Files
claude-mem/src/hooks/cleanup-hook.ts
T
Alex Newman 3030f518b5 refactor: Complete rewrite of worker-utils.ts and cleanup of worker-service.ts
- Removed fragile PM2 string parsing and replaced with direct PM2 restart logic.
- Eliminated silent error handling in worker-utils.ts for better error visibility.
- Extracted duplicated session auto-creation logic into a new helper method getOrCreateSession() in worker-service.ts.
- Centralized configuration values and replaced magic numbers with named constants.
- Updated health check logic to ensure worker is restarted if unhealthy.
- Removed unnecessary getWorkerPort() wrapper function.
- Improved overall code quality and maintainability by applying DRY and YAGNI principles.
2025-11-06 22:00:07 -05:00

103 lines
2.9 KiB
TypeScript

/**
* Cleanup Hook - SessionEnd
* Consolidated entry point + logic
*/
import { stdin } from 'process';
import { SessionStore } from '../services/sqlite/SessionStore.js';
import { getWorkerPort } from '../shared/worker-utils.js';
export interface SessionEndInput {
session_id: string;
cwd: string;
transcript_path?: string;
hook_event_name: string;
reason: 'exit' | 'clear' | 'logout' | 'prompt_input_exit' | 'other';
}
/**
* Cleanup Hook Main Logic
*/
async function cleanupHook(input?: SessionEndInput): Promise<void> {
// Log hook entry point
console.error('[claude-mem cleanup] Hook fired', {
input: input ? {
session_id: input.session_id,
cwd: input.cwd,
reason: input.reason
} : null
});
// Handle standalone execution (no input provided)
if (!input) {
console.log('No input provided - this script is designed to run as a Claude Code SessionEnd hook');
console.log('\nExpected input format:');
console.log(JSON.stringify({
session_id: "string",
cwd: "string",
transcript_path: "string",
hook_event_name: "SessionEnd",
reason: "exit"
}, null, 2));
process.exit(0);
}
const { session_id, reason } = input;
console.error('[claude-mem cleanup] Searching for active SDK session', { session_id, reason });
// Find active SDK session
const db = new SessionStore();
const session = db.findActiveSDKSession(session_id);
if (!session) {
// No active session - nothing to clean up
console.error('[claude-mem cleanup] No active SDK session found', { session_id });
db.close();
console.log('{"continue": true, "suppressOutput": true}');
process.exit(0);
}
console.error('[claude-mem cleanup] Active SDK session found', {
session_id: session.id,
sdk_session_id: session.sdk_session_id,
project: session.project,
worker_port: session.worker_port
});
// Mark session as completed in DB
db.markSessionCompleted(session.id);
console.error('[claude-mem cleanup] Session marked as completed in database');
db.close();
// Tell worker to stop spinner
try {
const workerPort = session.worker_port || getWorkerPort();
await fetch(`http://127.0.0.1:${workerPort}/sessions/${session.id}/complete`, {
method: 'POST',
signal: AbortSignal.timeout(1000)
});
console.error('[claude-mem cleanup] Worker notified to stop processing indicator');
} catch (err) {
// Non-critical - worker might be down
console.error('[claude-mem cleanup] Failed to notify worker (non-critical):', err);
}
console.error('[claude-mem cleanup] Cleanup completed successfully');
console.log('{"continue": true, "suppressOutput": true}');
process.exit(0);
}
// Entry Point
if (stdin.isTTY) {
// Running manually
cleanupHook(undefined);
} else {
let input = '';
stdin.on('data', (chunk) => input += chunk);
stdin.on('end', async () => {
const parsed = input ? JSON.parse(input) : undefined;
await cleanupHook(parsed);
});
}