Skip to content

Commit 3d003f8

Browse files
committed
Expand Claude hook events for better agent status detection
- Add PermissionRequest, PreToolUse, TaskCompleted hook events - Parse notification_type from Notification payload to distinguish idle_prompt/permission_prompt from informational notifications - Fix UI stuck on "working" when agent asks a question or permission
1 parent 0aa8524 commit 3d003f8

2 files changed

Lines changed: 26 additions & 7 deletions

File tree

hook_claude.go

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,15 @@ func claudeSettingsPath() string {
2424
const hookCommand = "aipilot-cli --agent-event"
2525

2626
// claudeHookEvents lists the Claude Code events we want to hook into
27-
var claudeHookEvents = []string{"UserPromptSubmit", "Stop", "StopFailure", "Notification"}
27+
var claudeHookEvents = []string{
28+
"UserPromptSubmit",
29+
"PreToolUse",
30+
"Stop",
31+
"StopFailure",
32+
"Notification",
33+
"PermissionRequest",
34+
"TaskCompleted",
35+
}
2836

2937
// ensureClaudeHooksInstalled reads ~/.claude/settings.json and adds
3038
// aipilot hook entries for agent status detection if not already present.

hook_client.go

Lines changed: 17 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -25,16 +25,17 @@ func agentEventMain() {
2525
os.Exit(0)
2626
}
2727

28-
// Extract hook_event_name from the payload
28+
// Extract hook_event_name and notification_type from the payload
2929
var payload struct {
30-
HookEventName string `json:"hook_event_name"`
30+
HookEventName string `json:"hook_event_name"`
31+
NotificationType string `json:"notification_type"`
3132
}
3233
if err := json.Unmarshal(input, &payload); err != nil {
3334
os.Exit(0)
3435
}
3536

3637
// Map agent-specific event to generic hook message
37-
msg := mapHookEvent(payload.HookEventName)
38+
msg := mapHookEvent(payload.HookEventName, payload.NotificationType)
3839
if msg == nil {
3940
// Unknown or unhandled event — ignore
4041
os.Exit(0)
@@ -58,12 +59,22 @@ func agentEventMain() {
5859

5960
// mapHookEvent maps a hook event name to a generic HookMessage.
6061
// Currently supports Claude Code events. Add other agents here.
61-
func mapHookEvent(eventName string) *HookMessage {
62+
func mapHookEvent(eventName string, notificationType string) *HookMessage {
6263
switch eventName {
63-
case "UserPromptSubmit":
64+
// Busy: agent is actively working
65+
case "UserPromptSubmit", "PreToolUse":
6466
return newAgentStatusMessage("busy")
65-
case "Stop", "StopFailure", "Notification":
67+
// Idle: agent finished or waiting for user input
68+
case "Stop", "StopFailure", "PermissionRequest", "TaskCompleted":
6669
return newAgentStatusMessage("idle")
70+
case "Notification":
71+
switch notificationType {
72+
case "idle_prompt", "permission_prompt", "elicitation_dialog":
73+
return newAgentStatusMessage("idle")
74+
default:
75+
// auth_success or unknown — no state change
76+
return nil
77+
}
6778
default:
6879
return nil
6980
}

0 commit comments

Comments
 (0)