Class: ClaudeHooks::Output::PreToolUse
- Inherits:
-
Base
- Object
- Base
- ClaudeHooks::Output::PreToolUse
show all
- Defined in:
- lib/claude_hooks/output/pre_tool_use.rb
Instance Attribute Summary
Attributes inherited from Base
#data
Class Method Summary
collapse
Instance Method Summary
collapse
Methods inherited from Base
#continue?, for_hook_type, #hook_specific_output, #initialize, #output_and_exit, #stop_reason, #suppress_output?, #system_message, #terminal_sequence, #to_json
Class Method Details
.merge(*outputs) ⇒ Object
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
|
# File 'lib/claude_hooks/output/pre_tool_use.rb', line 65
def self.merge(*outputs)
compacted_outputs = outputs.compact
return compacted_outputs.first if compacted_outputs.length == 1
return super(*outputs) if compacted_outputs.empty?
merged = super(*outputs)
merged_data = merged.data
permission_decision = 'allow'
permission_reasons = []
compacted_outputs.each do |output|
output_data = output.respond_to?(:data) ? output.data : output
next unless output_data.dig('hookSpecificOutput', 'permissionDecision')
current_decision = output_data['hookSpecificOutput']['permissionDecision']
case current_decision
when 'deny'
permission_decision = 'deny'
when 'defer'
permission_decision = 'defer' unless permission_decision == 'deny'
when 'ask'
permission_decision = 'ask' unless %w[deny defer].include?(permission_decision)
end
reason = output_data.dig('hookSpecificOutput', 'permissionDecisionReason')
permission_reasons << reason if reason && !reason.empty?
end
merged_data['hookSpecificOutput'] ||= { 'hookEventName' => 'PreToolUse' }
merged_data['hookSpecificOutput']['permissionDecision'] = permission_decision
merged_data['hookSpecificOutput']['permissionDecisionReason'] = if permission_reasons.any?
permission_reasons.join('; ')
else
''
end
updated_inputs = []
compacted_outputs.each do |output|
output_data = output.respond_to?(:data) ? output.data : output
updated = output_data.dig('hookSpecificOutput', 'updatedInput')
updated_inputs << updated if updated
end
merged_data['hookSpecificOutput']['updatedInput'] = updated_inputs.last if updated_inputs.any?
new(merged_data)
end
|
Instance Method Details
#allowed? ⇒ Boolean
24
25
26
|
# File 'lib/claude_hooks/output/pre_tool_use.rb', line 24
def allowed?
permission_decision == 'allow'
end
|
#deferred? ⇒ Boolean
41
42
43
|
# File 'lib/claude_hooks/output/pre_tool_use.rb', line 41
def deferred?
permission_decision == 'defer'
end
|
#denied? ⇒ Boolean
Also known as:
blocked?
28
29
30
|
# File 'lib/claude_hooks/output/pre_tool_use.rb', line 28
def denied?
permission_decision == 'deny'
end
|
#exit_code ⇒ Object
EXIT CODE LOGIC ===
PreToolUse hooks use the advanced JSON API with exit code 0.
Per Anthropic guidance: when using structured JSON with permissionDecision,
always output to stdout with exit 0 (not stderr with exit 2).
The permissionDecision field ('allow', 'deny', 'ask') controls behavior.
Reference: https://github.com/anthropics/claude-code/issues/10875
52
53
54
|
# File 'lib/claude_hooks/output/pre_tool_use.rb', line 52
def exit_code
0
end
|
37
38
39
|
# File 'lib/claude_hooks/output/pre_tool_use.rb', line 37
def input_updated?
!updated_input.nil?
end
|
#output_stream ⇒ Object
OUTPUT STREAM LOGIC ===
PreToolUse hooks always output to stdout when using the JSON API.
59
60
61
|
# File 'lib/claude_hooks/output/pre_tool_use.rb', line 59
def output_stream
:stdout
end
|
#permission_decision ⇒ Object
PERMISSION DECISION ACCESSORS ===
10
11
12
|
# File 'lib/claude_hooks/output/pre_tool_use.rb', line 10
def permission_decision
hook_specific_output['permissionDecision']
end
|
#permission_reason ⇒ Object
14
15
16
|
# File 'lib/claude_hooks/output/pre_tool_use.rb', line 14
def permission_reason
hook_specific_output['permissionDecisionReason'] || ''
end
|
#should_ask_permission? ⇒ Boolean
33
34
35
|
# File 'lib/claude_hooks/output/pre_tool_use.rb', line 33
def should_ask_permission?
permission_decision == 'ask'
end
|
18
19
20
|
# File 'lib/claude_hooks/output/pre_tool_use.rb', line 18
def updated_input
hook_specific_output['updatedInput']
end
|