e2b 0.2.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 +7 -0
- data/LICENSE.txt +21 -0
- data/README.md +181 -0
- data/lib/e2b/api/http_client.rb +164 -0
- data/lib/e2b/client.rb +201 -0
- data/lib/e2b/configuration.rb +119 -0
- data/lib/e2b/errors.rb +88 -0
- data/lib/e2b/models/entry_info.rb +243 -0
- data/lib/e2b/models/process_result.rb +127 -0
- data/lib/e2b/models/sandbox_info.rb +94 -0
- data/lib/e2b/sandbox.rb +407 -0
- data/lib/e2b/services/base_service.rb +485 -0
- data/lib/e2b/services/command_handle.rb +350 -0
- data/lib/e2b/services/commands.rb +229 -0
- data/lib/e2b/services/filesystem.rb +373 -0
- data/lib/e2b/services/git.rb +893 -0
- data/lib/e2b/services/pty.rb +297 -0
- data/lib/e2b/services/watch_handle.rb +110 -0
- data/lib/e2b/version.rb +5 -0
- data/lib/e2b.rb +87 -0
- metadata +142 -0
|
@@ -0,0 +1,297 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "base64"
|
|
4
|
+
require_relative "base_service"
|
|
5
|
+
require_relative "command_handle"
|
|
6
|
+
|
|
7
|
+
module E2B
|
|
8
|
+
module Services
|
|
9
|
+
# Pseudo-terminal size specification.
|
|
10
|
+
#
|
|
11
|
+
# @example Default 80x24 terminal
|
|
12
|
+
# size = PtySize.new
|
|
13
|
+
#
|
|
14
|
+
# @example Custom size
|
|
15
|
+
# size = PtySize.new(cols: 120, rows: 40)
|
|
16
|
+
class PtySize
|
|
17
|
+
# @return [Integer] Number of columns
|
|
18
|
+
attr_reader :cols
|
|
19
|
+
|
|
20
|
+
# @return [Integer] Number of rows
|
|
21
|
+
attr_reader :rows
|
|
22
|
+
|
|
23
|
+
# @param cols [Integer] Number of columns (default: 80)
|
|
24
|
+
# @param rows [Integer] Number of rows (default: 24)
|
|
25
|
+
def initialize(cols: 80, rows: 24)
|
|
26
|
+
@cols = cols
|
|
27
|
+
@rows = rows
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
# Convert to a Hash suitable for the Connect RPC request body.
|
|
31
|
+
#
|
|
32
|
+
# @return [Hash]
|
|
33
|
+
def to_h
|
|
34
|
+
{ cols: @cols, rows: @rows }
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
# PTY (pseudo-terminal) service for E2B sandbox.
|
|
39
|
+
#
|
|
40
|
+
# Provides methods to create, connect to, and manage interactive
|
|
41
|
+
# pseudo-terminals inside the sandbox. Uses Connect RPC protocol
|
|
42
|
+
# with the +process.Process+ service.
|
|
43
|
+
#
|
|
44
|
+
# @example Create a PTY and send commands
|
|
45
|
+
# pty = sandbox.pty
|
|
46
|
+
# handle = pty.create
|
|
47
|
+
# handle.send_stdin("ls -la\n")
|
|
48
|
+
# result = handle.wait(on_pty: ->(data) { print data })
|
|
49
|
+
#
|
|
50
|
+
# @example Resize a PTY
|
|
51
|
+
# pty.resize(handle.pid, PtySize.new(cols: 120, rows: 40))
|
|
52
|
+
#
|
|
53
|
+
# @example Connect to an existing PTY
|
|
54
|
+
# handle = pty.connect(pid)
|
|
55
|
+
class Pty < BaseService
|
|
56
|
+
# Default shell to use for PTY sessions
|
|
57
|
+
DEFAULT_SHELL = "/bin/bash"
|
|
58
|
+
|
|
59
|
+
# Default shell arguments for interactive login shell
|
|
60
|
+
DEFAULT_SHELL_ARGS = ["-i", "-l"].freeze
|
|
61
|
+
|
|
62
|
+
# Create a new PTY (pseudo-terminal) session in the sandbox.
|
|
63
|
+
#
|
|
64
|
+
# Starts an interactive shell process with a PTY attached. The
|
|
65
|
+
# returned {CommandHandle} can be used to send input, receive
|
|
66
|
+
# output, and manage the PTY lifecycle.
|
|
67
|
+
#
|
|
68
|
+
# @param size [PtySize] Terminal size (default: 80 columns x 24 rows)
|
|
69
|
+
# @param user [String, nil] User to run the PTY as
|
|
70
|
+
# @param cwd [String, nil] Working directory for the PTY shell
|
|
71
|
+
# @param envs [Hash{String => String}, nil] Environment variables
|
|
72
|
+
# @param cmd [String] Shell executable (default: /bin/bash)
|
|
73
|
+
# @param args [Array<String>] Shell arguments (default: ["-i", "-l"])
|
|
74
|
+
# @param timeout [Integer] Timeout for the PTY session in seconds
|
|
75
|
+
# @return [CommandHandle] Handle to interact with the PTY
|
|
76
|
+
# @raise [E2B::E2BError] if the PTY could not be started
|
|
77
|
+
#
|
|
78
|
+
# @example
|
|
79
|
+
# handle = sandbox.pty.create(
|
|
80
|
+
# size: PtySize.new(cols: 120, rows: 40),
|
|
81
|
+
# cwd: "/home/user/project",
|
|
82
|
+
# envs: { "EDITOR" => "vim" }
|
|
83
|
+
# )
|
|
84
|
+
def create(size: PtySize.new, user: nil, cwd: nil, envs: nil,
|
|
85
|
+
cmd: DEFAULT_SHELL, args: DEFAULT_SHELL_ARGS, timeout: 60)
|
|
86
|
+
envs = build_pty_envs(envs)
|
|
87
|
+
|
|
88
|
+
process_spec = {
|
|
89
|
+
cmd: cmd,
|
|
90
|
+
args: args,
|
|
91
|
+
envs: envs
|
|
92
|
+
}
|
|
93
|
+
process_spec[:cwd] = cwd if cwd
|
|
94
|
+
|
|
95
|
+
body = {
|
|
96
|
+
process: process_spec,
|
|
97
|
+
pty: {
|
|
98
|
+
size: size.to_h
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
pid = nil
|
|
103
|
+
|
|
104
|
+
# Use streaming RPC to capture the StartEvent and extract the PID
|
|
105
|
+
on_event = ->(event_data) {
|
|
106
|
+
event = event_data[:event]
|
|
107
|
+
if event.is_a?(Hash) && event["event"]
|
|
108
|
+
start_event = event["event"]["Start"] || event["event"]["start"]
|
|
109
|
+
if start_event && start_event["pid"]
|
|
110
|
+
pid = start_event["pid"]
|
|
111
|
+
end
|
|
112
|
+
end
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
response = envd_rpc(
|
|
116
|
+
"process.Process", "Start",
|
|
117
|
+
body: body,
|
|
118
|
+
timeout: timeout + 30,
|
|
119
|
+
on_event: on_event
|
|
120
|
+
)
|
|
121
|
+
|
|
122
|
+
# If PID was not captured from streaming, try the accumulated result
|
|
123
|
+
pid ||= extract_pid_from_result(response)
|
|
124
|
+
|
|
125
|
+
CommandHandle.new(
|
|
126
|
+
pid: pid,
|
|
127
|
+
handle_kill: -> { kill(pid) },
|
|
128
|
+
handle_send_stdin: ->(data) { send_stdin(pid, data) },
|
|
129
|
+
result: response
|
|
130
|
+
)
|
|
131
|
+
end
|
|
132
|
+
|
|
133
|
+
# Connect to an existing PTY process.
|
|
134
|
+
#
|
|
135
|
+
# Attaches to a running PTY process by PID and returns a handle
|
|
136
|
+
# for sending input and receiving output.
|
|
137
|
+
#
|
|
138
|
+
# @param pid [Integer] Process ID of the PTY to connect to
|
|
139
|
+
# @param timeout [Integer] Timeout for the connection in seconds
|
|
140
|
+
# @return [CommandHandle] Handle to interact with the PTY
|
|
141
|
+
# @raise [E2B::E2BError] if the process is not found or connection fails
|
|
142
|
+
#
|
|
143
|
+
# @example
|
|
144
|
+
# handle = sandbox.pty.connect(12345)
|
|
145
|
+
# handle.send_stdin("whoami\n")
|
|
146
|
+
def connect(pid, timeout: 60)
|
|
147
|
+
body = {
|
|
148
|
+
process: { pid: pid }
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
response = envd_rpc(
|
|
152
|
+
"process.Process", "Connect",
|
|
153
|
+
body: body,
|
|
154
|
+
timeout: timeout + 30
|
|
155
|
+
)
|
|
156
|
+
|
|
157
|
+
CommandHandle.new(
|
|
158
|
+
pid: pid,
|
|
159
|
+
handle_kill: -> { kill(pid) },
|
|
160
|
+
handle_send_stdin: ->(data) { send_stdin(pid, data) },
|
|
161
|
+
result: response
|
|
162
|
+
)
|
|
163
|
+
end
|
|
164
|
+
|
|
165
|
+
# Send input data to a PTY.
|
|
166
|
+
#
|
|
167
|
+
# The data is base64-encoded and sent as PTY input (not stdin),
|
|
168
|
+
# which means it goes through the terminal emulator and supports
|
|
169
|
+
# control characters, escape sequences, etc.
|
|
170
|
+
#
|
|
171
|
+
# @param pid [Integer] Process ID of the PTY
|
|
172
|
+
# @param data [String] Input data to send (e.g., "ls -la\n")
|
|
173
|
+
# @return [void]
|
|
174
|
+
# @raise [E2B::E2BError] if the process is not found
|
|
175
|
+
#
|
|
176
|
+
# @example Send a command
|
|
177
|
+
# sandbox.pty.send_stdin(pid, "echo hello\n")
|
|
178
|
+
#
|
|
179
|
+
# @example Send Ctrl+C
|
|
180
|
+
# sandbox.pty.send_stdin(pid, "\x03")
|
|
181
|
+
def send_stdin(pid, data)
|
|
182
|
+
encoded = Base64.strict_encode64(data.is_a?(String) ? data : data.to_s)
|
|
183
|
+
envd_rpc("process.Process", "SendInput", body: {
|
|
184
|
+
process: { pid: pid },
|
|
185
|
+
input: { pty: encoded }
|
|
186
|
+
})
|
|
187
|
+
end
|
|
188
|
+
|
|
189
|
+
# Kill a PTY process with SIGKILL.
|
|
190
|
+
#
|
|
191
|
+
# @param pid [Integer] Process ID of the PTY to kill
|
|
192
|
+
# @return [Boolean] true if the signal was sent, false if the process was not found
|
|
193
|
+
#
|
|
194
|
+
# @example
|
|
195
|
+
# sandbox.pty.kill(12345)
|
|
196
|
+
def kill(pid)
|
|
197
|
+
envd_rpc("process.Process", "SendSignal", body: {
|
|
198
|
+
process: { pid: pid },
|
|
199
|
+
signal: 9 # SIGKILL
|
|
200
|
+
})
|
|
201
|
+
true
|
|
202
|
+
rescue E2B::E2BError
|
|
203
|
+
false
|
|
204
|
+
end
|
|
205
|
+
|
|
206
|
+
# Resize a PTY terminal.
|
|
207
|
+
#
|
|
208
|
+
# Should be called when the terminal window size changes to keep
|
|
209
|
+
# the remote PTY in sync.
|
|
210
|
+
#
|
|
211
|
+
# @param pid [Integer] Process ID of the PTY
|
|
212
|
+
# @param size [PtySize] New terminal size
|
|
213
|
+
# @return [void]
|
|
214
|
+
# @raise [E2B::E2BError] if the process is not found
|
|
215
|
+
#
|
|
216
|
+
# @example
|
|
217
|
+
# sandbox.pty.resize(pid, PtySize.new(cols: 120, rows: 40))
|
|
218
|
+
def resize(pid, size)
|
|
219
|
+
envd_rpc("process.Process", "Update", body: {
|
|
220
|
+
process: { pid: pid },
|
|
221
|
+
pty: {
|
|
222
|
+
size: size.to_h
|
|
223
|
+
}
|
|
224
|
+
})
|
|
225
|
+
end
|
|
226
|
+
|
|
227
|
+
# Close the stdin of a PTY process.
|
|
228
|
+
#
|
|
229
|
+
# After calling this, no more input can be sent to the PTY via
|
|
230
|
+
# {#send_stdin}.
|
|
231
|
+
#
|
|
232
|
+
# @param pid [Integer] Process ID of the PTY
|
|
233
|
+
# @return [void]
|
|
234
|
+
# @raise [E2B::E2BError] if the process is not found
|
|
235
|
+
def close_stdin(pid)
|
|
236
|
+
envd_rpc("process.Process", "CloseStdin", body: {
|
|
237
|
+
process: { pid: pid }
|
|
238
|
+
})
|
|
239
|
+
end
|
|
240
|
+
|
|
241
|
+
# List running processes in the sandbox.
|
|
242
|
+
#
|
|
243
|
+
# @return [Array<Hash>] List of running process descriptors
|
|
244
|
+
def list
|
|
245
|
+
response = envd_rpc("process.Process", "List", body: {})
|
|
246
|
+
response["processes"] || response[:processes] || []
|
|
247
|
+
end
|
|
248
|
+
|
|
249
|
+
private
|
|
250
|
+
|
|
251
|
+
# Build environment variables hash with PTY defaults.
|
|
252
|
+
#
|
|
253
|
+
# Ensures TERM, LANG, and LC_ALL are set to sensible defaults
|
|
254
|
+
# for terminal operation unless the caller has overridden them.
|
|
255
|
+
#
|
|
256
|
+
# @param envs [Hash{String => String}, nil] Caller-provided env vars
|
|
257
|
+
# @return [Hash{String => String}]
|
|
258
|
+
def build_pty_envs(envs)
|
|
259
|
+
result = {}
|
|
260
|
+
result["TERM"] = "xterm-256color"
|
|
261
|
+
result["LANG"] = "C.UTF-8"
|
|
262
|
+
result["LC_ALL"] = "C.UTF-8"
|
|
263
|
+
|
|
264
|
+
if envs.is_a?(Hash)
|
|
265
|
+
envs.each { |k, v| result[k.to_s] = v.to_s }
|
|
266
|
+
end
|
|
267
|
+
|
|
268
|
+
result
|
|
269
|
+
end
|
|
270
|
+
|
|
271
|
+
# Extract PID from the StartEvent in a pre-materialized RPC result.
|
|
272
|
+
#
|
|
273
|
+
# The result hash from {EnvdHttpClient#handle_streaming_rpc} or
|
|
274
|
+
# {EnvdHttpClient#handle_rpc_response} contains an :events array.
|
|
275
|
+
# The first event with a Start sub-event carries the PID.
|
|
276
|
+
#
|
|
277
|
+
# @param response [Hash] RPC response hash with :events key
|
|
278
|
+
# @return [Integer, nil] Process ID, or nil if not found
|
|
279
|
+
def extract_pid_from_result(response)
|
|
280
|
+
return nil unless response.is_a?(Hash)
|
|
281
|
+
|
|
282
|
+
events = response[:events] || []
|
|
283
|
+
events.each do |event_hash|
|
|
284
|
+
next unless event_hash.is_a?(Hash) && event_hash["event"]
|
|
285
|
+
|
|
286
|
+
event = event_hash["event"]
|
|
287
|
+
start_event = event["Start"] || event["start"]
|
|
288
|
+
if start_event && start_event["pid"]
|
|
289
|
+
return start_event["pid"]
|
|
290
|
+
end
|
|
291
|
+
end
|
|
292
|
+
|
|
293
|
+
nil
|
|
294
|
+
end
|
|
295
|
+
end
|
|
296
|
+
end
|
|
297
|
+
end
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module E2B
|
|
4
|
+
module Services
|
|
5
|
+
# Handle for watching directory changes in the sandbox
|
|
6
|
+
#
|
|
7
|
+
# Returned by {Filesystem#watch_dir}. Uses the polling-based watcher RPCs
|
|
8
|
+
# (CreateWatcher/GetWatcherEvents/RemoveWatcher) from the filesystem proto service.
|
|
9
|
+
#
|
|
10
|
+
# The watcher is created externally and its ID is passed into this handle.
|
|
11
|
+
# Call {#get_new_events} to poll for new filesystem changes, and {#stop}
|
|
12
|
+
# to clean up the watcher when done.
|
|
13
|
+
#
|
|
14
|
+
# @example Basic usage
|
|
15
|
+
# handle = sandbox.files.watch_dir("/home/user/project")
|
|
16
|
+
# loop do
|
|
17
|
+
# events = handle.get_new_events
|
|
18
|
+
# events.each { |e| puts "#{e.name}: #{e.type}" }
|
|
19
|
+
# sleep 1
|
|
20
|
+
# end
|
|
21
|
+
# handle.stop
|
|
22
|
+
#
|
|
23
|
+
# @example With ensure block for cleanup
|
|
24
|
+
# handle = sandbox.files.watch_dir("/home/user/project")
|
|
25
|
+
# begin
|
|
26
|
+
# events = handle.get_new_events
|
|
27
|
+
# events.each { |e| process_event(e) }
|
|
28
|
+
# ensure
|
|
29
|
+
# handle.stop
|
|
30
|
+
# end
|
|
31
|
+
class WatchHandle
|
|
32
|
+
# @return [String] The watcher ID assigned by the CreateWatcher RPC
|
|
33
|
+
attr_reader :watcher_id
|
|
34
|
+
|
|
35
|
+
# Create a new WatchHandle
|
|
36
|
+
#
|
|
37
|
+
# @param watcher_id [String] The watcher ID returned by the CreateWatcher RPC
|
|
38
|
+
# @param envd_rpc_proc [Proc] A callable that performs RPC calls. It must accept
|
|
39
|
+
# three positional arguments (service, method) and keyword arguments (body:, timeout:).
|
|
40
|
+
# Typically a lambda wrapping {BaseService#envd_rpc}.
|
|
41
|
+
def initialize(watcher_id:, envd_rpc_proc:)
|
|
42
|
+
@watcher_id = watcher_id
|
|
43
|
+
@envd_rpc_proc = envd_rpc_proc
|
|
44
|
+
@stopped = false
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
# Poll for new filesystem events since the last check
|
|
48
|
+
#
|
|
49
|
+
# Calls the GetWatcherEvents RPC to retrieve any filesystem events
|
|
50
|
+
# that have occurred since the last poll (or since the watcher was created).
|
|
51
|
+
#
|
|
52
|
+
# @return [Array<Models::FilesystemEvent>] New events since last poll
|
|
53
|
+
# @raise [E2B::E2BError] If the watcher has been stopped
|
|
54
|
+
def get_new_events
|
|
55
|
+
raise E2B::E2BError, "Watcher has been stopped" if @stopped
|
|
56
|
+
|
|
57
|
+
response = @envd_rpc_proc.call(
|
|
58
|
+
"filesystem.Filesystem", "GetWatcherEvents",
|
|
59
|
+
body: { watcherId: @watcher_id }
|
|
60
|
+
)
|
|
61
|
+
|
|
62
|
+
events = extract_events(response)
|
|
63
|
+
events.map { |e| Models::FilesystemEvent.from_hash(e) }
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
# Stop watching and clean up the watcher
|
|
67
|
+
#
|
|
68
|
+
# Calls the RemoveWatcher RPC to release server-side resources.
|
|
69
|
+
# After calling this method, {#get_new_events} will raise an error.
|
|
70
|
+
# Calling stop on an already-stopped handle is a no-op.
|
|
71
|
+
#
|
|
72
|
+
# @return [void]
|
|
73
|
+
def stop
|
|
74
|
+
return if @stopped
|
|
75
|
+
|
|
76
|
+
@envd_rpc_proc.call(
|
|
77
|
+
"filesystem.Filesystem", "RemoveWatcher",
|
|
78
|
+
body: { watcherId: @watcher_id }
|
|
79
|
+
)
|
|
80
|
+
@stopped = true
|
|
81
|
+
rescue StandardError
|
|
82
|
+
@stopped = true
|
|
83
|
+
# Ignore errors on cleanup - the watcher may have already been
|
|
84
|
+
# removed server-side (e.g., sandbox shutdown)
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
# Check if the watcher has been stopped
|
|
88
|
+
#
|
|
89
|
+
# @return [Boolean] true if {#stop} has been called
|
|
90
|
+
def stopped?
|
|
91
|
+
@stopped
|
|
92
|
+
end
|
|
93
|
+
|
|
94
|
+
private
|
|
95
|
+
|
|
96
|
+
# Extract events array from the RPC response
|
|
97
|
+
#
|
|
98
|
+
# The response may contain events under different keys depending on
|
|
99
|
+
# the serialization format (camelCase JSON vs. symbol keys from parsed response).
|
|
100
|
+
#
|
|
101
|
+
# @param response [Hash] The parsed RPC response
|
|
102
|
+
# @return [Array<Hash>] Array of raw event hashes
|
|
103
|
+
def extract_events(response)
|
|
104
|
+
return [] unless response.is_a?(Hash)
|
|
105
|
+
|
|
106
|
+
response["events"] || response[:events] || []
|
|
107
|
+
end
|
|
108
|
+
end
|
|
109
|
+
end
|
|
110
|
+
end
|
data/lib/e2b/version.rb
ADDED
data/lib/e2b.rb
ADDED
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
# E2B Ruby SDK
|
|
4
|
+
# Ruby client for E2B sandbox API
|
|
5
|
+
|
|
6
|
+
# Core requires
|
|
7
|
+
require_relative "e2b/version"
|
|
8
|
+
require_relative "e2b/errors"
|
|
9
|
+
require_relative "e2b/configuration"
|
|
10
|
+
|
|
11
|
+
# API layer
|
|
12
|
+
require_relative "e2b/api/http_client"
|
|
13
|
+
|
|
14
|
+
# Models
|
|
15
|
+
require_relative "e2b/models/sandbox_info"
|
|
16
|
+
require_relative "e2b/models/process_result"
|
|
17
|
+
require_relative "e2b/models/entry_info"
|
|
18
|
+
|
|
19
|
+
# Services
|
|
20
|
+
require_relative "e2b/services/base_service"
|
|
21
|
+
require_relative "e2b/services/command_handle"
|
|
22
|
+
require_relative "e2b/services/commands"
|
|
23
|
+
require_relative "e2b/services/filesystem"
|
|
24
|
+
require_relative "e2b/services/watch_handle"
|
|
25
|
+
require_relative "e2b/services/pty"
|
|
26
|
+
require_relative "e2b/services/git"
|
|
27
|
+
|
|
28
|
+
# Core classes
|
|
29
|
+
require_relative "e2b/sandbox"
|
|
30
|
+
require_relative "e2b/client"
|
|
31
|
+
|
|
32
|
+
# E2B SDK for Ruby
|
|
33
|
+
#
|
|
34
|
+
# Provides access to E2B sandboxes - secure cloud environments
|
|
35
|
+
# for AI-generated code execution.
|
|
36
|
+
#
|
|
37
|
+
# @example Quick start with Sandbox class (recommended)
|
|
38
|
+
# sandbox = E2B::Sandbox.create(template: "base", api_key: "your-key")
|
|
39
|
+
#
|
|
40
|
+
# result = sandbox.commands.run("echo 'Hello, World!'")
|
|
41
|
+
# puts result.stdout
|
|
42
|
+
#
|
|
43
|
+
# sandbox.files.write("/home/user/hello.txt", "Hello!")
|
|
44
|
+
# content = sandbox.files.read("/home/user/hello.txt")
|
|
45
|
+
#
|
|
46
|
+
# sandbox.kill
|
|
47
|
+
#
|
|
48
|
+
# @example Using Client class
|
|
49
|
+
# client = E2B::Client.new(api_key: "your-api-key")
|
|
50
|
+
# sandbox = client.create(template: "base")
|
|
51
|
+
#
|
|
52
|
+
# @example Using global configuration
|
|
53
|
+
# E2B.configure do |config|
|
|
54
|
+
# config.api_key = "your-api-key"
|
|
55
|
+
# end
|
|
56
|
+
#
|
|
57
|
+
# sandbox = E2B::Sandbox.create(template: "base")
|
|
58
|
+
#
|
|
59
|
+
# @see https://e2b.dev/docs E2B Documentation
|
|
60
|
+
module E2B
|
|
61
|
+
class << self
|
|
62
|
+
# @return [Configuration, nil] Global configuration
|
|
63
|
+
attr_accessor :configuration
|
|
64
|
+
|
|
65
|
+
# Configure the E2B SDK globally
|
|
66
|
+
#
|
|
67
|
+
# @yield [config] Configuration block
|
|
68
|
+
# @yieldparam config [Configuration] Configuration instance
|
|
69
|
+
# @return [Configuration]
|
|
70
|
+
#
|
|
71
|
+
# @example
|
|
72
|
+
# E2B.configure do |config|
|
|
73
|
+
# config.api_key = "your-api-key"
|
|
74
|
+
# config.domain = "e2b.app"
|
|
75
|
+
# end
|
|
76
|
+
def configure
|
|
77
|
+
self.configuration ||= Configuration.new
|
|
78
|
+
yield(configuration) if block_given?
|
|
79
|
+
configuration
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
# Reset global configuration
|
|
83
|
+
def reset_configuration!
|
|
84
|
+
self.configuration = nil
|
|
85
|
+
end
|
|
86
|
+
end
|
|
87
|
+
end
|
metadata
ADDED
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
|
2
|
+
name: e2b
|
|
3
|
+
version: !ruby/object:Gem::Version
|
|
4
|
+
version: 0.2.0
|
|
5
|
+
platform: ruby
|
|
6
|
+
authors:
|
|
7
|
+
- Tao Luo
|
|
8
|
+
bindir: bin
|
|
9
|
+
cert_chain: []
|
|
10
|
+
date: 2026-03-12 00:00:00.000000000 Z
|
|
11
|
+
dependencies:
|
|
12
|
+
- !ruby/object:Gem::Dependency
|
|
13
|
+
name: faraday
|
|
14
|
+
requirement: !ruby/object:Gem::Requirement
|
|
15
|
+
requirements:
|
|
16
|
+
- - ">="
|
|
17
|
+
- !ruby/object:Gem::Version
|
|
18
|
+
version: '1.0'
|
|
19
|
+
- - "<"
|
|
20
|
+
- !ruby/object:Gem::Version
|
|
21
|
+
version: '3.0'
|
|
22
|
+
type: :runtime
|
|
23
|
+
prerelease: false
|
|
24
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
25
|
+
requirements:
|
|
26
|
+
- - ">="
|
|
27
|
+
- !ruby/object:Gem::Version
|
|
28
|
+
version: '1.0'
|
|
29
|
+
- - "<"
|
|
30
|
+
- !ruby/object:Gem::Version
|
|
31
|
+
version: '3.0'
|
|
32
|
+
- !ruby/object:Gem::Dependency
|
|
33
|
+
name: faraday-multipart
|
|
34
|
+
requirement: !ruby/object:Gem::Requirement
|
|
35
|
+
requirements:
|
|
36
|
+
- - "~>"
|
|
37
|
+
- !ruby/object:Gem::Version
|
|
38
|
+
version: '1.0'
|
|
39
|
+
type: :runtime
|
|
40
|
+
prerelease: false
|
|
41
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
42
|
+
requirements:
|
|
43
|
+
- - "~>"
|
|
44
|
+
- !ruby/object:Gem::Version
|
|
45
|
+
version: '1.0'
|
|
46
|
+
- !ruby/object:Gem::Dependency
|
|
47
|
+
name: rake
|
|
48
|
+
requirement: !ruby/object:Gem::Requirement
|
|
49
|
+
requirements:
|
|
50
|
+
- - "~>"
|
|
51
|
+
- !ruby/object:Gem::Version
|
|
52
|
+
version: '13.0'
|
|
53
|
+
type: :development
|
|
54
|
+
prerelease: false
|
|
55
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
56
|
+
requirements:
|
|
57
|
+
- - "~>"
|
|
58
|
+
- !ruby/object:Gem::Version
|
|
59
|
+
version: '13.0'
|
|
60
|
+
- !ruby/object:Gem::Dependency
|
|
61
|
+
name: rspec
|
|
62
|
+
requirement: !ruby/object:Gem::Requirement
|
|
63
|
+
requirements:
|
|
64
|
+
- - "~>"
|
|
65
|
+
- !ruby/object:Gem::Version
|
|
66
|
+
version: '3.0'
|
|
67
|
+
type: :development
|
|
68
|
+
prerelease: false
|
|
69
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
70
|
+
requirements:
|
|
71
|
+
- - "~>"
|
|
72
|
+
- !ruby/object:Gem::Version
|
|
73
|
+
version: '3.0'
|
|
74
|
+
- !ruby/object:Gem::Dependency
|
|
75
|
+
name: webmock
|
|
76
|
+
requirement: !ruby/object:Gem::Requirement
|
|
77
|
+
requirements:
|
|
78
|
+
- - "~>"
|
|
79
|
+
- !ruby/object:Gem::Version
|
|
80
|
+
version: '3.0'
|
|
81
|
+
type: :development
|
|
82
|
+
prerelease: false
|
|
83
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
84
|
+
requirements:
|
|
85
|
+
- - "~>"
|
|
86
|
+
- !ruby/object:Gem::Version
|
|
87
|
+
version: '3.0'
|
|
88
|
+
description: |
|
|
89
|
+
Ruby client for creating and managing E2B sandboxes - secure cloud environments
|
|
90
|
+
for AI-generated code execution. Supports sandbox lifecycle management, command
|
|
91
|
+
execution, file operations, PTY terminals, git operations, and directory watching.
|
|
92
|
+
email:
|
|
93
|
+
- luotao@hey.com
|
|
94
|
+
executables: []
|
|
95
|
+
extensions: []
|
|
96
|
+
extra_rdoc_files: []
|
|
97
|
+
files:
|
|
98
|
+
- LICENSE.txt
|
|
99
|
+
- README.md
|
|
100
|
+
- lib/e2b.rb
|
|
101
|
+
- lib/e2b/api/http_client.rb
|
|
102
|
+
- lib/e2b/client.rb
|
|
103
|
+
- lib/e2b/configuration.rb
|
|
104
|
+
- lib/e2b/errors.rb
|
|
105
|
+
- lib/e2b/models/entry_info.rb
|
|
106
|
+
- lib/e2b/models/process_result.rb
|
|
107
|
+
- lib/e2b/models/sandbox_info.rb
|
|
108
|
+
- lib/e2b/sandbox.rb
|
|
109
|
+
- lib/e2b/services/base_service.rb
|
|
110
|
+
- lib/e2b/services/command_handle.rb
|
|
111
|
+
- lib/e2b/services/commands.rb
|
|
112
|
+
- lib/e2b/services/filesystem.rb
|
|
113
|
+
- lib/e2b/services/git.rb
|
|
114
|
+
- lib/e2b/services/pty.rb
|
|
115
|
+
- lib/e2b/services/watch_handle.rb
|
|
116
|
+
- lib/e2b/version.rb
|
|
117
|
+
homepage: https://github.com/ya-luotao/e2b-ruby
|
|
118
|
+
licenses:
|
|
119
|
+
- MIT
|
|
120
|
+
metadata:
|
|
121
|
+
homepage_uri: https://github.com/ya-luotao/e2b-ruby
|
|
122
|
+
source_code_uri: https://github.com/ya-luotao/e2b-ruby
|
|
123
|
+
documentation_uri: https://e2b.dev/docs
|
|
124
|
+
changelog_uri: https://github.com/ya-luotao/e2b-ruby/blob/main/CHANGELOG.md
|
|
125
|
+
rdoc_options: []
|
|
126
|
+
require_paths:
|
|
127
|
+
- lib
|
|
128
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
|
129
|
+
requirements:
|
|
130
|
+
- - ">="
|
|
131
|
+
- !ruby/object:Gem::Version
|
|
132
|
+
version: 3.0.0
|
|
133
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
134
|
+
requirements:
|
|
135
|
+
- - ">="
|
|
136
|
+
- !ruby/object:Gem::Version
|
|
137
|
+
version: '0'
|
|
138
|
+
requirements: []
|
|
139
|
+
rubygems_version: 3.6.2
|
|
140
|
+
specification_version: 4
|
|
141
|
+
summary: Ruby SDK for E2B sandbox API
|
|
142
|
+
test_files: []
|