claude_hooks 1.1.0 → 1.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (95) hide show
  1. checksums.yaml +4 -4
  2. data/.agents/skills/ci-monitoring/SKILL.md +103 -0
  3. data/.agents/skills/run-tests/SKILL.md +45 -0
  4. data/.claude/settings.local.json +21 -0
  5. data/AGENTS.md +46 -0
  6. data/CHANGELOG.md +43 -0
  7. data/README.md +156 -21
  8. data/docs/API/COMMON.md +7 -1
  9. data/docs/API/CONFIG_CHANGE.md +39 -0
  10. data/docs/API/CWD_CHANGED.md +34 -0
  11. data/docs/API/ELICITATION.md +44 -0
  12. data/docs/API/ELICITATION_RESULT.md +43 -0
  13. data/docs/API/FILE_CHANGED.md +37 -0
  14. data/docs/API/INSTRUCTIONS_LOADED.md +30 -0
  15. data/docs/API/MESSAGE_DISPLAY.md +38 -0
  16. data/docs/API/PERMISSION_DENIED.md +37 -0
  17. data/docs/API/PERMISSION_REQUEST.md +11 -8
  18. data/docs/API/POST_COMPACT.md +30 -0
  19. data/docs/API/POST_TOOL_BATCH.md +39 -0
  20. data/docs/API/POST_TOOL_USE_FAILURE.md +31 -0
  21. data/docs/API/PRE_COMPACT.md +10 -2
  22. data/docs/API/PRE_TOOL_USE.md +5 -1
  23. data/docs/API/SETUP.md +37 -0
  24. data/docs/API/STOP_FAILURE.md +19 -0
  25. data/docs/API/SUBAGENT_START.md +40 -0
  26. data/docs/API/TASK_COMPLETED.md +43 -0
  27. data/docs/API/TASK_CREATED.md +43 -0
  28. data/docs/API/TEAMMATE_IDLE.md +40 -0
  29. data/docs/API/USER_PROMPT_EXPANSION.md +43 -0
  30. data/docs/API/WORKTREE_CREATE.md +39 -0
  31. data/docs/API/WORKTREE_REMOVE.md +33 -0
  32. data/docs/PROMPT_BASED_HOOKS.md +386 -0
  33. data/docs/external/claude-hooks-reference.md +2406 -854
  34. data/docs/mitts/ideabox.md +12 -0
  35. data/docs/mitts/prd.md +417 -0
  36. data/docs/mitts/setup.md +303 -0
  37. data/docs/mitts/task.md +44 -0
  38. data/lib/claude_hooks/base.rb +25 -0
  39. data/lib/claude_hooks/config_change.rb +28 -0
  40. data/lib/claude_hooks/cwd_changed.rb +28 -0
  41. data/lib/claude_hooks/elicitation.rb +61 -0
  42. data/lib/claude_hooks/elicitation_result.rb +57 -0
  43. data/lib/claude_hooks/file_changed.rb +41 -0
  44. data/lib/claude_hooks/instructions_loaded.rb +23 -0
  45. data/lib/claude_hooks/message_display.rb +58 -0
  46. data/lib/claude_hooks/output/base.rb +46 -1
  47. data/lib/claude_hooks/output/config_change.rb +47 -0
  48. data/lib/claude_hooks/output/cwd_changed.rb +42 -0
  49. data/lib/claude_hooks/output/elicitation.rb +67 -0
  50. data/lib/claude_hooks/output/elicitation_result.rb +63 -0
  51. data/lib/claude_hooks/output/file_changed.rb +42 -0
  52. data/lib/claude_hooks/output/instructions_loaded.rb +19 -0
  53. data/lib/claude_hooks/output/message_display.rb +49 -0
  54. data/lib/claude_hooks/output/permission_denied.rb +42 -0
  55. data/lib/claude_hooks/output/permission_request.rb +50 -25
  56. data/lib/claude_hooks/output/post_compact.rb +18 -0
  57. data/lib/claude_hooks/output/post_tool_batch.rb +51 -0
  58. data/lib/claude_hooks/output/post_tool_use.rb +12 -0
  59. data/lib/claude_hooks/output/post_tool_use_failure.rb +42 -0
  60. data/lib/claude_hooks/output/pre_compact.rb +34 -3
  61. data/lib/claude_hooks/output/pre_tool_use.rb +8 -2
  62. data/lib/claude_hooks/output/session_start.rb +30 -8
  63. data/lib/claude_hooks/output/setup.rb +42 -0
  64. data/lib/claude_hooks/output/stop.rb +15 -0
  65. data/lib/claude_hooks/output/stop_failure.rb +19 -0
  66. data/lib/claude_hooks/output/subagent_start.rb +42 -0
  67. data/lib/claude_hooks/output/task_completed.rb +18 -0
  68. data/lib/claude_hooks/output/task_created.rb +18 -0
  69. data/lib/claude_hooks/output/teammate_idle.rb +18 -0
  70. data/lib/claude_hooks/output/user_prompt_expansion.rb +51 -0
  71. data/lib/claude_hooks/output/worktree_create.rb +60 -0
  72. data/lib/claude_hooks/output/worktree_remove.rb +19 -0
  73. data/lib/claude_hooks/permission_denied.rb +41 -0
  74. data/lib/claude_hooks/permission_request.rb +16 -9
  75. data/lib/claude_hooks/post_compact.rb +23 -0
  76. data/lib/claude_hooks/post_tool_batch.rb +59 -0
  77. data/lib/claude_hooks/post_tool_use.rb +10 -0
  78. data/lib/claude_hooks/post_tool_use_failure.rb +45 -0
  79. data/lib/claude_hooks/pre_compact.rb +7 -0
  80. data/lib/claude_hooks/pre_tool_use.rb +20 -2
  81. data/lib/claude_hooks/session_start.rb +28 -0
  82. data/lib/claude_hooks/setup.rb +25 -0
  83. data/lib/claude_hooks/stop.rb +17 -0
  84. data/lib/claude_hooks/stop_failure.rb +27 -0
  85. data/lib/claude_hooks/subagent_start.rb +23 -0
  86. data/lib/claude_hooks/subagent_stop.rb +5 -1
  87. data/lib/claude_hooks/task_completed.rb +35 -0
  88. data/lib/claude_hooks/task_created.rb +35 -0
  89. data/lib/claude_hooks/teammate_idle.rb +23 -0
  90. data/lib/claude_hooks/user_prompt_expansion.rb +45 -0
  91. data/lib/claude_hooks/version.rb +1 -1
  92. data/lib/claude_hooks/worktree_create.rb +27 -0
  93. data/lib/claude_hooks/worktree_remove.rb +19 -0
  94. data/lib/claude_hooks.rb +40 -0
  95. metadata +71 -2
