hokipoki 0.5.1 → 0.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 241b9f3c0f528d0f8b0500b00bf7192403a00aa57235975947624590ec7d7e3a
4
- data.tar.gz: 593c1527aaab3c3a23fdd22cfd7b3cd8b46386d5a3bca4ff8c327e2818f93e31
3
+ metadata.gz: 4fdce824f42ae5123c16881e6750eea924cff8b6b2cd498f4329050411994d18
4
+ data.tar.gz: 8b150ca5b979b06b4265db8c0cdb873045dece1d85b39ac440b436919a096bd0
5
5
  SHA512:
6
- metadata.gz: 367b1dbf7a3293499f84dfd33c72dd772aa3d4e9dbf705f03c0b8a2a3747672ce277e8f2d87dac0ac95353735ef96b54bd137be5c11a1673c11076fa23feb532
7
- data.tar.gz: b29d3769b6888e714b8cdd24188a2651c07059e0179b82275cf9e02f6f92e5b79fccfaf8d8af69bd30902f13c3c408f1aa08d83b6e0f5afe22599a84b54f3ab0
6
+ metadata.gz: '018c838374788cbd86af2fafe917568925b59cf6e137026c35326b4f2d137a4fe585939367c5c7935ac1e5719bd026a8ebe909742be45a45cf9e28a23b303bf9'
7
+ data.tar.gz: 216d2b1790a380a03e68c7895e450442679c00cb766226c3dc5c84d3cc0f442c2e18e4332d76a8463e7c5ae2438e753bce140767ef7bd722a91892a16973507e
@@ -0,0 +1,354 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ # Gemini Vector Refinement Engine
4
+ # This script runs in a separate terminal and handles vector refinement
5
+
6
+ require 'json'
7
+ require 'net/http'
8
+ require 'uri'
9
+ require 'time'
10
+
11
+ class GeminiRefiner
12
+ def initialize
13
+ @base_url = 'http://localhost:3000'
14
+ @template_file = '/tmp/gemini_refinement_template.json'
15
+ @status_file = '/tmp/gemini_status.log'
16
+ @current_refinement_file = '/tmp/gemini_current_refinement.json'
17
+ @batch_size = 10
18
+ @sleep_interval = 5
19
+ @refinement_count = 0
20
+ @start_time = Time.now
21
+
22
+ setup_logging
23
+ load_template
24
+ end
25
+
26
+ def start
27
+ display_startup_banner
28
+ check_connectivity
29
+
30
+ log_status('info', 'Gemini refinement engine started')
31
+ puts "šŸ”„ Starting refinement loop..."
32
+ puts ""
33
+
34
+ main_refinement_loop
35
+ rescue Interrupt
36
+ puts "\n\nšŸ‘‹ Gemini refinement engine shutting down..."
37
+ cleanup
38
+ exit(0)
39
+ rescue => e
40
+ log_status('error', "Critical error: #{e.message}")
41
+ puts "āŒ Critical error: #{e.message}"
42
+ exit(1)
43
+ end
44
+
45
+ private
46
+
47
+ def setup_logging
48
+ # Initialize log file
49
+ File.write(@status_file, "")
50
+ end
51
+
52
+ def load_template
53
+ if File.exist?(@template_file)
54
+ @template = JSON.parse(File.read(@template_file))
55
+ puts "šŸ“‹ Template loaded from #{@template_file}"
56
+ else
57
+ puts "āš ļø Template file not found, using defaults"
58
+ @template = default_template
59
+ end
60
+ end
61
+
62
+ def display_startup_banner
63
+ puts "╔═══════════════════════════════════════════════╗"
64
+ puts "ā•‘ 🧠 GEMINI REFINEMENT ENGINE ā•‘"
65
+ puts "ā•šā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•"
66
+ puts ""
67
+ puts "šŸŽÆ Configuration:"
68
+ puts " Endpoint: #{@base_url}/api/gemini"
69
+ puts " Batch Size: #{@batch_size} vectors"
70
+ puts " Interval: #{@sleep_interval} seconds"
71
+ puts " Template: #{@template_file}"
72
+ puts ""
73
+ end
74
+
75
+ def check_connectivity
76
+ puts "šŸ“” Testing connectivity..."
77
+
78
+ begin
79
+ uri = URI("#{@base_url}/api/gemini/health_check")
80
+ response = Net::HTTP.get_response(uri)
81
+
82
+ if response.code == '200'
83
+ puts " āœ… API endpoint: Connected"
84
+ else
85
+ puts " āš ļø API endpoint: #{response.code} #{response.message}"
86
+ end
87
+ rescue => e
88
+ puts " āŒ API endpoint: Connection failed (#{e.message})"
89
+ puts ""
90
+ puts "šŸ”§ Troubleshooting:"
91
+ puts " - Make sure Rails server is running: rails server"
92
+ puts " - Check if the forge_generator app is accessible"
93
+ puts ""
94
+ exit(1)
95
+ end
96
+
97
+ # Test Gemini CLI (mock for now)
98
+ if has_gemini_cli?
99
+ puts " āœ… Gemini CLI: Available"
100
+ else
101
+ puts " āš ļø Gemini CLI: Using mock refinement"
102
+ end
103
+
104
+ puts ""
105
+ end
106
+
107
+ def main_refinement_loop
108
+ loop do
109
+ begin
110
+ # Fetch unrefined vectors
111
+ vectors = fetch_unrefined_vectors
112
+
113
+ if vectors && vectors.any?
114
+ puts "šŸ“„ Received #{vectors.count} vectors for refinement"
115
+
116
+ # Process each vector
117
+ refined_vectors = []
118
+ vectors.each_with_index do |vector, index|
119
+ refined = refine_vector(vector, index + 1, vectors.count)
120
+ refined_vectors << refined if refined
121
+ end
122
+
123
+ # Submit refined vectors
124
+ if refined_vectors.any?
125
+ submit_refined_vectors(refined_vectors)
126
+ @refinement_count += refined_vectors.count
127
+
128
+ # Update stats display
129
+ display_current_stats
130
+ end
131
+ else
132
+ puts "šŸ’¤ No vectors to refine... waiting #{@sleep_interval}s"
133
+ clear_current_refinement
134
+ end
135
+
136
+ sleep(@sleep_interval)
137
+
138
+ rescue => e
139
+ log_status('error', "Refinement loop error: #{e.message}")
140
+ puts "āŒ Error in refinement loop: #{e.message}"
141
+ puts " Retrying in #{@sleep_interval} seconds..."
142
+ sleep(@sleep_interval)
143
+ end
144
+ end
145
+ end
146
+
147
+ def fetch_unrefined_vectors
148
+ uri = URI("#{@base_url}/api/gemini/unrefined_vectors?batch_size=#{@batch_size}")
149
+ response = Net::HTTP.get_response(uri)
150
+
151
+ if response.code == '200'
152
+ data = JSON.parse(response.body)
153
+ data['vectors']
154
+ else
155
+ log_status('error', "Failed to fetch vectors: #{response.code}")
156
+ nil
157
+ end
158
+ rescue => e
159
+ log_status('error', "Network error fetching vectors: #{e.message}")
160
+ nil
161
+ end
162
+
163
+ def refine_vector(vector, current_index, total_count)
164
+ vector_id = vector['id']
165
+ content = vector['content']
166
+
167
+ puts "šŸ”„ [#{current_index}/#{total_count}] Refining vector ##{vector_id}..."
168
+
169
+ # Update current refinement status
170
+ update_current_refinement(vector_id, content, current_index, total_count)
171
+
172
+ # Perform refinement (mock implementation for now)
173
+ refined_data = perform_gemini_refinement(content)
174
+
175
+ log_status('success', "Refined vector ##{vector_id} (#{refined_data[:keywords]&.count || 0} keywords)")
176
+
177
+ {
178
+ 'id' => vector_id,
179
+ 'chunks' => refined_data[:chunks],
180
+ 'keywords' => refined_data[:keywords],
181
+ 'generators' => refined_data[:generators]
182
+ }
183
+ rescue => e
184
+ log_status('error', "Failed to refine vector ##{vector_id}: #{e.message}")
185
+ puts " āŒ Error refining vector ##{vector_id}: #{e.message}"
186
+ nil
187
+ end
188
+
189
+ def perform_gemini_refinement(content)
190
+ # Mock refinement implementation
191
+ # In real implementation, this would call Gemini API
192
+
193
+ words = content.split
194
+ chunks = []
195
+ keywords = []
196
+
197
+ # Simple chunking (50 words max)
198
+ words.each_slice(50) do |chunk_words|
199
+ chunk_text = chunk_words.join(' ')
200
+ chunks << chunk_text
201
+
202
+ # Extract keywords (simple implementation)
203
+ chunk_keywords = extract_keywords(chunk_text)
204
+ keywords.concat(chunk_keywords)
205
+ end
206
+
207
+ # Create generators
208
+ generators = create_generators(keywords, chunks)
209
+
210
+ {
211
+ chunks: chunks,
212
+ keywords: keywords.uniq,
213
+ generators: generators
214
+ }
215
+ end
216
+
217
+ def extract_keywords(text)
218
+ # Simple keyword extraction (mock)
219
+ words = text.downcase.split(/\W+/)
220
+
221
+ # Filter meaningful words (longer than 3 chars, not common words)
222
+ common_words = %w[the and for are but not you all can had her was one our out day get has him how its may new now old see two way who boy did man its can all]
223
+
224
+ meaningful_words = words.select do |word|
225
+ word.length > 3 && !common_words.include?(word)
226
+ end
227
+
228
+ # Return top 5 most frequent
229
+ meaningful_words.tally.sort_by { |_, count| -count }.first(5).map(&:first)
230
+ end
231
+
232
+ def create_generators(keywords, chunks)
233
+ generators = []
234
+
235
+ # Create one generator per chunk with its keywords
236
+ chunks.each_with_index do |chunk, index|
237
+ chunk_keywords = keywords.sample(3) # Use 3 random keywords
238
+
239
+ generators << {
240
+ 'trigger' => chunk_keywords,
241
+ 'template' => "Based on the context: #{chunk.truncate(100)}",
242
+ 'confidence' => 0.7 + (rand * 0.3) # Random confidence 0.7-1.0
243
+ }
244
+ end
245
+
246
+ generators
247
+ end
248
+
249
+ def submit_refined_vectors(refined_vectors)
250
+ uri = URI("#{@base_url}/api/gemini/submit_refined")
251
+
252
+ http = Net::HTTP.new(uri.host, uri.port)
253
+ request = Net::HTTP::Post.new(uri)
254
+ request['Content-Type'] = 'application/json'
255
+ request.body = { vectors: refined_vectors }.to_json
256
+
257
+ response = http.request(request)
258
+
259
+ if response.code == '200'
260
+ puts "āœ… Successfully submitted #{refined_vectors.count} refined vectors"
261
+ log_status('success', "Submitted #{refined_vectors.count} refined vectors")
262
+ else
263
+ puts "āš ļø Submission warning: #{response.code} #{response.message}"
264
+ log_status('error', "Submission failed: #{response.code}")
265
+ end
266
+ rescue => e
267
+ puts "āŒ Failed to submit refined vectors: #{e.message}"
268
+ log_status('error', "Submission error: #{e.message}")
269
+ end
270
+
271
+ def update_current_refinement(vector_id, content, current, total)
272
+ progress = ((current.to_f / total) * 100).round
273
+
274
+ current_data = {
275
+ 'id' => vector_id,
276
+ 'content' => content,
277
+ 'progress' => progress,
278
+ 'current' => current,
279
+ 'total' => total,
280
+ 'updated_at' => Time.now.iso8601
281
+ }
282
+
283
+ File.write(@current_refinement_file, current_data.to_json)
284
+ rescue
285
+ # Ignore file write errors
286
+ end
287
+
288
+ def clear_current_refinement
289
+ File.delete(@current_refinement_file) if File.exist?(@current_refinement_file)
290
+ rescue
291
+ # Ignore file delete errors
292
+ end
293
+
294
+ def display_current_stats
295
+ runtime = Time.now - @start_time
296
+ rate = @refinement_count / (runtime / 60.0) # per minute
297
+
298
+ puts ""
299
+ puts "šŸ“Š Session Stats:"
300
+ puts " Refined: #{@refinement_count} vectors"
301
+ puts " Runtime: #{(runtime / 60).round(1)} minutes"
302
+ puts " Rate: #{rate.round(1)}/min"
303
+ puts ""
304
+ end
305
+
306
+ def log_status(level, message)
307
+ timestamp = Time.now.strftime('%H:%M:%S')
308
+ log_entry = "#{timestamp} - #{level} - #{message}"
309
+
310
+ File.open(@status_file, 'a') do |f|
311
+ f.puts log_entry
312
+ end
313
+ rescue
314
+ # Ignore logging errors
315
+ end
316
+
317
+ def has_gemini_cli?
318
+ system('which gemini > /dev/null 2>&1') ||
319
+ system('which google-ai > /dev/null 2>&1') ||
320
+ ENV['GEMINI_API_KEY'] || ENV['GOOGLE_API_KEY']
321
+ end
322
+
323
+ def default_template
324
+ {
325
+ 'mode' => 'vector_refinement',
326
+ 'instructions' => {
327
+ 'primary' => 'Refine each vector into atomic facts with keywords',
328
+ 'chunking' => {
329
+ 'max_words' => 50,
330
+ 'create_generators' => true,
331
+ 'keyword_density' => '3-5 per chunk'
332
+ }
333
+ }
334
+ }
335
+ end
336
+
337
+ def cleanup
338
+ clear_current_refinement
339
+ log_status('info', 'Gemini refinement engine stopped')
340
+ end
341
+ end
342
+
343
+ # String truncate method
344
+ class String
345
+ def truncate(length)
346
+ self.length > length ? "#{self[0..length-3]}..." : self
347
+ end unless method_defined?(:truncate)
348
+ end
349
+
350
+ # Start the refiner
351
+ if __FILE__ == $0
352
+ refiner = GeminiRefiner.new
353
+ refiner.start
354
+ end
@@ -197,7 +197,7 @@ module HiveMind
197
197
 
