daytona 0.223.0.alpha.2 → 0.223.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 5c61adcc242e709cff5697fa6001636c5baf5ece820d68bb158c449625f84af4
4
- data.tar.gz: 652be235803821f815940b2230196ff4f57db02b54061445b58b0c5d920273b9
3
+ metadata.gz: 63db7dba8b656d1b2ba3c613a1ca9896211bf22b1c6430ed1d8e23e0e517a4c0
4
+ data.tar.gz: f8af7a09143410175e8936a76a1b8471578fded4267c5307b86cf3c9ddb1b834
5
5
  SHA512:
6
- metadata.gz: 89f8d37abacbe2191b5792819fb5895de27ecd81dcc4ded547e1549c893db382231029eb1fa17525b529e00e7328c22d487b0018b2398ce61322100f3fcd50cd
7
- data.tar.gz: d95e2b4af93d135fd06d4fd3ed3791edb485a5d1720ac9da4891fa929e0481bbb8b4fe49010eff7855bd226bf8d6f2c2a90063099a0b0b21be9521c479da4d22
6
+ metadata.gz: 497a18b1e9bd0f6077bac4195f05af4cc814140a875c2ae4308957a5be8389cf474ba0b504da18e2fa4f8414333111b4f9f64151f5ed111334b9d82e0b531df9
7
+ data.tar.gz: ed9e925a0c2516974204f11229e655eae7e7ca1365e018160e7d6d0a17e2790f491c044e3242f48bfeb4e25a4dfb01d8d8455a7848303b1fc41c33fc8ba53d9a
@@ -60,6 +60,8 @@ module Daytona
60
60
  # @param y [Integer] The y coordinate to click at
61
61
  # @param button [String] The mouse button to click ('left', 'right', 'middle'). Defaults to 'left'
62
62
  # @param double [Boolean] Whether to perform a double-click. Defaults to false
63
+ # @param clicks [Integer, nil] Number of clicks to perform (1-10). Omitted when nil, which is distinct from an explicit 0
64
+ # @param modifiers [Array<String>, nil] Modifier keys to hold during the click. Canonical names are 'ctrl', 'alt', 'shift', and 'cmd'
63
65
  # @return [DaytonaToolboxApiClient::MouseClickResponse] Click operation result
64
66
  # @raise [Daytona::Sdk::Error] If the operation fails
65
67
  #
@@ -72,13 +74,74 @@ module Daytona
72
74
  #
73
75
  # # Right click
74
76
  # right_click = sandbox.computer_use.mouse.click(x: 100, y: 200, button: 'right')
75
- def click(x:, y:, button: 'left', double: false)
76
- request = DaytonaToolboxApiClient::MouseClickRequest.new(x:, y:, button:, double:)
77
+ #
78
+ # # Triple click
79
+ # triple_click = sandbox.computer_use.mouse.click(x: 100, y: 200, clicks: 3)
80
+ #
81
+ # # Ctrl+click
82
+ # ctrl_click = sandbox.computer_use.mouse.click(x: 100, y: 200, modifiers: ['ctrl'])
83
+ def click(x:, y:, button: 'left', double: false, clicks: nil, modifiers: nil)
84
+ attrs = { x:, y:, button:, double: }
85
+ attrs[:clicks] = clicks unless clicks.nil?
86
+ attrs[:modifiers] = modifiers unless modifiers.nil?
87
+
88
+ request = DaytonaToolboxApiClient::MouseClickRequest.new(attrs)
77
89
  toolbox_api.click(request)
78
90
  rescue *Sdk::API_ERROR_CLASSES => e
79
91
  raise Sdk.wrap_error(e, 'Failed to click mouse')
80
92
  end
81
93
 
