daytona 0.184.0 → 0.185.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 +4 -4
- data/lib/daytona/code_interpreter.rb +26 -26
- data/lib/daytona/common/response.rb +1 -0
- data/lib/daytona/common/snapshot.rb +6 -1
- data/lib/daytona/file_system.rb +12 -7
- data/lib/daytona/file_transfer.rb +42 -7
- data/lib/daytona/git.rb +6 -2
- data/lib/daytona/process.rb +51 -48
- data/lib/daytona/sdk/version.rb +1 -1
- data/lib/daytona/snapshot_service.rb +1 -0
- metadata +5 -5
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: '0846ab327fc5ae0c55ee61872fb3c29bf266979387b8f362846d0856dee50b0d'
|
|
4
|
+
data.tar.gz: 6ea941ba9e0c6182cbd9c364174ff58ec32eba00fa9c252d2decb5131bd19676
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 8f7da0103eee9ba48d742003281d86530482aa1504e4c8d60734841c2c1229b47270c1d646b17cd70071e0fb314feb3c3fa262c92348324dd2015a062d67a853
|
|
7
|
+
data.tar.gz: 801300d22b0ebc53f76d870a4f98eca73b0bf267b8b877d33f6be41cf3c6c35790971d9abbec4e5241f4335ef7c0aa44b2e9958ea8fe7579d562e778fb8a49de
|
|
@@ -108,40 +108,40 @@ module Daytona
|
|
|
108
108
|
|
|
109
109
|
puts "[DEBUG] Connecting to WebSocket: #{ws_url}" if ENV['DEBUG']
|
|
110
110
|
|
|
111
|
-
ws = WebSocket::Client::Simple.connect(ws_url, headers:)
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
end
|
|
117
|
-
|
|
118
|
-
ws.on :message do |msg|
|
|
119
|
-
puts "[DEBUG] Received message (length=#{msg.data.length}): #{msg.data.inspect[0..200]}" if ENV['DEBUG']
|
|
111
|
+
ws = WebSocket::Client::Simple.connect(ws_url, headers:) do |client|
|
|
112
|
+
client.on :open do
|
|
113
|
+
puts '[DEBUG] WebSocket opened, sending request' if ENV['DEBUG']
|
|
114
|
+
client.send(JSON.dump(request))
|
|
115
|
+
end
|
|
120
116
|
|
|
121
|
-
|
|
122
|
-
|
|
117
|
+
client.on :message do |msg|
|
|
118
|
+
puts "[DEBUG] Received message (length=#{msg.data.length}): #{msg.data.inspect[0..200]}" if ENV['DEBUG']
|
|
123
119
|
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
completion_queue.push({ type: :error, error: e })
|
|
127
|
-
end
|
|
120
|
+
interpreter.send(:handle_message, msg.data, result, on_stdout, on_stderr, on_error, completion_queue)
|
|
121
|
+
end
|
|
128
122
|
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
reason = e&.reason || 'nil'
|
|
133
|
-
puts "[DEBUG] WebSocket closed: code=#{code}, reason=#{reason}"
|
|
123
|
+
client.on :error do |e|
|
|
124
|
+
puts "[DEBUG] WebSocket error: #{e.message}" if ENV['DEBUG']
|
|
125
|
+
completion_queue.push({ type: :error, error: e })
|
|
134
126
|
end
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
127
|
+
|
|
128
|
+
client.on :close do |e|
|
|
129
|
+
if ENV['DEBUG']
|
|
130
|
+
code = e&.code || 'nil'
|
|
131
|
+
reason = e&.reason || 'nil'
|
|
132
|
+
puts "[DEBUG] WebSocket closed: code=#{code}, reason=#{reason}"
|
|
133
|
+
end
|
|
134
|
+
error_info = interpreter.send(:handle_close, e)
|
|
135
|
+
if error_info
|
|
136
|
+
completion_queue.push({ type: :error_from_close, error: error_info })
|
|
137
|
+
else
|
|
138
|
+
completion_queue.push({ type: :close })
|
|
139
|
+
end
|
|
140
140
|
end
|
|
141
141
|
end
|
|
142
142
|
|
|
143
143
|
no_timeout = timeout.is_a?(Numeric) && timeout <= 0
|
|
144
|
-
max_wait = no_timeout ? nil : (timeout || 600) +
|
|
144
|
+
max_wait = no_timeout ? nil : (timeout || 600) + 30
|
|
145
145
|
start_time = Time.now
|
|
146
146
|
completion_reason = nil
|
|
147
147
|
|
|
@@ -6,6 +6,7 @@
|
|
|
6
6
|
module Daytona
|
|
7
7
|
# Re-export of api-client enum constants under the Daytona namespace so
|
|
8
8
|
# SDK consumers never need to import from DaytonaApiClient directly.
|
|
9
|
+
SandboxClass = DaytonaApiClient::SandboxClass
|
|
9
10
|
SandboxState = DaytonaApiClient::SandboxState
|
|
10
11
|
SandboxListSortField = DaytonaApiClient::SandboxListSortField
|
|
11
12
|
SandboxListSortDirection = DaytonaApiClient::SandboxListSortDirection
|
|
@@ -23,17 +23,22 @@ module Daytona
|
|
|
23
23
|
# Defaults to organization default region if not specified.
|
|
24
24
|
attr_reader :region_id
|
|
25
25
|
|
|
26
|
+
# @return [DaytonaApiClient::SandboxClass, nil] Target sandbox class.
|
|
27
|
+
attr_reader :sandbox_class
|
|
28
|
+
|
|
26
29
|
# @param name [String] Name of the snapshot
|
|
27
30
|
# @param image [String, Daytona::Image] Image of the snapshot
|
|
28
31
|
# @param resources [Daytona::Resources, nil] Resources of the snapshot
|
|
29
32
|
# @param entrypoint [Array<String>, nil] Entrypoint of the snapshot
|
|
30
33
|
# @param region_id [String, nil] ID of the region where the snapshot will be available
|
|
31
|
-
|
|
34
|
+
# @param sandbox_class [DaytonaApiClient::SandboxClass, nil] Target sandbox class
|
|
35
|
+
def initialize(name:, image:, resources: nil, entrypoint: nil, region_id: nil, sandbox_class: nil)
|
|
32
36
|
@name = name
|
|
33
37
|
@image = image
|
|
34
38
|
@resources = resources
|
|
35
39
|
@entrypoint = entrypoint
|
|
36
40
|
@region_id = region_id
|
|
41
|
+
@sandbox_class = sandbox_class
|
|
37
42
|
end
|
|
38
43
|
end
|
|
39
44
|
|
data/lib/daytona/file_system.rb
CHANGED
|
@@ -213,7 +213,7 @@ module Daytona
|
|
|
213
213
|
# # Upload binary data
|
|
214
214
|
# data = { key: "value" }.to_json
|
|
215
215
|
# sandbox.fs.upload_file(data, "tmp/config.json")
|
|
216
|
-
def upload_file(source, remote_path)
|
|
216
|
+
def upload_file(source, remote_path)
|
|
217
217
|
if source.is_a?(String) && File.exist?(source)
|
|
218
218
|
# Source is a file path
|
|
219
219
|
File.open(source, 'rb') { |file| toolbox_api.upload_file(remote_path, file) }
|
|
@@ -221,12 +221,17 @@ module Daytona
|
|
|
221
221
|
# Source is an IO object
|
|
222
222
|
toolbox_api.upload_file(remote_path, source)
|
|
223
223
|
else
|
|
224
|
-
#
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
224
|
+
# Tempfile.create yields a ::File (works with Typhoeus) but deletes
|
|
225
|
+
# on block exit — too early if curl reads asynchronously. Write via
|
|
226
|
+
# Tempfile, close it, then reopen as ::File for the upload.
|
|
227
|
+
tmp = Tempfile.new('daytona_upload')
|
|
228
|
+
begin
|
|
229
|
+
tmp.binmode
|
|
230
|
+
tmp.write(source.to_s.b)
|
|
231
|
+
tmp.close
|
|
232
|
+
File.open(tmp.path, 'rb') { |file| toolbox_api.upload_file(remote_path, file) }
|
|
233
|
+
ensure
|
|
234
|
+
tmp.unlink
|
|
230
235
|
end
|
|
231
236
|
end
|
|
232
237
|
rescue StandardError => e
|
|
@@ -18,6 +18,7 @@ module Daytona
|
|
|
18
18
|
class MultipartDownloadStreamParser
|
|
19
19
|
attr_reader :error_message
|
|
20
20
|
attr_reader :part_total_bytes
|
|
21
|
+
attr_reader :part_bytes_emitted
|
|
21
22
|
attr_writer :boundary_token
|
|
22
23
|
|
|
23
24
|
def initialize(&on_file_chunk)
|
|
@@ -27,6 +28,7 @@ module Daytona
|
|
|
27
28
|
@state = :preamble
|
|
28
29
|
@part_name = nil
|
|
29
30
|
@part_total_bytes = nil
|
|
31
|
+
@part_bytes_emitted = 0
|
|
30
32
|
@error_buffer = String.new.b
|
|
31
33
|
end
|
|
32
34
|
|
|
@@ -35,15 +37,13 @@ module Daytona
|
|
|
35
37
|
process!
|
|
36
38
|
end
|
|
37
39
|
|
|
40
|
+
# Raises if the response ended before the closing multipart boundary, so
|
|
41
|
+
# truncations surface as typed errors instead of silently short downloads.
|
|
38
42
|
def finish!
|
|
39
43
|
process!
|
|
44
|
+
return if @state == :done
|
|
40
45
|
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
emit(@buffer)
|
|
44
|
-
finalize_part!
|
|
45
|
-
@buffer = String.new.b
|
|
46
|
-
@state = :done
|
|
46
|
+
raise Sdk::Error, "Truncated multipart response: closing boundary not received (state=#{@state})"
|
|
47
47
|
end
|
|
48
48
|
|
|
49
49
|
private
|
|
@@ -110,6 +110,7 @@ module Daytona
|
|
|
110
110
|
|
|
111
111
|
case @part_name
|
|
112
112
|
when 'file'
|
|
113
|
+
@part_bytes_emitted += data.bytesize
|
|
113
114
|
@on_file_chunk.call(data)
|
|
114
115
|
when 'error'
|
|
115
116
|
@error_buffer << data
|
|
@@ -201,7 +202,7 @@ module Daytona
|
|
|
201
202
|
|
|
202
203
|
request.on_complete do |completed_response|
|
|
203
204
|
response = completed_response
|
|
204
|
-
parser.finish!
|
|
205
|
+
parser.finish! unless cancel_event&.set?
|
|
205
206
|
end
|
|
206
207
|
|
|
207
208
|
request.run
|
|
@@ -209,6 +210,16 @@ module Daytona
|
|
|
209
210
|
raise Sdk::Error, "Download cancelled: #{remote_path}" if cancel_event&.set?
|
|
210
211
|
raise Sdk::Error, parser.error_message if parser.error_message
|
|
211
212
|
raise Sdk::Error, "HTTP #{response.code}" if response && !response.success?
|
|
213
|
+
|
|
214
|
+
assert_download_length!(parser, remote_path)
|
|
215
|
+
end
|
|
216
|
+
|
|
217
|
+
def self.assert_download_length!(parser, remote_path)
|
|
218
|
+
return unless parser.part_total_bytes && parser.part_bytes_emitted != parser.part_total_bytes
|
|
219
|
+
|
|
220
|
+
raise Sdk::Error,
|
|
221
|
+
"Multipart response length mismatch for #{remote_path}: " \
|
|
222
|
+
"got #{parser.part_bytes_emitted} bytes, expected #{parser.part_total_bytes}"
|
|
212
223
|
end
|
|
213
224
|
# rubocop:enable Metrics/AbcSize, Metrics/MethodLength, Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
|
|
214
225
|
|
|
@@ -232,6 +243,7 @@ module Daytona
|
|
|
232
243
|
def self.stream_upload(api_client:, remote_path:, source:, timeout:, on_progress: nil, cancel_event: nil)
|
|
233
244
|
with_upload_file(source, cancel_event, remote_path) do |upload_path|
|
|
234
245
|
config = api_client.config
|
|
246
|
+
expected_bytes = File.size(upload_path)
|
|
235
247
|
progress_callback = upload_progress_callback(on_progress, cancel_event)
|
|
236
248
|
response = with_open_upload_file(upload_path) do |file|
|
|
237
249
|
upload_request(
|
|
@@ -244,6 +256,7 @@ module Daytona
|
|
|
244
256
|
).run
|
|
245
257
|
end
|
|
246
258
|
raise_upload_error(response, cancel_event, remote_path)
|
|
259
|
+
verify_upload_response(response, remote_path, expected_bytes)
|
|
247
260
|
end
|
|
248
261
|
end
|
|
249
262
|
# rubocop:enable Metrics/MethodLength, Metrics/ParameterLists
|
|
@@ -338,6 +351,28 @@ module Daytona
|
|
|
338
351
|
raise Sdk::Error, "HTTP #{response.code}: #{response.body}" unless response.success?
|
|
339
352
|
end
|
|
340
353
|
|
|
354
|
+
# Compares the daemon's reported bytes-written against what the SDK sent.
|
|
355
|
+
# Catches server-side miscounts (or extra-byte injection) at the upload
|
|
356
|
+
# call site instead of surfacing later as a download mismatch.
|
|
357
|
+
def self.verify_upload_response(response, remote_path, expected_bytes)
|
|
358
|
+
recorded = recorded_upload_bytes(response.body, remote_path)
|
|
359
|
+
return if recorded.nil? || recorded == expected_bytes
|
|
360
|
+
|
|
361
|
+
raise Sdk::Error,
|
|
362
|
+
"Upload size mismatch for #{remote_path}: sent #{expected_bytes} bytes, " \
|
|
363
|
+
"daemon recorded #{recorded}"
|
|
364
|
+
end
|
|
365
|
+
|
|
366
|
+
def self.recorded_upload_bytes(body, remote_path)
|
|
367
|
+
parsed = JSON.parse(body) rescue nil # rubocop:disable Style/RescueModifier
|
|
368
|
+
return nil unless parsed.is_a?(Hash)
|
|
369
|
+
|
|
370
|
+
files = Array(parsed['files'])
|
|
371
|
+
match = files.find { |f| f.is_a?(Hash) && f['path'] == remote_path }
|
|
372
|
+
bytes = match&.dig('bytes')
|
|
373
|
+
bytes.is_a?(Integer) ? bytes : nil
|
|
374
|
+
end
|
|
375
|
+
|
|
341
376
|
def self.open_drain_source(source)
|
|
342
377
|
return [source, false] if source.respond_to?(:read)
|
|
343
378
|
return [StringIO.new(source.b), true] if source.is_a?(String)
|
data/lib/daytona/git.rb
CHANGED
|
@@ -82,6 +82,9 @@ module Daytona
|
|
|
82
82
|
# the repository will be left in a detached HEAD state at this commit.
|
|
83
83
|
# @param username [String, nil] Git username for authentication.
|
|
84
84
|
# @param password [String, nil] Git password or token for authentication.
|
|
85
|
+
# @param insecure_skip_tls [Boolean, nil] Skip TLS certificate verification (insecure).
|
|
86
|
+
# Use only for trusted internal Git servers with self-signed or private-CA certs;
|
|
87
|
+
# credentials, if supplied, are transmitted over an unverified TLS connection.
|
|
85
88
|
# @return [void]
|
|
86
89
|
# @raise [Daytona::Sdk::Error] if cloning repository fails
|
|
87
90
|
#
|
|
@@ -107,7 +110,7 @@ module Daytona
|
|
|
107
110
|
# path: "workspace/repo-old",
|
|
108
111
|
# commit_id: "abc123"
|
|
109
112
|
# )
|
|
110
|
-
def clone(url:, path:, branch: nil, commit_id: nil, username: nil, password: nil) # rubocop:disable Metrics/MethodLength, Metrics/ParameterLists
|
|
113
|
+
def clone(url:, path:, branch: nil, commit_id: nil, username: nil, password: nil, insecure_skip_tls: nil) # rubocop:disable Metrics/MethodLength, Metrics/ParameterLists
|
|
111
114
|
toolbox_api.clone_repository(
|
|
112
115
|
DaytonaToolboxApiClient::GitCloneRequest.new(
|
|
113
116
|
url: url,
|
|
@@ -115,7 +118,8 @@ module Daytona
|
|
|
115
118
|
path: path,
|
|
116
119
|
username: username,
|
|
117
120
|
password: password,
|
|
118
|
-
commit_id: commit_id
|
|
121
|
+
commit_id: commit_id,
|
|
122
|
+
insecure_skip_tls: insecure_skip_tls
|
|
119
123
|
)
|
|
120
124
|
)
|
|
121
125
|
rescue DaytonaToolboxApiClient::ApiError => e
|
data/lib/daytona/process.rb
CHANGED
|
@@ -235,34 +235,34 @@ module Daytona
|
|
|
235
235
|
|
|
236
236
|
completion_queue = Queue.new
|
|
237
237
|
|
|
238
|
-
|
|
238
|
+
WebSocket::Client::Simple.connect(
|
|
239
239
|
url.to_s,
|
|
240
240
|
headers: toolbox_api.api_client.default_headers.dup.merge(
|
|
241
241
|
'X-Daytona-Preview-Token' => preview_link.token,
|
|
242
242
|
'Content-Type' => 'text/plain',
|
|
243
243
|
'Accept' => 'text/plain'
|
|
244
244
|
)
|
|
245
|
-
)
|
|
245
|
+
) do |client|
|
|
246
|
+
client.on(:message) do |message|
|
|
247
|
+
if message.type == :close
|
|
248
|
+
client.close
|
|
249
|
+
completion_queue.push(:close)
|
|
250
|
+
else
|
|
251
|
+
stdout, stderr = Util.demux(message.data.to_s)
|
|
252
|
+
|
|
253
|
+
on_stdout.call(stdout) unless stdout.empty?
|
|
254
|
+
on_stderr.call(stderr) unless stderr.empty?
|
|
255
|
+
end
|
|
256
|
+
end
|
|
246
257
|
|
|
247
|
-
|
|
248
|
-
if message.type == :close
|
|
249
|
-
ws.close
|
|
258
|
+
client.on(:close) do
|
|
250
259
|
completion_queue.push(:close)
|
|
251
|
-
else
|
|
252
|
-
stdout, stderr = Util.demux(message.data.to_s)
|
|
253
|
-
|
|
254
|
-
on_stdout.call(stdout) unless stdout.empty?
|
|
255
|
-
on_stderr.call(stderr) unless stderr.empty?
|
|
256
260
|
end
|
|
257
|
-
end
|
|
258
|
-
|
|
259
|
-
ws.on(:close) do
|
|
260
|
-
completion_queue.push(:close)
|
|
261
|
-
end
|
|
262
261
|
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
262
|
+
client.on(:error) do |e|
|
|
263
|
+
completion_queue.push(:error)
|
|
264
|
+
raise Sdk::Error, "WebSocket error: #{e.message}"
|
|
265
|
+
end
|
|
266
266
|
end
|
|
267
267
|
|
|
268
268
|
# Wait for completion
|
|
@@ -302,34 +302,34 @@ module Daytona
|
|
|
302
302
|
|
|
303
303
|
completion_queue = Queue.new
|
|
304
304
|
|
|
305
|
-
|
|
305
|
+
WebSocket::Client::Simple.connect(
|
|
306
306
|
url.to_s,
|
|
307
307
|
headers: toolbox_api.api_client.default_headers.dup.merge(
|
|
308
308
|
'X-Daytona-Preview-Token' => preview_link.token,
|
|
309
309
|
'Content-Type' => 'text/plain',
|
|
310
310
|
'Accept' => 'text/plain'
|
|
311
311
|
)
|
|
312
|
-
)
|
|
312
|
+
) do |client|
|
|
313
|
+
client.on(:message) do |message|
|
|
314
|
+
if message.type == :close
|
|
315
|
+
client.close
|
|
316
|
+
completion_queue.push(:close)
|
|
317
|
+
else
|
|
318
|
+
stdout, stderr = Util.demux(message.data.to_s)
|
|
319
|
+
|
|
320
|
+
on_stdout.call(stdout) unless stdout.empty?
|
|
321
|
+
on_stderr.call(stderr) unless stderr.empty?
|
|
322
|
+
end
|
|
323
|
+
end
|
|
313
324
|
|
|
314
|
-
|
|
315
|
-
if message.type == :close
|
|
316
|
-
ws.close
|
|
325
|
+
client.on(:close) do
|
|
317
326
|
completion_queue.push(:close)
|
|
318
|
-
else
|
|
319
|
-
stdout, stderr = Util.demux(message.data.to_s)
|
|
320
|
-
|
|
321
|
-
on_stdout.call(stdout) unless stdout.empty?
|
|
322
|
-
on_stderr.call(stderr) unless stderr.empty?
|
|
323
327
|
end
|
|
324
|
-
end
|
|
325
|
-
|
|
326
|
-
ws.on(:close) do
|
|
327
|
-
completion_queue.push(:close)
|
|
328
|
-
end
|
|
329
328
|
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
329
|
+
client.on(:error) do |e|
|
|
330
|
+
completion_queue.push(:error)
|
|
331
|
+
raise Sdk::Error, "WebSocket error: #{e.message}"
|
|
332
|
+
end
|
|
333
333
|
end
|
|
334
334
|
|
|
335
335
|
# Wait for completion
|
|
@@ -448,18 +448,21 @@ module Daytona
|
|
|
448
448
|
url.scheme = url.scheme == 'https' ? 'wss' : 'ws'
|
|
449
449
|
url.path = "/process/pty/#{session_id}/connect"
|
|
450
450
|
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
451
|
+
handle = nil
|
|
452
|
+
WebSocket::Client::Simple.connect(
|
|
453
|
+
url.to_s,
|
|
454
|
+
headers: toolbox_api.api_client.default_headers.dup.merge(
|
|
455
|
+
'X-Daytona-Preview-Token' => preview_link.token
|
|
456
|
+
)
|
|
457
|
+
) do |client|
|
|
458
|
+
handle = PtyHandle.new(
|
|
459
|
+
client,
|
|
460
|
+
session_id:,
|
|
461
|
+
handle_resize: ->(pty_size) { resize_pty_session(session_id, pty_size) },
|
|
462
|
+
handle_kill: -> { delete_pty_session(session_id) }
|
|
463
|
+
)
|
|
464
|
+
end
|
|
465
|
+
handle.tap(&:wait_for_connection)
|
|
463
466
|
end
|
|
464
467
|
|
|
465
468
|
# Resizes a PTY session to the specified dimensions
|
data/lib/daytona/sdk/version.rb
CHANGED
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: daytona
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.185.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Daytona Platforms Inc.
|
|
@@ -85,28 +85,28 @@ dependencies:
|
|
|
85
85
|
requirements:
|
|
86
86
|
- - '='
|
|
87
87
|
- !ruby/object:Gem::Version
|
|
88
|
-
version: 0.
|
|
88
|
+
version: 0.185.0
|
|
89
89
|
type: :runtime
|
|
90
90
|
prerelease: false
|
|
91
91
|
version_requirements: !ruby/object:Gem::Requirement
|
|
92
92
|
requirements:
|
|
93
93
|
- - '='
|
|
94
94
|
- !ruby/object:Gem::Version
|
|
95
|
-
version: 0.
|
|
95
|
+
version: 0.185.0
|
|
96
96
|
- !ruby/object:Gem::Dependency
|
|
97
97
|
name: daytona_toolbox_api_client
|
|
98
98
|
requirement: !ruby/object:Gem::Requirement
|
|
99
99
|
requirements:
|
|
100
100
|
- - '='
|
|
101
101
|
- !ruby/object:Gem::Version
|
|
102
|
-
version: 0.
|
|
102
|
+
version: 0.185.0
|
|
103
103
|
type: :runtime
|
|
104
104
|
prerelease: false
|
|
105
105
|
version_requirements: !ruby/object:Gem::Requirement
|
|
106
106
|
requirements:
|
|
107
107
|
- - '='
|
|
108
108
|
- !ruby/object:Gem::Version
|
|
109
|
-
version: 0.
|
|
109
|
+
version: 0.185.0
|
|
110
110
|
- !ruby/object:Gem::Dependency
|
|
111
111
|
name: dotenv
|
|
112
112
|
requirement: !ruby/object:Gem::Requirement
|