Class: Chocomint::Tools::Edit

Inherits:
Base
  • Object
show all
Defined in:
lib/chocomint/tools/edit.rb

Overview

許可ディレクトリ内のファイルで文字列置換を行う (Claude Code の Edit 相当)。 old_string は一意でなければならない (replace_all=true で全置換)。

Instance Method Summary collapse

Methods inherited from Base

#to_tool_definition

Constructor Details

#initialize(path_guard:, max_file_bytes:) ⇒ Edit

Returns a new instance of Edit.



10
11
12
13
# File 'lib/chocomint/tools/edit.rb', line 10

def initialize(path_guard:, max_file_bytes:)
  @path_guard = path_guard
  @max_file_bytes = max_file_bytes
end

Instance Method Details

#call(args) ⇒ Object



36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
# File 'lib/chocomint/tools/edit.rb', line 36

def call(args)
  measure do
    old_str = args["old_string"].to_s
    new_str = args["new_string"].to_s
    replace_all = args["replace_all"] == true

    abs = @path_guard.resolve(args["path"])
    next fail(stderr: "no such file: #{args['path']}") unless File.file?(abs)
    next fail(stderr: "old_string and new_string are identical") if old_str == new_str

    content = File.read(abs)
    count = content.scan(Regexp.new(Regexp.escape(old_str))).size
    next fail(stderr: "old_string not found") if count.zero?
    if count > 1 && !replace_all
      next fail(stderr: "old_string is not unique (#{count} matches); use replace_all")
    end

    updated = replace_all ? content.gsub(old_str, new_str) : content.sub(old_str, new_str)
    if updated.bytesize > @max_file_bytes
      next fail(stderr: "resulting file exceeds max_file_bytes (#{@max_file_bytes})")
    end

    replaced = replace_all ? count : 1
    File.write(abs, updated)
    ok(stdout: "replaced #{replaced} occurrence(s) in #{args['path']}")
  end
end

#descriptionObject



17
18
19
20
# File 'lib/chocomint/tools/edit.rb', line 17

def description
  "ファイル内の old_string を new_string に置換する。既定では old_string が一意である" \
    "必要があり、replace_all=true で全置換。path は許可ディレクトリ内であること。"
end

#nameObject



15
# File 'lib/chocomint/tools/edit.rb', line 15

def name = "edit"

#schemaObject



22
23
24
25
26
27
28
29
30
31
32
33
34
# File 'lib/chocomint/tools/edit.rb', line 22

def schema
  {
    "type" => "object",
    "properties" => {
      "path" => { "type" => "string" },
      "old_string" => { "type" => "string" },
      "new_string" => { "type" => "string" },
      "replace_all" => { "type" => "boolean" }
    },
    "required" => %w[path old_string new_string],
    "additionalProperties" => false
  }
end