@@ -0,0 +1,59 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'base'
4
+
5
+ module ClaudeHooks
6
+ class PostToolBatch < Base
7
+ def self.hook_type
8
+ 'PostToolBatch'
9
+ end
10
+
11
+ def self.input_fields
12
+ %w[tool_calls]
13
+ end
14
+
15
+ def tool_calls
16
+ @input_data['tool_calls'] || @input_data['toolCalls'] || []
17
+ end
18
+
19
+ # Convenience partitions over tool_calls. Entries carry a `tool_response`
20
+ # rather than an explicit success flag, so success is derived from the
21
+ # presence of a response that isn't flagged as an error. When your payload
22
+ # shape differs, use the raw `tool_calls` array instead.
23
+ def succeeded_calls
24
+ tool_calls.reject { |call| failed_call?(call) }
25
+ end
26
+
27
+ def failed_calls
28
+ tool_calls.select { |call| failed_call?(call) }
29
+ end
30
+
31
+ def block!(reason = '')
32
+ @output_data['decision'] = 'block'
33
+ @output_data['reason'] = reason
34
+ end
35
+
36
+ def add_additional_context!(context)
37
+ @output_data['hookSpecificOutput'] ||= { 'hookEventName' => hook_event_name }
38
+ @output_data['hookSpecificOutput']['additionalContext'] = context
39
+ end
40
+
41
+ private
42
+
43
+ # A call is considered failed when its response is missing or carries an
44
+ # error marker (`is_error`/`isError` true, or an `error` key).
45
+ def failed_call?(call)
46
+ return true unless call.is_a?(Hash)
47
+
48
+ response = call['tool_response'] || call['toolResponse']
49
+ return true if response.nil?
50
+
51
+ if response.is_a?(Hash)
52
+ return true if response['is_error'] == true || response['isError'] == true
53
+ return true if response.key?('error') && !response['error'].nil?
54
+ end
55
+
56
+ false
57
+ end
58
+ end
59
+ end
@@ -49,5 +49,15 @@ module ClaudeHooks
49
49
  }
