Class: Yorishiro::Tools::ExecuteCommand

Inherits:
Yorishiro::Tool show all
Defined in:
lib/yorishiro/tools/execute_command.rb

Constant Summary collapse

SHELL_METACHARACTERS =

Commands run via sh -c, so these characters can chain or inject additional commands (;, &, |, newlines), substitute commands ($, backtick, (, )), or redirect files (<, >). Commands containing any of them never auto-match allow_commands and always fall back to the interactive permission prompt.

/[;&|`$<>()\n\r]/

Instance Method Summary collapse

Methods inherited from Yorishiro::Tool

#definition, #preview, #read_only?

Constructor Details

#initializeExecuteCommand

Returns a new instance of ExecuteCommand.



15
16
17
18
19
# File 'lib/yorishiro/tools/execute_command.rb', line 15

def initialize
  super
  @allow_commands = []
  @session_allowed = Set.new
end

Instance Method Details

#configure(options) ⇒ Object



64
65
66
# File 'lib/yorishiro/tools/execute_command.rb', line 64

def configure(options)
  @allow_commands = Array(options[:allow_commands] || options["allow_commands"])
end

#descriptionObject



25
26
27
# File 'lib/yorishiro/tools/execute_command.rb', line 25

def description
  "Execute a shell command and return its output. Requires user permission unless the command matches an allowed pattern."
end

#execute(**params) ⇒ Object



39
40
41
42
43
44
45
46
47
48
49
# File 'lib/yorishiro/tools/execute_command.rb', line 39

def execute(**params)
  command = params[:command] || params["command"]

  stdout, stderr, status = Open3.capture3(command)

  output = +""
  output << stdout unless stdout.empty?
  output << "\nSTDERR: #{stderr}" unless stderr.empty?
  output << "\nExit code: #{status.exitstatus}"
  output
end

#nameObject



21
22
23
# File 'lib/yorishiro/tools/execute_command.rb', line 21

def name
  "execute_command"
end

#parametersObject



29
30
31
32
33
34
35
36
37
# File 'lib/yorishiro/tools/execute_command.rb', line 29

def parameters
  {
    type: "object",
    properties: {
      command: { type: "string", description: "The shell command to execute" }
    },
    required: ["command"]
  }
end

#permission_check(arguments) ⇒ Object



51
52
53
54
55
56
57
58
# File 'lib/yorishiro/tools/execute_command.rb', line 51

def permission_check(arguments)
  command = arguments[:command] || arguments["command"]
  return :ask unless command

  return :allowed if command_allowed?(command)

  :ask
end

#session_allow!(command) ⇒ Object



60
61
62
# File 'lib/yorishiro/tools/execute_command.rb', line 60

def session_allow!(command)
  @session_allowed << command
end