Matt Rubens 8 месяцев назад
Родитель
Сommit
e41d6a42ac

+ 1 - 1
src/core/tools/applyDiffTool.ts

@@ -108,7 +108,7 @@ export async function applyDiffTool(
 				}
 
 				if (currentCount >= 2) {
-					await cline.say("error", formattedError)
+					await cline.say("diff_error", formattedError)
 				}
 				pushToolResult(formattedError)
 				return

+ 2 - 0
src/exports/roo-code.d.ts

@@ -387,6 +387,7 @@ type ClineMessage = {
 				| "subtask_result"
 				| "checkpoint_saved"
 				| "rooignore_error"
+				| "diff_error"
 		  )
 		| undefined
 	text?: string | undefined
@@ -467,6 +468,7 @@ type RooCodeEvents = {
 							| "subtask_result"
 							| "checkpoint_saved"
 							| "rooignore_error"
+							| "diff_error"
 					  )
 					| undefined
 				text?: string | undefined

+ 2 - 0
src/exports/types.ts

@@ -392,6 +392,7 @@ type ClineMessage = {
 				| "subtask_result"
 				| "checkpoint_saved"
 				| "rooignore_error"
+				| "diff_error"
 		  )
 		| undefined
 	text?: string | undefined
@@ -476,6 +477,7 @@ type RooCodeEvents = {
 							| "subtask_result"
 							| "checkpoint_saved"
 							| "rooignore_error"
+							| "diff_error"
 					  )
 					| undefined
 				text?: string | undefined

+ 1 - 0
src/schemas/index.ts

@@ -742,6 +742,7 @@ export const clineSays = [
 	"subtask_result",
 	"checkpoint_saved",
 	"rooignore_error",
+	"diff_error",
 ] as const
 
 export const clineSaySchema = z.enum(clineSays)

+ 95 - 0
webview-ui/src/components/chat/ChatRow.tsx

