Class: Rubino::Tools::GlobTool

Inherits:
Base
  • Object
show all
Defined in:
lib/rubino/tools/glob_tool.rb

Overview

Tool for finding files by glob patterns. Returns matching file paths sorted by modification time.

Instance Attribute Summary

Attributes inherited from Base

#cancel_token, #read_tracker, #stream_chunk, #stream_kind

Instance Method Summary collapse

Methods inherited from Base

#cancellation_requested?, #config_key, #emit_chunk, #risky?, #to_tool_definition, workspace_root, workspace_roots

Instance Method Details

#call(arguments) ⇒ Object



47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
# File 'lib/rubino/tools/glob_tool.rb', line 47

def call(arguments)
  pattern     = arguments["pattern"] || arguments[:pattern]
  path        = arguments["path"]    || arguments[:path] || "."
  max_results = arguments["max_results"] || arguments[:max_results] || 100
  include_ignored = arguments["include_ignored"] || arguments[:include_ignored] || false

  # Glob is BROAD (#406): it resolves any path like Hermes/Claude/Codex.
  # The read allowlist was never the data-loss boundary (that's on the
  # WRITE path); glob only lists file PATHS (no content), so there is
  # nothing to denylist here — secret protection lives on read/grep.
  expanded_path = File.expand_path(path, workspace_root)
  full_pattern  = resolve_pattern(pattern, path, expanded_path)
  return full_pattern if full_pattern.is_a?(String) && full_pattern.start_with?("Error:")

  files = matching_files(full_pattern, expanded_path, max_results, include_ignored)

  if files.empty?
    "No files matched pattern: #{pattern}"
  else
    relative_files = files.map { |f| f.sub("#{expanded_path}/", "") }
    full = "#{relative_files.size} file(s) found:\n\n#{relative_files.join("\n")}"
    { output: full,
      metrics: "#{relative_files.size} file#{"s" if relative_files.size != 1}",
      body: Util::Output.preview(full),
      body_kind: :plain }
  end
end

#descriptionObject



12
13
14
15
# File 'lib/rubino/tools/glob_tool.rb', line 12

def description
  "Find files by glob pattern (e.g., '**/*.rb', 'src/**/*.ts'). " \
    "Returns matching file paths sorted by modification time."
end

#input_schemaObject



17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
# File 'lib/rubino/tools/glob_tool.rb', line 17

def input_schema
  {
    type: "object",
    properties: {
      pattern: {
        type: "string",
        description: "The glob pattern to match files against (e.g., '**/*.rb')"
      },
      path: {
        type: "string",
        description: "Base directory to search in (defaults to current directory)"
      },
      max_results: {
        type: "integer",
        description: "Maximum number of results (default: 100)"
      },
      include_ignored: {
        type: "boolean",
        description: "Include files git ignores (.gitignore, build artifacts). " \
                     "Default false — results honor .gitignore like grep does."
      }
    },
    required: %w[pattern]
  }
end

#nameObject



8
9
10
# File 'lib/rubino/tools/glob_tool.rb', line 8

def name
  "glob"
end

#risk_levelObject



43
44
45
# File 'lib/rubino/tools/glob_tool.rb', line 43

def risk_level
  :low
end