fix: forward hook event data to notifications

The server was dropping the `data` field from hook-event POST requests,
so notifications always showed generic messages. Now forwards tool name,
command, question text, and reason to the frontend.

Notifications now show:
- permission_prompt: "Bash: docker push prod:latest"
- elicitation_dialog: "Merge PR #42 to main?"
- idle_prompt: custom message if provided
- stop: reason if provided

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
arkon
2026-01-24 03:58:51 +01:00
co-authored by Claude Opus 4.5
parent a2d4303300
commit 6393e00e95
3 changed files with 9 additions and 6 deletions
+2
View File
@@ -382,6 +382,8 @@ export interface HookEventRequest {
event: HookEventType;
/** Session ID from CLAUDEMAN_SESSION_ID env var */
sessionId: string;
/** Additional event data (tool name, command, question, etc.) */
data?: Record<string, unknown>;
}
// ========== API Response Types ==========
+5 -4
View File
@@ -1135,7 +1135,7 @@ class ClaudemanApp {
sessionId: data.sessionId,
sessionName: session?.name || data.sessionId,
title: 'Waiting for Input',
message: 'Claude is idle and waiting for a prompt',
message: data.message || 'Claude is idle and waiting for a prompt',
});
});
@@ -1146,13 +1146,14 @@ class ClaudemanApp {
this.tabAlerts.set(data.sessionId, 'action');
this.renderSessionTabs();
}
const toolInfo = data.tool ? `${data.tool}${data.command ? ': ' + data.command : data.file ? ': ' + data.file : ''}` : '';
this.notificationManager?.notify({
urgency: 'critical',
category: 'hook-permission',
sessionId: data.sessionId,
sessionName: session?.name || data.sessionId,
title: 'Permission Required',
message: 'Claude needs tool approval to continue',
message: toolInfo || 'Claude needs tool approval to continue',
});
});
@@ -1169,7 +1170,7 @@ class ClaudemanApp {
sessionId: data.sessionId,
sessionName: session?.name || data.sessionId,
title: 'Question Asked',
message: 'Claude is asking a question and waiting for your answer',
message: data.question || 'Claude is asking a question and waiting for your answer',
});
});
@@ -1182,7 +1183,7 @@ class ClaudemanApp {
sessionId: data.sessionId,
sessionName: session?.name || data.sessionId,
title: 'Response Complete',
message: 'Claude has finished responding',
message: data.reason || 'Claude has finished responding',
});
});
}
+2 -2
View File
@@ -1459,7 +1459,7 @@ export class WebServer extends EventEmitter {
// ========== Hook Events ==========
this.app.post('/api/hook-event', async (req) => {
const { event, sessionId } = req.body as HookEventRequest;
const { event, sessionId, data } = req.body as HookEventRequest;
const validEvents = ['idle_prompt', 'permission_prompt', 'elicitation_dialog', 'stop'] as const;
if (!event || !validEvents.includes(event as typeof validEvents[number])) {
return createErrorResponse(ApiErrorCode.INVALID_INPUT, 'Invalid event type');
@@ -1476,7 +1476,7 @@ export class WebServer extends EventEmitter {
}
}
this.broadcast(`hook:${event}`, { sessionId, timestamp: Date.now() });
this.broadcast(`hook:${event}`, { sessionId, timestamp: Date.now(), ...data });
return { success: true };
});
}