Class: Rubino::Tools::PatchTool

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

Overview

Tool for applying unified diff patches to files.

Instance Attribute Summary

Attributes inherited from Base

#cancel_token, #read_tracker, #stream_chunk

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



39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
# File 'lib/rubino/tools/patch_tool.rb', line 39

def call(arguments)
  patch     = arguments["patch"]     || arguments[:patch]
  base_path = arguments["base_path"] || arguments[:base_path] || Dir.pwd

  hunks = parse_patch(patch)
  return "No changes applied" if hunks.empty?

  # Pass 1: validate every hunk against current disk state and compute
  # the new content for each file in memory. NO disk writes here. If
  # any single hunk fails (missing file, context mismatch, workspace
  # escape) we abort the whole patch — partial application across
  # multiple files leaves the tree in a state neither the user nor
  # the agent can easily reason about, and reverting it requires
  # knowing the prior contents which we no longer have.
  pending, error = plan_operations(hunks, base_path)
  return error if error

  # Pass 2: execute. cancellation_requested? polled between operations
  # so a Ctrl+C lands cleanly — at most one application is in flight.
  apply_operations(pending)
end

#descriptionObject



13
14
15
16
# File 'lib/rubino/tools/patch_tool.rb', line 13

def description
  "Apply a unified diff patch to one or more files. " \
    "Accepts standard unified diff format (like output from 'git diff')."
end

#input_schemaObject



18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
# File 'lib/rubino/tools/patch_tool.rb', line 18

def input_schema
  {
    type: "object",
    properties: {
      patch: {
        type: "string",
        description: "The unified diff patch content to apply"
      },
      base_path: {
        type: "string",
        description: "Base directory for relative paths in the patch (defaults to cwd)"
      }
    },
    required: %w[patch]
  }
end

#nameObject



9
10
11
# File 'lib/rubino/tools/patch_tool.rb', line 9

def name
  "apply_patch"
end

#risk_levelObject



35
36
37
# File 'lib/rubino/tools/patch_tool.rb', line 35

def risk_level
  :medium
end