@@ -86,6 +86,9 @@ export const ChatRowContent = ({
 	const { t } = useTranslation()
 	const { mcpServers, alwaysAllowMcp, currentCheckpoint } = useExtensionState()
 	const [reasoningCollapsed, setReasoningCollapsed] = useState(true)
+	const [isDiffErrorExpanded, setIsDiffErrorExpanded] = useState(false)
+	const [showCopySuccess, setShowCopySuccess] = useState(false)
+	const { copyWithFeedback } = useCopyToClipboard()
 
 	const [cost, apiReqCancelReason, apiReqStreamingFailedMessage] = useMemo(() => {
 		if (message.text !== null && message.text !== undefined && message.say === "api_req_started") {
@@ -602,6 +605,98 @@ export const ChatRowContent = ({
 	switch (message.type) {
 		case "say":
 			switch (message.say) {
+				case "diff_error":
+					return (
+						<div>
+							<div
+								style={{
+									marginTop: "0px",
+									overflow: "hidden",
+									marginBottom: "8px",
+								}}>
+								<div
+									style={{
+										borderBottom: isDiffErrorExpanded
+											? "1px solid var(--vscode-editorGroup-border)"
+											: "none",
+										fontWeight: "normal",
+										fontSize: "var(--vscode-font-size)",
+										color: "var(--vscode-editor-foreground)",
+										display: "flex",
+										alignItems: "center",
+										justifyContent: "space-between",
+										cursor: "pointer",
+									}}
+									onClick={() => setIsDiffErrorExpanded(!isDiffErrorExpanded)}>
+									<div
+										style={{
+											display: "flex",
+											alignItems: "center",
+											gap: "10px",
+											flexGrow: 1,
+										}}>
+										<span
+											className="codicon codicon-warning"
+											style={{
+												color: "var(--vscode-editorWarning-foreground)",
+												opacity: 0.8,
+												fontSize: 16,
+												marginBottom: "-1.5px",
+											}}></span>
+										<span style={{ fontWeight: "bold" }}>{t("chat:diffError.title")}</span>
+									</div>
+									<div style={{ display: "flex", alignItems: "center" }}>
+										<VSCodeButton
+											appearance="icon"
+											style={{
+												padding: "3px",
+												height: "24px",
+												marginRight: "4px",
+												color: "var(--vscode-editor-foreground)",
+												display: "flex",
+												alignItems: "center",
+												justifyContent: "center",
+												background: "transparent",
+											}}
+											onClick={(e) => {
+												e.stopPropagation()
+
+												// Call copyWithFeedback and handle the Promise
+												copyWithFeedback(message.text || "").then((success) => {
+													if (success) {
+														// Show checkmark
+														setShowCopySuccess(true)
+
+														// Reset after a brief delay
+														setTimeout(() => {
+															setShowCopySuccess(false)
+														}, 1000)
+													}
+												})
+											}}>
+											<span
+												className={`codicon codicon-${showCopySuccess ? "check" : "copy"}`}></span>
+										</VSCodeButton>
+										<span
+											className={`codicon codicon-chevron-${isDiffErrorExpanded ? "up" : "down"}`}></span>
+									</div>
+								</div>
+								{isDiffErrorExpanded && (
+									<div
+										style={{
+											padding: "8px",
+											backgroundColor: "var(--vscode-editor-background)",
+											borderTop: "none",
+										}}>
+										<CodeBlock
+											source={`${"```"}plaintext\n${message.text || ""}\n${"```"}`}
+											forceWrap={true}
+										/>
+									</div>
+								)}
+							</div>
+						</div>
+					)
 				case "subtask_result":
 					return (
 						<div>

+ 3 - 0
webview-ui/src/i18n/locales/ca/chat.json

@@ -83,6 +83,9 @@
 	"edit": "Edita...",
 	"forNextMode": "per al següent mode",
 	"error": "Error",
+	"diffError": {
+		"title": "Edició fallida"
+	},
 	"troubleMessage": "Roo està tenint problemes...",
 	"apiRequest": {
 		"title": "Sol·licitud API",

+ 3 - 0
webview-ui/src/i18n/locales/de/chat.json

@@ -83,6 +83,9 @@
 	"edit": "Bearbeiten...",
 	"forNextMode": "für nächsten Modus",
 	"error": "Fehler",
+	"diffError": {
+		"title": "Bearbeitung fehlgeschlagen"
+	},
 	"troubleMessage": "Roo hat Probleme...",
 	"apiRequest": {
 		"title": "API-Anfrage",

+ 3 - 0
webview-ui/src/i18n/locales/en/chat.json

@@ -154,6 +154,9 @@
 	},
 	"taskCompleted": "Task Completed",
 	"error": "Error",
+	"diffError": {
+		"title": "Edit Unsuccessful"
+	},
 	"troubleMessage": "Roo is having trouble...",
 	"shellIntegration": {
 		"unavailable": "Shell Integration Unavailable",

+ 3 - 0
webview-ui/src/i18n/locales/es/chat.json

@@ -83,6 +83,9 @@
 	"edit": "Editar...",
 	"forNextMode": "para el siguiente modo",
 	"error": "Error",
+	"diffError": {
+		"title": "Edición fallida"
+	},
 	"troubleMessage": "Roo está teniendo problemas...",
 	"apiRequest": {
 		"title": "Solicitud API",

+ 3 - 0
webview-ui/src/i18n/locales/fr/chat.json

@@ -83,6 +83,9 @@
 	"edit": "Éditer...",
 	"forNextMode": "pour le prochain mode",
 	"error": "Erreur",
+	"diffError": {
+		"title": "Modification échouée"
+	},
 	"troubleMessage": "Roo rencontre des difficultés...",
 	"apiRequest": {
 		"title": "Requête API",

+ 3 - 0
webview-ui/src/i18n/locales/hi/chat.json

@@ -83,6 +83,9 @@
 	"edit": "संपादित करें...",
 	"forNextMode": "अगले मोड के लिए",
 	"error": "त्रुटि",
+	"diffError": {
+		"title": "संपादन असफल"
+	},
 	"troubleMessage": "Roo को समस्या हो रही है...",
 	"apiRequest": {
 		"title": "API अनुरोध",

+ 3 - 0
webview-ui/src/i18n/locales/it/chat.json

@@ -86,6 +86,9 @@
 		"wantsToFetch": "Roo vuole recuperare istruzioni dettagliate per aiutare con l'attività corrente"
 	},
 	"error": "Errore",
+	"diffError": {
+		"title": "Modifica non riuscita"
+	},
 	"troubleMessage": "Roo sta avendo problemi...",
 	"apiRequest": {
 		"title": "Richiesta API",

+ 3 - 0
webview-ui/src/i18n/locales/ja/chat.json

@@ -83,6 +83,9 @@
 	"edit": "編集...",
 	"forNextMode": "次のモード用",
 	"error": "エラー",
+	"diffError": {
+		"title": "編集に失敗しました"
+	},
 	"troubleMessage": "Rooに問題が発生しています...",
 	"apiRequest": {
 		"title": "APIリクエスト",

+ 3 - 0
webview-ui/src/i18n/locales/ko/chat.json

@@ -83,6 +83,9 @@
 	"edit": "편집...",
 	"forNextMode": "다음 모드용",
 	"error": "오류",
+	"diffError": {
+		"title": "편집 실패"
+	},
 	"troubleMessage": "Roo에 문제가 발생했습니다...",
 	"apiRequest": {
 		"title": "API 요청",

+ 3 - 0
webview-ui/src/i18n/locales/pl/chat.json

@@ -83,6 +83,9 @@
 	"edit": "Edytuj...",
 	"forNextMode": "dla następnego trybu",
 	"error": "Błąd",
+	"diffError": {
+		"title": "Edycja nieudana"
+	},
 	"troubleMessage": "Roo ma problemy...",
 	"apiRequest": {
 		"title": "Zapytanie API",

+ 3 - 0
webview-ui/src/i18n/locales/pt-BR/chat.json

@@ -83,6 +83,9 @@
 	"edit": "Editar...",
 	"forNextMode": "para o próximo modo",
 	"error": "Erro",
+	"diffError": {
+		"title": "Edição mal-sucedida"
+	},
 	"troubleMessage": "Roo está tendo problemas...",
 	"apiRequest": {
 		"title": "Requisição API",

+ 3 - 0
webview-ui/src/i18n/locales/tr/chat.json

@@ -83,6 +83,9 @@
 	"edit": "Düzenle...",
 	"forNextMode": "sonraki mod için",
 	"error": "Hata",
+	"diffError": {
+		"title": "Düzenleme Başarısız"
+	},
 	"troubleMessage": "Roo sorun yaşıyor...",
 	"apiRequest": {
 		"title": "API İsteği",

+ 3 - 0
webview-ui/src/i18n/locales/vi/chat.json

@@ -83,6 +83,9 @@
 	"edit": "Chỉnh sửa...",
 	"forNextMode": "cho chế độ tiếp theo",
 	"error": "Lỗi",
+	"diffError": {
+		"title": "Chỉnh sửa không thành công"
+	},
 	"troubleMessage": "Roo đang gặp sự cố...",
 	"apiRequest": {
 		"title": "Yêu cầu API",

+ 3 - 0
webview-ui/src/i18n/locales/zh-CN/chat.json

@@ -83,6 +83,9 @@
 	"edit": "编辑...",
 	"forNextMode": "用于下一个模式",
 	"error": "错误",
+	"diffError": {
+		"title": "编辑失败"
+	},
 	"troubleMessage": "Roo遇到问题...",
 	"apiRequest": {
 		"title": "API请求",

+ 3 - 0
webview-ui/src/i18n/locales/zh-TW/chat.json

@@ -83,6 +83,9 @@
 	"edit": "編輯...",
 	"forNextMode": "用於下一個模式",
 	"error": "錯誤",
+	"diffError": {
+		"title": "編輯失敗"
+	},
 	"troubleMessage": "Roo 遇到問題...",
 	"apiRequest": {
 		"title": "API 請求",