llama_bot_rails 0.1.11 → 0.1.14

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.
Files changed (46) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +17 -0
  3. data/app/channels/llama_bot_rails/chat_channel.rb +75 -73
  4. data/app/controllers/llama_bot_rails/agent_controller.rb +36 -32
  5. data/app/views/llama_bot_rails/agent/chat.html.erb +2 -1
  6. data/app/views/llama_bot_rails/agent/chat_ws.html.erb +11 -2
  7. data/bin/bundle +29 -0
  8. data/bin/bundle.lock +0 -0
  9. data/bin/bundler +29 -0
  10. data/bin/bundler.lock +0 -0
  11. data/bin/byebug +29 -0
  12. data/bin/coderay +29 -0
  13. data/bin/erb +29 -0
  14. data/bin/faker +29 -0
  15. data/bin/htmldiff +29 -0
  16. data/bin/irb +29 -0
  17. data/bin/ldiff +29 -0
  18. data/bin/nokogiri +29 -0
  19. data/bin/pry +29 -0
  20. data/bin/puma +29 -0
  21. data/bin/pumactl +29 -0
  22. data/bin/racc +29 -0
  23. data/bin/rackup +29 -0
  24. data/bin/rake +29 -0
  25. data/bin/rdoc +29 -0
  26. data/bin/ri +29 -0
  27. data/bin/rspec +29 -0
  28. data/bin/ruby-parse +29 -0
  29. data/bin/ruby-rewrite +29 -0
  30. data/bin/sprockets +29 -0
  31. data/bin/thor +29 -0
  32. data/lib/generators/llama_bot_rails/install/install_generator.rb +68 -0
  33. data/lib/generators/llama_bot_rails/install/templates/agent_state_builder.rb.erb +3 -3
  34. data/lib/llama_bot_rails/agent_auth.rb +158 -0
  35. data/lib/llama_bot_rails/agent_auth_2.rb +149 -0
  36. data/lib/llama_bot_rails/agent_state_builder.rb +6 -6
  37. data/lib/llama_bot_rails/controller_extensions.rb +40 -0
  38. data/lib/llama_bot_rails/engine.rb +8 -2
  39. data/lib/llama_bot_rails/llama_bot.rb +3 -0
  40. data/lib/llama_bot_rails/railtie.rb +6 -0
  41. data/lib/llama_bot_rails/route_helper.rb +117 -0
  42. data/lib/llama_bot_rails/version.rb +1 -1
  43. data/lib/llama_bot_rails.rb +64 -21
  44. metadata +31 -4
  45. data/bin/rails +0 -26
  46. data/bin/rubocop +0 -8
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: ab8f2052c6695abc545b10879f23262d1c444011c28aa60e035fe94e12e62e35
4
- data.tar.gz: 21532f0afe7f6bf345da06b89e0e472d6e219eba9a3da0a5387a09a2f3ddbc39
3
+ metadata.gz: 4a2a7cba5de6b95658edf2f1445ddd883bf0fa7b6f0a844fc7b65d75696bbe93
4
+ data.tar.gz: 471a4c54a3f26dd4d6b68c6d208d3c8e553cfcf2933436bad3e7b30af2d50296
5
5
  SHA512:
6
- metadata.gz: a4400caf025fb253e8734003046a8256d6dcd6862ef6ddc9b45a3ac7a0a016749ef77eccf5ed9b17d5310ed1029a98af4873737765471d17aa665e0f60c7865c
7
- data.tar.gz: 5ee28cfaa7c097dcce2fd95490c3721643abc0600cdbb3bd591bb255a2d21c27558810f43194206a10ae4ea0de7ee1ec71e9c5c0c62defb731238751fc8f1dd5
6
+ metadata.gz: 49afcfcec2697177cccc266cbdca5b7b0859feef23fb45d2626435c686368e0231d9cf0c66b894a3a0696dc50d54c9e285fc6b66905b42be752ac24126c82d97
7
+ data.tar.gz: ada3ecb0a74f2fef56122ffcc97889b7c877d670296a5f8a556d3afad685b53332f7be4306cfdf901f2b00744f8fd600c56041605aef02db666d9e51fe633a72
data/README.md CHANGED
@@ -160,6 +160,23 @@ Rails.application.configure do
160
160
  end
