claude_hooks 1.1.0 → 1.2.1
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.
- checksums.yaml +4 -4
- data/.agents/skills/ci-monitoring/SKILL.md +103 -0
- data/.agents/skills/run-tests/SKILL.md +45 -0
- data/AGENTS.md +46 -0
- data/CHANGELOG.md +64 -0
- data/README.md +303 -239
- data/docs/1.0.0_MIGRATION_GUIDE.md +6 -7
- data/docs/API/COMMON.md +7 -1
- data/docs/API/CONFIG_CHANGE.md +39 -0
- data/docs/API/CWD_CHANGED.md +34 -0
- data/docs/API/ELICITATION.md +44 -0
- data/docs/API/ELICITATION_RESULT.md +43 -0
- data/docs/API/FILE_CHANGED.md +37 -0
- data/docs/API/INSTRUCTIONS_LOADED.md +30 -0
- data/docs/API/MESSAGE_DISPLAY.md +38 -0
- data/docs/API/PERMISSION_DENIED.md +37 -0
- data/docs/API/PERMISSION_REQUEST.md +11 -8
- data/docs/API/POST_COMPACT.md +30 -0
- data/docs/API/POST_TOOL_BATCH.md +39 -0
- data/docs/API/POST_TOOL_USE_FAILURE.md +31 -0
- data/docs/API/PRE_COMPACT.md +10 -2
- data/docs/API/PRE_TOOL_USE.md +5 -1
- data/docs/API/SETUP.md +37 -0
- data/docs/API/STOP_FAILURE.md +19 -0
- data/docs/API/SUBAGENT_START.md +40 -0
- data/docs/API/TASK_COMPLETED.md +43 -0
- data/docs/API/TASK_CREATED.md +43 -0
- data/docs/API/TEAMMATE_IDLE.md +40 -0
- data/docs/API/USER_PROMPT_EXPANSION.md +43 -0
- data/docs/API/WORKTREE_CREATE.md +39 -0
- data/docs/API/WORKTREE_REMOVE.md +33 -0
- data/docs/PROMPT_BASED_HOOKS.md +386 -0
- data/docs/external/claude-hooks-reference.md +2406 -854
- data/docs/mitts/ideabox.md +12 -0
- data/docs/mitts/prd.md +417 -0
- data/docs/mitts/setup.md +303 -0
- data/docs/mitts/task.md +44 -0
- data/example_dotclaude/hooks/entrypoints/session_end.rb +5 -22
- data/example_dotclaude/hooks/entrypoints/user_prompt_submit.rb +4 -26
- data/example_dotclaude/hooks/{handlers/pre_tool_use/github_guard.rb → github_guard.rb} +7 -13
- data/example_dotclaude/settings.json +1 -1
- data/lib/claude_hooks/base.rb +25 -0
- data/lib/claude_hooks/cli.rb +84 -149
- data/lib/claude_hooks/config_change.rb +28 -0
- data/lib/claude_hooks/cwd_changed.rb +28 -0
- data/lib/claude_hooks/elicitation.rb +61 -0
- data/lib/claude_hooks/elicitation_result.rb +57 -0
- data/lib/claude_hooks/file_changed.rb +41 -0
- data/lib/claude_hooks/instructions_loaded.rb +23 -0
- data/lib/claude_hooks/message_display.rb +58 -0
- data/lib/claude_hooks/output/base.rb +46 -1
- data/lib/claude_hooks/output/config_change.rb +47 -0
- data/lib/claude_hooks/output/cwd_changed.rb +42 -0
- data/lib/claude_hooks/output/elicitation.rb +67 -0
- data/lib/claude_hooks/output/elicitation_result.rb +63 -0
- data/lib/claude_hooks/output/file_changed.rb +42 -0
- data/lib/claude_hooks/output/instructions_loaded.rb +19 -0
- data/lib/claude_hooks/output/message_display.rb +49 -0
- data/lib/claude_hooks/output/permission_denied.rb +42 -0
- data/lib/claude_hooks/output/permission_request.rb +50 -25
- data/lib/claude_hooks/output/post_compact.rb +18 -0
- data/lib/claude_hooks/output/post_tool_batch.rb +51 -0
- data/lib/claude_hooks/output/post_tool_use.rb +12 -0
- data/lib/claude_hooks/output/post_tool_use_failure.rb +42 -0
- data/lib/claude_hooks/output/pre_compact.rb +34 -3
- data/lib/claude_hooks/output/pre_tool_use.rb +8 -2
- data/lib/claude_hooks/output/session_start.rb +30 -8
- data/lib/claude_hooks/output/setup.rb +42 -0
- data/lib/claude_hooks/output/stop.rb +15 -0
- data/lib/claude_hooks/output/stop_failure.rb +19 -0
- data/lib/claude_hooks/output/subagent_start.rb +42 -0
- data/lib/claude_hooks/output/task_completed.rb +18 -0
- data/lib/claude_hooks/output/task_created.rb +18 -0
- data/lib/claude_hooks/output/teammate_idle.rb +18 -0
- data/lib/claude_hooks/output/user_prompt_expansion.rb +51 -0
- data/lib/claude_hooks/output/worktree_create.rb +60 -0
- data/lib/claude_hooks/output/worktree_remove.rb +19 -0
- data/lib/claude_hooks/permission_denied.rb +41 -0
- data/lib/claude_hooks/permission_request.rb +16 -9
- data/lib/claude_hooks/post_compact.rb +23 -0
- data/lib/claude_hooks/post_tool_batch.rb +59 -0
- data/lib/claude_hooks/post_tool_use.rb +10 -0
- data/lib/claude_hooks/post_tool_use_failure.rb +45 -0
- data/lib/claude_hooks/pre_compact.rb +7 -0
- data/lib/claude_hooks/pre_tool_use.rb +20 -2
- data/lib/claude_hooks/session_start.rb +28 -0
- data/lib/claude_hooks/setup.rb +25 -0
- data/lib/claude_hooks/stop.rb +17 -0
- data/lib/claude_hooks/stop_failure.rb +27 -0
- data/lib/claude_hooks/subagent_start.rb +23 -0
- data/lib/claude_hooks/subagent_stop.rb +5 -1
- data/lib/claude_hooks/task_completed.rb +35 -0
- data/lib/claude_hooks/task_created.rb +35 -0
- data/lib/claude_hooks/teammate_idle.rb +23 -0
- data/lib/claude_hooks/user_prompt_expansion.rb +45 -0
- data/lib/claude_hooks/version.rb +1 -1
- data/lib/claude_hooks/worktree_create.rb +27 -0
- data/lib/claude_hooks/worktree_remove.rb +19 -0
- data/lib/claude_hooks.rb +40 -0
- metadata +71 -4
- data/example_dotclaude/hooks/entrypoints/pre_tool_use.rb +0 -25
|
@@ -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
|
data/lib/claude_hooks/stop.rb
CHANGED
|
@@ -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
|
|
@@ -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
|
data/lib/claude_hooks/version.rb
CHANGED
|
@@ -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
|
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: claude_hooks
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 1.1
|
|
4
|
+
version: 1.2.1
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Gabriel Dehan
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: exe
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2026-
|
|
11
|
+
date: 2026-07-14 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: json
|
|
@@ -61,30 +61,57 @@ executables: []
|
|
|
61
61
|
extensions: []
|
|
62
62
|
extra_rdoc_files: []
|
|
63
63
|
files:
|
|
64
|
+
- ".agents/skills/ci-monitoring/SKILL.md"
|
|
65
|
+
- ".agents/skills/run-tests/SKILL.md"
|
|
64
66
|
- ".claude/auto-fix.md"
|
|
67
|
+
- AGENTS.md
|
|
65
68
|
- CHANGELOG.md
|
|
66
69
|
- README.md
|
|
67
70
|
- claude_hooks.gemspec
|
|
68
71
|
- docs/1.0.0_MIGRATION_GUIDE.md
|
|
69
72
|
- docs/1.1.0_UPGRADE_GUIDE.md
|
|
70
73
|
- docs/API/COMMON.md
|
|
74
|
+
- docs/API/CONFIG_CHANGE.md
|
|
75
|
+
- docs/API/CWD_CHANGED.md
|
|
76
|
+
- docs/API/ELICITATION.md
|
|
77
|
+
- docs/API/ELICITATION_RESULT.md
|
|
78
|
+
- docs/API/FILE_CHANGED.md
|
|
79
|
+
- docs/API/INSTRUCTIONS_LOADED.md
|
|
80
|
+
- docs/API/MESSAGE_DISPLAY.md
|
|
71
81
|
- docs/API/NOTIFICATION.md
|
|
82
|
+
- docs/API/PERMISSION_DENIED.md
|
|
72
83
|
- docs/API/PERMISSION_REQUEST.md
|
|
84
|
+
- docs/API/POST_COMPACT.md
|
|
85
|
+
- docs/API/POST_TOOL_BATCH.md
|
|
73
86
|
- docs/API/POST_TOOL_USE.md
|
|
87
|
+
- docs/API/POST_TOOL_USE_FAILURE.md
|
|
74
88
|
- docs/API/PRE_COMPACT.md
|
|
75
89
|
- docs/API/PRE_TOOL_USE.md
|
|
76
90
|
- docs/API/SESSION_END.md
|
|
77
91
|
- docs/API/SESSION_START.md
|
|
92
|
+
- docs/API/SETUP.md
|
|
78
93
|
- docs/API/STOP.md
|
|
94
|
+
- docs/API/STOP_FAILURE.md
|
|
95
|
+
- docs/API/SUBAGENT_START.md
|
|
79
96
|
- docs/API/SUBAGENT_STOP.md
|
|
97
|
+
- docs/API/TASK_COMPLETED.md
|
|
98
|
+
- docs/API/TASK_CREATED.md
|
|
99
|
+
- docs/API/TEAMMATE_IDLE.md
|
|
100
|
+
- docs/API/USER_PROMPT_EXPANSION.md
|
|
80
101
|
- docs/API/USER_PROMPT_SUBMIT.md
|
|
102
|
+
- docs/API/WORKTREE_CREATE.md
|
|
103
|
+
- docs/API/WORKTREE_REMOVE.md
|
|
104
|
+
- docs/PROMPT_BASED_HOOKS.md
|
|
81
105
|
- docs/WHY.md
|
|
82
106
|
- docs/external/claude-hooks-reference.md
|
|
107
|
+
- docs/mitts/ideabox.md
|
|
108
|
+
- docs/mitts/prd.md
|
|
109
|
+
- docs/mitts/setup.md
|
|
110
|
+
- docs/mitts/task.md
|
|
83
111
|
- example_dotclaude/commands/.gitkeep
|
|
84
|
-
- example_dotclaude/hooks/entrypoints/pre_tool_use.rb
|
|
85
112
|
- example_dotclaude/hooks/entrypoints/session_end.rb
|
|
86
113
|
- example_dotclaude/hooks/entrypoints/user_prompt_submit.rb
|
|
87
|
-
- example_dotclaude/hooks/
|
|
114
|
+
- example_dotclaude/hooks/github_guard.rb
|
|
88
115
|
- example_dotclaude/hooks/handlers/session_end/cleanup_handler.rb
|
|
89
116
|
- example_dotclaude/hooks/handlers/session_end/log_session_stats.rb
|
|
90
117
|
- example_dotclaude/hooks/handlers/user_prompt_submit/append_rules.rb
|
|
@@ -94,30 +121,70 @@ files:
|
|
|
94
121
|
- lib/claude_hooks.rb
|
|
95
122
|
- lib/claude_hooks/base.rb
|
|
96
123
|
- lib/claude_hooks/cli.rb
|
|
124
|
+
- lib/claude_hooks/config_change.rb
|
|
97
125
|
- lib/claude_hooks/configuration.rb
|
|
126
|
+
- lib/claude_hooks/cwd_changed.rb
|
|
127
|
+
- lib/claude_hooks/elicitation.rb
|
|
128
|
+
- lib/claude_hooks/elicitation_result.rb
|
|
129
|
+
- lib/claude_hooks/file_changed.rb
|
|
130
|
+
- lib/claude_hooks/instructions_loaded.rb
|
|
98
131
|
- lib/claude_hooks/logger.rb
|
|
132
|
+
- lib/claude_hooks/message_display.rb
|
|
99
133
|
- lib/claude_hooks/notification.rb
|
|
100
134
|
- lib/claude_hooks/output/base.rb
|
|
135
|
+
- lib/claude_hooks/output/config_change.rb
|
|
136
|
+
- lib/claude_hooks/output/cwd_changed.rb
|
|
137
|
+
- lib/claude_hooks/output/elicitation.rb
|
|
138
|
+
- lib/claude_hooks/output/elicitation_result.rb
|
|
139
|
+
- lib/claude_hooks/output/file_changed.rb
|
|
140
|
+
- lib/claude_hooks/output/instructions_loaded.rb
|
|
141
|
+
- lib/claude_hooks/output/message_display.rb
|
|
101
142
|
- lib/claude_hooks/output/notification.rb
|
|
143
|
+
- lib/claude_hooks/output/permission_denied.rb
|
|
102
144
|
- lib/claude_hooks/output/permission_request.rb
|
|
145
|
+
- lib/claude_hooks/output/post_compact.rb
|
|
146
|
+
- lib/claude_hooks/output/post_tool_batch.rb
|
|
103
147
|
- lib/claude_hooks/output/post_tool_use.rb
|
|
148
|
+
- lib/claude_hooks/output/post_tool_use_failure.rb
|
|
104
149
|
- lib/claude_hooks/output/pre_compact.rb
|
|
105
150
|
- lib/claude_hooks/output/pre_tool_use.rb
|
|
106
151
|
- lib/claude_hooks/output/session_end.rb
|
|
107
152
|
- lib/claude_hooks/output/session_start.rb
|
|
153
|
+
- lib/claude_hooks/output/setup.rb
|
|
108
154
|
- lib/claude_hooks/output/stop.rb
|
|
155
|
+
- lib/claude_hooks/output/stop_failure.rb
|
|
156
|
+
- lib/claude_hooks/output/subagent_start.rb
|
|
109
157
|
- lib/claude_hooks/output/subagent_stop.rb
|
|
158
|
+
- lib/claude_hooks/output/task_completed.rb
|
|
159
|
+
- lib/claude_hooks/output/task_created.rb
|
|
160
|
+
- lib/claude_hooks/output/teammate_idle.rb
|
|
161
|
+
- lib/claude_hooks/output/user_prompt_expansion.rb
|
|
110
162
|
- lib/claude_hooks/output/user_prompt_submit.rb
|
|
163
|
+
- lib/claude_hooks/output/worktree_create.rb
|
|
164
|
+
- lib/claude_hooks/output/worktree_remove.rb
|
|
165
|
+
- lib/claude_hooks/permission_denied.rb
|
|
111
166
|
- lib/claude_hooks/permission_request.rb
|
|
167
|
+
- lib/claude_hooks/post_compact.rb
|
|
168
|
+
- lib/claude_hooks/post_tool_batch.rb
|
|
112
169
|
- lib/claude_hooks/post_tool_use.rb
|
|
170
|
+
- lib/claude_hooks/post_tool_use_failure.rb
|
|
113
171
|
- lib/claude_hooks/pre_compact.rb
|
|
114
172
|
- lib/claude_hooks/pre_tool_use.rb
|
|
115
173
|
- lib/claude_hooks/session_end.rb
|
|
116
174
|
- lib/claude_hooks/session_start.rb
|
|
175
|
+
- lib/claude_hooks/setup.rb
|
|
117
176
|
- lib/claude_hooks/stop.rb
|
|
177
|
+
- lib/claude_hooks/stop_failure.rb
|
|
178
|
+
- lib/claude_hooks/subagent_start.rb
|
|
118
179
|
- lib/claude_hooks/subagent_stop.rb
|
|
180
|
+
- lib/claude_hooks/task_completed.rb
|
|
181
|
+
- lib/claude_hooks/task_created.rb
|
|
182
|
+
- lib/claude_hooks/teammate_idle.rb
|
|
183
|
+
- lib/claude_hooks/user_prompt_expansion.rb
|
|
119
184
|
- lib/claude_hooks/user_prompt_submit.rb
|
|
120
185
|
- lib/claude_hooks/version.rb
|
|
186
|
+
- lib/claude_hooks/worktree_create.rb
|
|
187
|
+
- lib/claude_hooks/worktree_remove.rb
|
|
121
188
|
homepage: https://github.com/gabriel-dehan/claude_hooks
|
|
122
189
|
licenses:
|
|
123
190
|
- MIT
|
|
@@ -1,25 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env ruby
|
|
2
|
-
# frozen_string_literal: true
|
|
3
|
-
|
|
4
|
-
require 'claude_hooks'
|
|
5
|
-
require_relative '../handlers/pre_tool_use/github_guard'
|
|
6
|
-
|
|
7
|
-
begin
|
|
8
|
-
# Read Claude Code input from stdin
|
|
9
|
-
input_data = JSON.parse($stdin.read)
|
|
10
|
-
|
|
11
|
-
github_guard = GithubGuard.new(input_data)
|
|
12
|
-
github_guard.call
|
|
13
|
-
|
|
14
|
-
github_guard.output_and_exit
|
|
15
|
-
rescue StandardError => e
|
|
16
|
-
puts JSON.generate(
|
|
17
|
-
{
|
|
18
|
-
continue: false,
|
|
19
|
-
stopReason: "Error in PreToolUse hook, #{e.message}, #{e.backtrace.join("\n")}",
|
|
20
|
-
suppressOutput: false,
|
|
21
|
-
},
|
|
22
|
-
)
|
|
23
|
-
# Allow anyway, to not block developers if there is an issue with the hook
|
|
24
|
-
exit 1
|
|
25
|
-
end
|