daytona 0.126.0.pre.alpha.5 → 0.134.0.alpha.1
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/.rubocop.yml +1 -1
- data/README.md +2 -1
- data/lib/daytona/code_interpreter.rb +365 -0
- data/lib/daytona/code_toolbox/sandbox_js_code_toolbox.rb +19 -0
- data/lib/daytona/common/code_interpreter.rb +53 -0
- data/lib/daytona/common/snapshot.rb +7 -1
- data/lib/daytona/computer_use.rb +3 -3
- data/lib/daytona/config.rb +46 -10
- data/lib/daytona/daytona.rb +30 -9
- data/lib/daytona/git.rb +10 -10
- data/lib/daytona/lsp_server.rb +7 -7
- data/lib/daytona/object_storage.rb +2 -2
- data/lib/daytona/process.rb +26 -12
- data/lib/daytona/sandbox.rb +115 -1
- data/lib/daytona/sdk/version.rb +1 -1
- data/lib/daytona/sdk.rb +4 -2
- data/lib/daytona/snapshot_service.rb +33 -10
- data/lib/daytona.rb +0 -1
- data/project.json +13 -2
- data/scripts/generate-docs.rb +395 -0
- metadata +9 -5
|
@@ -0,0 +1,395 @@
|
|
|
1
|
+
#!/usr/bin/env ruby
|
|
2
|
+
# frozen_string_literal: true
|
|
3
|
+
|
|
4
|
+
require 'fileutils'
|
|
5
|
+
require 'tmpdir'
|
|
6
|
+
require 'yard'
|
|
7
|
+
|
|
8
|
+
# Configuration
|
|
9
|
+
DOCS_OUTPUT_DIR = File.expand_path('../../../apps/docs/src/content/docs/en/ruby-sdk', __dir__)
|
|
10
|
+
LIB_DIR = File.expand_path('../lib/daytona', __dir__)
|
|
11
|
+
|
|
12
|
+
# Classes to document: [file_path, output_filename, class_name]
|
|
13
|
+
CLASSES_TO_DOCUMENT = [
|
|
14
|
+
['config.rb', 'config.mdx', 'Daytona::Config'],
|
|
15
|
+
['daytona.rb', 'daytona.mdx', 'Daytona::Daytona'],
|
|
16
|
+
['sandbox.rb', 'sandbox.mdx', 'Daytona::Sandbox'],
|
|
17
|
+
['file_system.rb', 'file-system.mdx', 'Daytona::FileSystem'],
|
|
18
|
+
['git.rb', 'git.mdx', 'Daytona::Git'],
|
|
19
|
+
['process.rb', 'process.mdx', 'Daytona::Process'],
|
|
20
|
+
['lsp_server.rb', 'lsp-server.mdx', 'Daytona::LspServer'],
|
|
21
|
+
['volume.rb', 'volume.mdx', 'Daytona::Volume'],
|
|
22
|
+
['object_storage.rb', 'object-storage.mdx', 'Daytona::ObjectStorage'],
|
|
23
|
+
['computer_use.rb', 'computer-use.mdx', 'Daytona::ComputerUse'],
|
|
24
|
+
['snapshot_service.rb', 'snapshot.mdx', 'Daytona::SnapshotService'],
|
|
25
|
+
['volume_service.rb', 'volume-service.mdx', 'Daytona::VolumeService'],
|
|
26
|
+
['common/charts.rb', 'charts.mdx', 'Daytona::Chart'],
|
|
27
|
+
['common/image.rb', 'image.mdx', 'Daytona::Image']
|
|
28
|
+
]
|
|
29
|
+
|
|
30
|
+
def extract_class_name_from_path(class_name)
|
|
31
|
+
# Extract the simple class name from the full path
|
|
32
|
+
class_name.split('::').last
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
def add_frontmatter(content, class_name)
|
|
36
|
+
simple_name = extract_class_name_from_path(class_name)
|
|
37
|
+
frontmatter = <<~FRONTMATTER
|
|
38
|
+
---
|
|
39
|
+
title: "#{simple_name}"
|
|
40
|
+
hideTitleOnPage: true
|
|
41
|
+
---
|
|
42
|
+
|
|
43
|
+
FRONTMATTER
|
|
44
|
+
|
|
45
|
+
frontmatter + content
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
def format_type(types)
|
|
49
|
+
return 'Object' if types.nil? || types.empty?
|
|
50
|
+
|
|
51
|
+
# Join types and escape special characters that break MDX
|
|
52
|
+
type_str = types.join(', ')
|
|
53
|
+
# Escape special chars that break MDX parsing
|
|
54
|
+
# Replace :: with a single : to avoid MDX issues while keeping readability
|
|
55
|
+
type_str = type_str.gsub('::', ':')
|
|
56
|
+
# Escape angle brackets
|
|
57
|
+
type_str.gsub('<', '\\<').gsub('>', '\\>')
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
def clean_description(description)
|
|
61
|
+
return '' if description.nil? || description.empty?
|
|
62
|
+
|
|
63
|
+
# Remove rubocop directive lines
|
|
64
|
+
cleaned = description.to_s.lines.reject { |line| line.strip.start_with?('rubocop:') }.join
|
|
65
|
+
cleaned.strip
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
def extract_class_description(obj)
|
|
69
|
+
description = clean_description(obj.docstring)
|
|
70
|
+
|
|
71
|
+
# If no class-level description, try to get it from the first method or constructor
|
|
72
|
+
if description.empty? && obj.is_a?(YARD::CodeObjects::ClassObject)
|
|
73
|
+
# Try to find a description from the constructor or first documented method
|
|
74
|
+
constructor = obj.meths.find { |m| m.name == :initialize }
|
|
75
|
+
if constructor && constructor.docstring && !constructor.docstring.empty?
|
|
76
|
+
# Extract just the summary (first paragraph) from constructor docs
|
|
77
|
+
constructor_desc = clean_description(constructor.docstring)
|
|
78
|
+
first_paragraph = constructor_desc.split("\n\n").first
|
|
79
|
+
if first_paragraph && !first_paragraph.empty?
|
|
80
|
+
# Make it a class-level description
|
|
81
|
+
extract_class_name_from_path(obj.path)
|
|
82
|
+
description = first_paragraph.gsub(/^(Initializes|Creates a new)/, 'Main class for')
|
|
83
|
+
end
|
|
84
|
+
end
|
|
85
|
+
|
|
86
|
+
# If still empty, generate a basic description
|
|
87
|
+
if description.empty?
|
|
88
|
+
simple_name = extract_class_name_from_path(obj.path)
|
|
89
|
+
description = "#{simple_name} class for Daytona SDK."
|
|
90
|
+
end
|
|
91
|
+
end
|
|
92
|
+
|
|
93
|
+
description
|
|
94
|
+
end
|
|
95
|
+
|
|
96
|
+
def extract_attributes(obj)
|
|
97
|
+
attributes = []
|
|
98
|
+
|
|
99
|
+
return attributes unless obj.is_a?(YARD::CodeObjects::ClassObject)
|
|
100
|
+
|
|
101
|
+
# Collect all attributes
|
|
102
|
+
read_attrs = obj.attributes[:read] || {}
|
|
103
|
+
write_attrs = obj.attributes[:write] || {}
|
|
104
|
+
all_attrs = (read_attrs.keys + write_attrs.keys).uniq
|
|
105
|
+
|
|
106
|
+
all_attrs.each do |name|
|
|
107
|
+
attr_obj = read_attrs[name] || write_attrs[name]
|
|
108
|
+
type = attr_obj.docstring.tag(:return)&.types
|
|
109
|
+
type_str = format_type(type)
|
|
110
|
+
desc = attr_obj.docstring.to_s.split("\n").first || ''
|
|
111
|
+
|
|
112
|
+
attributes << {
|
|
113
|
+
name: name,
|
|
114
|
+
type: type_str,
|
|
115
|
+
description: desc
|
|
116
|
+
}
|
|
117
|
+
end
|
|
118
|
+
|
|
119
|
+
attributes
|
|
120
|
+
end
|
|
121
|
+
|
|
122
|
+
def generate_markdown_for_object(obj)
|
|
123
|
+
content = []
|
|
124
|
+
|
|
125
|
+
# Add main heading
|
|
126
|
+
content << "## #{obj.name}"
|
|
127
|
+
content << ''
|
|
128
|
+
|
|
129
|
+
# Add class description
|
|
130
|
+
description = extract_class_description(obj)
|
|
131
|
+
unless description.empty?
|
|
132
|
+
content << description
|
|
133
|
+
content << ''
|
|
134
|
+
end
|
|
135
|
+
|
|
136
|
+
# Add attributes/properties section (matching Python/TypeScript format)
|
|
137
|
+
if obj.is_a?(YARD::CodeObjects::ClassObject)
|
|
138
|
+
attributes = extract_attributes(obj)
|
|
139
|
+
|
|
140
|
+
if attributes.any?
|
|
141
|
+
content << '**Attributes**:'
|
|
142
|
+
content << ''
|
|
143
|
+
attributes.each do |attr|
|
|
144
|
+
content << "- `#{attr[:name]}` _#{attr[:type]}_ - #{attr[:description]}"
|
|
145
|
+
end
|
|
146
|
+
content << ''
|
|
147
|
+
end
|
|
148
|
+
end
|
|
149
|
+
|
|
150
|
+
# Add class-level examples (before constructors, matching Python/TypeScript)
|
|
151
|
+
examples = obj.tags(:example)
|
|
152
|
+
if examples.any?
|
|
153
|
+
content << '**Examples:**'
|
|
154
|
+
content << ''
|
|
155
|
+
examples.each do |example|
|
|
156
|
+
content << '```ruby'
|
|
157
|
+
content << example.text.strip
|
|
158
|
+
content << '```'
|
|
159
|
+
content << ''
|
|
160
|
+
end
|
|
161
|
+
end
|
|
162
|
+
|
|
163
|
+
# Add constructors section
|
|
164
|
+
if obj.is_a?(YARD::CodeObjects::ClassObject)
|
|
165
|
+
constructor = obj.meths.find { |m| m.name == :initialize }
|
|
166
|
+
if constructor
|
|
167
|
+
content << '### Constructors'
|
|
168
|
+
content << ''
|
|
169
|
+
content << "#### new #{extract_class_name_from_path(obj.path)}()"
|
|
170
|
+
content << ''
|
|
171
|
+
|
|
172
|
+
# Method signature
|
|
173
|
+
content << '```ruby'
|
|
174
|
+
params_str = constructor.parameters.map { |p| p[0] }.join(', ')
|
|
175
|
+
content << "def initialize(#{params_str})"
|
|
176
|
+
content << '```'
|
|
177
|
+
content << ''
|
|
178
|
+
|
|
179
|
+
# Constructor description
|
|
180
|
+
if constructor.docstring && !constructor.docstring.empty?
|
|
181
|
+
desc = clean_description(constructor.docstring)
|
|
182
|
+
unless desc.empty?
|
|
183
|
+
content << desc
|
|
184
|
+
content << ''
|
|
185
|
+
end
|
|
186
|
+
end
|
|
187
|
+
|
|
188
|
+
# Parameters
|
|
189
|
+
params = constructor.tags(:param)
|
|
190
|
+
if params.any?
|
|
191
|
+
content << '**Parameters**:'
|
|
192
|
+
content << ''
|
|
193
|
+
params.each do |param|
|
|
194
|
+
types = format_type(param.types)
|
|
195
|
+
content << "- `#{param.name}` _#{types}_ - #{param.text}"
|
|
196
|
+
end
|
|
197
|
+
content << ''
|
|
198
|
+
end
|
|
199
|
+
|
|
200
|
+
# Returns
|
|
201
|
+
return_tag = constructor.tag(:return)
|
|
202
|
+
if return_tag
|
|
203
|
+
types = format_type(return_tag.types)
|
|
204
|
+
text = return_tag.text.to_s.strip
|
|
205
|
+
content << '**Returns**:'
|
|
206
|
+
content << ''
|
|
207
|
+
content << if text.empty?
|
|
208
|
+
"- `#{types}`"
|
|
209
|
+
else
|
|
210
|
+
"- `#{types}` - #{text}"
|
|
211
|
+
end
|
|
212
|
+
content << ''
|
|
213
|
+
end
|
|
214
|
+
|
|
215
|
+
# Raises
|
|
216
|
+
raises = constructor.tags(:raise)
|
|
217
|
+
if raises.any?
|
|
218
|
+
content << '**Raises**:'
|
|
219
|
+
content << ''
|
|
220
|
+
raises.each do |raise_tag|
|
|
221
|
+
types = format_type(raise_tag.types)
|
|
222
|
+
content << "- `#{types}` - #{raise_tag.text}"
|
|
223
|
+
end
|
|
224
|
+
content << ''
|
|
225
|
+
end
|
|
226
|
+
end
|
|
227
|
+
end
|
|
228
|
+
|
|
229
|
+
# Add methods section
|
|
230
|
+
if obj.is_a?(YARD::CodeObjects::ClassObject)
|
|
231
|
+
methods = obj.meths.select { |m| m.scope == :instance && m.visibility == :public && m.name != :initialize }
|
|
232
|
+
|
|
233
|
+
if methods.any?
|
|
234
|
+
content << '### Methods'
|
|
235
|
+
content << ''
|
|
236
|
+
|
|
237
|
+
methods.each do |method|
|
|
238
|
+
content << "#### #{method.name}()"
|
|
239
|
+
content << ''
|
|
240
|
+
|
|
241
|
+
# Method signature
|
|
242
|
+
content << '```ruby'
|
|
243
|
+
params_str = method.parameters.map { |p| p[0] }.join(', ')
|
|
244
|
+
content << "def #{method.name}(#{params_str})"
|
|
245
|
+
content << '```'
|
|
246
|
+
content << ''
|
|
247
|
+
|
|
248
|
+
# Method description
|
|
249
|
+
if method.docstring && !method.docstring.empty?
|
|
250
|
+
desc = clean_description(method.docstring)
|
|
251
|
+
unless desc.empty?
|
|
252
|
+
content << desc
|
|
253
|
+
content << ''
|
|
254
|
+
end
|
|
255
|
+
end
|
|
256
|
+
|
|
257
|
+
# Parameters
|
|
258
|
+
params = method.tags(:param)
|
|
259
|
+
if params.any?
|
|
260
|
+
content << '**Parameters**:'
|
|
261
|
+
content << ''
|
|
262
|
+
params.each do |param|
|
|
263
|
+
types = format_type(param.types)
|
|
264
|
+
content << "- `#{param.name}` _#{types}_ - #{param.text}"
|
|
265
|
+
end
|
|
266
|
+
content << ''
|
|
267
|
+
end
|
|
268
|
+
|
|
269
|
+
# Returns
|
|
270
|
+
return_tag = method.tag(:return)
|
|
271
|
+
if return_tag
|
|
272
|
+
types = format_type(return_tag.types)
|
|
273
|
+
text = return_tag.text.to_s.strip
|
|
274
|
+
content << '**Returns**:'
|
|
275
|
+
content << ''
|
|
276
|
+
# Only add description if it's meaningful and not just repeating the type
|
|
277
|
+
content << if text.empty? || text.start_with?('Array<') || text.start_with?('Hash<')
|
|
278
|
+
"- `#{types}`"
|
|
279
|
+
else
|
|
280
|
+
"- `#{types}` - #{text}"
|
|
281
|
+
end
|
|
282
|
+
content << ''
|
|
283
|
+
end
|
|
284
|
+
|
|
285
|
+
# Raises
|
|
286
|
+
raises = method.tags(:raise)
|
|
287
|
+
if raises.any?
|
|
288
|
+
content << '**Raises**:'
|
|
289
|
+
content << ''
|
|
290
|
+
raises.each do |raise_tag|
|
|
291
|
+
types = format_type(raise_tag.types)
|
|
292
|
+
content << "- `#{types}` - #{raise_tag.text}"
|
|
293
|
+
end
|
|
294
|
+
content << ''
|
|
295
|
+
end
|
|
296
|
+
|
|
297
|
+
# Method-level examples
|
|
298
|
+
examples = method.tags(:example)
|
|
299
|
+
next unless examples.any?
|
|
300
|
+
|
|
301
|
+
content << '**Examples:**'
|
|
302
|
+
content << ''
|
|
303
|
+
examples.each do |example|
|
|
304
|
+
content << '```ruby'
|
|
305
|
+
content << example.text.strip
|
|
306
|
+
content << '```'
|
|
307
|
+
content << ''
|
|
308
|
+
end
|
|
309
|
+
end
|
|
310
|
+
end
|
|
311
|
+
end
|
|
312
|
+
|
|
313
|
+
content.join("\n")
|
|
314
|
+
end
|
|
315
|
+
|
|
316
|
+
def post_process_markdown(content)
|
|
317
|
+
# Remove excessive blank lines (more than 2 consecutive)
|
|
318
|
+
content = content.gsub(/\n{3,}/, "\n\n")
|
|
319
|
+
|
|
320
|
+
# Remove blank lines inside code blocks
|
|
321
|
+
content = content.gsub("```ruby\n\n", "```ruby\n")
|
|
322
|
+
content = content.gsub("\n\n```", "\n```")
|
|
323
|
+
|
|
324
|
+
# Ensure consistent spacing around sections
|
|
325
|
+
content = content.gsub(/\n(\*\*[^*]+\*\*:)\n([^\n])/, "\n\\1\n\n\\2")
|
|
326
|
+
|
|
327
|
+
# Ensure code blocks have proper spacing
|
|
328
|
+
content = content.gsub(/([^\n])\n```/, "\\1\n\n```")
|
|
329
|
+
content = content.gsub(/```\n([^\n])/, "```\n\n\\1")
|
|
330
|
+
|
|
331
|
+
# Clean up trailing whitespace
|
|
332
|
+
content = content.lines.map(&:rstrip).join("\n")
|
|
333
|
+
|
|
334
|
+
# Ensure file ends with single newline
|
|
335
|
+
content.strip + "\n"
|
|
336
|
+
end
|
|
337
|
+
|
|
338
|
+
def generate_docs_for_class(file_path, output_filename, class_name)
|
|
339
|
+
full_path = File.join(LIB_DIR, file_path)
|
|
340
|
+
|
|
341
|
+
unless File.exist?(full_path)
|
|
342
|
+
puts "⚠️ File not found: #{full_path}"
|
|
343
|
+
return
|
|
344
|
+
end
|
|
345
|
+
|
|
346
|
+
puts "📝 Generating docs for #{class_name}..."
|
|
347
|
+
|
|
348
|
+
begin
|
|
349
|
+
# Clear and parse with YARD
|
|
350
|
+
YARD::Registry.clear
|
|
351
|
+
YARD::Parser::SourceParser.parse(full_path)
|
|
352
|
+
|
|
353
|
+
# Get the class object
|
|
354
|
+
obj = YARD::Registry.at(class_name)
|
|
355
|
+
|
|
356
|
+
unless obj
|
|
357
|
+
puts "⚠️ Class #{class_name} not found in registry"
|
|
358
|
+
return
|
|
359
|
+
end
|
|
360
|
+
|
|
361
|
+
# Generate markdown content
|
|
362
|
+
markdown_content = generate_markdown_for_object(obj)
|
|
363
|
+
|
|
364
|
+
# Post-process for consistency
|
|
365
|
+
markdown_content = post_process_markdown(markdown_content)
|
|
366
|
+
|
|
367
|
+
# Add frontmatter
|
|
368
|
+
final_content = add_frontmatter(markdown_content, class_name)
|
|
369
|
+
|
|
370
|
+
# Write to output file
|
|
371
|
+
output_path = File.join(DOCS_OUTPUT_DIR, output_filename)
|
|
372
|
+
File.write(output_path, final_content)
|
|
373
|
+
|
|
374
|
+
puts "✅ Generated: #{output_filename}"
|
|
375
|
+
rescue StandardError => e
|
|
376
|
+
puts "❌ Error generating docs for #{class_name}: #{e.message}"
|
|
377
|
+
puts e.backtrace.first(5).join("\n") if ENV['DEBUG']
|
|
378
|
+
end
|
|
379
|
+
end
|
|
380
|
+
|
|
381
|
+
# Main execution
|
|
382
|
+
puts '🚀 Starting documentation generation...'
|
|
383
|
+
puts "📂 Output directory: #{DOCS_OUTPUT_DIR}"
|
|
384
|
+
puts ''
|
|
385
|
+
|
|
386
|
+
# Ensure output directory exists
|
|
387
|
+
FileUtils.mkdir_p(DOCS_OUTPUT_DIR)
|
|
388
|
+
|
|
389
|
+
# Generate docs for each class
|
|
390
|
+
CLASSES_TO_DOCUMENT.each do |file_path, output_filename, class_name|
|
|
391
|
+
generate_docs_for_class(file_path, output_filename, class_name)
|
|
392
|
+
end
|
|
393
|
+
|
|
394
|
+
puts ''
|
|
395
|
+
puts '✨ Documentation generation complete!'
|
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.134.0.alpha.1
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Daytona Platforms Inc.
|
|
@@ -29,28 +29,28 @@ dependencies:
|
|
|
29
29
|
requirements:
|
|
30
30
|
- - '='
|
|
31
31
|
- !ruby/object:Gem::Version
|
|
32
|
-
version: 0.
|
|
32
|
+
version: 0.134.0.alpha.1
|
|
33
33
|
type: :runtime
|
|
34
34
|
prerelease: false
|
|
35
35
|
version_requirements: !ruby/object:Gem::Requirement
|
|
36
36
|
requirements:
|
|
37
37
|
- - '='
|
|
38
38
|
- !ruby/object:Gem::Version
|
|
39
|
-
version: 0.
|
|
39
|
+
version: 0.134.0.alpha.1
|
|
40
40
|
- !ruby/object:Gem::Dependency
|
|
41
41
|
name: daytona_toolbox_api_client
|
|
42
42
|
requirement: !ruby/object:Gem::Requirement
|
|
43
43
|
requirements:
|
|
44
44
|
- - '='
|
|
45
45
|
- !ruby/object:Gem::Version
|
|
46
|
-
version: 0.
|
|
46
|
+
version: 0.134.0.alpha.1
|
|
47
47
|
type: :runtime
|
|
48
48
|
prerelease: false
|
|
49
49
|
version_requirements: !ruby/object:Gem::Requirement
|
|
50
50
|
requirements:
|
|
51
51
|
- - '='
|
|
52
52
|
- !ruby/object:Gem::Version
|
|
53
|
-
version: 0.
|
|
53
|
+
version: 0.134.0.alpha.1
|
|
54
54
|
- !ruby/object:Gem::Dependency
|
|
55
55
|
name: dotenv
|
|
56
56
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -107,9 +107,12 @@ files:
|
|
|
107
107
|
- README.md
|
|
108
108
|
- Rakefile
|
|
109
109
|
- lib/daytona.rb
|
|
110
|
+
- lib/daytona/code_interpreter.rb
|
|
111
|
+
- lib/daytona/code_toolbox/sandbox_js_code_toolbox.rb
|
|
110
112
|
- lib/daytona/code_toolbox/sandbox_python_code_toolbox.rb
|
|
111
113
|
- lib/daytona/code_toolbox/sandbox_ts_code_toolbox.rb
|
|
112
114
|
- lib/daytona/common/charts.rb
|
|
115
|
+
- lib/daytona/common/code_interpreter.rb
|
|
113
116
|
- lib/daytona/common/code_language.rb
|
|
114
117
|
- lib/daytona/common/daytona.rb
|
|
115
118
|
- lib/daytona/common/file_system.rb
|
|
@@ -136,6 +139,7 @@ files:
|
|
|
136
139
|
- lib/daytona/volume.rb
|
|
137
140
|
- lib/daytona/volume_service.rb
|
|
138
141
|
- project.json
|
|
142
|
+
- scripts/generate-docs.rb
|
|
139
143
|
- sig/daytona/sdk.rbs
|
|
140
144
|
homepage: https://github.com/daytonaio/daytona
|
|
141
145
|
licenses: []
|