Class: RubynCode::Skills::AutoSuggest

Inherits:
Object
  • Object
show all
Defined in:
lib/rubyn_code/skills/auto_suggest.rb

Overview

Suggests skill packs based on gems detected in the project’s Gemfile.

On session start, parses the Gemfile, queries the registry for matching packs, and shows a one-time suggestion. Tracks shown suggestions in ‘.rubyn-code/suggested.json` to avoid repeating.

The registry lookup runs in a background thread (see #start) and responses are cached in ‘.rubyn-code/suggestions_cache.json` keyed by the Gemfile’s gem list, so session start never blocks on the network.

Constant Summary collapse

SUGGESTED_FILE =
'suggested.json'
CACHE_FILE =
'suggestions_cache.json'
CACHE_TTL =

24 hours

86_400
FETCH_TIMEOUT =
3

Instance Method Summary collapse

Constructor Details

#initialize(project_root:, registry_client: nil) ⇒ AutoSuggest

Returns a new instance of AutoSuggest.

Parameters:

  • project_root (String)
  • registry_client (RegistryClient) (defaults to: nil)


26
27
28
29
30
# File 'lib/rubyn_code/skills/auto_suggest.rb', line 26

def initialize(project_root:, registry_client: nil)
  @project_root = project_root
  @client = registry_client || RegistryClient.new(timeout: FETCH_TIMEOUT)
  @thread = nil
end

Instance Method Details

#checkString?

Check for suggestable packs and return a display message if any. Returns nil if no suggestions or if all have been shown/dismissed.

This method never raises — registry failures are silently swallowed to avoid blocking session start.

Returns:

  • (String, nil)

    suggestion message or nil



60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
# File 'lib/rubyn_code/skills/auto_suggest.rb', line 60

def check
  gems = parse_gemfile
  return nil if gems.empty?

  suggestions = fetch_suggestions(gems)
  return nil if suggestions.empty?

  new_suggestions = filter_shown(suggestions)
  return nil if new_suggestions.empty?

  record_shown(new_suggestions)
  format_message(new_suggestions)
rescue StandardError
  nil
end

#mark_dismissed(name) ⇒ Object

Mark a suggestion as dismissed.

Parameters:

  • name (String)

    pack name



89
90
91
92
93
94
# File 'lib/rubyn_code/skills/auto_suggest.rb', line 89

def mark_dismissed(name)
  state = load_state
  state['dismissed'] ||= []
  state['dismissed'] << name unless state['dismissed'].include?(name)
  save_state(state)
end

#mark_installed(name) ⇒ Object

Mark a pack as installed so it won’t be suggested again.

Parameters:

  • name (String)

    pack name



79
80
81
82
83
84
# File 'lib/rubyn_code/skills/auto_suggest.rb', line 79

def mark_installed(name)
  state = load_state
  state['installed'] ||= []
  state['installed'] << name unless state['installed'].include?(name)
  save_state(state)
end

#pending_messageString?

Non-blocking: returns the suggestion message once the background check has finished, nil while it’s still running or after the message has already been consumed.

Returns:

  • (String, nil)


44
45
46
47
48
49
50
51
# File 'lib/rubyn_code/skills/auto_suggest.rb', line 44

def pending_message
  return nil unless @thread
  return nil if @thread.alive?

  message = @message
  @message = nil
  message
end

#startObject

Kicks off the suggestion check in a background thread. Call ‘pending_message` later to collect the result without blocking.



34
35
36
37
# File 'lib/rubyn_code/skills/auto_suggest.rb', line 34

def start
  @thread = Thread.new { @message = check }
  @thread.abort_on_exception = false
end