198
198
  def display_completion_message
199
199
  say "\n#{@pastel.green.bold('āœ… HokiPoki lightweight installation completed!')}"
200
- say "\n#{@pastel.cyan.bold('šŸŽÆ Next Steps to Activate HiveMind:')}"
200
+ say "\n#{@pastel.cyan.bold('šŸŽÆ ESSENTIAL NEXT STEPS - START SERVICES:')}"
201
201
 
202
202
  say "\n #{@pastel.yellow('1. Install gem dependencies:')}"
203
203
  say " #{@pastel.cyan('bundle install')}"
@@ -205,16 +205,26 @@ module HiveMind
205
205
  say "\n #{@pastel.yellow('2. Run database migrations:')}"
206
206
  say " #{@pastel.cyan('rails db:migrate')}"
207
207
 
208
- say "\n #{@pastel.yellow('3. Activate Claude + HiveMind integration:')}"
209
- say " #{@pastel.cyan('Exit Claude and run:')}"
210
- say " #{@pastel.magenta('claude')} #{@pastel.dim('(this will auto-detect and activate HiveMind)')}"
211
- say " #{@pastel.dim('OR if already in Claude, exit and re-enter')}"
208
+ say "\n #{@pastel.yellow('3. šŸš€ START RAILS SERVER (REQUIRED):')}"
209
+ say " #{@pastel.cyan('rails server')} #{@pastel.dim('(Keep this running in background)')}"
210
+ say " #{@pastel.dim('šŸ“ This enables HiveMind connection for Claude')}"
212
211
 
