ask-tools-shell 0.1.0 → 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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: df1f5ba13ed96fd946f5fae6eaa010ac2ae9c8ef6c87a48fcec7ec0b994f1164
4
- data.tar.gz: 79a8c50c47d6b43ba2fbe9dddd8a514aac6f2baa5951c240131003f4f88ac22d
3
+ metadata.gz: 40e217bcf42a1f1cdf4b3bf6d256e06aa21ee4e9c946706a1728dc8bf049e6a0
4
+ data.tar.gz: cb157c2d84e1c162de9cab25394dec75ffdf65276e55a70537acc145424a7c1f
5
5
  SHA512:
6
- metadata.gz: d918ba9bd43e27f511c82f9adc4de3d6daa8817531555cfc567729f807f92df8e18f28932aa6e59738c0d2f1e653562255240df5974f3e128249e8ac04258418
7
- data.tar.gz: 226ea5d605b60d10a8b6839c4469d5cbc97076f3c08596e59c0adb0fe29ed0b03bc95b54261af51a3c6babd074489a9b0ca3b55f47281d0cd8a4d1f41e01fe24
6
+ metadata.gz: 9b204fd0304eb672ad90c8359bafe27454441019079a64a38a73026f8fc3b0003098cb9df034827feb19324490c82f88d67b9642d521a3a7aad0769cb0cab9c7
7
+ data.tar.gz: 9150cd2ccab75a75dfec81125b6ab6c8308ae2853a07e4d158e3244a231777acbd2f03895deacf53c910f2229f06005c70a032253ee6c14a02c2d7381e9e1149
@@ -1,15 +1,12 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require "open3"
4
- require "tempfile"
5
- require "stringio"
6
- require "tmpdir"
3
+ require "ask-sandbox-providers"
7
4
 
8
5
  module Ask
9
6
  module Tools
10
7
  # Execute shell commands in a sandboxed environment.
11
- # Returns stdout, stderr, exit code, and a timed_out flag.
12
- # Output is truncated to 100KB.
8
+ # Runs via Ask::Sandbox.provider (Local by default, configurable for
9
+ # stronger isolation via Docker, Daytona, or Cloudflare).
13
10
  class Bash < Ask::Tool
14
11
  description "Execute a bash command in a sandboxed environment. " \
15
12
  "Returns stdout, stderr, and exit code. " \
@@ -19,59 +16,26 @@ module Ask
19
16
  param :timeout, type: :integer, desc: "Timeout in seconds", required: false
20
17
  param :workdir, type: :string, desc: "Working directory", required: false
21
18
 
22
- MAX_OUTPUT_SIZE = 102_400
23
-
24
19
  def execute(command:, timeout: 30, workdir: nil)
25
- Dir.mktmpdir("ask_bash") do |dir|
26
- workdir ||= dir
27
-
28
- stdout = StringIO.new
29
- stderr = StringIO.new
30
- timed_out = false
31
- exit_code = -1
32
-
33
- begin
34
- Open3.popen3("bash", "-c", command, chdir: workdir) do |stdin, out, err, wait_thr|
35
- stdin.close
36
-
37
- threads = [
38
- Thread.new { IO.copy_stream(out, stdout) rescue nil },
39
- Thread.new { IO.copy_stream(err, stderr) rescue nil }
40
- ]
41
-
42
- unless wait_thr.join(timeout)
43
- Process.kill("-KILL", wait_thr.pid) rescue nil
44
- timed_out = true
45
- end
46
-
47
- threads.each(&:join)
48
- exit_code = timed_out ? -1 : wait_thr.value.exitstatus
49
- end
50
- rescue => e
51
- return Ask::Result.error(message: "Bash execution failed: #{e.message}",
52
- metadata: { stdout: stdout.string, stderr: stderr.string })
53
- end
54
-
55
- out_text = stdout.string
56
- err_text = stderr.string
57
-
58
- if out_text.length > MAX_OUTPUT_SIZE
59
- header = "[Output truncated to #{MAX_OUTPUT_SIZE / 1024}KB]\n"
60
- out_text = "#{header}#{out_text[-(MAX_OUTPUT_SIZE - header.length)..]}"
61
- end
62
-
63
- if err_text.length > MAX_OUTPUT_SIZE
64
- header = "[Error output truncated to #{MAX_OUTPUT_SIZE / 1024}KB]\n"
65
- err_text = "#{header}#{err_text[-(MAX_OUTPUT_SIZE - header.length)..]}"
66
- end
67
-
68
- Ask::Result.ok(data: {
69
- stdout: out_text,
70
- stderr: err_text,
71
- exit_code: exit_code,
72
- timed_out: timed_out
73
- })
20
+ result = Ask::Sandbox.provider.call(
21
+ command,
22
+ timeout: timeout,
23
+ workdir: workdir
24
+ )
25
+
26
+ if result.timed_out
27
+ return Ask::Result.error(
28
+ message: "Command timed out",
29
+ metadata: { stdout: result.stdout, stderr: result.stderr }
30
+ )
74
31
  end
32
+
33
+ Ask::Result.ok(data: {
34
+ stdout: result.stdout,
35
+ stderr: result.stderr,
36
+ exit_code: result.exit_code,
37
+ timed_out: result.timed_out
38
+ })
75
39
  end
76
40
  end
77
41
  end
@@ -1,12 +1,12 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require "open3"
4
- require "tmpdir"
3
+ require "ask-sandbox-providers"
5
4
 