50
50
  end
51
51
  alias_method :add_context!, :add_additional_context!
52
+
53
+ def update_tool_output!(value)
54
+ @output_data['hookSpecificOutput'] ||= { 'hookEventName' => hook_event_name }
55
+ @output_data['hookSpecificOutput']['updatedToolOutput'] = value
56
+ end
57
+
58
+ def update_mcp_tool_output!(value)
59
+ @output_data['hookSpecificOutput'] ||= { 'hookEventName' => hook_event_name }
60
+ @output_data['hookSpecificOutput']['updatedMCPToolOutput'] = value
61
+ end
52
62
  end
53
63
  end
@@ -0,0 +1,45 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'base'
4
+
5
+ module ClaudeHooks
6
+ class PostToolUseFailure < Base
7
+ def self.hook_type
8
+ 'PostToolUseFailure'
9
+ end
10
+
11
+ def self.input_fields
12
+ %w[tool_name tool_input tool_use_id error]
13
+ end
14
+
15
+ def tool_name
16
+ @input_data['tool_name']
17
+ end
18
+
19
+ def tool_input
20
+ @input_data['tool_input']
21
+ end
22
+
23
+ def tool_use_id
24
+ @input_data['tool_use_id'] || @input_data['toolUseId']
25
+ end
26
+
27
+ def error
28
+ @input_data['error']
29
+ end
30
+
31
+ def is_interrupt
32
+ @input_data.key?('is_interrupt') ? @input_data['is_interrupt'] : @input_data['isInterrupt']
33
+ end
34
+ alias_method :interrupt?, :is_interrupt
35
+
36
+ def duration_ms
37
+ @input_data['duration_ms'] || @input_data['durationMs']
38
+ end
39
+
40
+ def add_additional_context!(context)
41
+ @output_data['hookSpecificOutput'] ||= { 'hookEventName' => hook_event_name }
42
+ @output_data['hookSpecificOutput']['additionalContext'] = context
43
+ end
44
+ end
45
+ end
@@ -27,6 +27,13 @@ module ClaudeHooks
27
27
  end
28
28
  end
29
29
 
30
+ # === OUTPUT DATA HELPERS ===
31
+
32
+ def block!(reason = '')
33
+ @output_data['decision'] = 'block'
34
+ @output_data['reason'] = reason
35
+ end
36
+
30
37
  # === UTILITY HELPERS ===
31
38
 
32
39
  def backup_transcript!(backup_file_path)
@@ -58,9 +58,27 @@ module ClaudeHooks
58
58
  'permissionDecision' => 'allow'
59
59
  }
60
60
  @output_data['hookSpecificOutput']['updatedInput'] = updated_input
61
-
62
- # Ensure permission decision is 'allow' when updating input
63
61
  @output_data['hookSpecificOutput']['permissionDecision'] = 'allow'
64
62
  end
63
+
64
+ def defer_permission!
65
+ @output_data['hookSpecificOutput'] = {
66
+ 'hookEventName' => hook_event_name,
67
+ 'permissionDecision' => 'defer'
68
+ }
69
+ end
70
+
71
+ def update_input!(updated_input)
72
+ @output_data['hookSpecificOutput'] ||= {
73
+ 'hookEventName' => hook_event_name,
74
+ 'permissionDecision' => 'allow'
75
+ }
76
+ @output_data['hookSpecificOutput']['updatedInput'] = updated_input
77
+ end
78
+
79
+ def add_additional_context!(context)
80
+ @output_data['hookSpecificOutput'] ||= { 'hookEventName' => hook_event_name }
81
+ @output_data['hookSpecificOutput']['additionalContext'] = context
82
+ end
65
83
  end
66
84
  end
@@ -18,6 +18,14 @@ module ClaudeHooks
18
18
  @input_data['source']
19
19
  end
20
20
 
21
+ def model
22
+ @input_data['model']
23
+ end
24
+
25
+ def session_title
26
+ @input_data['session_title'] || @input_data['sessionTitle']
27
+ end
28
+
21
29
  # === OUTPUT DATA HELPERS ===
22
30
 
23
31
  def add_additional_context!(context)
@@ -31,5 +39,25 @@ module ClaudeHooks
31
39
  def empty_additional_context!
32
40
  @output_data['hookSpecificOutput'] = nil
33
41
  end