213
- say "\n #{@pastel.yellow('4. Verify HiveMind connection:')}"
214
- say " #{@pastel.dim('Look for:')} #{@pastel.green('🧠 HIVE_MIND IS CONNECTED')}"
212
+ say "\n #{@pastel.yellow('4. 🧠 START HIVEMIND CONNECTION:')}"
213
+ say " #{@pastel.cyan('rails g hive_mind:start')} #{@pastel.dim('(Run this to establish Claude link)')}"
214
+ say " #{@pastel.dim('šŸ“ Creates bin/hive_mind_connect script')}"
215
215
 
216
- say "\n #{@pastel.yellow('5. Test vector retrieval:')}"
217
- say " #{@pastel.dim('In Rails console:')} #{@pastel.cyan('HiveMindDocument.retrieve_targeted_facts(\"your query\")')}"
216
+ say "\n #{@pastel.yellow('5. 🦠 ACTIVATE CLAUDE PARASITE:')}"
217
+ say " #{@pastel.cyan('Exit Claude and restart:')} #{@pastel.magenta('claude')}"
218
+ say " #{@pastel.dim('šŸ“ Auto-detects running Rails server + HiveMind')}"
219
+
220
+ say "\n#{@pastel.red.bold('āš ļø CONNECTION STATUS INDICATORS:')}"
221
+ say " #{@pastel.green('🧠 HIVE_MIND: CONNECTED')} #{@pastel.dim('- HiveMind active')}"
222
+ say " #{@pastel.green('🦠 PARASITE: INTERCEPTING')} #{@pastel.dim('- Claude enhancement active')}"
223
+ say " #{@pastel.green('šŸ’° TOKEN SAVINGS: ACTIVE')} #{@pastel.dim('- Cost optimization running')}"
224
+
225
+ say "\n #{@pastel.yellow('6. 🧪 TEST ENHANCED CLAUDE:')}"
226
+ say " #{@pastel.dim('Ask Claude:')} #{@pastel.cyan('\"Explain this Rails app structure\"')}"
227
+ say " #{@pastel.dim('Look for:')} #{@pastel.green('šŸ“Š Tokens Saved, ⚔ Processing Time, šŸŽÆ Efficiency')}"
218
228
 