94
+ # Presses and holds a mouse button, optionally moving to the coordinates first.
95
+ #
96
+ # The button stays held until a matching {#up} call.
97
+ #
98
+ # @param x [Integer, nil] The x coordinate to move to before pressing. Omitted when nil
99
+ # @param y [Integer, nil] The y coordinate to move to before pressing. Omitted when nil
100
+ # @param button [String] The mouse button to press ('left', 'right', 'middle'). Defaults to 'left'
101
+ # @return [DaytonaToolboxApiClient::MousePositionResponse] Cursor position after the press
102
+ # @raise [Daytona::Sdk::Error] If the operation fails
103
+ #
104
+ # @example
105
+ # # Press at the current cursor position
106
+ # sandbox.computer_use.mouse.down
107
+ #
108
+ # # Move to coordinates and press
109
+ # sandbox.computer_use.mouse.down(x: 100, y: 200, button: 'left')
110
+ def down(x: nil, y: nil, button: 'left')
111
+ attrs = { button: }
112
+ attrs[:x] = x unless x.nil?
113
+ attrs[:y] = y unless y.nil?
114
+
115
+ request = DaytonaToolboxApiClient::MouseDownRequest.new(attrs)
116
+ toolbox_api.mouse_down(request)
117
+ rescue *Sdk::API_ERROR_CLASSES => e
118
+ raise Sdk.wrap_error(e, 'Failed to press mouse button')
119
+ end
120
+
121
+ # Releases a held mouse button, optionally moving to the coordinates first.
122
+ #
123
+ # @param x [Integer, nil] The x coordinate to move to before releasing. Omitted when nil
124
+ # @param y [Integer, nil] The y coordinate to move to before releasing. Omitted when nil
125
+ # @param button [String] The mouse button to release ('left', 'right', 'middle'). Defaults to 'left'
126
+ # @return [DaytonaToolboxApiClient::MousePositionResponse] Cursor position after the release
127
+ # @raise [Daytona::Sdk::Error] If the operation fails
128
+ #
129
+ # @example
130
+ # # Drag by holding, moving, then releasing
131
+ # sandbox.computer_use.mouse.down(x: 10, y: 10)
132
+ # sandbox.computer_use.mouse.move(x: 200, y: 200)
133
+ # sandbox.computer_use.mouse.up(x: 200, y: 200)
134
+ def up(x: nil, y: nil, button: 'left')
135
+ attrs = { button: }
136
+ attrs[:x] = x unless x.nil?
137
+ attrs[:y] = y unless y.nil?
138
+
139
+ request = DaytonaToolboxApiClient::MouseUpRequest.new(attrs)
140
+ toolbox_api.mouse_up(request)
141
+ rescue *Sdk::API_ERROR_CLASSES => e
142
+ raise Sdk.wrap_error(e, 'Failed to release mouse button')
143
+ end
144
+
82
145
  # Drags the mouse from start coordinates to end coordinates.
83
146
  #
84
147
  # @param start_x [Integer] The starting x coordinate
@@ -86,14 +149,21 @@ module Daytona
86
149
  # @param end_x [Integer] The ending x coordinate
87
150
  # @param end_y [Integer] The ending y coordinate
88
151
  # @param button [String] The mouse button to use for dragging. Defaults to 'left'
152
+ # @param modifiers [Array<String>, nil] Modifier keys to hold during the drag. Canonical names are 'ctrl', 'alt', 'shift', and 'cmd'
89
153
  # @return [DaytonaToolboxApiClient::MouseDragResponse] Drag operation result
90
154
  # @raise [Daytona::Sdk::Error] If the operation fails
91
155
  #
92
156
  # @example
93
157
  # result = sandbox.computer_use.mouse.drag(start_x: 50, start_y: 50, end_x: 150, end_y: 150)
94
158
  # puts "Drag ended at #{result.x}, #{result.y}"
95
- def drag(start_x:, start_y:, end_x:, end_y:, button: 'left')
96
- request = DaytonaToolboxApiClient::MouseDragRequest.new(start_x:, start_y:, end_x:, end_y:, button:)
159
+ #
160
+ # # Drag while holding Shift
161
+ # sandbox.computer_use.mouse.drag(start_x: 50, start_y: 50, end_x: 150, end_y: 150, modifiers: ['shift'])
162
+ def drag(start_x:, start_y:, end_x:, end_y:, button: 'left', modifiers: nil)
163
+ attrs = { start_x:, start_y:, end_x:, end_y:, button: }
164
+ attrs[:modifiers] = modifiers unless modifiers.nil?
165
+
166
+ request = DaytonaToolboxApiClient::MouseDragRequest.new(attrs)
97
167
  toolbox_api.drag(request)
98
168
  rescue *Sdk::API_ERROR_CLASSES => e
99
169
  raise Sdk.wrap_error(e, 'Failed to drag mouse')
@@ -103,8 +173,9 @@ module Daytona
103
173
  #
104
174
  # @param x [Integer] The x coordinate to scroll at
105
175
  # @param y [Integer] The y coordinate to scroll at
106
- # @param direction [String] The direction to scroll ('up' or 'down')
176
+ # @param direction [String] The direction to scroll ('up', 'down', 'left', or 'right')
107
177
  # @param amount [Integer] The amount to scroll. Defaults to 1
