@@ -15,37 +15,88 @@ import (
1515
1616type ToggleDiffViewMsg struct {}
1717
18+ // New creates the edit_file tool UI model.
1819func New (msg * types.Message , sessionState * service.SessionState ) layout.Model {
1920 return toolcommon .NewBase (msg , sessionState , render )
2021}
2122
22- func render (msg * types.Message , s spinner.Spinner , sessionState * service.SessionState , width , _ int ) string {
23+ // render displays the edit_file tool output in the TUI.
24+ // It prioritizes the agent-provided friendly header when available,
25+ // hides results when collapsed by the user, and renders tool errors
26+ // in a single-line error style consistent with other tools.
27+ func render (
28+ msg * types.Message ,
29+ s spinner.Spinner ,
30+ sessionState * service.SessionState ,
31+ width ,
32+ _ int ,
33+ ) string {
34+ // Parse tool arguments to extract the file path for display.
2335 var args builtin.EditFileArgs
2436 if err := json .Unmarshal ([]byte (msg .ToolCall .Function .Arguments ), & args ); err != nil {
37+ // If arguments cannot be parsed, fail silently to avoid breaking the TUI.
2538 return ""
2639 }
2740
41+ // When the tool failed, render a single-line error header
42+ // consistent with other tool error renderings.
43+ if msg .ToolStatus == types .ToolStatusError {
44+ if msg .Content == "" {
45+ return ""
46+ }
47+
48+ // Render everything on a single line:
49+ // - error icon
50+ // - tool name in error style
51+ // - rejection/error message
52+ line := fmt .Sprintf (
53+ "%s%s %s" ,
54+ toolcommon .Icon (msg , s ),
55+ styles .ToolNameError .Render (msg .ToolDefinition .DisplayName ()),
56+ styles .ToolErrorMessageStyle .Render (msg .Content ),
57+ )
58+
59+ // Truncate to terminal width to avoid wrapping
60+ return styles .BaseStyle .
61+ MaxWidth (width ).
62+ Render (line )
63+ }
64+
65+ // ---- Normal (non-error) rendering ----
66+
2867 // Check for friendly description first
2968 var content string
3069 if header , ok := toolcommon .RenderFriendlyHeader (msg , s ); ok {
3170 content = header
3271 } else {
33- content = fmt .Sprintf ("%s%s %s" ,
72+ content = fmt .Sprintf (
73+ "%s%s %s" ,
3474 toolcommon .Icon (msg , s ),
3575 styles .ToolName .Render (msg .ToolDefinition .DisplayName ()),
36- styles .ToolMessageStyle .Render (toolcommon .ShortenPath (args .Path )))
76+ styles .ToolMessageStyle .Render (toolcommon .ShortenPath (args .Path )),
77+ )
3778 }
3879
39- if ! sessionState .HideToolResults () {
40- if msg .ToolCall .Function .Arguments != "" {
41- contentWidth := width - styles .ToolCallResult .GetHorizontalFrameSize ()
42- content += "\n " + styles .ToolCallResult .Render (
43- renderEditFile (msg .ToolCall , contentWidth , sessionState .SplitDiffView (), msg .ToolStatus ))
44- }
80+ // Tool results are hidden when the user collapses them.
81+ if sessionState .HideToolResults () {
82+ return content
83+ }
4584
46- if (msg .ToolStatus == types .ToolStatusError ) && msg .Content != "" {
47- content += toolcommon .FormatToolResult (msg .Content , width )
48- }
85+ // Successful (or pending/confirmation) execution:
86+ // render the diff output inside the ToolCallResult container.
87+ if msg .ToolCall .Function .Arguments != "" {
88+ // Calculate available width for diff rendering, accounting for
89+ // ToolCallResult frame padding.
90+ contentWidth := width - styles .ToolCallResult .GetHorizontalFrameSize ()
91+
92+ content += "\n " + styles .ToolCallResult .Render (
93+ renderEditFile (
94+ msg .ToolCall ,
95+ contentWidth ,
96+ sessionState .SplitDiffView (),
97+ msg .ToolStatus ,
98+ ),
99+ )
49100 }
50101
51102 return content
0 commit comments