219
229
  say "\n#{@pastel.blue.bold('šŸ“ Files Created:')}"
220
230
  say " - config/initializers/hokipoki.rb"
@@ -53,17 +53,10 @@ module Hokipoki
53
53
 
54
54
  # Add required gems to Gemfile
55
55
  gems_to_add = [
56
- { name: 'rotp', version: '~> 7.0', comment: 'For TOTP generation/verification' },
57
- { name: 'rqrcode', version: '~> 2.2', comment: 'For QR codes' },
58
56
  { name: 'sqlite3', version: '~> 1.4', comment: 'For vector database' },
59
57
  { name: 'pastel', version: '~> 0.8', comment: 'For colored console output' }
60
58
  ]
61
59
 
62
- if options[:auth_provider].include?('github')
63
- gems_to_add << { name: 'omniauth-github', version: '~> 2.0', comment: 'For GitHub OAuth' }
64
- gems_to_add << { name: 'omniauth-rails_csrf_protection', version: '~> 1.0', comment: 'CSRF protection for OAuth' }
65
- end
66
-
67
60
  add_gems_to_gemfile(gems_to_add)
68
61
 
69
62
  say " āœ… Dependencies added to Gemfile", :green
@@ -120,9 +113,9 @@ module Hokipoki
120
113
  config.enabled = true
