Class: Clacky::UI2::Components::CommandSuggestions

Inherits:
Object
  • Object
show all
Defined in:
lib/clacky/ui2/components/command_suggestions.rb

Overview

CommandSuggestions displays a dropdown menu of available commands Supports keyboard navigation and filtering

Constant Summary collapse

SYSTEM_COMMANDS =

System commands available by default

[
  { command: "/clear", description: "Clear chat history and restart session" },
  { command: "/config", description: "Open configuration (models, API keys, settings)" },
  { command: "/undo", description: "Undo the last task and restore previous state" },
  { command: "/help", description: "Show help information" },
  { command: "/exit", description: "Exit the chat session" },
  { command: "/quit", description: "Quit the application" }
].freeze

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initializeCommandSuggestions

Returns a new instance of CommandSuggestions.



24
25
26
27
28
29
30
31
32
33
34
35
# File 'lib/clacky/ui2/components/command_suggestions.rb', line 24

def initialize
  @pastel = Pastel.new
  @commands = []
  @filtered_commands = []
  @selected_index = 0
  @visible = false
  @filter_text = ""
  @skill_commands = []
  
  # Initialize with system commands
  update_commands
end

Instance Attribute Details

#selected_indexObject (readonly)

Returns the value of attribute selected_index.



12
13
14
# File 'lib/clacky/ui2/components/command_suggestions.rb', line 12

def selected_index
  @selected_index
end

#visibleObject (readonly)

Returns the value of attribute visible.



12
13
14
# File 'lib/clacky/ui2/components/command_suggestions.rb', line 12

def visible
  @visible
end

Instance Method Details

#clear_from_screen(row:, col:) ⇒ Object

Clear the rendered dropdown from screen

Parameters:

  • row (Integer)

    Starting row position

  • col (Integer)

    Starting column position



174
175
176
177
178
179
180
181
182
183
184
185
186
# File 'lib/clacky/ui2/components/command_suggestions.rb', line 174

def clear_from_screen(row:, col:)
  return unless @visible

  height = required_height
  output = []
  
  height.times do |i|
    output << position_cursor(row + i, col) + clear_line
  end
  
  print output.join
  flush
end

#has_suggestions?Boolean

Check if there are any suggestions to show

Returns:

  • (Boolean)


123
124
125
# File 'lib/clacky/ui2/components/command_suggestions.rb', line 123

def has_suggestions?
  @visible && !@filtered_commands.empty?
end

#hideObject

Hide the suggestions dropdown



73
74
75
76
77
78
# File 'lib/clacky/ui2/components/command_suggestions.rb', line 73

def hide
  @visible = false
  @filter_text = ""
  @filtered_commands = []
  @selected_index = 0
end

#load_skill_commands(skill_loader, agent_profile = nil) ⇒ Object

Load skill commands from skill loader, filtered by agent profile whitelist

Parameters:



45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
# File 'lib/clacky/ui2/components/command_suggestions.rb', line 45

def load_skill_commands(skill_loader, agent_profile = nil)
  return unless skill_loader

  skills = skill_loader.user_invocable_skills
  skills = skills.select { |s| s.allowed_for_agent?(agent_profile.name) } if agent_profile

  @skill_commands = skills.map do |skill|
    {
      command: skill.slash_command,
      description: skill.description || "No description available",
      type: :skill,
      argument_hint: skill.argument_hint
    }
  end

  update_commands
end

#render(row:, col:, width: 60) ⇒ String

Render the suggestions dropdown

Parameters:

  • row (Integer)

    Starting row position

  • col (Integer)

    Starting column position

  • width (Integer) (defaults to: 60)

    Maximum width for the dropdown

Returns:

  • (String)

    Rendered output



142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
# File 'lib/clacky/ui2/components/command_suggestions.rb', line 142

def render(row:, col:, width: 60)
  return "" unless @visible
  return "" if @filtered_commands.empty?

  output = []
  max_items = 5  # Maximum visible items
  visible_commands = @filtered_commands.take(max_items)

  # Header
  header = @pastel.dim("┌─ Commands ") + @pastel.dim("" * (width - 13)) + @pastel.dim("")
  output << position_cursor(row, col) + header

  # Items
  visible_commands.each_with_index do |cmd, idx|
    is_selected = (idx == @selected_index)
    line = render_command_item(cmd, is_selected, width)
    output << position_cursor(row + 1 + idx, col) + line
  end

  # Footer with navigation hint
  footer_row = row + 1 + visible_commands.size
  total = @filtered_commands.size
  hint = total > max_items ? " (#{total - max_items} more...)" : ""
  footer = @pastel.dim("") + @pastel.dim("" * (width - 2)) + @pastel.dim("")
  output << position_cursor(footer_row, col) + footer

  output.join
end

#required_heightInteger

Calculate required height for rendering

Returns:

  • (Integer)

    Number of lines needed



129
130
131
132
133
134
135
# File 'lib/clacky/ui2/components/command_suggestions.rb', line 129

def required_height
  return 0 unless @visible
  return 0 if @filtered_commands.empty?

  # Header + commands + footer
  1 + [@filtered_commands.size, 5].min + 1  # Max 5 visible items
end

#select_nextObject

Move selection down



95
96
97
98
# File 'lib/clacky/ui2/components/command_suggestions.rb', line 95

def select_next
  return if @filtered_commands.empty?
  @selected_index = (@selected_index + 1) % @filtered_commands.size
end

#select_previousObject

Move selection up



89
90
91
92
# File 'lib/clacky/ui2/components/command_suggestions.rb', line 89

def select_previous
  return if @filtered_commands.empty?
  @selected_index = (@selected_index - 1) % @filtered_commands.size
end

#selected_argument_hintString?

Get the argument hint for the currently selected command

Returns:

  • (String, nil)

    Argument hint string or nil if none



116
117
118
119
# File 'lib/clacky/ui2/components/command_suggestions.rb', line 116

def selected_argument_hint
  cmd = selected_command
  cmd ? cmd[:argument_hint] : nil
end

#selected_commandHash?

Get the currently selected command

Returns:

  • (Hash, nil)

    Selected command hash or nil if none selected



102
103
104
105
# File 'lib/clacky/ui2/components/command_suggestions.rb', line 102

def selected_command
  return nil if @filtered_commands.empty?
  @filtered_commands[@selected_index]
end

#selected_command_textString?

Get the currently selected command text

Returns:

  • (String, nil)

    Selected command text or nil if none selected



109
110
111
112
# File 'lib/clacky/ui2/components/command_suggestions.rb', line 109

def selected_command_text
  cmd = selected_command
  cmd ? cmd[:command] : nil
end

#show(filter_text = "") ⇒ Object

Show the suggestions dropdown

Parameters:

  • filter_text (String) (defaults to: "")

    Initial filter text (everything after the /)



65
66
67
68
69
70
# File 'lib/clacky/ui2/components/command_suggestions.rb', line 65

def show(filter_text = "")
  @filter_text = filter_text
  @visible = true
  update_filtered_commands
  @selected_index = 0
end

#themeObject

Get current theme from ThemeManager



38
39
40
# File 'lib/clacky/ui2/components/command_suggestions.rb', line 38

def theme
  UI2::ThemeManager.current_theme
end

#update_filter(text) ⇒ Object

Update filter text and refresh filtered commands

Parameters:

  • text (String)

    Filter text (everything after the /)



82
83
84
85
86
# File 'lib/clacky/ui2/components/command_suggestions.rb', line 82

def update_filter(text)
  @filter_text = text
  update_filtered_commands
  @selected_index = 0  # Reset selection when filter changes
end