178
+ # @param modifiers [Array<String>, nil] Modifier keys to hold during the scroll. Canonical names are 'ctrl', 'alt', 'shift', and 'cmd'
108
179
  # @return [Boolean] Whether the scroll operation was successful
109
180
  # @raise [Daytona::Sdk::Error] If the operation fails
110
181
  #
@@ -114,15 +185,24 @@ module Daytona
114
185
  #
115
186
  # # Scroll down
116
187
  # scroll_down = sandbox.computer_use.mouse.scroll(x: 100, y: 200, direction: 'down', amount: 5)
117
- def scroll(x:, y:, direction:, amount: 1)
118
- request = DaytonaToolboxApiClient::MouseScrollRequest.new(x:, y:, direction:, amount:)
188
+ #
189
+ # # Scroll horizontally
190
+ # scroll_left = sandbox.computer_use.mouse.scroll(x: 100, y: 200, direction: 'left', amount: 2)
191
+ #
192
+ # # Ctrl+scroll to zoom
193
+ # zoom_in = sandbox.computer_use.mouse.scroll(x: 100, y: 200, direction: 'up', modifiers: ['ctrl'])
194
+ def scroll(x:, y:, direction:, amount: 1, modifiers: nil)
195
+ attrs = { x:, y:, direction:, amount: }
196
+ attrs[:modifiers] = modifiers unless modifiers.nil?
197
+
198
+ request = DaytonaToolboxApiClient::MouseScrollRequest.new(attrs)
119
199
  toolbox_api.scroll(request)
120
200
  true
121
201
  rescue *Sdk::API_ERROR_CLASSES => e
122
202
  raise Sdk.wrap_error(e, 'Failed to scroll mouse')
123
203
  end
124
204
 
125
- instrument :position, :move, :click, :drag, :scroll, component: 'Mouse'
205
+ instrument :position, :move, :click, :down, :up, :drag, :scroll, component: 'Mouse'
126
206
 
127
207
  private
128
208
 
@@ -191,6 +271,43 @@ module Daytona
191
271
  raise Sdk.wrap_error(e, 'Failed to press key')
192
272
  end
193
273
 
274
+ # Presses and holds a key or modifier until a matching {#up} call.
275
+ #
276
+ # @param key [String] The key or modifier to hold. Uses the same normalized key contract as #press, so 'ctrl', 'shift', and 'a' are all valid
277
+ # @return [void]
278
+ # @raise [Daytona::Sdk::Error] If the operation fails
279
+ #
280
+ # @example
281
+ # # Hold Shift while typing. Release in `ensure` so a failed press cannot
282
+ # # leave Shift stuck down.
283
+ # sandbox.computer_use.keyboard.down(key: 'shift')
284
+ # begin
285
+ # sandbox.computer_use.keyboard.press(key: 'a')
286
+ # ensure
287
+ # sandbox.computer_use.keyboard.up(key: 'shift')
288
+ # end
289
+ def down(key:)
290
+ request = DaytonaToolboxApiClient::KeyboardKeyDownRequest.new(key:)
291
+ toolbox_api.key_down(request)
292
+ rescue *Sdk::API_ERROR_CLASSES => e
293
+ raise Sdk.wrap_error(e, 'Failed to press key down')
294
+ end
295
+
296
+ # Releases a key or modifier that is currently held down.
297
+ #
298
+ # @param key [String] The key or modifier to release. Uses the same normalized key contract as #press
299
+ # @return [void]
300
+ # @raise [Daytona::Sdk::Error] If the operation fails
301
+ #
302
+ # @example
303
+ # sandbox.computer_use.keyboard.up(key: 'ctrl')
304
+ def up(key:)
305
+ request = DaytonaToolboxApiClient::KeyboardKeyUpRequest.new(key:)
306
+ toolbox_api.key_up(request)
307
+ rescue *Sdk::API_ERROR_CLASSES => e
308
+ raise Sdk.wrap_error(e, 'Failed to release key')
309
+ end
310
+
194
311
  # Presses a hotkey combination.
195
312
  #
196
313
  # @param keys [String] A single atomic hotkey chord (e.g., 'ctrl+c', 'alt+tab', 'cmd+shift+t', 'ctrl + c', 'shift'). Uses the same normalized key contract as #press.
@@ -213,7 +330,7 @@ module Daytona
213
330
  raise Sdk.wrap_error(e, 'Failed to press hotkey')
214
331
  end
215
332
 
216
- instrument :type, :press, :hotkey, component: 'Keyboard'
333
+ instrument :type, :press, :down, :up, :hotkey, component: 'Keyboard'
217
334
 
218
335
  private
219
336
 