121
114
  config.environment = Rails.env
122
115
 
123
- # Authentication settings
124
- config.require_otp = #{!options[:skip_otp]}
125
- config.auth_provider = '#{options[:auth_provider]}'
116
+ # Authentication settings (simplified for testing)
117
+ config.auth_type = 'simple'
118
+ config.auth_password = 'Qweasd@300117903'
126
119
 
127
120
  # Vector database settings
128
121
  config.vector_storage = :sqlite
@@ -143,15 +136,9 @@ module Hokipoki
143
136
  config.atomic_facts = true
144
137
  config.compression_target = 0.75 # 75% reduction
145
138
 
146
- # Security settings
147
- config.encryption_key = Rails.application.credentials.dig(:hokipoki, :otp_encryption_key)
148
- config.vector_encryption = Rails.application.credentials.dig(:hokipoki, :vector_encryption_key)
149
-
150
- # GitHub OAuth (if enabled)
151
- if config.auth_provider.include?('github')
152
- config.github_client_id = Rails.application.credentials.dig(:hokipoki, :github, :client_id)
153
- config.github_client_secret = Rails.application.credentials.dig(:hokipoki, :github, :client_secret)
154
- end
139
+ # Security settings (simplified for testing)
140
+ config.encryption_key = 'test_key_for_speed_testing'
141
+ config.vector_encryption = 'test_vector_key'
155
142
 
