@@ -139,17 +139,31 @@ func (w *WriteToolRenderContext) RenderTool(sty *styles.Styles, width int, opts
139 return header
139 return header
142+ if !opts.HasResult() {
142− if earlyState, ok := toolEarlyStateContent(sty, opts, cappedWidth); ok {
143+ if earlyState, ok := toolEarlyStateContent(sty, opts, cappedWidth); ok {
143− return joinToolParts(header, earlyState)
144+ return joinToolParts(header, earlyState)
146− if params.Content == "" {
149+ // On error with diff metadata (e.g. denied permission), show error + diff.
147− return header
150+ if opts.Result.IsError {
151+ var meta tools.WriteResponseMetadata
152+ if err := json.Unmarshal([]byte(opts.Result.Metadata), &meta); err == nil && meta.Diff != "" {
153+ errLine := toolErrorContent(sty, opts.Result, cappedWidth)
154+ diff := toolOutputDiffContentFromUnified(sty, meta.Diff, cappedWidth, opts.ExpandedContent)
155+ return strings.Join([]string{header, "", errLine, "", diff}, "\n")
157+ return joinToolParts(header, toolErrorContent(sty, opts.Result, cappedWidth))
150 // Render code content with syntax highlighting.
160 // Render code content with syntax highlighting.
161+ if params.Content != "" {
151− body := toolOutputCodeContent(sty, params.FilePath, params.Content, 0, cappedWidth, opts.ExpandedContent)
162+ body := toolOutputCodeContent(sty, params.FilePath, params.Content, 0, cappedWidth, opts.ExpandedContent)
152− return joinToolParts(header, body)
163+ return joinToolParts(header, body)
155// -----------------------------------------------------------------------------
169// -----------------------------------------------------------------------------
@@ -194,11 +208,10 @@ func (e *EditToolRenderContext) RenderTool(sty *styles.Styles, width int, opts *
194 return header
208 return header
197− if earlyState, ok := toolEarlyStateContent(sty, opts, width); ok {
198− return joinToolParts(header, earlyState)
201 if !opts.HasResult() {
211 if !opts.HasResult() {
212+ if earlyState, ok := toolEarlyStateContent(sty, opts, width); ok {
213+ return joinToolParts(header, earlyState)
202 return header
215 return header
@@ -210,9 +223,15 @@ func (e *EditToolRenderContext) RenderTool(sty *styles.Styles, width int, opts *
210 return joinToolParts(header, body)
223 return joinToolParts(header, body)
214− body := toolOutputDiffContent(sty, file, meta.OldContent, meta.NewContent, width, opts.ExpandedContent)
226+ diff := toolOutputDiffContent(sty, file, meta.OldContent, meta.NewContent, width, opts.ExpandedContent)
228+ // On error (e.g. denied permission), show error above the diff.
229+ if opts.Result.IsError {
230+ errLine := toolErrorContent(sty, opts.Result, width)
231+ return strings.Join([]string{header, "", errLine, "", diff}, "\n")
215− return joinToolParts(header, body)
234+ return joinToolParts(header, diff)
218// -----------------------------------------------------------------------------
237// -----------------------------------------------------------------------------
@@ -262,11 +281,10 @@ func (m *MultiEditToolRenderContext) RenderTool(sty *styles.Styles, width int, o
262 return header
281 return header
265− if earlyState, ok := toolEarlyStateContent(sty, opts, width); ok {
266− return joinToolParts(header, earlyState)
269 if !opts.HasResult() {
284 if !opts.HasResult() {
285+ if earlyState, ok := toolEarlyStateContent(sty, opts, width); ok {
286+ return joinToolParts(header, earlyState)
270 return header
288 return header
@@ -279,8 +297,15 @@ func (m *MultiEditToolRenderContext) RenderTool(sty *styles.Styles, width int, o
281 // Render diff with optional failed edits note.
299 // Render diff with optional failed edits note.
282− body := toolOutputMultiEditDiffContent(sty, file, meta, len(params.Edits), width, opts.ExpandedContent)
300+ diff := toolOutputMultiEditDiffContent(sty, file, meta, len(params.Edits), width, opts.ExpandedContent)
302+ // On error (e.g. denied permission), show error above the diff.
303+ if opts.Result.IsError {
304+ errLine := toolErrorContent(sty, opts.Result, width)
305+ return strings.Join([]string{header, "", errLine, "", diff}, "\n")
283− return joinToolParts(header, body)
308+ return joinToolParts(header, diff)
286// -----------------------------------------------------------------------------
311// -----------------------------------------------------------------------------