@@ -90,103 +90,15 @@ This command sets up basic Claude Code hooks in your project:
9090 }
9191
9292 private async generateHookFiles ( ) : Promise < void > {
93- // Copy lib.ts
93+ // Get templates directory path
9494 const distDir = path . dirname ( fileURLToPath ( import . meta. url ) )
9595 const rootDir = path . join ( distDir , '..' , '..' )
9696 const templatesDir = path . join ( rootDir , 'templates' )
97- await fs . copy ( path . join ( templatesDir , 'hooks' , 'lib.ts' ) , '.claude/hooks/lib.ts' )
9897
99- // Add session.ts with the saveSessionData function
100- const sessionContent = `import { mkdir } from 'node:fs/promises';
101- import { writeFile, readFile } from 'node:fs/promises';
102- import * as path from 'path';
103- import { tmpdir } from 'node:os';
104-
105- const SESSIONS_DIR = path.join(tmpdir(), 'claude-hooks-sessions');
106-
107- export async function saveSessionData(hookType: string, payload: any): Promise<void> {
108- try {
109- // Ensure sessions directory exists
110- await mkdir(SESSIONS_DIR, { recursive: true });
111-
112- const timestamp = new Date().toISOString();
113- const sessionFile = path.join(SESSIONS_DIR, \`\${payload.session_id}.json\`);
114-
115- let sessionData: any[] = [];
116- try {
117- const existing = await readFile(sessionFile, 'utf-8');
118- sessionData = JSON.parse(existing);
119- } catch {
120- // File doesn't exist yet
121- }
122-
123- sessionData.push({
124- timestamp,
125- hookType,
126- payload
127- });
128-
129- await writeFile(sessionFile, JSON.stringify(sessionData, null, 2));
130- } catch (error) {
131- console.error('Failed to save session data:', error);
132- }
133- }
134- `
135- await fs . writeFile ( '.claude/hooks/session.ts' , sessionContent )
136-
137- // Generate default index.ts
138- const indexContent = `#!/usr/bin/env bun
139-
140- import { runHook, log, type PreToolUsePayload, type PostToolUsePayload, type NotificationPayload, type StopPayload, type HookResponse, type BashToolInput } from './lib';
141- import { saveSessionData } from './session';
142-
143- // PreToolUse handler - validate and potentially block dangerous commands
144- async function preToolUse(payload: PreToolUsePayload): Promise<HookResponse> {
145- // Save session data
146- await saveSessionData('PreToolUse', payload);
147-
148- // Example: Block dangerous commands
149- if (payload.tool_name === 'Bash' && payload.tool_input && 'command' in payload.tool_input) {
150- const bashInput = payload.tool_input as BashToolInput;
151- const command = bashInput.command;
152-
153- // Block rm -rf commands
154- if (command && (command.includes('rm -rf /') || command.includes('rm -rf ~'))) {
155- return {
156- action: 'block',
157- stopReason: 'Dangerous command detected: rm -rf on system directories'
158- };
159- }
160- }
161-
162- // Allow all other commands
163- return { action: 'continue' };
164- }
165-
166- // PostToolUse handler - log tool results
167- async function postToolUse(payload: PostToolUsePayload): Promise<void> {
168- await saveSessionData('PostToolUse', payload);
169- }
170-
171- // Notification handler - log notifications
172- async function notification(payload: NotificationPayload): Promise<void> {
173- await saveSessionData('Notification', payload);
174- }
175-
176- // Stop handler - log session end
177- async function stop(payload: StopPayload): Promise<void> {
178- await saveSessionData('Stop', payload);
179- }
180-
181- // Run the hook with our handlers
182- runHook({
183- preToolUse,
184- postToolUse,
185- notification,
186- stop
187- });
188- `
189- await fs . writeFile ( '.claude/hooks/index.ts' , indexContent )
98+ // Copy all hook template files
99+ await fs . copy ( path . join ( templatesDir , 'hooks' , 'lib.ts' ) , '.claude/hooks/lib.ts' )
100+ await fs . copy ( path . join ( templatesDir , 'hooks' , 'session.ts' ) , '.claude/hooks/session.ts' )
101+ await fs . copy ( path . join ( templatesDir , 'hooks' , 'index.ts' ) , '.claude/hooks/index.ts' )
190102 }
191103
192104 private async updateSettings ( ) : Promise < void > {
0 commit comments