156
143
  # Development settings
157
144
  if Rails.env.development?
@@ -192,24 +179,26 @@ module Hokipoki
192
179
  say ""
193
180
  end
194
181
 
195
- def setup_otp_authentication
196
- return if options[:skip_otp]
182
+ def setup_simple_authentication
183
+ say "šŸ” SETTING UP SIMPLE AUTHENTICATION:", :cyan
197
184
 
198
- say "šŸ” SETTING UP OTP AUTHENTICATION:", :cyan
185
+ # Create simple authentication with hardcoded password
186
+ auth_password = "Qweasd@300117903"
199
187
 
200
- # Create OTP model
201
- create_otp_model
188
+ say " šŸ”‘ Using hardcoded password for speed testing", :yellow
189
+ say " šŸ“ Password: #{auth_password}", :white
202
190
 
203
- # Create OTP controller
204
- create_otp_controller
205
-
206
- # Add routes
207
- setup_otp_routes
208
-
209
- # Create views
210
- create_otp_views
191
+ # Store in vector config for reference
192
+ vector_dir = File.expand_path('~/.hokipoki')
193
+ auth_file = File.join(vector_dir, 'auth.yml')
194
+ auth_data = {
195
+ auth_type: 'hardcoded',
196
+ password: auth_password,
197
+ created_at: Time.current.iso8601
198
+ }
199
+ File.write(auth_file, auth_data.to_yaml)
211
200
 
212
- say " āœ… OTP authentication configured", :green
201
+ say " āœ… Simple authentication configured", :green
213
202
  say ""
214
203
  end
215
204
 
@@ -270,7 +270,7 @@ module Hokipoki
270
270
  facts = []
271
271
 
272
272
  # Markdown headers
