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.
- checksums.yaml +4 -4
- data/README.md +17 -0
- data/app/channels/llama_bot_rails/chat_channel.rb +75 -73
- data/app/controllers/llama_bot_rails/agent_controller.rb +36 -32
- data/app/views/llama_bot_rails/agent/chat.html.erb +2 -1
- data/app/views/llama_bot_rails/agent/chat_ws.html.erb +11 -2
- data/bin/bundle +29 -0
- data/bin/bundle.lock +0 -0
- data/bin/bundler +29 -0
- data/bin/bundler.lock +0 -0
- data/bin/byebug +29 -0
- data/bin/coderay +29 -0
- data/bin/erb +29 -0
- data/bin/faker +29 -0
- data/bin/htmldiff +29 -0
- data/bin/irb +29 -0
- data/bin/ldiff +29 -0
- data/bin/nokogiri +29 -0
- data/bin/pry +29 -0
- data/bin/puma +29 -0
- data/bin/pumactl +29 -0
- data/bin/racc +29 -0
- data/bin/rackup +29 -0
- data/bin/rake +29 -0
- data/bin/rdoc +29 -0
- data/bin/ri +29 -0
- data/bin/rspec +29 -0
- data/bin/ruby-parse +29 -0
- data/bin/ruby-rewrite +29 -0
- data/bin/sprockets +29 -0
- data/bin/thor +29 -0
- data/lib/generators/llama_bot_rails/install/install_generator.rb +68 -0
- data/lib/generators/llama_bot_rails/install/templates/agent_state_builder.rb.erb +3 -3
- data/lib/llama_bot_rails/agent_auth.rb +158 -0
- data/lib/llama_bot_rails/agent_auth_2.rb +149 -0
- data/lib/llama_bot_rails/agent_state_builder.rb +6 -6
- data/lib/llama_bot_rails/controller_extensions.rb +40 -0
- data/lib/llama_bot_rails/engine.rb +8 -2
- data/lib/llama_bot_rails/llama_bot.rb +3 -0
- data/lib/llama_bot_rails/railtie.rb +6 -0
- data/lib/llama_bot_rails/route_helper.rb +117 -0
- data/lib/llama_bot_rails/version.rb +1 -1
- data/lib/llama_bot_rails.rb +64 -21
- metadata +31 -4
- data/bin/rails +0 -26
- data/bin/rubocop +0 -8
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 4a2a7cba5de6b95658edf2f1445ddd883bf0fa7b6f0a844fc7b65d75696bbe93
|
4
|
+
data.tar.gz: 471a4c54a3f26dd4d6b68c6d208d3c8e553cfcf2933436bad3e7b30af2d50296
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
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
|
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
|
-
|
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
|
-
|
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
|
-
|
282
|
-
|
283
|
-
|
284
|
-
|
285
|
-
|
286
|
-
|
287
|
-
|
288
|
-
|
289
|
-
|
290
|
-
|
291
|
-
|
292
|
-
|
293
|
-
|
294
|
-
|
295
|
-
|
296
|
-
|
297
|
-
|
298
|
-
Rails.logger.error "[LlamaBot]
|
299
|
-
|
300
|
-
|
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
|
-
|
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
|
-
|
318
|
-
|
319
|
-
|
320
|
-
|
321
|
-
|
322
|
-
|
323
|
-
|
324
|
-
|
325
|
-
|
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
|
-
|
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
|
-
#
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
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
|
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
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
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
|
-
|
146
|
-
|
147
|
-
|
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 =
|
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>
|
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 =
|
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
|