diff --git a/lib/roast/cogs/agent/providers/claude/tool_use.rb b/lib/roast/cogs/agent/providers/claude/tool_use.rb index 024d6157..0d6404a5 100644 --- a/lib/roast/cogs/agent/providers/claude/tool_use.rb +++ b/lib/roast/cogs/agent/providers/claude/tool_use.rb @@ -141,6 +141,31 @@ def format_grep modifiers.empty? ? base : "#{base} (#{modifiers})" end + # Formats a Write tool-use line. + # + # Input fields: + # :file_path (String) – absolute path to write [required] + # :content (String) – full file contents [required] + # + # Output: 'WRITE "" (+ lines)', where + # is the first line of :content (stripped, truncated to + # TRUNCATE_LIMIT chars) and is the total number of lines written + # (singular " line" when is 1). The count is always shown. + # + # Examples: + # WRITE /app/models/user.rb "class User < ApplicationRecord" (+10 lines) + # WRITE /config/app.yml "enabled: true" (+1 line) + # + #: () -> String + def format_write + file_path, content = input.values_at(:file_path, :content) + lines = content.to_s.lines + preview = truncate(lines.first.to_s.strip) + count = lines.length + line_label = count == 1 ? "line" : "lines" + "WRITE #{file_path} \"#{preview}\" (+#{count} #{line_label})" + end + #: () -> String def format_unknown "UNKNOWN [#{name}] #{input.inspect}" diff --git a/test/roast/cogs/agent/providers/claude/tool_use_test.rb b/test/roast/cogs/agent/providers/claude/tool_use_test.rb index 83bcf3d3..905ac5a6 100644 --- a/test/roast/cogs/agent/providers/claude/tool_use_test.rb +++ b/test/roast/cogs/agent/providers/claude/tool_use_test.rb @@ -165,6 +165,34 @@ class ToolUseTest < ActiveSupport::TestCase assert_equal "GREP \"#{truncated}\" #{long}", output end + # format_write + + test "format_write shows the preview and a singular count for one line" do + tool_use = ToolUse.new(name: :write, input: { file_path: "/a.rb", content: "hello" }) + + output = tool_use.format + + assert_equal "WRITE /a.rb \"hello\" (+1 line)", output + end + + test "format_write strips the preview and counts every line" do + tool_use = ToolUse.new(name: :write, input: { file_path: "/a.rb", content: " def foo\n bar\n baz" }) + + output = tool_use.format + + assert_equal "WRITE /a.rb \"def foo\" (+3 lines)", output + end + + test "format_write truncates the preview" do + long = "a" * (ToolUse::TRUNCATE_LIMIT + 10) + truncated = "#{"a" * (ToolUse::TRUNCATE_LIMIT - 3)}..." + tool_use = ToolUse.new(name: :write, input: { file_path: "/a.rb", content: long }) + + output = tool_use.format + + assert_equal "WRITE /a.rb \"#{truncated}\" (+1 line)", output + end + test "format calls format_unknown for unknown tool" do tool_use = ToolUse.new(name: :unknown_tool, input: { arg: "value" })