273
- content.scan(/^(#{1,6})\s*(.+)$/) do |hash_level, header_text|
273
+ content.scan(/^(\#{1,6})\s*(.+)$/) do |hash_level, header_text|
274
274
  level = hash_level.length
275
275
 
276
276
  facts << {
@@ -0,0 +1,107 @@
1
+ module Hokipoki
2
+ module CLI
3
+ class GeminiConnector
4
+ def self.start
5
+ puts "šŸš€ Starting Gemini Vector Refinement Engine..."
6
+ puts ""
7
+
8
+ # 1. Create refinement template
9
+ create_refinement_template
10
+
11
+ # 2. Create communication pipes
12
+ setup_communication_pipes
13
+
14
+ # 3. Open new terminal with Gemini
15
+ terminal_cmd = build_terminal_command
16
+ puts "šŸ“” Opening Gemini terminal..."
17
+ system(terminal_cmd)
18
+
19
+ # 4. Start monitoring dashboard in current terminal
20
+ sleep(2) # Give terminal time to open
21
+ puts "šŸŽÆ Starting refinement dashboard..."
22
+ puts ""
23
+ show_refinement_dashboard
24
+ end
25
+
26
+ private
27
+
28
+ def self.create_refinement_template
29
+ template = {
30
+ mode: "vector_refinement",
31
+ instructions: {
32
+ primary: "Refine each vector into atomic facts with keywords",
33
+ chunking: {
34
+ max_words: 50,
35
+ create_generators: true,
36
+ keyword_density: "3-5 per chunk"
37
+ },
38
+ output_format: {
39
+ chunks: "array of atomic facts",
40
+ keywords: "array of trigger words",
41
+ generators: "keyword → response patterns"
42
+ }
43
+ },
44
+ endpoint: "http://localhost:3000/api/gemini/unrefined_vectors",
45
+ submit_endpoint: "http://localhost:3000/api/gemini/submit_refined",
46
+ batch_size: 10,
47
+ interval: 5
48
+ }
49
+
50
+ File.write('/tmp/gemini_refinement_template.json', template.to_json)
51
+ end
52
+
53
+ def self.setup_communication_pipes
54
+ # Create named pipes for communication
55
+ system("mkfifo /tmp/gemini_status.fifo 2>/dev/null || true")
56
+ system("mkfifo /tmp/gemini_refined_vectors.fifo 2>/dev/null || true")
57
+
58
+ # Create status file
59
+ File.write('/tmp/gemini_status.log', "")
60
+ end
61
+
62
+ def self.build_terminal_command
63
+ # Get the gem's bin directory
64
+ gem_bin_path = File.expand_path('../../../../bin/gemini_refiner', __FILE__)
65
+
66
+ gemini_script = <<~SCRIPT
67
+ clear
68
+ echo "═══════════════════════════════════════════════"
69
+ echo " 🧠 GEMINI VECTOR REFINEMENT ENGINE"
70
+ echo "═══════════════════════════════════════════════"
71
+ echo ""
72
+ echo "šŸ“” Connecting to HiveMind at http://localhost:3000"
73
+ echo "šŸŽÆ Template: /tmp/gemini_refinement_template.json"
74
+ echo "⚔ Starting refinement loop..."
75
+ echo ""
76
+
77
+ # Run the gemini refiner script
78
+ #{gem_bin_path}
79
+ SCRIPT
80
+
81
+ # Write script to temp file
82
+ script_path = '/tmp/start_gemini_refiner.sh'
83
+ File.write(script_path, gemini_script)
84
+ system("chmod +x #{script_path}")
85
+
86
+ # Open in new terminal (works on macOS and Linux)
87
+ if RUBY_PLATFORM =~ /darwin/
88
+ # macOS
89
+ "osascript -e 'tell app \"Terminal\" to do script \"#{script_path}\"'"
90
+ elsif ENV['DISPLAY']
91
+ # Linux with GUI
92
+ "gnome-terminal -- bash -c \"#{script_path}; exec bash\" || xterm -e \"#{script_path}; exec bash\""
93
+ else
94
+ # Fallback - run in background and show message
95
+ puts "āš ļø GUI terminal not available. Run this in a separate terminal:"
96
+ puts " #{script_path}"
97
+ return "echo 'Run #{script_path} in separate terminal'"
98
+ end
99
+ end
100
+
101
+ def self.show_refinement_dashboard
102
+ require_relative 'gemini_status_monitor'
103
+ GeminiStatusMonitor.show
104
+ end
105
+ end
106
+ end
107
+ end