diff --git a/src/components/diff/unified-diff-preview.tsx b/src/components/diff/unified-diff-preview.tsx index f25113e..4813de7 100644 --- a/src/components/diff/unified-diff-preview.tsx +++ b/src/components/diff/unified-diff-preview.tsx @@ -351,7 +351,18 @@ function parseUnifiedDiff(diffText: string): ParsedDiffFile[] { continue } - const hunk = getActiveHunk() + let hunk = getActiveHunk() + // Auto-create an implicit hunk for patch formats (e.g. *** Add File) + // that emit +/- lines without a preceding @@ header. + if ( + !hunk && + (line.startsWith("+") || line.startsWith("-") || line.startsWith(" ")) + ) { + if (getActiveFile()) { + startHunk("@@") + hunk = getActiveHunk() + } + } if (!hunk) continue if (line.startsWith("+") && !line.startsWith("+++")) { @@ -487,6 +498,26 @@ function HunkLines({ rows }: { rows: ParsedDiffRow[] }) { ) } +/** Clean file content view for new files (no diff signs or green highlight) */ +function NewFileLines({ rows }: { rows: ParsedDiffRow[] }) { + return ( +
+ {rows.map((row, i) => ( +
+ + {row.newLine ?? i + 1} + + {row.text} +
+ ))} +
+ ) +} + +function isNewFileOnly(file: ParsedDiffFile): boolean { + return file.mode === "added" && file.deletions === 0 +} + export function UnifiedDiffPreview({ diffText, className, @@ -526,43 +557,52 @@ export function UnifiedDiffPreview({ return (
- {files.map((file) => ( -
-
- - {t(modeKey(file.mode))} - - - {toDisplayPath(file.path, folder?.path ?? null)} - - - - +{file.additions} + {files.map((file) => { + const newFile = isNewFileOnly(file) + return ( +
+
+ + {newFile ? "WRITE" : t(modeKey(file.mode))} - - -{file.deletions} + + {toDisplayPath(file.path, folder?.path ?? null)} - -
+ {!newFile && ( + + + +{file.additions} + + + -{file.deletions} + + + )} +
-
-
- {file.hunks.map((hunk, hunkIdx) => ( -
- {hunkIdx > 0 && } - -
- ))} +
+
+ {newFile + ? file.hunks.map((hunk) => ( + + )) + : file.hunks.map((hunk, hunkIdx) => ( +
+ {hunkIdx > 0 && } + +
+ ))} +
-
-
- ))} + + ) + })}
) diff --git a/src/lib/tool-call-normalization.ts b/src/lib/tool-call-normalization.ts index c8e89d9..675dc00 100644 --- a/src/lib/tool-call-normalization.ts +++ b/src/lib/tool-call-normalization.ts @@ -203,6 +203,17 @@ function inferFromInput( const hasPath = hasAnyKey(parsed, ["file_path", "notebook_path", "path"]) if (hasPath) { + // Check write-specific input keys first — they take priority over + // kind/title because ACP ToolKind::Edit ("edit") is a category that + // covers both Edit and Write tools. Without this, a Write tool call + // (with {content, file_path}) would be classified as "edit" due to + // its kind, then rendered with EditToolInput which expects + // old_string/new_string and produces blank output for new files. + if ( + hasAnyKey(parsed, ["content", "new_source", "cell_type", "edit_mode"]) + ) { + return "write" + } if ( normalizedKind === "read" || normalizedKind === "edit" || @@ -219,11 +230,6 @@ function inferFromInput( ) { return normalizedTitle } - if ( - hasAnyKey(parsed, ["content", "new_source", "cell_type", "edit_mode"]) - ) { - return "write" - } return "read" }