@@ -40,6 +40,20 @@ module Daytona
40
40
 
41
41
  # Execute a shell command in the Sandbox
42
42
  #
43
+ # The command is run by the first available of zsh, bash or sh in the sandbox, which is zsh
44
+ # in the default snapshots. Quote arguments that contain glob characters, for example
45
+ # `pip install -e '.[test]'`, or wrap bash-specific scripts in `bash -c '...'`.
46
+ #
47
+ # The call returns when the command finishes. To start a long-running process such as a
48
+ # server, run it in the background with its output redirected, e.g.
49
+ # `python3 -m http.server 8000 > server.log 2>&1 &`, or use a session with `run_async: true`
50
+ # (see {#execute_session_command}). A background process that keeps the command's output open
51
+ # (`cmd &` without a redirect) can block the call until that process exits.
52
+ #
53
+ # Tools in the sandbox may report the host's CPU count and memory (for example `nproc` or
54
+ # `Etc.nprocessors`) rather than the sandbox's own limits. Size worker pools from the
55
+ # sandbox's cpu and memory instead, e.g. `pytest -n 2` rather than `pytest -n auto`.
56
+ #
43
57
  # @param command [String] Shell command to execute
44
58
  # @param cwd [String, nil] Working directory for command execution. If not specified, uses the sandbox working directory
45
59
  # @param env [Hash<String, String>, nil] Environment variables to set for the command
@@ -48,15 +62,18 @@ module Daytona
48
62
  #
49
63
  # @example
50
64
  # # Simple command
51
- # response = sandbox.process.exec("echo 'Hello'")
65
+ # response = sandbox.process.exec(command: "echo 'Hello'")
52
66
  # puts response.artifacts.stdout
53
67
  # => "Hello\n"
54
68
  #
55
69
  # # Command with working directory
56
- # result = sandbox.process.exec("ls", cwd: "workspace/src")
70
+ # result = sandbox.process.exec(command: "ls", cwd: "workspace/src")
57
71
  #
58
72
  # # Command with timeout
59
- # result = sandbox.process.exec("sleep 10", timeout: 5)
73
+ # result = sandbox.process.exec(command: "sleep 10", timeout: 5)
74
+ #
75
+ # # Start a server in the background
76
+ # sandbox.process.exec(command: "python3 -m http.server 8000 > server.log 2>&1 &")
60
77
  def exec(command:, cwd: nil, env: nil, timeout: nil)
61
78
  envs = env&.empty? ? nil : env
62
79
 
@@ -364,6 +364,21 @@ module Daytona
364
364
  process_response(data)
365
365
  end
366
366
 
367
+ # Sets whether the Sandbox's preview URLs are publicly accessible.
368
+ # When public, preview URLs (see #preview_url) can be opened without a preview token or API key.
369
+ # When private, every preview request must authenticate.
370
+ #
371
+ # @param is_public [Boolean]
372
+ # @return [Boolean]
373
+ # @raise [Daytona::Sdk::Error]
374
+ #
375
+ # @example
376
+ # sandbox.public = true
377
+ def public=(is_public)
378
+ sandbox_api.update_public_status(id, is_public)
379
+ @public = is_public
380
+ end
381
+
367
382
  # Sets the auto-stop interval for the Sandbox.
368
383
  # The Sandbox will automatically stop after being idle (no new events) for the specified interval.
369
384
  # Events include any state changes or interactions with the Sandbox through the SDK.
@@ -555,8 +570,21 @@ module Daytona
555
570
  # it will be opened automatically. For private sandboxes, a token is included to grant access
556
571
  # to the URL.
557
572
  #
573
+ # For a private sandbox, requests to the URL must authenticate, otherwise they are answered
574
+ # with 401 Unauthorized. Send the returned token in the X-Daytona-Preview-Token header, or
575
+ # send your Daytona API key as "Authorization: Bearer <api key>". To get a URL that works
576
+ # without extra headers (for example to open it in a browser or share it), use
577
+ # {#create_signed_preview_url} instead. Public sandboxes need no credentials.
578
+ #
558
579
  # @param port [Integer]
559
580
  # @return [DaytonaApiClient::PortPreviewUrl]
581
+ #
582
+ # @example
583
+ # preview = sandbox.preview_url(3000)
584
+ # uri = URI(preview.url)
585
+ # request = Net::HTTP::Get.new(uri)
586
+ # request['X-Daytona-Preview-Token'] = preview.token
587
+ # response = Net::HTTP.start(uri.host, uri.port, use_ssl: true) { |http| http.request(request) }
560
588
  def preview_url(port)