42
+
43
+ def session_title!(title)
44
+ @output_data['hookSpecificOutput'] ||= { 'hookEventName' => hook_event_name }
45
+ @output_data['hookSpecificOutput']['sessionTitle'] = title
46
+ end
47
+
48
+ def initial_user_message!(message)
49
+ @output_data['hookSpecificOutput'] ||= { 'hookEventName' => hook_event_name }
50
+ @output_data['hookSpecificOutput']['initialUserMessage'] = message
51
+ end
52
+
53
+ def watch_paths!(paths)
54
+ @output_data['hookSpecificOutput'] ||= { 'hookEventName' => hook_event_name }
55
+ @output_data['hookSpecificOutput']['watchPaths'] = Array(paths)
56
+ end
57
+
58
+ def reload_skills!(value = true)
59
+ @output_data['hookSpecificOutput'] ||= { 'hookEventName' => hook_event_name }
60
+ @output_data['hookSpecificOutput']['reloadSkills'] = value
61
+ end
34
62
  end
35
63
  end
@@ -0,0 +1,25 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'base'
4
+
5
+ module ClaudeHooks
6
+ class Setup < Base
7
+ def self.hook_type
8
+ 'Setup'
9
+ end
10
+
11
+ def self.input_fields
12
+ %w[source]
13
+ end
14
+
15
+ def source
16
+ @input_data['source']
17
+ end
18
+
19
+ def add_additional_context!(context)
20
+ @output_data['hookSpecificOutput'] ||= { 'hookEventName' => hook_event_name }
21
+ @output_data['hookSpecificOutput']['additionalContext'] = context
22
+ end
23
+ alias_method :add_context!, :add_additional_context!
24
+ end
25
+ end
@@ -26,6 +26,18 @@ module ClaudeHooks
26
26
  @input_data['stop_hook_active']
27
27
  end
28
28
 
29
+ def last_assistant_message
30
+ @input_data['last_assistant_message'] || @input_data['lastAssistantMessage']
31
+ end
32
+
33
+ def background_tasks
34
+ @input_data['background_tasks'] || @input_data['backgroundTasks'] || []
35
+ end
36
+
37
+ def session_crons
38
+ @input_data['session_crons'] || @input_data['sessionCrons'] || []
39
+ end
40
+
29
41
  # === OUTPUT DATA HELPERS ===
30
42
 
31
43
  # Block Claude from stopping (force it to continue)
@@ -40,5 +52,10 @@ module ClaudeHooks
40
52
  @output_data.delete('decision')
41
53
  @output_data.delete('reason')
42
54
  end
55
+
56
+ def add_additional_context!(context)
57
+ @output_data['hookSpecificOutput'] ||= { 'hookEventName' => hook_event_name }
58
+ @output_data['hookSpecificOutput']['additionalContext'] = context
59
+ end
43
60
  end
44
61
  end
@@ -0,0 +1,27 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'base'
4
+
5
+ module ClaudeHooks
6
+ class StopFailure < Base
7
+ def self.hook_type
8
+ 'StopFailure'
9
+ end
10
+
11
+ def self.input_fields
12
+ %w[error]
13
+ end
14
+
15
+ def error
16
+ @input_data['error']
17
+ end
18
+
19
+ def error_details
20
+ @input_data['error_details'] || @input_data['errorDetails']
21
+ end
22
+
23
+ def last_assistant_message
24
+ @input_data['last_assistant_message'] || @input_data['lastAssistantMessage']
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,23 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'base'
4
+
5
+ module ClaudeHooks
6
+ class SubagentStart < Base
7
+ def self.hook_type
8
+ 'SubagentStart'
9
+ end
10
+
11
+ def self.input_fields
12
+ %w[agent_id agent_type]
13
+ end
14
+
15
+ # agent_id and agent_type readers come from Base (Part A)
16
+
17
+ def add_additional_context!(context)
18
+ @output_data['hookSpecificOutput'] ||= { 'hookEventName' => hook_event_name }
19
+ @output_data['hookSpecificOutput']['additionalContext'] = context
20
+ end
21
+ alias_method :add_context!, :add_additional_context!
22
+ end
23
+ end
@@ -7,5 +7,9 @@ module ClaudeHooks
7
7
  def self.hook_type
8
8
  'SubagentStop'
9
9
  end
10
+
11
+ def agent_transcript_path
12
+ @input_data['agent_transcript_path'] || @input_data['agentTranscriptPath']
13
+ end
10
14
  end
