Class: RubynCode::Hooks::Registry

Inherits:
Object
  • Object
show all
Includes:
MonitorMixin
Defined in:
lib/rubyn_code/hooks/registry.rb

Overview

Thread-safe registry for hook callables keyed by event type.

Hooks can be registered as blocks or any object responding to #call. Each hook is stored with an optional priority (lower runs first).

Defined Under Namespace

Classes: Hook

Constant Summary collapse

VALID_EVENTS =
%i[
  pre_tool_use
  post_tool_use
  pre_llm_call
  post_llm_call
  on_stall
  on_error
  on_session_end
  session_start
  user_prompt_submit
  permission_request
  stop
].freeze

Instance Method Summary collapse

Constructor Details

#initializeRegistry

Returns a new instance of Registry.



30
31
32
33
34
# File 'lib/rubyn_code/hooks/registry.rb', line 30

def initialize
  super # MonitorMixin
  @hooks = {}
  VALID_EVENTS.each { |event| @hooks[event] = [] }
end

Instance Method Details

#clear!(event = nil) ⇒ void

This method returns an undefined value.

Clears hooks for a specific event, or all hooks if no event is given.

Parameters:

  • event (Symbol, nil) (defaults to: nil)


73
74
75
76
77
78
79
80
81
82
# File 'lib/rubyn_code/hooks/registry.rb', line 73

def clear!(event = nil)
  synchronize do
    if event
      event = event.to_sym
      @hooks[event] = [] if @hooks.key?(event)
    else
      @hooks.each_key { |e| @hooks[e] = [] }
    end
  end
end

#hooks_for(event) ⇒ Array<#call>

Returns an array of callables registered for the given event, ordered by priority (lowest first).

Parameters:

  • event (Symbol)

Returns:

  • (Array<#call>)


62
63
64
65
66
67
# File 'lib/rubyn_code/hooks/registry.rb', line 62

def hooks_for(event)
  event = event.to_sym
  synchronize do
    (@hooks[event] || []).map(&:callable)
  end
end

#on(event, callable = nil, priority: 100) { ... } ⇒ void

This method returns an undefined value.

Registers a hook for the given event.

Parameters:

  • event (Symbol)

    one of VALID_EVENTS

  • callable (#call, nil) (defaults to: nil)

    an object responding to #call, or nil if a block is given

  • priority (Integer) (defaults to: 100)

    execution order (lower runs first, default 100)

Yields:

  • the hook block (used when callable is nil)

Raises:

  • (ArgumentError)


43
44
45
46
47
48
49
50
51
52
53
54
55
# File 'lib/rubyn_code/hooks/registry.rb', line 43

def on(event, callable = nil, priority: 100, &block)
  event = event.to_sym
  validate_event!(event)

  handler = callable || block
  raise ArgumentError, 'A callable or block is required' unless handler
  raise ArgumentError, 'Hook must respond to #call' unless handler.respond_to?(:call)

  synchronize do
    @hooks[event] << Hook.new(callable: handler, priority: priority)
    @hooks[event].sort_by!(&:priority)
  end
end

#registered_eventsArray<Symbol>

Returns a list of event types that have at least one hook registered.

Returns:

  • (Array<Symbol>)


87
88
89
90
91
# File 'lib/rubyn_code/hooks/registry.rb', line 87

def registered_events
  synchronize do
    @hooks.select { |_, hooks| hooks.any? }.keys
  end
end