561
589
  sandbox_api.get_port_preview_url(id, port)
562
590
  end
@@ -633,9 +661,14 @@ module Daytona
633
661
 
634
662
  # Creates a signed preview URL for the sandbox at the specified port.
635
663
  #
664
+ # The access token is embedded in the returned URL, so it can be used without any headers,
665
+ # for example in a browser or by another service. The URL stops working when it expires or
666
+ # when it is expired with {#expire_signed_preview_url}.
667
+ #
636
668
  # @param port [Integer] The port to open the preview link on
637
669
  # @param expires_in_seconds [Integer, nil] The number of seconds the signed preview URL
638
- # will be valid for. Defaults to 60 seconds.
670
+ # will be valid for. Defaults to 60 seconds; set a longer value for links that need to
671
+ # stay usable, e.g. 3600 for one hour.
639
672
  # @return [DaytonaApiClient::SignedPortPreviewUrl] The signed preview URL response object
640
673
  #
641
674
  # @example
@@ -951,7 +984,7 @@ module Daytona
951
984
  end
952
985
  end
953
986
 
954
- with_events :archive, :auto_archive_interval=, :auto_delete_interval=, :auto_stop_interval=,
987
+ with_events :archive, :auto_archive_interval=, :auto_delete_interval=, :auto_stop_interval=, :public=,
955
988
  :create_ssh_access, :delete, :get_user_home_dir, :get_work_dir, :labels=,
956
989
  :preview_url, :create_signed_preview_url, :expire_signed_preview_url,
957
990
  :refresh, :refresh_activity, :revoke_ssh_access, :start, :recover, :stop,
@@ -960,7 +993,7 @@ module Daytona
960
993
  :fork, :create_snapshot, :pause
961
994
 
962
995
  instrument :archive, :auto_archive_interval=, :auto_delete_interval=, :auto_pause_interval=, :auto_stop_interval=,
963
- :ttl_minutes=,
996
+ :ttl_minutes=, :public=,
964
997
  :update_network_settings, :update_secrets, :update_env,
965
998
  :create_ssh_access, :delete, :get_user_home_dir, :get_work_dir, :get_metrics, :get_metrics_latest,
966
999
  :labels=,
@@ -5,6 +5,6 @@
5
5
 
6
6
  module Daytona
7
7
  module Sdk
8
- VERSION = '0.223.0.alpha.2'
8
+ VERSION = '0.223.1'
9
9
  end
10
10
  end
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.223.0.alpha.2
4
+ version: 0.223.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Daytona Platforms Inc.
@@ -91,42 +91,42 @@ dependencies:
91
91
  requirements:
92
92
  - - '='
93
93
  - !ruby/object:Gem::Version
94
- version: 0.223.0.alpha.2
94
+ version: 0.223.1
95
95
  type: :runtime
96
96
  prerelease: false
97
97
  version_requirements: !ruby/object:Gem::Requirement
98
98
  requirements:
99
99
  - - '='
100
100
  - !ruby/object:Gem::Version
101
- version: 0.223.0.alpha.2
101
+ version: 0.223.1
102
102
  - !ruby/object:Gem::Dependency
103
103
  name: daytona_api_client
104
104
  requirement: !ruby/object:Gem::Requirement
105
105
  requirements:
106
106
  - - '='
107
107
  - !ruby/object:Gem::Version
108
- version: 0.223.0.alpha.2
108
+ version: 0.223.1
109
109
  type: :runtime
110
110
  prerelease: false
111
111
  version_requirements: !ruby/object:Gem::Requirement
112
112
  requirements:
113
113
  - - '='
114
114
  - !ruby/object:Gem::Version
115
- version: 0.223.0.alpha.2
115
+ version: 0.223.1
116
116
  - !ruby/object:Gem::Dependency
117
117
  name: daytona_toolbox_api_client
118
118
  requirement: !ruby/object:Gem::Requirement
119
119
  requirements:
120
120
  - - '='
121
121
  - !ruby/object:Gem::Version
122
- version: 0.223.0.alpha.2
122
+ version: 0.223.1
123
123
  type: :runtime
124
124
  prerelease: false
125
125
  version_requirements: !ruby/object:Gem::Requirement
126
126
  requirements:
127
127
  - - '='
128
128
  - !ruby/object:Gem::Version
129
- version: 0.223.0.alpha.2
129
+ version: 0.223.1
130
130
  - !ruby/object:Gem::Dependency
131
131
  name: dotenv
132
132
  requirement: !ruby/object:Gem::Requirement