11
- end
15
+ end
@@ -0,0 +1,35 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'base'
4
+
5
+ module ClaudeHooks
6
+ class TaskCompleted < Base
7
+ def self.hook_type
8
+ 'TaskCompleted'
9
+ end
10
+
11
+ def self.input_fields
12
+ %w[task_id task_subject]
13
+ end
14
+
15
+ def task_id
16
+ @input_data['task_id'] || @input_data['taskId']
17
+ end
18
+
19
+ def task_subject
20
+ @input_data['task_subject'] || @input_data['taskSubject']
21
+ end
22
+
23
+ def task_description
24
+ @input_data['task_description'] || @input_data['taskDescription']
25
+ end
26
+
27
+ def teammate_name
28
+ @input_data['teammate_name'] || @input_data['teammateName']
29
+ end
30
+
31
+ def team_name
32
+ @input_data['team_name'] || @input_data['teamName']
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,35 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'base'
4
+
5
+ module ClaudeHooks
6
+ class TaskCreated < Base
7
+ def self.hook_type
8
+ 'TaskCreated'
9
+ end
10
+
11
+ def self.input_fields
12
+ %w[task_id task_subject]
13
+ end
14
+
15
+ def task_id
16
+ @input_data['task_id'] || @input_data['taskId']
17
+ end
18
+
19
+ def task_subject
20
+ @input_data['task_subject'] || @input_data['taskSubject']
21
+ end
22
+
23
+ def task_description
24
+ @input_data['task_description'] || @input_data['taskDescription']
25
+ end
26
+
27
+ def teammate_name
28
+ @input_data['teammate_name'] || @input_data['teammateName']
29
+ end
30
+
31
+ def team_name
32
+ @input_data['team_name'] || @input_data['teamName']
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,23 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'base'
4
+
5
+ module ClaudeHooks
6
+ class TeammateIdle < Base
7
+ def self.hook_type
8
+ 'TeammateIdle'
9
+ end
10
+
11
+ def self.input_fields
12
+ %w[teammate_name team_name]
13
+ end
14
+
15
+ def teammate_name
16
+ @input_data['teammate_name'] || @input_data['teammateName']
17
+ end
18
+
19
+ def team_name
20
+ @input_data['team_name'] || @input_data['teamName']
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,45 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'base'
4
+
5
+ module ClaudeHooks
6
+ class UserPromptExpansion < Base
7
+ def self.hook_type
8
+ 'UserPromptExpansion'
9
+ end
10
+
11
+ def self.input_fields
12
+ %w[expansion_type command_name command_args command_source prompt]
13
+ end
14
+
15
+ def expansion_type
16
+ @input_data['expansion_type'] || @input_data['expansionType']
17
+ end
18
+
19
+ def command_name
20
+ @input_data['command_name'] || @input_data['commandName']
21
+ end
22
+
23
+ def command_args
24
+ @input_data['command_args'] || @input_data['commandArgs']
25
+ end
26
+
27
+ def command_source
28
+ @input_data['command_source'] || @input_data['commandSource']
29
+ end
30
+
31
+ def prompt
32
+ @input_data['prompt']
33
+ end
34
+
35
+ def block!(reason = '')
36
+ @output_data['decision'] = 'block'
37
+ @output_data['reason'] = reason
38
+ end
39
+
40
+ def add_additional_context!(context)
41
+ @output_data['hookSpecificOutput'] ||= { 'hookEventName' => hook_event_name }
42
+ @output_data['hookSpecificOutput']['additionalContext'] = context
43
+ end
44
+ end
45
+ end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module ClaudeHooks
4
- VERSION = "1.1.0"
4
+ VERSION = "1.2.0"
5
5
  end
