Class: RubyAiGemContext::Interactive
- Inherits:
-
Object
- Object
- RubyAiGemContext::Interactive
- Defined in:
- lib/ruby_ai_gem_context/interactive.rb
Overview
Interactive terminal UI for rake tasks
Instance Attribute Summary collapse
-
#project_root ⇒ Object
readonly
Returns the value of attribute project_root.
-
#prompt ⇒ Object
readonly
Returns the value of attribute prompt.
Instance Method Summary collapse
-
#ask_folder_list ⇒ Object
Ask for specific folder list.
-
#ask_gem_name ⇒ Object
Ask for gem name.
-
#confirm_source_folders(folders, summary) ⇒ Object
Confirm source folders and show what will be scanned.
- #error(message) ⇒ Object
-
#handle_collision(platform_class) ⇒ Object
Handle collision when file exists.
- #header(message) ⇒ Object
- #info(message) ⇒ Object
-
#initialize(project_root = Dir.pwd) ⇒ Interactive
constructor
A new instance of Interactive.
- #review_reminder ⇒ Object
-
#select_platforms ⇒ Object
Ask which platforms to generate boilerplate for.
-
#select_platforms_to_regenerate(existing_platforms) ⇒ Object
Select which existing platforms to regenerate.
-
#select_source_folders ⇒ Object
Ask about source folders.
-
#show_diff(existing, new_content) ⇒ Object
Show diff between existing and new content.
-
#success(message) ⇒ Object
Output Helpers ===.
- #warning(message) ⇒ Object
-
#with_spinner(message) ⇒ Object
Show spinner while doing work.
Constructor Details
#initialize(project_root = Dir.pwd) ⇒ Interactive
Returns a new instance of Interactive.
11 12 13 14 |
# File 'lib/ruby_ai_gem_context/interactive.rb', line 11 def initialize(project_root = Dir.pwd) @prompt = TTY::Prompt.new @project_root = project_root end |
Instance Attribute Details
#project_root ⇒ Object (readonly)
Returns the value of attribute project_root.
9 10 11 |
# File 'lib/ruby_ai_gem_context/interactive.rb', line 9 def project_root @project_root end |
#prompt ⇒ Object (readonly)
Returns the value of attribute prompt.
9 10 11 |
# File 'lib/ruby_ai_gem_context/interactive.rb', line 9 def prompt @prompt end |
Instance Method Details
#ask_folder_list ⇒ Object
Ask for specific folder list
83 84 85 86 87 88 89 90 |
# File 'lib/ruby_ai_gem_context/interactive.rb', line 83 def ask_folder_list input = prompt.ask( "Enter folder paths (comma-separated, relative to project root):", default: "lib, app" ) input.split(",").map(&:strip).reject(&:empty?) end |
#ask_gem_name ⇒ Object
Ask for gem name
119 120 121 122 123 124 |
# File 'lib/ruby_ai_gem_context/interactive.rb', line 119 def ask_gem_name prompt.ask("Enter the gem name:") do |q| q.required true q.validate(/\A[\w-]+\z/, "Invalid gem name format") end end |
#confirm_source_folders(folders, summary) ⇒ Object
Confirm source folders and show what will be scanned
93 94 95 96 97 98 99 100 |
# File 'lib/ruby_ai_gem_context/interactive.rb', line 93 def confirm_source_folders(folders, summary) puts puts "Will scan #{summary[:total_files]} files (#{format_size(summary[:total_size])})" puts "File types: #{summary[:by_extension].map { |ext, count| "#{ext || 'no ext'}: #{count}" }.join(', ')}" puts prompt.yes?("Proceed with generation?") end |
#error(message) ⇒ Object
150 151 152 |
# File 'lib/ruby_ai_gem_context/interactive.rb', line 150 def error() puts prompt.decorate("✗ #{message}", :red) end |
#handle_collision(platform_class) ⇒ Object
Handle collision when file exists
33 34 35 36 37 38 39 40 41 42 43 |
# File 'lib/ruby_ai_gem_context/interactive.rb', line 33 def handle_collision(platform_class) prompt.select( "#{platform_class.filename} already exists. What would you like to do?", [ { name: "Skip (keep existing)", value: :skip }, { name: "Backup & overwrite (saves #{platform_class.filename}.backup)", value: :backup }, { name: "Show diff (compare before deciding)", value: :diff }, { name: "Overwrite (replace existing)", value: :overwrite } ] ) end |
#header(message) ⇒ Object
158 159 160 161 162 163 164 |
# File 'lib/ruby_ai_gem_context/interactive.rb', line 158 def header() puts puts prompt.decorate("═" * 50, :blue) puts prompt.decorate(" #{message}", :blue, :bold) puts prompt.decorate("═" * 50, :blue) puts end |
#info(message) ⇒ Object
154 155 156 |
# File 'lib/ruby_ai_gem_context/interactive.rb', line 154 def info() puts prompt.decorate("ℹ #{message}", :cyan) end |
#review_reminder ⇒ Object
166 167 168 169 170 171 172 173 174 175 176 177 178 |
# File 'lib/ruby_ai_gem_context/interactive.rb', line 166 def review_reminder puts warning "IMPORTANT: Review the generated files carefully!" puts " AI-generated context is a first draft. The quality of your future" puts " AI interactions depends on the accuracy of these files." puts puts " Suggested review steps:" puts " 1. Read through each generated file" puts " 2. Fix any inaccuracies or missing information" puts " 3. Add project-specific details the AI might have missed" puts " 4. Remove any incorrect assumptions" puts end |
#select_platforms ⇒ Object
Ask which platforms to generate boilerplate for
19 20 21 22 23 24 25 26 27 28 29 30 |
# File 'lib/ruby_ai_gem_context/interactive.rb', line 19 def select_platforms choices = RubyAiGemContext::PLATFORMS.map do |key, platform_class| { name: "#{platform_class.name} (#{platform_class.filename})", value: key } end prompt.multi_select( "Which platforms do you want to generate context files for?", choices, help: "(Use space to select, enter to confirm)", min: 1 ) end |
#select_platforms_to_regenerate(existing_platforms) ⇒ Object
Select which existing platforms to regenerate
103 104 105 106 107 108 109 110 111 112 113 114 |
# File 'lib/ruby_ai_gem_context/interactive.rb', line 103 def select_platforms_to_regenerate(existing_platforms) choices = existing_platforms.map do |key| platform_class = RubyAiGemContext.platform(key) { name: "#{platform_class.name} (#{platform_class.filename})", value: key } end prompt.multi_select( "Which context files do you want to regenerate?", choices, help: "(Use space to select, enter to confirm)" ) end |
#select_source_folders ⇒ Object
Ask about source folders
65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 |
# File 'lib/ruby_ai_gem_context/interactive.rb', line 65 def select_source_folders choice = prompt.select( "Where should we read source files from?", [ { name: "Project root (scan everything)", value: :root }, { name: "Specific folders (you'll provide a list)", value: :specific } ] ) case choice when :root nil # nil means scan from root when :specific ask_folder_list end end |
#show_diff(existing, new_content) ⇒ Object
Show diff between existing and new content
46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 |
# File 'lib/ruby_ai_gem_context/interactive.rb', line 46 def show_diff(existing, new_content) puts "\n--- Existing content ---" puts existing.lines.first(20).join puts "..." if existing.lines.size > 20 puts "\n--- New content ---" puts new_content.lines.first(20).join puts "..." if new_content.lines.size > 20 puts prompt.select("What would you like to do?", [ { name: "Keep existing", value: :skip }, { name: "Use new content", value: :overwrite }, { name: "Backup & use new", value: :backup } ]) end |
#success(message) ⇒ Object
Output Helpers ===
142 143 144 |
# File 'lib/ruby_ai_gem_context/interactive.rb', line 142 def success() puts prompt.decorate("✓ #{message}", :green) end |
#warning(message) ⇒ Object
146 147 148 |
# File 'lib/ruby_ai_gem_context/interactive.rb', line 146 def warning() puts prompt.decorate("⚠ #{message}", :yellow) end |
#with_spinner(message) ⇒ Object
Show spinner while doing work
129 130 131 132 133 134 135 136 137 138 |
# File 'lib/ruby_ai_gem_context/interactive.rb', line 129 def with_spinner() spinner = TTY::Spinner.new("[:spinner] #{message}", format: :dots) spinner.auto_spin result = yield spinner.success("Done!") result rescue StandardError => e spinner.error("Failed!") raise e end |