161
161
  ```
162
162
 
163
+ ## **Principle of Least Priviledge**: Whitelisting Controller Actions
164
+
165
+ Rather than giving the agent full access to your Rails app via the Rails console, You can whitelist controller actions instead.
166
+
167
+ ```
168
+ class PagesController < ApplicationController
169
+ include LlamaBotRails::ControllerExtensions
170
+ include LlamaBotRails::AgentAuth
171
+
172
+ # ─── Allow the agent to hit these actions ────────────────────────────────
173
+ llama_bot_allow :update #uses llama_bot_rails "authenticate_user_or_agent!" on top of your existing devise authentication.
174
+
175
+ skip_before_action :authenticate_user_or_agent!, only: [:show] #NOTE: You must change any skip_before_action callbacks that skip devise Authentication, to use :authenticate_user_or_agent!
176
+ ```
177
+
178
+ When you include LlamaBotRails::AgentAuth, the gem aliases any authenticate_<scope>! filters to a unified guard. You can keep your old callbacks/skips for now, but you’ll see a deprecation warning—switch to authenticate_user_or_agent! at your convenience.
179
+
163
180
  ## 🧪 **What You Can Build**
164
181
 
165
182
  ### Developer Assistant
@@ -47,11 +47,6 @@ module LlamaBotRails
47
47
  # Use a begin/rescue block to catch thread creation errors
48
48
  begin
49
49
 
50
- @api_token = Rails.application.message_verifier(:llamabot_ws).generate(
51
- { session_id: SecureRandom.uuid },
52
- expires_in: 30.minutes
53
- )
54
-
55
50
  @worker = Thread.new do
56
51
  Thread.current[:connection_id] = @connection_id
57
52
  Thread.current.abort_on_exception = true # This will help surface errors
@@ -93,6 +88,16 @@ module LlamaBotRails
93
88
  end
94
89
  end
95
90
 
91
+ # Close the external WebSocket connection BEFORE stopping async tasks
92
+ if @external_ws_connection
93
+ begin
94
+ @external_ws_connection.close
95
+ Rails.logger.info "👋 [LlamaBot] Gracefully closed external WebSocket connection for: #{connection_id}"
96
+ rescue => e
97
+ Rails.logger.warn "❌ [LlamaBot] Could not close WebSocket connection: #{e.message}"
98
+ end
99
+ end
100
+
96
101
  # Clean up async tasks with better error handling
97
102
  begin
98
103
  @listener_task&.stop rescue nil
@@ -102,16 +107,6 @@ module LlamaBotRails
102
107
  Rails.logger.error "[LlamaBot] Error stopping async tasks: #{e.message}"
103
108
  end
104
109
 
105
- # Clean up the connection
106
- if @external_ws_connection
107
- begin
108
- @external_ws_connection.close
109
- Rails.logger.info "[LlamaBot] Closed external WebSocket connection for: #{connection_id}"
110
- rescue => e
111
- Rails.logger.warn "[LlamaBot] Could not close WebSocket connection: #{e.message}"
112
- end
113
- end
114
-
115
110
  # Force garbage collection in development/test environments to help clean up
116
111
  if !Rails.env.production?
117
112
  GC.start
@@ -126,7 +121,15 @@ module LlamaBotRails
126
121
  # through external websocket to FastAPI/Python backend.
127
122
  def receive(data)
128
123
  begin
129
- #used to validate the message before it's sent to the backend.
124
+ #used to validate the message before it's sent to the llamabot-backend.
125
+
126
+ # Get the currently logged in user from the environment.
127
+ current_user = LlamaBotRails.current_user_resolver.call(connection.env)
128
+
129
+ @api_token = Rails.application.message_verifier(:llamabot_ws).generate(
130
+ { session_id: SecureRandom.uuid, user_id: current_user&.id},
131
+ expires_in: 30.minutes
132
+ )
130
133
 
131
134
  #This could be an example of how we might implement hooks & filters in the future.
132
135
  validate_message(data) #Placeholder for now, we are using this to mock errors being thrown. In the future, we can add actual validation logic.
@@ -135,7 +138,7 @@ module LlamaBotRails
135
138
 
136
139
  builder = state_builder_class.new(
137
140
  params: data,
138
- context: { api_token: @api_token }
141
+ context: { api_token: @api_token }.with_indifferent_access
139
142
  )
140
143
 
141
144
  # 2. Construct the LangGraph-ready state
@@ -148,6 +151,7 @@ module LlamaBotRails
148
151
  Rails.logger.info "[LlamaBot] Got message from Javascript LlamaBot Frontend: #{data.inspect}"
149
152
  rescue => e
150
153
  Rails.logger.error "[LlamaBot] Error in receive method: #{e.message}"
154
+ Rails.logger.error "[LlamaBot] Backtrace: #{e.backtrace.join("\n")}"
151
155
  send_message_to_frontend("error", e.message)
152
156
  end
153
157
  end
@@ -249,84 +253,82 @@ module LlamaBotRails
249
253
  # Wait for tasks to complete or connection to close
250
254
  [@listener_task, @keepalive_task].each(&:wait)
251
255
  rescue => e
252
- Rails.logger.error "[LlamaBot] Failed to connect to external WebSocket for connection #{connection_id}: #{e.message}"
256
+ Rails.logger.error "[LlamaBot] Failed to connect to external WebSocket for connection #{connection_id}: #{e.message}"
253
257
  ensure
254
258
  # Clean up tasks if they exist
255
259
  @listener_task&.stop
256
260
  @keepalive_task&.stop
257
- @external_ws_connection&.close
261
+ if @external_ws_connection
262
+ @external_ws_connection.close
263
+ Rails.logger.info "👋 [LlamaBot] Cleaned up external WebSocket connection in ensure block"
264
+ end
258
265
  end
259
266
  end
260
267
  end
261
268
 
262
269
  # Listen for messages from the LlamaBot Backend
263
270
  def listen_to_external_websocket(connection)
264
- while message = connection.read
271
+ begin
272
+ while message = connection.read
273
+ # Extract the actual message content
274
+ message_content = message.buffer if message.buffer
275
+ next unless message_content.present?
265
276
 
266
- #Try to fix the ping/pong issue keepliave
267
- # if message.type == :ping
268
-
269
- # # respond with :pong
270
- # connection.write(Async::WebSocket::Messages::ControlFrame.new(:pong, frame.data))
271
- # connection.flush
272
- # next
273
- # end
274
- # Extract the actual message content
275
- if message.buffer
276
- message_content = message.buffer # Use .data to get the message content
277
- else
278
- message_content = message.content
279
- end
277
+ Rails.logger.info "[LlamaBot] Received from external WebSocket: #{message_content}"
280
278
 
281
- Rails.logger.info "[LlamaBot] Received from external WebSocket: #{message_content}"
282
-
283
- begin
284
- parsed_message = JSON.parse(message_content)
285
-
286
- if parsed_message["type"] != "pong"
287
- # byebug
288
- end
289
-
290
- case parsed_message["type"]
291
- when "ai"
292
- # Add any additional handling for write_code messages here
293
- formatted_message = { message: {type: "ai", content: parsed_message['content'], base_message: parsed_message["base_message"]} }.to_json
294
- when "tool"
295
- # Add any additional handling for tool messages here
296
- formatted_message = { message: {type: "tool", content: parsed_message['content'], base_message: parsed_message["base_message"]} }.to_json
297
- when "error"
298
- Rails.logger.error "[LlamaBot] ---------Received error message!----------"
299
- response = parsed_message['content']
300
- formatted_message = { message: message_content }.to_json
301
- Rails.logger.error "[LlamaBot] ---------------------> Response: #{response}"
302
- Rails.logger.error "[LlamaBot] ---------Completed error message!----------"
303
- when "pong"
304
- # Tell llamabot frontend that we've received a pong response, and we're still connected
305
- formatted_message = { message: {type: "pong"} }.to_json
279
+ begin
280
+ parsed_message = JSON.parse(message_content)
281
+
282
+ formatted_message = { message: {type: parsed_message["type"], content: parsed_message['content'], base_message: parsed_message["base_message"]} }.to_json
283
+ case parsed_message["type"]
284
+ when "error"
285
+ Rails.logger.error "[LlamaBot] ---------Received error message!----------"
286
+ response = parsed_message['content']
287
+ formatted_message = { message: message_content }.to_json
288
+ Rails.logger.error "[LlamaBot] ---------------------> Response: #{response}"
289
+ Rails.logger.error "[LlamaBot] ---------Completed error message!----------"
290
+ when "pong"
291
+ # Tell llamabot frontend that we've received a pong response, and we're still connected
292
+ formatted_message = { message: {type: "pong"} }.to_json
293
+ end
294
+ ActionCable.server.broadcast "chat_channel_#{params[:session_id]}", formatted_message
295
+ rescue JSON::ParserError => e
296
+ Rails.logger.error "[LlamaBot] Failed to parse message as JSON: #{e.message}"
297
+ # Continue to the next message without crashing the listener.
298
+ next
306
299
  end
307
- rescue JSON::ParserError => e
308
- Rails.logger.error "[LlamaBot] Failed to parse message as JSON: #{e.message}"
309
300
  end
310
- ActionCable.server.broadcast "chat_channel_#{params[:session_id]}", formatted_message
301
+ rescue IOError, Errno::ECONNRESET => e
302
+ # This is a recoverable error. Log it and allow the task to end gracefully.
303
+ # The `ensure` block in `setup_external_websocket` will handle the cleanup.
304
+ Rails.logger.warn "❌ [LlamaBot] Connection lost while listening: #{e.message}. The connection will be closed."
311
305
  end
312
306
  end
313
307
 
314
308
  ###
315
309
  def send_keep_alive_pings(connection)
316
310
  loop do
317
- ping_message = {
318
- type: 'ping',
319
- connection_id: @connection_id,
320
- connection_state: !connection.closed? ? 'connected' : 'disconnected',
321
- connection_class: connection.class.name
322
- }.to_json
323
- connection.write(ping_message)
324
- connection.flush
325
- Rails.logger.debug "[LlamaBot] Sent keep-alive ping: #{ping_message}"
311
+ # Stop the loop gracefully if the connection has already been closed.
312
+ break if connection.closed?
313
+
314
+ begin
315
+ ping_message = {
316
+ type: 'ping',
317
+ connection_id: @connection_id,
318
+ connection_state: !connection.closed? ? 'connected' : 'disconnected',
319
+ connection_class: connection.class.name
320
+ }.to_json
321
+ connection.write(ping_message)
322
+ connection.flush
323
+ Rails.logger.debug "[LlamaBot] Sent keep-alive ping: #{ping_message}"
324
+ rescue IOError, Errno::ECONNRESET => e
325
+ Rails.logger.warn "❌ [LlamaBot] Could not send ping, connection likely closed: #{e.message}"
326
+ # Break the loop to allow the task to terminate gracefully.
327
+ break
328
+ end
329
+
326
330
  Async::Task.current.sleep(30)
327
331
  end
328
- rescue => e
329
- Rails.logger.error "[LlamaBot] Error in keep-alive ping: #{e.message} | Connection type: #{connection.class.name}"
330
332
  end
331
333
 
332
334
  # Send messages from the user to the LlamaBot Backend Socket
@@ -2,11 +2,25 @@ require 'llama_bot_rails/llama_bot'
2
2
  module LlamaBotRails
3
3
  class AgentController < ActionController::Base
4
4
  include ActionController::Live
5
+ include LlamaBotRails::AgentAuth
6
+ include LlamaBotRails::ControllerExtensions
7
+
8
+ llama_bot_allow :command
9
+
5
10
  skip_before_action :verify_authenticity_token, only: [:command, :send_message]
6
- before_action :authenticate_agent!, only: [:command]
11
+ # skip_before_action :authenticate_user_or_agent!, only: [:command]
12
+
13
+ before_action :check_agent_authentication
7
14
 
8
15
  # POST /agent/command
9
16
  def command
17
+
18
+ unless LlamaBotRails.config.enable_console_tool
19
+ Rails.logger.warn("[[LlamaBot Debug]] Console tool is disabled")
20
+ render json: { error: "Console tool is disabled" }, status: :forbidden
21
+ return
22
+ end
23
+
10
24
  input = params[:command]
11
25
 
12
26
  # Capture both stdout and return value
@@ -16,18 +30,15 @@ module LlamaBotRails
16
30
  $stdout = output
17
31
  result = safety_eval(input)
18
32
  $stdout = STDOUT
19
-
20
- # If result is a string and output has content, prefer output
21
- final_result = if output.string.present?
22
- output.string.strip
23
- else
24
- result
25
- end
26
-
27
- render json: { result: final_result }
33
+
34
+ # Return both output and result
35
+ render json: {
36
+ output: output.string.strip,
37
+ result: result
38
+ }
28
39
  rescue => e
29
40
  $stdout = STDOUT # Reset stdout on error
30
- render json: { error: e.class.name, message: e.message }, status: :unprocessable_entity
41
+ render json: { error: "#{e.class.name}: #{e.message}" }
31
42
  end
32
43
 
33
44
  def index
@@ -78,15 +89,18 @@ module LlamaBotRails
78
89
  response.headers['Cache-Control'] = 'no-cache'
79
90
  response.headers['Connection'] = 'keep-alive'
80
91
 
92
+ # Get the currently logged in user from the environment.
93
+ current_user = LlamaBotRails.current_user_resolver.call(request.env)
94
+
81
95
  @api_token = Rails.application.message_verifier(:llamabot_ws).generate(
82
- { session_id: SecureRandom.uuid },
96
+ { session_id: SecureRandom.uuid, user_id: current_user&.id},
83
97
  expires_in: 30.minutes
84
- )
98
+ )
85
99
 
86
100
  # 1. Instantiate the builder
87
101
  builder = state_builder_class.new(
88
102
  params: params,
89
- context: { api_token: @api_token }
103
+ context: { api_token: @api_token }.with_indifferent_access
90
104
  )
91
105
 
92
106
  # 2. Construct the LangGraph-ready state
@@ -131,25 +145,15 @@ module LlamaBotRails
131
145
  private
132
146
 
133
147
  def safety_eval(input)
134
- begin
135
- # Change to Rails root directory for file operations
136
- Dir.chdir(Rails.root) do
137
- # Create a safer evaluation context
138
- Rails.logger.info "[[LlamaBot]] Evaluating input: #{input}"
139
- binding.eval(input)
140
- end
141
- rescue => exception
142
- Rails.logger.error "Error in safety_eval: #{exception.message}"
143
- return exception.message
148
+ # Change to Rails root directory for file operations
149
+ Dir.chdir(Rails.root) do
150
+ # Create a safer evaluation context
151
+ Rails.logger.info "[[LlamaBot]] Evaluating input: #{input}"
152
+ binding.eval(input)
144
153
  end
145
- end
146
-
147
- def authenticate_agent!
148
- auth_header = request.headers["Authorization"]
149
- token = auth_header&.split("Bearer ")&.last # Extract token after "Bearer "
150
- @session_payload = Rails.application.message_verifier(:llamabot_ws).verify(token)
151
- rescue ActiveSupport::MessageVerifier::InvalidSignature
152
- head :unauthorized
154
+ rescue => exception
155
+ Rails.logger.error "Error in safety_eval: #{exception.message}"
156
+ raise exception
153
157
  end
154
158
 
155
159
  def state_builder_class
@@ -586,7 +586,7 @@
586
586
  let currentThreadId = null;
587
587
  let isSidebarCollapsed = false;
588
588
  let streamingTimeout = null;
589
- const STREAMING_TIMEOUT_MS = 30000; // 30 seconds timeout
589
+ const STREAMING_TIMEOUT_MS = 3000000; // 3000 seconds timeout
590
590
 
591
591
  // Initialize the app
592
592
  document.addEventListener('DOMContentLoaded', function() {
@@ -968,6 +968,7 @@
968
968
  }
969
969
 
970
970
  } catch (parseError) {
971
+ addMessage(`Error: ${parseError} - Data: ${jsonData}`, 'error');
971
972
  console.error('Error parsing SSE data:', parseError, 'Data:', jsonData);
972
973
  }
973
974
  }
@@ -575,7 +575,7 @@ This deprecated and will be removed over time.
575
575
  <img src="https://service-jobs-images.s3.us-east-2.amazonaws.com/7rl98t1weu387r43il97h6ipk1l7" alt="LlamaBot Logo" class="logo">
576
576
  <div id="connectionStatusIconForLlamaBot" class="connection-status status-yellow"></div>
577
577
  </div>
578
- <h1>LlamaBot Chat</h1>
578
+ <h1>Lenny the Llama</h1>
579
579
  </div>
580
580
  <button class="compose-button" onclick="startNewConversation()">
581
581
  <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
@@ -659,7 +659,10 @@ This deprecated and will be removed over time.
659
659
  },
660
660
  received(data) {
661
661
  const parsedData = JSON.parse(data).message;
662
+ console.log("LLM Response:", parsedData);
662
663
  switch (parsedData.type) {
664
+ case "AIMessageChunk":
665
+ addMessage(parsedData.content, parsedData.type, parsedData.base_message);
663
666
  case "ai":
664
667
  addMessage(parsedData.content, parsedData.type, parsedData.base_message);
665
668
  break;
@@ -966,6 +969,11 @@ This deprecated and will be removed over time.
966
969
  const messageDiv = document.createElement('div');
967
970
  messageDiv.className = `message ${sender}-message`;
968
971
 
972
+ if (sender == "AIMessageChunk"){
973
+ console.log("AIMessageChunk" + base_message);
974
+ messageDiv.innerHTML += text;
975
+ }
976
+
969
977
  // Parse markdown for bot messages using Snarkdown, keep plain text for user messages
970
978
  if (sender === 'ai') { //Arghh. We're having issues with difference in formats between when we're streaming from updates mode, and when pulling state from checkpoint.
971
979
  if (text == ''){ //this is most likely a tool call.
@@ -1151,7 +1159,8 @@ This deprecated and will be removed over time.
1151
1159
 
1152
1160
  }
1153
1161
  else {
1154
- messageDiv.innerHTML = snarkdown(text);
1162
+ messageDiv.innerHTML = text;
1163
+ // messageDiv.innerHTML = snarkdown(text);
1155
1164
  }
1156
1165
  } else if (sender === 'tool') { //tool messages are not parsed as markdown
1157
1166
  if (base_message.name == 'run_rails_console_command') {
data/bin/bundle ADDED
@@ -0,0 +1,29 @@
1
+ #!/usr/bin/env ruby
2
+ #
3
+ # This file was generated by RubyGems.
4
+ #
5
+ # The application 'bundler' is installed as part of a gem, and
6
+ # this file is here to facilitate running it.
7
+ #
8
+
9
+ require 'rubygems'
10
+
11
+ version = ">= 0.a"
12
+
13
+ str = ARGV.first
14
+ if str
15
+ str = str.b[/\A_(.*)_\z/, 1]
16
+ if str and Gem::Version.correct?(str)
17
+ version = str
18
+ ENV['BUNDLER_VERSION'] = str
19
+
20
+ ARGV.shift
21
+ end
22
+ end
23
+
24
+ if Gem.respond_to?(:activate_bin_path)
25
+ load Gem.activate_bin_path('bundler', 'bundle', version)
26
+ else
27
+ gem "bundler", version
28
+ load Gem.bin_path("bundler", "bundle", version)
29
+ end
data/bin/bundle.lock ADDED
File without changes
data/bin/bundler ADDED
@@ -0,0 +1,29 @@
1
+ #!/usr/bin/env ruby
2
+ #
3
+ # This file was generated by RubyGems.
4
+ #
5
+ # The application 'bundler' is installed as part of a gem, and
6
+ # this file is here to facilitate running it.
7
+ #
8
+
9
+ require 'rubygems'
10
+
11
+ version = ">= 0.a"
12
+
13
+ str = ARGV.first
14
+ if str
15
+ str = str.b[/\A_(.*)_\z/, 1]
16
+ if str and Gem::Version.correct?(str)
17
+ version = str
18
+ ENV['BUNDLER_VERSION'] = str
19
+
20
+ ARGV.shift
21
+ end
22
+ end
23
+
24
+ if Gem.respond_to?(:activate_bin_path)
25
+ load Gem.activate_bin_path('bundler', 'bundler', version)
26
+ else
27
+ gem "bundler", version
28
+ load Gem.bin_path("bundler", "bundler", version)
29
+ end
data/bin/bundler.lock ADDED
File without changes
data/bin/byebug ADDED
@@ -0,0 +1,29 @@
1
+ #!/usr/bin/env ruby
2
+ #
3
+ # This file was generated by RubyGems.
4
+ #
5
+ # The application 'byebug' is installed as part of a gem, and
6
+ # this file is here to facilitate running it.
7
+ #
8
+
9
+ require 'rubygems'
10
+
11
+ Gem.use_gemdeps
12
+
13
+ version = ">= 0.a"
14
+
15
+ str = ARGV.first
16
+ if str
17
+ str = str.b[/\A_(.*)_\z/, 1]
18
+ if str and Gem::Version.correct?(str)
19
+ version = str
20
+ ARGV.shift
21
+ end
22
+ end
23
+
24
+ if Gem.respond_to?(:activate_bin_path)
25
+ load Gem.activate_bin_path('byebug', 'byebug', version)
26
+ else
27
+ gem "byebug", version
28
+ load Gem.bin_path("byebug", "byebug", version)
29
+ end
data/bin/coderay ADDED
@@ -0,0 +1,29 @@
1
+ #!/usr/bin/env ruby
2
+ #
3
+ # This file was generated by RubyGems.
4
+ #
5
+ # The application 'coderay' is installed as part of a gem, and
6
+ # this file is here to facilitate running it.
7
+ #
8
+
9
+ require 'rubygems'
10
+
11
+ Gem.use_gemdeps
12
+
13
+ version = ">= 0.a"
14
+
15
+ str = ARGV.first
16
+ if str
17
+ str = str.b[/\A_(.*)_\z/, 1]
18
+ if str and Gem::Version.correct?(str)
19
+ version = str
20
+ ARGV.shift
21
+ end
22
+ end
23
+
24
+ if Gem.respond_to?(:activate_bin_path)
25
+ load Gem.activate_bin_path('coderay', 'coderay', version)
26
+ else
27
+ gem "coderay", version
28
+ load Gem.bin_path("coderay", "coderay", version)
29
+ end
data/bin/erb ADDED
@@ -0,0 +1,29 @@
1
+ #!/usr/bin/env ruby
2
+ #
3
+ # This file was generated by RubyGems.
4
+ #
5
+ # The application 'erb' is installed as part of a gem, and
6
+ # this file is here to facilitate running it.
7
+ #
8
+
9
+ require 'rubygems'
10
+
11
+ Gem.use_gemdeps
12
+
13
+ version = ">= 0.a"
14
+
15
+ str = ARGV.first
16
+ if str
17
+ str = str.b[/\A_(.*)_\z/, 1]
18
+ if str and Gem::Version.correct?(str)
19
+ version = str
20
+ ARGV.shift
21
+ end
22
+ end
23
+
24
+ if Gem.respond_to?(:activate_bin_path)
25
+ load Gem.activate_bin_path('erb', 'erb', version)
26
+ else
27
+ gem "erb", version
28
+ load Gem.bin_path("erb", "erb", version)
29
+ end
data/bin/faker ADDED
@@ -0,0 +1,29 @@
1
+ #!/usr/bin/env ruby
2
+ #
3
+ # This file was generated by RubyGems.
4
+ #
5
+ # The application 'faker' is installed as part of a gem, and
6
+ # this file is here to facilitate running it.
7
+ #
8
+
9
+ require 'rubygems'
10
+
11
+ Gem.use_gemdeps
12
+
13
+ version = ">= 0.a"
14
+
15
+ str = ARGV.first
16
+ if str
17
+ str = str.b[/\A_(.*)_\z/, 1]
18
+ if str and Gem::Version.correct?(str)
19
+ version = str
20
+ ARGV.shift
21
+ end
22
+ end
23
+
24
+ if Gem.respond_to?(:activate_bin_path)
25
+ load Gem.activate_bin_path('faker', 'faker', version)
26
+ else
27
+ gem "faker", version
28
+ load Gem.bin_path("faker", "faker", version)
29
+ end
data/bin/htmldiff ADDED
@@ -0,0 +1,29 @@
1
+ #!/usr/bin/env ruby
2
+ #
3
+ # This file was generated by RubyGems.
4
+ #
5
+ # The application 'diff-lcs' is installed as part of a gem, and
6
+ # this file is here to facilitate running it.
7
+ #
8
+
9
+ require 'rubygems'
10
+
11
+ Gem.use_gemdeps
12
+
13
+ version = ">= 0.a"
14
+
15
+ str = ARGV.first
16
+ if str
17
+ str = str.b[/\A_(.*)_\z/, 1]
18
+ if str and Gem::Version.correct?(str)
19
+ version = str
20
+ ARGV.shift
21
+ end
22
+ end
23
+
24
+ if Gem.respond_to?(:activate_bin_path)
25
+ load Gem.activate_bin_path('diff-lcs', 'htmldiff', version)
26
+ else
27
+ gem "diff-lcs", version
28
+ load Gem.bin_path("diff-lcs", "htmldiff", version)
29
+ end
data/bin/irb ADDED
@@ -0,0 +1,29 @@
1
+ #!/usr/bin/env ruby
2
+ #
3
+ # This file was generated by RubyGems.
4
+ #
5
+ # The application 'irb' is installed as part of a gem, and
6
+ # this file is here to facilitate running it.
7
+ #
8
+
9
+ require 'rubygems'
10
+
11
+ Gem.use_gemdeps
12
+
13
+ version = ">= 0.a"
14
+
15
+ str = ARGV.first
16
+ if str
17
+ str = str.b[/\A_(.*)_\z/, 1]
18
+ if str and Gem::Version.correct?(str)
19
+ version = str
20
+ ARGV.shift
21
+ end
22
+ end
23
+
24
+ if Gem.respond_to?(:activate_bin_path)
25
+ load Gem.activate_bin_path('irb', 'irb', version)
26
+ else
27
+ gem "irb", version
28
+ load Gem.bin_path("irb", "irb", version)
29
+ end