@@ -0,0 +1,27 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'base'
4
+
5
+ module ClaudeHooks
6
+ class WorktreeCreate < Base
7
+ def self.hook_type
8
+ 'WorktreeCreate'
9
+ end
10
+
11
+ def self.input_fields
12
+ %w[name]
13
+ end
14
+
15
+ def name
16
+ @input_data['name']
17
+ end
18
+
19
+ # Emit the worktree path as bare stdout (last non-empty line).
20
+ # Also sets hookSpecificOutput.worktreePath for programmatic access.
21
+ def worktree_path!(path)
22
+ @output_data['_worktree_path'] = path
23
+ @output_data['hookSpecificOutput'] ||= { 'hookEventName' => hook_event_name }
24
+ @output_data['hookSpecificOutput']['worktreePath'] = path
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,19 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'base'
4
+
5
+ module ClaudeHooks
6
+ class WorktreeRemove < Base
7
+ def self.hook_type
8
+ 'WorktreeRemove'
9
+ end
10
+
11
+ def self.input_fields
12
+ %w[worktree_path]
13
+ end
14
+
15
+ def worktree_path
16
+ @input_data['worktree_path'] || @input_data['worktreePath']
17
+ end
18
+ end
19
+ end
data/lib/claude_hooks.rb CHANGED
@@ -12,11 +12,31 @@ require_relative "claude_hooks/pre_tool_use"
12
12
  require_relative "claude_hooks/permission_request"
13
13
  require_relative "claude_hooks/post_tool_use"
14
14
  require_relative "claude_hooks/notification"
15
+ require_relative "claude_hooks/message_display"
15
16
  require_relative "claude_hooks/stop"
16
17
  require_relative "claude_hooks/subagent_stop"
17
18
  require_relative "claude_hooks/pre_compact"
18
19
  require_relative "claude_hooks/session_start"
19
20
  require_relative "claude_hooks/session_end"
21
+ require_relative "claude_hooks/setup"
22
+ require_relative "claude_hooks/subagent_start"
23
+ require_relative "claude_hooks/user_prompt_expansion"
24
+ require_relative "claude_hooks/post_tool_batch"
25
+ require_relative "claude_hooks/config_change"
26
+ require_relative "claude_hooks/task_created"
27
+ require_relative "claude_hooks/task_completed"
28
+ require_relative "claude_hooks/teammate_idle"
29
+ require_relative "claude_hooks/post_tool_use_failure"
30
+ require_relative "claude_hooks/stop_failure"
31
+ require_relative "claude_hooks/post_compact"
32
+ require_relative "claude_hooks/cwd_changed"
33
+ require_relative "claude_hooks/file_changed"
34
+ require_relative "claude_hooks/instructions_loaded"
35
+ require_relative "claude_hooks/worktree_remove"
36
+ require_relative "claude_hooks/permission_denied"
37
+ require_relative "claude_hooks/elicitation"
38
+ require_relative "claude_hooks/elicitation_result"
39
+ require_relative "claude_hooks/worktree_create"
20
40
 
21
41
  # Output classes
22
42
  require_relative "claude_hooks/output/base"
@@ -25,11 +45,31 @@ require_relative "claude_hooks/output/pre_tool_use"
25
45
  require_relative "claude_hooks/output/permission_request"
26
46
  require_relative "claude_hooks/output/post_tool_use"
27
47
  require_relative "claude_hooks/output/notification"
48
+ require_relative "claude_hooks/output/message_display"
28
49
  require_relative "claude_hooks/output/stop"
29
50
  require_relative "claude_hooks/output/subagent_stop"
30
51
  require_relative "claude_hooks/output/pre_compact"
31
52
  require_relative "claude_hooks/output/session_start"
32
53
  require_relative "claude_hooks/output/session_end"
54
+ require_relative "claude_hooks/output/setup"
55
+ require_relative "claude_hooks/output/subagent_start"
56
+ require_relative "claude_hooks/output/user_prompt_expansion"
57
+ require_relative "claude_hooks/output/post_tool_batch"
58
+ require_relative "claude_hooks/output/config_change"
59
+ require_relative "claude_hooks/output/task_created"
60
+ require_relative "claude_hooks/output/task_completed"
61
+ require_relative "claude_hooks/output/teammate_idle"
62
+ require_relative "claude_hooks/output/post_tool_use_failure"
63
+ require_relative "claude_hooks/output/stop_failure"
64
+ require_relative "claude_hooks/output/post_compact"
65
+ require_relative "claude_hooks/output/cwd_changed"
66
+ require_relative "claude_hooks/output/file_changed"
67
+ require_relative "claude_hooks/output/instructions_loaded"
68
+ require_relative "claude_hooks/output/worktree_remove"
69
+ require_relative "claude_hooks/output/permission_denied"
70
+ require_relative "claude_hooks/output/elicitation"
71
+ require_relative "claude_hooks/output/elicitation_result"
72
+ require_relative "claude_hooks/output/worktree_create"
33
73
 
34
74
  module ClaudeHooks
35
75
  class Error < StandardError; end