diff --git a/src/core/prompts/__tests__/sections.test.ts b/src/core/prompts/__tests__/sections.test.ts index 2716f610f49..8ace0c6ff2c 100644 --- a/src/core/prompts/__tests__/sections.test.ts +++ b/src/core/prompts/__tests__/sections.test.ts @@ -13,7 +13,7 @@ describe("addCustomInstructions", () => { ) expect(result).toContain("Language Preference:") - expect(result).toContain('You should always speak and think in the "fr" language') + expect(result).toContain('You should always speak and think in the "Français" (fr) language') }) test("works without vscode language", async () => { diff --git a/src/core/prompts/sections/__tests__/custom-instructions.test.ts b/src/core/prompts/sections/__tests__/custom-instructions.test.ts index 1922a22efcf..4dbb51c845b 100644 --- a/src/core/prompts/sections/__tests__/custom-instructions.test.ts +++ b/src/core/prompts/sections/__tests__/custom-instructions.test.ts @@ -117,7 +117,8 @@ describe("addCustomInstructions", () => { ) expect(result).toContain("Language Preference:") - expect(result).toContain("es") + expect(result).toContain("Español") // Check for language name + expect(result).toContain("(es)") // Check for language code in parentheses expect(result).toContain("Global Instructions:\nglobal instructions") expect(result).toContain("Mode-specific Instructions:\nmode instructions") expect(result).toContain("Rules from .clinerules-test-mode:\nmode specific rules") @@ -145,6 +146,22 @@ describe("addCustomInstructions", () => { expect(result).not.toContain("Rules from .clinerules-test-mode") }) + it("should handle unknown language codes properly", async () => { + mockedFs.readFile.mockRejectedValue({ code: "ENOENT" }) + + const result = await addCustomInstructions( + "mode instructions", + "global instructions", + "/fake/path", + "test-mode", + { language: "xyz" }, // Unknown language code + ) + + expect(result).toContain("Language Preference:") + expect(result).toContain('"xyz" (xyz) language') // For unknown codes, the code is used as the name too + expect(result).toContain("Global Instructions:\nglobal instructions") + }) + it("should throw on unexpected errors", async () => { const error = new Error("Permission denied") as NodeJS.ErrnoException error.code = "EPERM" diff --git a/src/core/prompts/sections/custom-instructions.ts b/src/core/prompts/sections/custom-instructions.ts index 04ef5b06c95..f076777585d 100644 --- a/src/core/prompts/sections/custom-instructions.ts +++ b/src/core/prompts/sections/custom-instructions.ts @@ -1,6 +1,7 @@ import fs from "fs/promises" import path from "path" import * as vscode from "vscode" +import { LANGUAGES } from "../../../shared/language" async function safeReadFile(filePath: string): Promise { try { @@ -47,8 +48,9 @@ export async function addCustomInstructions( // Add language preference if provided if (options.language) { + const languageName = LANGUAGES[options.language] || options.language sections.push( - `Language Preference:\nYou should always speak and think in the "${options.language}" language unless the user gives you instructions below to do otherwise.`, + `Language Preference:\nYou should always speak and think in the "${languageName}" (${options.language}) language unless the user gives you instructions below to do otherwise.`, ) } diff --git a/src/shared/language.ts b/src/shared/language.ts index b5cb4228b5c..c7bc53b00c7 100644 --- a/src/shared/language.ts +++ b/src/shared/language.ts @@ -1,3 +1,24 @@ +/** + * Language name mapping from ISO codes to full language names + */ +export const LANGUAGES: Record = { + ca: "Català", + de: "Deutsch", + en: "English", + es: "Español", + fr: "Français", + hi: "हिन्दी", + it: "Italiano", + ja: "日本語", + ko: "한국어", + pl: "Polski", + "pt-BR": "Português", + tr: "Türkçe", + vi: "Tiếng Việt", + "zh-CN": "简体中文", + "zh-TW": "繁體中文", +} + /** * Formats a VSCode locale string to ensure the region code is uppercase. * For example, transforms "en-us" to "en-US" or "fr-ca" to "fr-CA". diff --git a/webview-ui/src/components/settings/LanguageSettings.tsx b/webview-ui/src/components/settings/LanguageSettings.tsx index 74f35b891ae..7e6d1ea9bcb 100644 --- a/webview-ui/src/components/settings/LanguageSettings.tsx +++ b/webview-ui/src/components/settings/LanguageSettings.tsx @@ -4,29 +4,12 @@ import { Globe } from "lucide-react" import { cn } from "@/lib/utils" import { Select, SelectContent, SelectGroup, SelectItem, SelectTrigger, SelectValue } from "@/components/ui" +import { LANGUAGES } from "../../../../src/shared/language" import { SetCachedStateField } from "./types" import { SectionHeader } from "./SectionHeader" import { Section } from "./Section" -const LANGUAGES: Record = { - ca: "Català", - de: "Deutsch", - en: "English", - es: "Español", - fr: "Français", - hi: "हिन्दी", - it: "Italiano", - ja: "日本語", - ko: "한국어", - pl: "Polski", - "pt-BR": "Português", - tr: "Türkçe", - vi: "Tiếng Việt", - "zh-CN": "简体中文", - "zh-TW": "繁體中文", -} - type LanguageSettingsProps = HTMLAttributes & { language: string setCachedStateField: SetCachedStateField<"language">