6
5
  module Ask
7
6
  module Tools
8
7
  # Write and execute Ruby code in a subprocess.
9
- # Runs in a temp directory via ruby -e.
8
+ # Runs via Ask::Sandbox.provider (Local by default, configurable for
9
+ # stronger isolation via Docker, Daytona, or Cloudflare).
10
10
  class Code < Ask::Tool
11
11
  description "Write and execute Ruby code in a subprocess. " \
12
12
  "Returns stdout, stderr, and exit code. " \
@@ -14,45 +14,24 @@ module Ask
14
14
 
15
15
  param :code, type: :string, desc: "Ruby source code to execute", required: true
16
16
 
17
- MAX_OUTPUT_SIZE = 102_400
18
-
19
17
  def execute(code:)
20
- Dir.mktmpdir("ask_code") do |_dir|
21
- stdout = StringIO.new
22
- stderr = StringIO.new
23
- exit_code = -1
24
-
25
- begin
26
- Open3.popen3("ruby", "-e", code, chdir: Dir.pwd) do |stdin, out, err, wait_thr|
27
- stdin.close
28
-
29
- threads = [
30
- Thread.new { IO.copy_stream(out, stdout) rescue nil },
31
- Thread.new { IO.copy_stream(err, stderr) rescue nil }
32
- ]
33
-
34
- threads.each(&:join)
35
- exit_code = wait_thr.value.exitstatus
36
- end
37
- rescue => e
38
- return Ask::Result.error(message: "Code execution failed: #{e.message}",
39
- metadata: { stdout: stdout.string, stderr: stderr.string })
40
- end
41
-
42
- out_text = stdout.string
43
- err_text = stderr.string
44
-
45
- if out_text.length > MAX_OUTPUT_SIZE
46
- header = "[Output truncated to #{MAX_OUTPUT_SIZE / 1024}KB]\n"
47
- out_text = "#{header}#{out_text[-(MAX_OUTPUT_SIZE - header.length)..]}"
48
- end
49
-
50
- Ask::Result.ok(data: {
51
- stdout: out_text,
52
- stderr: err_text,
53
- exit_code: exit_code
54
- })
18
+ result = Ask::Sandbox.provider.call(
19
+ ["ruby", "-e", code],
20
+ timeout: 30
21
+ )
22
+
23
+ if result.timed_out
24
+ return Ask::Result.error(
25
+ message: "Code execution timed out",
26
+ metadata: { stdout: result.stdout, stderr: result.stderr }
27
+ )
55
28
  end
29
+
30
+ Ask::Result.ok(data: {
31
+ stdout: result.stdout,
32
+ stderr: result.stderr,
33
+ exit_code: result.exit_code
34
+ })
56
35
  end
57
36
  end
58
37
  end
@@ -3,7 +3,7 @@
3
3
  module Ask
4
4
  module Tools
5
5
  module Shell
6
- VERSION = "0.1.0"
6
+ VERSION = "0.2.0"
7
7
  end
8
8
  end
9
9
  end
@@ -1,20 +1,18 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require_relative "shell/version"
4
+ require_relative "shell/bash"
5
+ require_relative "shell/read"
6
+ require_relative "shell/write"
7
+ require_relative "shell/edit"
8
+ require_relative "shell/glob"
9
+ require_relative "shell/grep"
10
+ require_relative "shell/code"
11
+
3
12
  module Ask
4
13
  module Tools
5
- # Collection point for shell tools.
6
- #
7
- # Ask::Tools::Shell.all # => [Bash, Read, Write, ...] instances
8
- #
9
14
  module Shell
10
15
  TOOLS = [Bash, Read, Write, Edit, Glob, Grep, Code].freeze
11
-
12
- # Return an instance of every registered shell tool.
13
- #
14
- # @return [Array<Ask::Tool>]
15
- def self.all
16
- TOOLS.map(&:new)
17
- end
18
16
  end
19
17
  end
20
18
  end
@@ -1,13 +1,4 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require "ask-tools"
4
-
5
- require_relative "ask/tools/shell/version"
6
- require_relative "ask/tools/shell/bash"
7
- require_relative "ask/tools/shell/read"
8
- require_relative "ask/tools/shell/write"
9
- require_relative "ask/tools/shell/edit"
10
- require_relative "ask/tools/shell/glob"
11
- require_relative "ask/tools/shell/grep"
12
- require_relative "ask/tools/shell/code"
13
- require_relative "ask/tools/shell"
4
+ require "ask/tools/shell"
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ask-tools-shell
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Kaka Ruto
@@ -23,6 +23,20 @@ dependencies:
23
23
  - - "~>"
24
24
  - !ruby/object:Gem::Version
25
25
  version: '0.1'
26
+ - !ruby/object:Gem::Dependency
27
+ name: ask-sandbox-providers
28
+ requirement: !ruby/object:Gem::Requirement
29
+ requirements:
30
+ - - "~>"
31
+ - !ruby/object:Gem::Version
32
+ version: '0.1'
33
+ type: :runtime
34
+ prerelease: false
35
+ version_requirements: !ruby/object:Gem::Requirement
36
+ requirements:
37
+ - - "~>"
38
+ - !ruby/object:Gem::Version
39
+ version: '0.1'
26
40
  - !ruby/object:Gem::Dependency
27
41
  name: minitest
28
42
  requirement: !ruby/object:Gem::Requirement