Parcourir la source

Remove preferredLanguage and just rely on VSCode language

Matt Rubens il y a 9 mois
Parent
commit
baa346dc46

+ 9 - 0
src/__mocks__/vscode.js

@@ -1,4 +1,13 @@
 const vscode = {
 const vscode = {
+	env: {
+		language: "en", // Default language for tests
+		appName: "Visual Studio Code Test",
+		appHost: "desktop",
+		appRoot: "/test/path",
+		machineId: "test-machine-id",
+		sessionId: "test-session-id",
+		shell: "/bin/zsh",
+	},
 	window: {
 	window: {
 		showInformationMessage: jest.fn(),
 		showInformationMessage: jest.fn(),
 		showErrorMessage: jest.fn(),
 		showErrorMessage: jest.fn(),

+ 1 - 4
src/core/Cline.ts

@@ -1102,7 +1102,6 @@ export class Cline {
 			browserViewportSize,
 			browserViewportSize,
 			mode,
 			mode,
 			customModePrompts,
 			customModePrompts,
-			preferredLanguage,
 			experiments,
 			experiments,
 			enableMcpServerCreation,
 			enableMcpServerCreation,
 			browserToolEnabled,
 			browserToolEnabled,
@@ -1124,7 +1123,6 @@ export class Cline {
 				customModePrompts,
 				customModePrompts,
 				customModes,
 				customModes,
 				this.customInstructions,
 				this.customInstructions,
-				preferredLanguage,
 				this.diffEnabled,
 				this.diffEnabled,
 				experiments,
 				experiments,
 				enableMcpServerCreation,
 				enableMcpServerCreation,
@@ -3665,13 +3663,12 @@ export class Cline {
 			customModePrompts,
 			customModePrompts,
 			experiments = {} as Record<ExperimentId, boolean>,
 			experiments = {} as Record<ExperimentId, boolean>,
 			customInstructions: globalCustomInstructions,
 			customInstructions: globalCustomInstructions,
-			preferredLanguage,
 		} = (await this.providerRef.deref()?.getState()) ?? {}
 		} = (await this.providerRef.deref()?.getState()) ?? {}
 		const currentMode = mode ?? defaultModeSlug
 		const currentMode = mode ?? defaultModeSlug
 		const modeDetails = await getFullModeDetails(currentMode, customModes, customModePrompts, {
 		const modeDetails = await getFullModeDetails(currentMode, customModes, customModePrompts, {
 			cwd,
 			cwd,
 			globalCustomInstructions,
 			globalCustomInstructions,
-			preferredLanguage,
+			vscodeLanguage: vscode.env.language,
 		})
 		})
 		details += `\n\n# Current Mode\n`
 		details += `\n\n# Current Mode\n`
 		details += `<slug>${currentMode}</slug>\n`
 		details += `<slug>${currentMode}</slug>\n`

Fichier diff supprimé car celui-ci est trop grand
+ 1120 - 0
src/core/prompts/__tests__/__snapshots__/system.test.ts.snap


+ 33 - 40
src/core/prompts/__tests__/custom-system-prompt.test.ts

@@ -46,8 +46,6 @@ const mockContext = {
 } as unknown as vscode.ExtensionContext
 } as unknown as vscode.ExtensionContext
 
 
 describe("File-Based Custom System Prompt", () => {
 describe("File-Based Custom System Prompt", () => {
-	const experiments = {}
-
 	beforeEach(() => {
 	beforeEach(() => {
 		// Reset mocks before each test
 		// Reset mocks before each test
 		jest.clearAllMocks()
 		jest.clearAllMocks()
@@ -66,18 +64,17 @@ describe("File-Based Custom System Prompt", () => {
 		const prompt = await SYSTEM_PROMPT(
 		const prompt = await SYSTEM_PROMPT(
 			mockContext,
 			mockContext,
 			"test/path", // Using a relative path without leading slash
 			"test/path", // Using a relative path without leading slash
-			false,
-			undefined,
-			undefined,
-			undefined,
-			defaultModeSlug,
-			customModePrompts,
-			undefined,
-			undefined,
-			undefined,
-			undefined,
-			experiments,
-			true,
+			false, // supportsComputerUse
+			undefined, // mcpHub
+			undefined, // diffStrategy
+			undefined, // browserViewportSize
+			defaultModeSlug, // mode
+			customModePrompts, // customModePrompts
+			undefined, // customModes
+			undefined, // globalCustomInstructions
+			undefined, // diffEnabled
+			undefined, // experiments
+			true, // enableMcpServerCreation
 		)
 		)
 
 
 		// Should contain default sections
 		// Should contain default sections
@@ -101,18 +98,17 @@ describe("File-Based Custom System Prompt", () => {
 		const prompt = await SYSTEM_PROMPT(
 		const prompt = await SYSTEM_PROMPT(
 			mockContext,
 			mockContext,
 			"test/path", // Using a relative path without leading slash
 			"test/path", // Using a relative path without leading slash
-			false,
-			undefined,
-			undefined,
-			undefined,
-			defaultModeSlug,
-			undefined,
-			undefined,
-			undefined,
-			undefined,
-			undefined,
-			experiments,
-			true,
+			false, // supportsComputerUse
+			undefined, // mcpHub
+			undefined, // diffStrategy
+			undefined, // browserViewportSize
+			defaultModeSlug, // mode
+			undefined, // customModePrompts
+			undefined, // customModes
+			undefined, // globalCustomInstructions
+			undefined, // diffEnabled
+			undefined, // experiments
+			true, // enableMcpServerCreation
 		)
 		)
 
 
 		// Should contain role definition and file-based system prompt
 		// Should contain role definition and file-based system prompt
@@ -120,7 +116,6 @@ describe("File-Based Custom System Prompt", () => {
 		expect(prompt).toContain(fileCustomSystemPrompt)
 		expect(prompt).toContain(fileCustomSystemPrompt)
 
 
 		// Should not contain any of the default sections
 		// Should not contain any of the default sections
-		expect(prompt).not.toContain("TOOL USE")
 		expect(prompt).not.toContain("CAPABILITIES")
 		expect(prompt).not.toContain("CAPABILITIES")
 		expect(prompt).not.toContain("MODES")
 		expect(prompt).not.toContain("MODES")
 	})
 	})
@@ -146,18 +141,17 @@ describe("File-Based Custom System Prompt", () => {
 		const prompt = await SYSTEM_PROMPT(
 		const prompt = await SYSTEM_PROMPT(
 			mockContext,
 			mockContext,
 			"test/path", // Using a relative path without leading slash
 			"test/path", // Using a relative path without leading slash
-			false,
-			undefined,
-			undefined,
-			undefined,
-			defaultModeSlug,
-			customModePrompts,
-			undefined,
-			undefined,
-			undefined,
-			undefined,
-			experiments,
-			true,
+			false, // supportsComputerUse
+			undefined, // mcpHub
+			undefined, // diffStrategy
+			undefined, // browserViewportSize
+			defaultModeSlug, // mode
+			customModePrompts, // customModePrompts
+			undefined, // customModes
+			undefined, // globalCustomInstructions
+			undefined, // diffEnabled
+			undefined, // experiments
+			true, // enableMcpServerCreation
 		)
 		)
 
 
 		// Should contain custom role definition and file-based system prompt
 		// Should contain custom role definition and file-based system prompt
@@ -165,7 +159,6 @@ describe("File-Based Custom System Prompt", () => {
 		expect(prompt).toContain(fileCustomSystemPrompt)
 		expect(prompt).toContain(fileCustomSystemPrompt)
 
 
 		// Should not contain any of the default sections
 		// Should not contain any of the default sections
-		expect(prompt).not.toContain("TOOL USE")
 		expect(prompt).not.toContain("CAPABILITIES")
 		expect(prompt).not.toContain("CAPABILITIES")
 		expect(prompt).not.toContain("MODES")
 		expect(prompt).not.toContain("MODES")
 	})
 	})

+ 4 - 4
src/core/prompts/__tests__/sections.test.ts

@@ -3,20 +3,20 @@ import { getCapabilitiesSection } from "../sections/capabilities"
 import { DiffStrategy, DiffResult } from "../../diff/types"
 import { DiffStrategy, DiffResult } from "../../diff/types"
 
 
 describe("addCustomInstructions", () => {
 describe("addCustomInstructions", () => {
-	test("adds preferred language to custom instructions", async () => {
+	test("adds vscode language to custom instructions", async () => {
 		const result = await addCustomInstructions(
 		const result = await addCustomInstructions(
 			"mode instructions",
 			"mode instructions",
 			"global instructions",
 			"global instructions",
 			"/test/path",
 			"/test/path",
 			"test-mode",
 			"test-mode",
-			{ preferredLanguage: "French" },
+			{ vscodeLanguage: "fr" },
 		)
 		)
 
 
 		expect(result).toContain("Language Preference:")
 		expect(result).toContain("Language Preference:")
-		expect(result).toContain("You should always speak and think in the French language")
+		expect(result).toContain('You should always speak and think in the "fr" language')
 	})
 	})
 
 
-	test("works without preferred language", async () => {
+	test("works without vscode language", async () => {
 		const result = await addCustomInstructions(
 		const result = await addCustomInstructions(
 			"mode instructions",
 			"mode instructions",
 			"global instructions",
 			"global instructions",

+ 154 - 113
src/core/prompts/__tests__/system.test.ts

@@ -6,7 +6,7 @@ import { SearchReplaceDiffStrategy } from "../../../core/diff/strategies/search-
 import * as vscode from "vscode"
 import * as vscode from "vscode"
 import fs from "fs/promises"
 import fs from "fs/promises"
 import os from "os"
 import os from "os"
-import { defaultModeSlug, modes } from "../../../shared/modes"
+import { defaultModeSlug, modes, Mode, isToolAllowedForMode } from "../../../shared/modes"
 // Import path utils to get access to toPosix string extension
 // Import path utils to get access to toPosix string extension
 import "../../../utils/path"
 import "../../../utils/path"
 import { addCustomInstructions } from "../sections/custom-instructions"
 import { addCustomInstructions } from "../sections/custom-instructions"
@@ -18,46 +18,63 @@ jest.mock("../sections/modes", () => ({
 	getModesSection: jest.fn().mockImplementation(async () => `====\n\nMODES\n\n- Test modes section`),
 	getModesSection: jest.fn().mockImplementation(async () => `====\n\nMODES\n\n- Test modes section`),
 }))
 }))
 
 
-jest.mock("../sections/custom-instructions", () => ({
-	addCustomInstructions: jest
-		.fn()
-		.mockImplementation(async (modeCustomInstructions, globalCustomInstructions, cwd, mode, options) => {
-			const sections = []
-
-			// Add language preference if provided
-			if (options?.preferredLanguage) {
-				sections.push(
-					`Language Preference:\nYou should always speak and think in the ${options.preferredLanguage} language.`,
-				)
-			}
+// Mock the custom instructions
+jest.mock("../sections/custom-instructions", () => {
+	const addCustomInstructions = jest.fn()
+	return {
+		addCustomInstructions,
+		__setMockImplementation: (impl: any) => {
+			addCustomInstructions.mockImplementation(impl)
+		},
+	}
+})
 
 
-			// Add global instructions first
-			if (globalCustomInstructions?.trim()) {
-				sections.push(`Global Instructions:\n${globalCustomInstructions.trim()}`)
-			}
+// Set up default mock implementation
+const { __setMockImplementation } = jest.requireMock("../sections/custom-instructions")
+__setMockImplementation(
+	async (
+		modeCustomInstructions: string,
+		globalCustomInstructions: string,
+		cwd: string,
+		mode: string,
+		options?: { vscodeLanguage?: string },
+	) => {
+		const sections = []
+
+		// Add language preference if provided
+		if (options?.vscodeLanguage) {
+			sections.push(
+				`Language Preference:\nYou should always speak and think in the "${options.vscodeLanguage}" language.`,
+			)
+		}
 
 
-			// Add mode-specific instructions after
-			if (modeCustomInstructions?.trim()) {
-				sections.push(`Mode-specific Instructions:\n${modeCustomInstructions}`)
-			}
+		// Add global instructions first
+		if (globalCustomInstructions?.trim()) {
+			sections.push(`Global Instructions:\n${globalCustomInstructions.trim()}`)
+		}
 
 
-			// Add rules
-			const rules = []
-			if (mode) {
-				rules.push(`# Rules from .clinerules-${mode}:\nMock mode-specific rules`)
-			}
-			rules.push(`# Rules from .clinerules:\nMock generic rules`)
+		// Add mode-specific instructions after
+		if (modeCustomInstructions?.trim()) {
+			sections.push(`Mode-specific Instructions:\n${modeCustomInstructions}`)
+		}
 
 
-			if (rules.length > 0) {
-				sections.push(`Rules:\n${rules.join("\n")}`)
-			}
+		// Add rules
+		const rules = []
+		if (mode) {
+			rules.push(`# Rules from .clinerules-${mode}:\nMock mode-specific rules`)
+		}
+		rules.push(`# Rules from .clinerules:\nMock generic rules`)
 
 
-			const joinedSections = sections.join("\n\n")
-			return joinedSections
-				? `\n====\n\nUSER'S CUSTOM INSTRUCTIONS\n\nThe following additional instructions are provided by the user, and should be followed to the best of your ability without interfering with the TOOL USE guidelines.\n\n${joinedSections}`
-				: ""
-		}),
-}))
+		if (rules.length > 0) {
+			sections.push(`Rules:\n${rules.join("\n")}`)
+		}
+
+		const joinedSections = sections.join("\n\n")
+		return joinedSections
+			? `\n====\n\nUSER'S CUSTOM INSTRUCTIONS\n\nThe following additional instructions are provided by the user, and should be followed to the best of your ability without interfering with the TOOL USE guidelines.\n\n${joinedSections}`
+			: ""
+	},
+)
 
 
 // Mock environment-specific values for consistent tests
 // Mock environment-specific values for consistent tests
 jest.mock("os", () => ({
 jest.mock("os", () => ({
@@ -69,6 +86,13 @@ jest.mock("default-shell", () => "/bin/zsh")
 
 
 jest.mock("os-name", () => () => "Linux")
 jest.mock("os-name", () => () => "Linux")
 
 
+// Mock vscode language
+jest.mock("vscode", () => ({
+	env: {
+		language: "en",
+	},
+}))
+
 jest.mock("../../../utils/shell", () => ({
 jest.mock("../../../utils/shell", () => ({
 	getShell: () => "/bin/zsh",
 	getShell: () => "/bin/zsh",
 }))
 }))
@@ -126,7 +150,7 @@ const createMockMcpHub = (): McpHub =>
 
 
 describe("SYSTEM_PROMPT", () => {
 describe("SYSTEM_PROMPT", () => {
 	let mockMcpHub: McpHub
 	let mockMcpHub: McpHub
-	let experiments: Record<string, boolean>
+	let experiments: Record<string, boolean> | undefined
 
 
 	beforeAll(() => {
 	beforeAll(() => {
 		// Ensure fs mock is properly initialized
 		// Ensure fs mock is properly initialized
@@ -146,6 +170,10 @@ describe("SYSTEM_PROMPT", () => {
 			"/mock/mcp/path",
 			"/mock/mcp/path",
 		]
 		]
 		dirs.forEach((dir) => mockFs._mockDirectories.add(dir))
 		dirs.forEach((dir) => mockFs._mockDirectories.add(dir))
+	})
+
+	beforeEach(() => {
+		// Reset experiments before each test to ensure they're disabled by default
 		experiments = {
 		experiments = {
 			[EXPERIMENT_IDS.SEARCH_AND_REPLACE]: false,
 			[EXPERIMENT_IDS.SEARCH_AND_REPLACE]: false,
 			[EXPERIMENT_IDS.INSERT_BLOCK]: false,
 			[EXPERIMENT_IDS.INSERT_BLOCK]: false,
@@ -175,7 +203,6 @@ describe("SYSTEM_PROMPT", () => {
 			undefined, // customModePrompts
 			undefined, // customModePrompts
 			undefined, // customModes
 			undefined, // customModes
 			undefined, // globalCustomInstructions
 			undefined, // globalCustomInstructions
-			undefined, // preferredLanguage
 			undefined, // diffEnabled
 			undefined, // diffEnabled
 			experiments,
 			experiments,
 			true, // enableMcpServerCreation
 			true, // enableMcpServerCreation
@@ -196,7 +223,6 @@ describe("SYSTEM_PROMPT", () => {
 			undefined, // customModePrompts
 			undefined, // customModePrompts
 			undefined, // customModes,
 			undefined, // customModes,
 			undefined, // globalCustomInstructions
 			undefined, // globalCustomInstructions
-			undefined, // preferredLanguage
 			undefined, // diffEnabled
 			undefined, // diffEnabled
 			experiments,
 			experiments,
 			true, // enableMcpServerCreation
 			true, // enableMcpServerCreation
@@ -219,7 +245,6 @@ describe("SYSTEM_PROMPT", () => {
 			undefined, // customModePrompts
 			undefined, // customModePrompts
 			undefined, // customModes,
 			undefined, // customModes,
 			undefined, // globalCustomInstructions
 			undefined, // globalCustomInstructions
-			undefined, // preferredLanguage
 			undefined, // diffEnabled
 			undefined, // diffEnabled
 			experiments,
 			experiments,
 			true, // enableMcpServerCreation
 			true, // enableMcpServerCreation
@@ -240,7 +265,6 @@ describe("SYSTEM_PROMPT", () => {
 			undefined, // customModePrompts
 			undefined, // customModePrompts
 			undefined, // customModes,
 			undefined, // customModes,
 			undefined, // globalCustomInstructions
 			undefined, // globalCustomInstructions
-			undefined, // preferredLanguage
 			undefined, // diffEnabled
 			undefined, // diffEnabled
 			experiments,
 			experiments,
 			true, // enableMcpServerCreation
 			true, // enableMcpServerCreation
@@ -261,7 +285,6 @@ describe("SYSTEM_PROMPT", () => {
 			undefined, // customModePrompts
 			undefined, // customModePrompts
 			undefined, // customModes,
 			undefined, // customModes,
 			undefined, // globalCustomInstructions
 			undefined, // globalCustomInstructions
-			undefined, // preferredLanguage
 			undefined, // diffEnabled
 			undefined, // diffEnabled
 			experiments,
 			experiments,
 			true, // enableMcpServerCreation
 			true, // enableMcpServerCreation
@@ -282,7 +305,6 @@ describe("SYSTEM_PROMPT", () => {
 			undefined, // customModePrompts
 			undefined, // customModePrompts
 			undefined, // customModes
 			undefined, // customModes
 			undefined, // globalCustomInstructions
 			undefined, // globalCustomInstructions
-			undefined, // preferredLanguage
 			true, // diffEnabled
 			true, // diffEnabled
 			experiments,
 			experiments,
 			true, // enableMcpServerCreation
 			true, // enableMcpServerCreation
@@ -304,7 +326,6 @@ describe("SYSTEM_PROMPT", () => {
 			undefined, // customModePrompts
 			undefined, // customModePrompts
 			undefined, // customModes
 			undefined, // customModes
 			undefined, // globalCustomInstructions
 			undefined, // globalCustomInstructions
-			undefined, // preferredLanguage
 			false, // diffEnabled
 			false, // diffEnabled
 			experiments,
 			experiments,
 			true, // enableMcpServerCreation
 			true, // enableMcpServerCreation
@@ -326,7 +347,6 @@ describe("SYSTEM_PROMPT", () => {
 			undefined, // customModePrompts
 			undefined, // customModePrompts
 			undefined, // customModes
 			undefined, // customModes
 			undefined, // globalCustomInstructions
 			undefined, // globalCustomInstructions
-			undefined, // preferredLanguage
 			undefined, // diffEnabled
 			undefined, // diffEnabled
 			experiments,
 			experiments,
 			true, // enableMcpServerCreation
 			true, // enableMcpServerCreation
@@ -336,7 +356,11 @@ describe("SYSTEM_PROMPT", () => {
 		expect(prompt).toMatchSnapshot()
 		expect(prompt).toMatchSnapshot()
 	})
 	})
 
 
-	it("should include preferred language in custom instructions", async () => {
+	it("should include vscode language in custom instructions", async () => {
+		// Mock vscode.env.language
+		const vscode = jest.requireMock("vscode")
+		vscode.env = { language: "es" }
+
 		const prompt = await SYSTEM_PROMPT(
 		const prompt = await SYSTEM_PROMPT(
 			mockContext,
 			mockContext,
 			"/test/path",
 			"/test/path",
@@ -348,14 +372,16 @@ describe("SYSTEM_PROMPT", () => {
 			undefined, // customModePrompts
 			undefined, // customModePrompts
 			undefined, // customModes
 			undefined, // customModes
 			undefined, // globalCustomInstructions
 			undefined, // globalCustomInstructions
-			"Spanish", // preferredLanguage
 			undefined, // diffEnabled
 			undefined, // diffEnabled
-			experiments,
+			undefined, // experiments
 			true, // enableMcpServerCreation
 			true, // enableMcpServerCreation
 		)
 		)
 
 
 		expect(prompt).toContain("Language Preference:")
 		expect(prompt).toContain("Language Preference:")
-		expect(prompt).toContain("You should always speak and think in the Spanish language")
+		expect(prompt).toContain('You should always speak and think in the "es" language')
+
+		// Reset mock
+		vscode.env = { language: "en" }
 	})
 	})
 
 
 	it("should include custom mode role definition at top and instructions at bottom", async () => {
 	it("should include custom mode role definition at top and instructions at bottom", async () => {
@@ -381,7 +407,6 @@ describe("SYSTEM_PROMPT", () => {
 			undefined, // customModePrompts
 			undefined, // customModePrompts
 			customModes, // customModes
 			customModes, // customModes
 			"Global instructions", // globalCustomInstructions
 			"Global instructions", // globalCustomInstructions
-			undefined, // preferredLanguage
 			undefined, // diffEnabled
 			undefined, // diffEnabled
 			experiments,
 			experiments,
 			true, // enableMcpServerCreation
 			true, // enableMcpServerCreation
@@ -409,18 +434,17 @@ describe("SYSTEM_PROMPT", () => {
 		const prompt = await SYSTEM_PROMPT(
 		const prompt = await SYSTEM_PROMPT(
 			mockContext,
 			mockContext,
 			"/test/path",
 			"/test/path",
-			false,
-			undefined,
-			undefined,
-			undefined,
-			defaultModeSlug,
-			customModePrompts,
-			undefined,
-			undefined,
-			undefined,
-			undefined,
-			experiments,
-			true, // enableMcpServerCreation
+			false, // supportsComputerUse
+			undefined, // mcpHub
+			undefined, // diffStrategy
+			undefined, // browserViewportSize
+			defaultModeSlug as Mode, // mode
+			customModePrompts, // customModePrompts
+			undefined, // customModes
+			undefined, // globalCustomInstructions
+			undefined, // diffEnabled
+			undefined, // experiments
+			false, // enableMcpServerCreation
 		)
 		)
 
 
 		// Role definition from promptComponent should be at the top
 		// Role definition from promptComponent should be at the top
@@ -440,18 +464,17 @@ describe("SYSTEM_PROMPT", () => {
 		const prompt = await SYSTEM_PROMPT(
 		const prompt = await SYSTEM_PROMPT(
 			mockContext,
 			mockContext,
 			"/test/path",
 			"/test/path",
-			false,
-			undefined,
-			undefined,
-			undefined,
-			defaultModeSlug,
-			customModePrompts,
-			undefined,
-			undefined,
-			undefined,
-			undefined,
-			experiments,
-			true, // enableMcpServerCreation
+			false, // supportsComputerUse
+			undefined, // mcpHub
+			undefined, // diffStrategy
+			undefined, // browserViewportSize
+			defaultModeSlug as Mode, // mode
+			customModePrompts, // customModePrompts
+			undefined, // customModes
+			undefined, // globalCustomInstructions
+			undefined, // diffEnabled
+			undefined, // experiments
+			false, // enableMcpServerCreation
 		)
 		)
 
 
 		// Should use the default mode's role definition
 		// Should use the default mode's role definition
@@ -460,6 +483,15 @@ describe("SYSTEM_PROMPT", () => {
 
 
 	describe("experimental tools", () => {
 	describe("experimental tools", () => {
 		it("should disable experimental tools by default", async () => {
 		it("should disable experimental tools by default", async () => {
+			// Set experiments to explicitly disable experimental tools
+			const experimentsConfig = {
+				[EXPERIMENT_IDS.SEARCH_AND_REPLACE]: false,
+				[EXPERIMENT_IDS.INSERT_BLOCK]: false,
+			}
+
+			// Reset experiments
+			experiments = experimentsConfig
+
 			const prompt = await SYSTEM_PROMPT(
 			const prompt = await SYSTEM_PROMPT(
 				mockContext,
 				mockContext,
 				"/test/path",
 				"/test/path",
@@ -471,23 +503,29 @@ describe("SYSTEM_PROMPT", () => {
 				undefined, // customModePrompts
 				undefined, // customModePrompts
 				undefined, // customModes
 				undefined, // customModes
 				undefined, // globalCustomInstructions
 				undefined, // globalCustomInstructions
-				undefined, // preferredLanguage
 				undefined, // diffEnabled
 				undefined, // diffEnabled
-				experiments, // experiments - undefined should disable all experimental tools
+				experimentsConfig, // Explicitly disable experimental tools
 				true, // enableMcpServerCreation
 				true, // enableMcpServerCreation
 			)
 			)
 
 
-			// Verify experimental tools are not included in the prompt
-			expect(prompt).not.toContain(EXPERIMENT_IDS.SEARCH_AND_REPLACE)
-			expect(prompt).not.toContain(EXPERIMENT_IDS.INSERT_BLOCK)
+			// Check that experimental tool sections are not included
+			const toolSections = prompt.split("\n## ").slice(1)
+			const toolNames = toolSections.map((section) => section.split("\n")[0].trim())
+			expect(toolNames).not.toContain("search_and_replace")
+			expect(toolNames).not.toContain("insert_content")
+			expect(prompt).toMatchSnapshot()
 		})
 		})
 
 
 		it("should enable experimental tools when explicitly enabled", async () => {
 		it("should enable experimental tools when explicitly enabled", async () => {
-			const experiments = {
+			// Set experiments for testing experimental features
+			const experimentsEnabled = {
 				[EXPERIMENT_IDS.SEARCH_AND_REPLACE]: true,
 				[EXPERIMENT_IDS.SEARCH_AND_REPLACE]: true,
 				[EXPERIMENT_IDS.INSERT_BLOCK]: true,
 				[EXPERIMENT_IDS.INSERT_BLOCK]: true,
 			}
 			}
 
 
+			// Reset default experiments
+			experiments = undefined
+
 			const prompt = await SYSTEM_PROMPT(
 			const prompt = await SYSTEM_PROMPT(
 				mockContext,
 				mockContext,
 				"/test/path",
 				"/test/path",
@@ -499,23 +537,31 @@ describe("SYSTEM_PROMPT", () => {
 				undefined, // customModePrompts
 				undefined, // customModePrompts
 				undefined, // customModes
 				undefined, // customModes
 				undefined, // globalCustomInstructions
 				undefined, // globalCustomInstructions
-				undefined, // preferredLanguage
 				undefined, // diffEnabled
 				undefined, // diffEnabled
-				experiments,
+				experimentsEnabled, // Use the enabled experiments
 				true, // enableMcpServerCreation
 				true, // enableMcpServerCreation
 			)
 			)
 
 
+			// Get all tool sections
+			const toolSections = prompt.split("## ").slice(1) // Split by section headers and remove first non-tool part
+			const toolNames = toolSections.map((section) => section.split("\n")[0].trim())
+
 			// Verify experimental tools are included in the prompt when enabled
 			// Verify experimental tools are included in the prompt when enabled
-			expect(prompt).toContain(EXPERIMENT_IDS.SEARCH_AND_REPLACE)
-			expect(prompt).toContain(EXPERIMENT_IDS.INSERT_BLOCK)
+			expect(toolNames).toContain("search_and_replace")
+			expect(toolNames).toContain("insert_content")
+			expect(prompt).toMatchSnapshot()
 		})
 		})
 
 
 		it("should selectively enable experimental tools", async () => {
 		it("should selectively enable experimental tools", async () => {
-			const experiments = {
+			// Set experiments for testing selective enabling
+			const experimentsSelective = {
 				[EXPERIMENT_IDS.SEARCH_AND_REPLACE]: true,
 				[EXPERIMENT_IDS.SEARCH_AND_REPLACE]: true,
 				[EXPERIMENT_IDS.INSERT_BLOCK]: false,
 				[EXPERIMENT_IDS.INSERT_BLOCK]: false,
 			}
 			}
 
 
+			// Reset default experiments
+			experiments = undefined
+
 			const prompt = await SYSTEM_PROMPT(
 			const prompt = await SYSTEM_PROMPT(
 				mockContext,
 				mockContext,
 				"/test/path",
 				"/test/path",
@@ -527,15 +573,19 @@ describe("SYSTEM_PROMPT", () => {
 				undefined, // customModePrompts
 				undefined, // customModePrompts
 				undefined, // customModes
 				undefined, // customModes
 				undefined, // globalCustomInstructions
 				undefined, // globalCustomInstructions
-				undefined, // preferredLanguage
 				undefined, // diffEnabled
 				undefined, // diffEnabled
-				experiments,
+				experimentsSelective, // Use the selective experiments
 				true, // enableMcpServerCreation
 				true, // enableMcpServerCreation
 			)
 			)
 
 
+			// Get all tool sections
+			const toolSections = prompt.split("## ").slice(1) // Split by section headers and remove first non-tool part
+			const toolNames = toolSections.map((section) => section.split("\n")[0].trim())
+
 			// Verify only enabled experimental tools are included
 			// Verify only enabled experimental tools are included
-			expect(prompt).toContain(EXPERIMENT_IDS.SEARCH_AND_REPLACE)
-			expect(prompt).not.toContain(EXPERIMENT_IDS.INSERT_BLOCK)
+			expect(toolNames).toContain("search_and_replace")
+			expect(toolNames).not.toContain("insert_content")
+			expect(prompt).toMatchSnapshot()
 		})
 		})
 
 
 		it("should list all available editing tools in base instruction", async () => {
 		it("should list all available editing tools in base instruction", async () => {
@@ -555,9 +605,8 @@ describe("SYSTEM_PROMPT", () => {
 				undefined,
 				undefined,
 				undefined,
 				undefined,
 				undefined,
 				undefined,
-				undefined,
 				true, // diffEnabled
 				true, // diffEnabled
-				experiments,
+				experiments, // experiments
 				true, // enableMcpServerCreation
 				true, // enableMcpServerCreation
 			)
 			)
 
 
@@ -567,7 +616,6 @@ describe("SYSTEM_PROMPT", () => {
 			expect(prompt).toContain("insert_content (for adding lines to existing files)")
 			expect(prompt).toContain("insert_content (for adding lines to existing files)")
 			expect(prompt).toContain("search_and_replace (for finding and replacing individual pieces of text)")
 			expect(prompt).toContain("search_and_replace (for finding and replacing individual pieces of text)")
 		})
 		})
-
 		it("should provide detailed instructions for each enabled tool", async () => {
 		it("should provide detailed instructions for each enabled tool", async () => {
 			const experiments = {
 			const experiments = {
 				[EXPERIMENT_IDS.SEARCH_AND_REPLACE]: true,
 				[EXPERIMENT_IDS.SEARCH_AND_REPLACE]: true,
@@ -585,8 +633,7 @@ describe("SYSTEM_PROMPT", () => {
 				undefined,
 				undefined,
 				undefined,
 				undefined,
 				undefined,
 				undefined,
-				undefined,
-				true,
+				true, // diffEnabled
 				experiments,
 				experiments,
 				true, // enableMcpServerCreation
 				true, // enableMcpServerCreation
 			)
 			)
@@ -606,7 +653,7 @@ describe("SYSTEM_PROMPT", () => {
 })
 })
 
 
 describe("addCustomInstructions", () => {
 describe("addCustomInstructions", () => {
-	let experiments: Record<string, boolean>
+	let experiments: Record<string, boolean> | undefined
 	beforeAll(() => {
 	beforeAll(() => {
 		// Ensure fs mock is properly initialized
 		// Ensure fs mock is properly initialized
 		const mockFs = jest.requireMock("fs/promises")
 		const mockFs = jest.requireMock("fs/promises")
@@ -619,10 +666,8 @@ describe("addCustomInstructions", () => {
 			throw new Error(`ENOENT: no such file or directory, mkdir '${path}'`)
 			throw new Error(`ENOENT: no such file or directory, mkdir '${path}'`)
 		})
 		})
 
 
-		experiments = {
-			[EXPERIMENT_IDS.SEARCH_AND_REPLACE]: false,
-			[EXPERIMENT_IDS.INSERT_BLOCK]: false,
-		}
+		// Initialize experiments as undefined by default
+		experiments = undefined
 	})
 	})
 
 
 	beforeEach(() => {
 	beforeEach(() => {
@@ -640,10 +685,9 @@ describe("addCustomInstructions", () => {
 			"architect", // mode
 			"architect", // mode
 			undefined, // customModePrompts
 			undefined, // customModePrompts
 			undefined, // customModes
 			undefined, // customModes
-			undefined,
-			undefined,
-			undefined,
-			experiments,
+			undefined, // globalCustomInstructions
+			undefined, // diffEnabled
+			undefined, // experiments
 			true, // enableMcpServerCreation
 			true, // enableMcpServerCreation
 		)
 		)
 
 
@@ -661,10 +705,9 @@ describe("addCustomInstructions", () => {
 			"ask", // mode
 			"ask", // mode
 			undefined, // customModePrompts
 			undefined, // customModePrompts
 			undefined, // customModes
 			undefined, // customModes
-			undefined,
-			undefined,
-			undefined,
-			experiments,
+			undefined, // globalCustomInstructions
+			undefined, // diffEnabled
+			undefined, // experiments
 			true, // enableMcpServerCreation
 			true, // enableMcpServerCreation
 		)
 		)
 
 
@@ -685,9 +728,8 @@ describe("addCustomInstructions", () => {
 			undefined, // customModePrompts
 			undefined, // customModePrompts
 			undefined, // customModes,
 			undefined, // customModes,
 			undefined, // globalCustomInstructions
 			undefined, // globalCustomInstructions
-			undefined, // preferredLanguage
 			undefined, // diffEnabled
 			undefined, // diffEnabled
-			experiments,
+			undefined, // experiments
 			true, // enableMcpServerCreation
 			true, // enableMcpServerCreation
 		)
 		)
 
 
@@ -709,9 +751,8 @@ describe("addCustomInstructions", () => {
 			undefined, // customModePrompts
 			undefined, // customModePrompts
 			undefined, // customModes,
 			undefined, // customModes,
 			undefined, // globalCustomInstructions
 			undefined, // globalCustomInstructions
-			undefined, // preferredLanguage
 			undefined, // diffEnabled
 			undefined, // diffEnabled
-			experiments,
+			undefined, // experiments
 			false, // enableMcpServerCreation
 			false, // enableMcpServerCreation
 		)
 		)
 
 
@@ -751,7 +792,7 @@ describe("addCustomInstructions", () => {
 
 
 	it("should include preferred language when provided", async () => {
 	it("should include preferred language when provided", async () => {
 		const instructions = await addCustomInstructions("", "", "/test/path", defaultModeSlug, {
 		const instructions = await addCustomInstructions("", "", "/test/path", defaultModeSlug, {
-			preferredLanguage: "Spanish",
+			vscodeLanguage: "es",
 		})
 		})
 		expect(instructions).toMatchSnapshot()
 		expect(instructions).toMatchSnapshot()
 	})
 	})
@@ -767,7 +808,7 @@ describe("addCustomInstructions", () => {
 			"",
 			"",
 			"/test/path",
 			"/test/path",
 			defaultModeSlug,
 			defaultModeSlug,
-			{ preferredLanguage: "French" },
+			{ vscodeLanguage: "fr" },
 		)
 		)
 		expect(instructions).toMatchSnapshot()
 		expect(instructions).toMatchSnapshot()
 	})
 	})

+ 2 - 2
src/core/prompts/sections/__tests__/custom-instructions.test.ts

@@ -113,11 +113,11 @@ describe("addCustomInstructions", () => {
 			"global instructions",
 			"global instructions",
 			"/fake/path",
 			"/fake/path",
 			"test-mode",
 			"test-mode",
-			{ preferredLanguage: "Spanish" },
+			{ vscodeLanguage: "es" },
 		)
 		)
 
 
 		expect(result).toContain("Language Preference:")
 		expect(result).toContain("Language Preference:")
-		expect(result).toContain("Spanish")
+		expect(result).toContain("es")
 		expect(result).toContain("Global Instructions:\nglobal instructions")
 		expect(result).toContain("Global Instructions:\nglobal instructions")
 		expect(result).toContain("Mode-specific Instructions:\nmode instructions")
 		expect(result).toContain("Mode-specific Instructions:\nmode instructions")
 		expect(result).toContain("Rules from .clinerules-test-mode:\nmode specific rules")
 		expect(result).toContain("Rules from .clinerules-test-mode:\nmode specific rules")

+ 4 - 3
src/core/prompts/sections/custom-instructions.ts

@@ -1,5 +1,6 @@
 import fs from "fs/promises"
 import fs from "fs/promises"
 import path from "path"
 import path from "path"
+import * as vscode from "vscode"
 
 
 async function safeReadFile(filePath: string): Promise<string> {
 async function safeReadFile(filePath: string): Promise<string> {
 	try {
 	try {
@@ -33,7 +34,7 @@ export async function addCustomInstructions(
 	globalCustomInstructions: string,
 	globalCustomInstructions: string,
 	cwd: string,
 	cwd: string,
 	mode: string,
 	mode: string,
-	options: { preferredLanguage?: string; rooIgnoreInstructions?: string } = {},
+	options: { vscodeLanguage?: string; rooIgnoreInstructions?: string } = {},
 ): Promise<string> {
 ): Promise<string> {
 	const sections = []
 	const sections = []
 
 
@@ -45,9 +46,9 @@ export async function addCustomInstructions(
 	}
 	}
 
 
 	// Add language preference if provided
 	// Add language preference if provided
-	if (options.preferredLanguage) {
+	if (options.vscodeLanguage) {
 		sections.push(
 		sections.push(
-			`Language Preference:\nYou should always speak and think in the ${options.preferredLanguage} language.`,
+			`Language Preference:\nYou should always speak and think in the "${options.vscodeLanguage}" language.`,
 		)
 		)
 	}
 	}
 
 

+ 1 - 0
src/core/prompts/sections/rules.ts

@@ -16,6 +16,7 @@ function getEditingInstructions(diffStrategy?: DiffStrategy, experiments?: Recor
 	} else {
 	} else {
 		availableTools.push("write_to_file (for creating new files or complete file rewrites)")
 		availableTools.push("write_to_file (for creating new files or complete file rewrites)")
 	}
 	}
+
 	if (experiments?.["insert_content"]) {
 	if (experiments?.["insert_content"]) {
 		availableTools.push("insert_content (for adding lines to existing files)")
 		availableTools.push("insert_content (for adding lines to existing files)")
 	}
 	}

+ 26 - 10
src/core/prompts/system.ts

@@ -37,9 +37,8 @@ async function generatePrompt(
 	promptComponent?: PromptComponent,
 	promptComponent?: PromptComponent,
 	customModeConfigs?: ModeConfig[],
 	customModeConfigs?: ModeConfig[],
 	globalCustomInstructions?: string,
 	globalCustomInstructions?: string,
-	preferredLanguage?: string,
 	diffEnabled?: boolean,
 	diffEnabled?: boolean,
-	experiments?: Record<string, boolean>,
+	experiments?: Record<string, boolean> | boolean | undefined,
 	enableMcpServerCreation?: boolean,
 	enableMcpServerCreation?: boolean,
 	rooIgnoreInstructions?: string,
 	rooIgnoreInstructions?: string,
 ): Promise<string> {
 ): Promise<string> {
@@ -61,6 +60,12 @@ async function generatePrompt(
 			: Promise.resolve(""),
 			: Promise.resolve(""),
 	])
 	])
 
 
+	// Convert experiments to an object if it's a boolean
+	const experimentSettings =
+		typeof experiments === "boolean"
+			? {} // Empty object if experiments is just a boolean
+			: (experiments ?? {})
+
 	const basePrompt = `${roleDefinition}
 	const basePrompt = `${roleDefinition}
 
 
 ${getSharedToolUseSection()}
 ${getSharedToolUseSection()}
@@ -73,7 +78,7 @@ ${getToolDescriptionsForMode(
 	browserViewportSize,
 	browserViewportSize,
 	mcpHub,
 	mcpHub,
 	customModeConfigs,
 	customModeConfigs,
-	experiments,
+	experimentSettings,
 )}
 )}
 
 
 ${getToolUseGuidelinesSection()}
 ${getToolUseGuidelinesSection()}
@@ -84,13 +89,13 @@ ${getCapabilitiesSection(cwd, supportsComputerUse, mcpHub, effectiveDiffStrategy
 
 
 ${modesSection}
 ${modesSection}
 
 
-${getRulesSection(cwd, supportsComputerUse, effectiveDiffStrategy, experiments)}
+${getRulesSection(cwd, supportsComputerUse, effectiveDiffStrategy, experimentSettings)}
 
 
 ${getSystemInfoSection(cwd, mode, customModeConfigs)}
 ${getSystemInfoSection(cwd, mode, customModeConfigs)}
 
 
 ${getObjectiveSection()}
 ${getObjectiveSection()}
 
 
-${await addCustomInstructions(promptComponent?.customInstructions || modeConfig.customInstructions || "", globalCustomInstructions || "", cwd, mode, { preferredLanguage, rooIgnoreInstructions })}`
+${await addCustomInstructions(promptComponent?.customInstructions || modeConfig.customInstructions || "", globalCustomInstructions || "", cwd, mode, { vscodeLanguage: vscode.env.language, rooIgnoreInstructions })}`
 
 
 	return basePrompt
 	return basePrompt
 }
 }
@@ -106,9 +111,8 @@ export const SYSTEM_PROMPT = async (
 	customModePrompts?: CustomModePrompts,
 	customModePrompts?: CustomModePrompts,
 	customModes?: ModeConfig[],
 	customModes?: ModeConfig[],
 	globalCustomInstructions?: string,
 	globalCustomInstructions?: string,
-	preferredLanguage?: string,
 	diffEnabled?: boolean,
 	diffEnabled?: boolean,
-	experiments?: Record<string, boolean>,
+	experiments?: Record<string, boolean> | boolean | undefined,
 	enableMcpServerCreation?: boolean,
 	enableMcpServerCreation?: boolean,
 	rooIgnoreInstructions?: string,
 	rooIgnoreInstructions?: string,
 ): Promise<string> => {
 ): Promise<string> => {
@@ -135,15 +139,28 @@ export const SYSTEM_PROMPT = async (
 	// If a file-based custom system prompt exists, use it
 	// If a file-based custom system prompt exists, use it
 	if (fileCustomSystemPrompt) {
 	if (fileCustomSystemPrompt) {
 		const roleDefinition = promptComponent?.roleDefinition || currentMode.roleDefinition
 		const roleDefinition = promptComponent?.roleDefinition || currentMode.roleDefinition
+		const customInstructions = await addCustomInstructions(
+			promptComponent?.customInstructions || currentMode.customInstructions || "",
+			globalCustomInstructions || "",
+			cwd,
+			mode,
+			{ vscodeLanguage: vscode.env.language, rooIgnoreInstructions },
+		)
+		// For file-based prompts, don't include the tool sections
 		return `${roleDefinition}
 		return `${roleDefinition}
 
 
 ${fileCustomSystemPrompt}
 ${fileCustomSystemPrompt}
 
 
-${await addCustomInstructions(promptComponent?.customInstructions || currentMode.customInstructions || "", globalCustomInstructions || "", cwd, mode, { preferredLanguage, rooIgnoreInstructions })}`
+${customInstructions}`
 	}
 	}
 
 
 	// If diff is disabled, don't pass the diffStrategy
 	// If diff is disabled, don't pass the diffStrategy
 	const effectiveDiffStrategy = diffEnabled ? diffStrategy : undefined
 	const effectiveDiffStrategy = diffEnabled ? diffStrategy : undefined
+	// Convert experiments to an object if it's a boolean
+	const experimentSettings =
+		typeof experiments === "boolean"
+			? {} // Empty object if experiments is just a boolean
+			: (experiments ?? {})
 
 
 	return generatePrompt(
 	return generatePrompt(
 		context,
 		context,
@@ -156,9 +173,8 @@ ${await addCustomInstructions(promptComponent?.customInstructions || currentMode
 		promptComponent,
 		promptComponent,
 		customModes,
 		customModes,
 		globalCustomInstructions,
 		globalCustomInstructions,
-		preferredLanguage,
 		diffEnabled,
 		diffEnabled,
-		experiments,
+		experimentSettings,
 		enableMcpServerCreation,
 		enableMcpServerCreation,
 		rooIgnoreInstructions,
 		rooIgnoreInstructions,
 	)
 	)

+ 3 - 1
src/core/prompts/tools/index.ts

@@ -61,13 +61,15 @@ export function getToolDescriptionsForMode(
 
 
 	const tools = new Set<string>()
 	const tools = new Set<string>()
 
 
+	const experimentSettings = experiments ?? {}
+
 	// Add tools from mode's groups
 	// Add tools from mode's groups
 	config.groups.forEach((groupEntry) => {
 	config.groups.forEach((groupEntry) => {
 		const groupName = getGroupName(groupEntry)
 		const groupName = getGroupName(groupEntry)
 		const toolGroup = TOOL_GROUPS[groupName]
 		const toolGroup = TOOL_GROUPS[groupName]
 		if (toolGroup) {
 		if (toolGroup) {
 			toolGroup.tools.forEach((tool) => {
 			toolGroup.tools.forEach((tool) => {
-				if (isToolAllowedForMode(tool as ToolName, mode, customModes ?? [], experiments ?? {})) {
+				if (isToolAllowedForMode(tool as ToolName, mode, customModes ?? [], experimentSettings)) {
 					tools.add(tool)
 					tools.add(tool)
 				}
 				}
 			})
 			})

+ 2 - 39
src/core/webview/ClineProvider.ts

@@ -1389,10 +1389,6 @@ export class ClineProvider implements vscode.WebviewViewProvider {
 						await this.updateGlobalState("rateLimitSeconds", message.value ?? 0)
 						await this.updateGlobalState("rateLimitSeconds", message.value ?? 0)
 						await this.postStateToWebview()
 						await this.postStateToWebview()
 						break
 						break
-					case "preferredLanguage":
-						await this.updateGlobalState("preferredLanguage", message.text)
-						await this.postStateToWebview()
-						break
 					case "writeDelayMs":
 					case "writeDelayMs":
 						await this.updateGlobalState("writeDelayMs", message.value)
 						await this.updateGlobalState("writeDelayMs", message.value)
 						await this.postStateToWebview()
 						await this.postStateToWebview()
@@ -1930,7 +1926,6 @@ export class ClineProvider implements vscode.WebviewViewProvider {
 				apiConfiguration,
 				apiConfiguration,
 				customModePrompts,
 				customModePrompts,
 				customInstructions,
 				customInstructions,
-				preferredLanguage,
 				browserViewportSize,
 				browserViewportSize,
 				diffEnabled,
 				diffEnabled,
 				mcpEnabled,
 				mcpEnabled,
@@ -1968,7 +1963,6 @@ export class ClineProvider implements vscode.WebviewViewProvider {
 				customModePrompts,
 				customModePrompts,
 				customModes,
 				customModes,
 				customInstructions,
 				customInstructions,
-				preferredLanguage,
 				diffEnabled,
 				diffEnabled,
 				experiments,
 				experiments,
 				enableMcpServerCreation,
 				enableMcpServerCreation,
@@ -2344,7 +2338,6 @@ export class ClineProvider implements vscode.WebviewViewProvider {
 			screenshotQuality,
 			screenshotQuality,
 			remoteBrowserHost,
 			remoteBrowserHost,
 			remoteBrowserEnabled,
 			remoteBrowserEnabled,
-			preferredLanguage,
 			writeDelayMs,
 			writeDelayMs,
 			terminalOutputLineLimit,
 			terminalOutputLineLimit,
 			fuzzyMatchThreshold,
 			fuzzyMatchThreshold,
@@ -2404,7 +2397,6 @@ export class ClineProvider implements vscode.WebviewViewProvider {
 			screenshotQuality: screenshotQuality ?? 75,
 			screenshotQuality: screenshotQuality ?? 75,
 			remoteBrowserHost,
 			remoteBrowserHost,
 			remoteBrowserEnabled: remoteBrowserEnabled ?? false,
 			remoteBrowserEnabled: remoteBrowserEnabled ?? false,
-			preferredLanguage: preferredLanguage ?? "English",
 			writeDelayMs: writeDelayMs ?? 1000,
 			writeDelayMs: writeDelayMs ?? 1000,
 			terminalOutputLineLimit: terminalOutputLineLimit ?? 500,
 			terminalOutputLineLimit: terminalOutputLineLimit ?? 500,
 			fuzzyMatchThreshold: fuzzyMatchThreshold ?? 1.0,
 			fuzzyMatchThreshold: fuzzyMatchThreshold ?? 1.0,
@@ -2563,37 +2555,8 @@ export class ClineProvider implements vscode.WebviewViewProvider {
 			writeDelayMs: stateValues.writeDelayMs ?? 1000,
 			writeDelayMs: stateValues.writeDelayMs ?? 1000,
 			terminalOutputLineLimit: stateValues.terminalOutputLineLimit ?? 500,
 			terminalOutputLineLimit: stateValues.terminalOutputLineLimit ?? 500,
 			mode: stateValues.mode ?? defaultModeSlug,
 			mode: stateValues.mode ?? defaultModeSlug,
-			preferredLanguage:
-				stateValues.preferredLanguage ??
-				(() => {
-					// Get VSCode's locale setting
-					const vscodeLang = vscode.env.language
-					// Map VSCode locale to our supported languages
-					const langMap: { [key: string]: string } = {
-						en: "English",
-						ar: "Arabic",
-						"pt-br": "Brazilian Portuguese",
-						ca: "Catalan",
-						cs: "Czech",
-						fr: "French",
-						de: "German",
-						hi: "Hindi",
-						hu: "Hungarian",
-						it: "Italian",
-						ja: "Japanese",
-						ko: "Korean",
-						pl: "Polish",
-						pt: "Portuguese",
-						ru: "Russian",
-						zh: "Simplified Chinese",
-						"zh-cn": "Simplified Chinese",
-						es: "Spanish",
-						"zh-tw": "Traditional Chinese",
-						tr: "Turkish",
-					}
-					// Return mapped language or default to English
-					return langMap[vscodeLang] ?? langMap[vscodeLang.split("-")[0]] ?? "English"
-				})(),
+			// Pass the VSCode language code directly
+			vscodeLanguage: vscode.env.language,
 			mcpEnabled: stateValues.mcpEnabled ?? true,
 			mcpEnabled: stateValues.mcpEnabled ?? true,
 			enableMcpServerCreation: stateValues.enableMcpServerCreation ?? true,
 			enableMcpServerCreation: stateValues.enableMcpServerCreation ?? true,
 			alwaysApproveResubmit: stateValues.alwaysApproveResubmit ?? false,
 			alwaysApproveResubmit: stateValues.alwaysApproveResubmit ?? false,

+ 4 - 13
src/core/webview/__tests__/ClineProvider.test.ts

@@ -420,7 +420,6 @@ describe("ClineProvider", () => {
 
 
 		const mockState: ExtensionState = {
 		const mockState: ExtensionState = {
 			version: "1.0.0",
 			version: "1.0.0",
-			preferredLanguage: "English",
 			clineMessages: [],
 			clineMessages: [],
 			taskHistory: [],
 			taskHistory: [],
 			shouldShowAnnouncement: false,
 			shouldShowAnnouncement: false,
@@ -535,20 +534,12 @@ describe("ClineProvider", () => {
 		expect(state).toHaveProperty("writeDelayMs")
 		expect(state).toHaveProperty("writeDelayMs")
 	})
 	})
 
 
-	test("preferredLanguage defaults to VSCode language when not set", async () => {
+	test("vscodeLanguage is set to VSCode language", async () => {
 		// Mock VSCode language as Spanish
 		// Mock VSCode language as Spanish
 		;(vscode.env as any).language = "es-ES"
 		;(vscode.env as any).language = "es-ES"
 
 
 		const state = await provider.getState()
 		const state = await provider.getState()
-		expect(state.preferredLanguage).toBe("Spanish")
-	})
-
-	test("preferredLanguage defaults to English for unsupported VSCode language", async () => {
-		// Mock VSCode language as an unsupported language
-		;(vscode.env as any).language = "unsupported-LANG"
-
-		const state = await provider.getState()
-		expect(state.preferredLanguage).toBe("English")
+		expect(state.vscodeLanguage).toBe("es-ES")
 	})
 	})
 
 
 	test("diffEnabled defaults to true when not set", async () => {
 	test("diffEnabled defaults to true when not set", async () => {
@@ -1216,7 +1207,7 @@ describe("ClineProvider", () => {
 			expect(callArgs[4]).toHaveProperty("getToolDescription") // diffStrategy
 			expect(callArgs[4]).toHaveProperty("getToolDescription") // diffStrategy
 			expect(callArgs[5]).toBe("900x600") // browserViewportSize
 			expect(callArgs[5]).toBe("900x600") // browserViewportSize
 			expect(callArgs[6]).toBe("code") // mode
 			expect(callArgs[6]).toBe("code") // mode
-			expect(callArgs[11]).toBe(true) // diffEnabled
+			expect(callArgs[10]).toBe(true) // diffEnabled
 
 
 			// Run the test again to verify it's consistent
 			// Run the test again to verify it's consistent
 			await handler({ type: "getSystemPrompt", mode: "code" })
 			await handler({ type: "getSystemPrompt", mode: "code" })
@@ -1274,7 +1265,7 @@ describe("ClineProvider", () => {
 			expect(callArgs[4]).toHaveProperty("getToolDescription") // diffStrategy
 			expect(callArgs[4]).toHaveProperty("getToolDescription") // diffStrategy
 			expect(callArgs[5]).toBe("900x600") // browserViewportSize
 			expect(callArgs[5]).toBe("900x600") // browserViewportSize
 			expect(callArgs[6]).toBe("code") // mode
 			expect(callArgs[6]).toBe("code") // mode
-			expect(callArgs[11]).toBe(false) // diffEnabled should be false
+			expect(callArgs[10]).toBe(false) // diffEnabled should be false
 		})
 		})
 
 
 		test("uses correct mode-specific instructions when mode is specified", async () => {
 		test("uses correct mode-specific instructions when mode is specified", async () => {

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

@@ -164,7 +164,6 @@ export type GlobalStateKey =
 	| "screenshotQuality"
 	| "screenshotQuality"
 	| "remoteBrowserHost"
 	| "remoteBrowserHost"
 	| "fuzzyMatchThreshold"
 	| "fuzzyMatchThreshold"
-	| "preferredLanguage" // Language setting for Cline's communication
 	| "writeDelayMs"
 	| "writeDelayMs"
 	| "terminalOutputLineLimit"
 	| "terminalOutputLineLimit"
 	| "mcpEnabled"
 	| "mcpEnabled"

+ 1 - 1
src/shared/ExtensionMessage.ts

@@ -131,7 +131,7 @@ export interface ExtensionState {
 	remoteBrowserHost?: string
 	remoteBrowserHost?: string
 	remoteBrowserEnabled?: boolean
 	remoteBrowserEnabled?: boolean
 	fuzzyMatchThreshold?: number
 	fuzzyMatchThreshold?: number
-	preferredLanguage: string
+	vscodeLanguage?: string
 	writeDelayMs: number
 	writeDelayMs: number
 	terminalOutputLineLimit?: number
 	terminalOutputLineLimit?: number
 	mcpEnabled: boolean
 	mcpEnabled: boolean

+ 0 - 1
src/shared/WebviewMessage.ts

@@ -64,7 +64,6 @@ export interface WebviewMessage {
 		| "toggleMcpServer"
 		| "toggleMcpServer"
 		| "updateMcpTimeout"
 		| "updateMcpTimeout"
 		| "fuzzyMatchThreshold"
 		| "fuzzyMatchThreshold"
-		| "preferredLanguage"
 		| "writeDelayMs"
 		| "writeDelayMs"
 		| "enhancePrompt"
 		| "enhancePrompt"
 		| "enhancedPrompt"
 		| "enhancedPrompt"

+ 2 - 3
src/shared/__tests__/modes.test.ts

@@ -6,7 +6,6 @@ jest.mock("../../core/prompts/sections/custom-instructions", () => ({
 }))
 }))
 
 
 import { isToolAllowedForMode, FileRestrictionError, ModeConfig, getFullModeDetails, modes } from "../modes"
 import { isToolAllowedForMode, FileRestrictionError, ModeConfig, getFullModeDetails, modes } from "../modes"
-import * as vscode from "vscode"
 import { addCustomInstructions } from "../../core/prompts/sections/custom-instructions"
 import { addCustomInstructions } from "../../core/prompts/sections/custom-instructions"
 
 
 describe("isToolAllowedForMode", () => {
 describe("isToolAllowedForMode", () => {
@@ -402,7 +401,7 @@ describe("FileRestrictionError", () => {
 			const options = {
 			const options = {
 				cwd: "/test/path",
 				cwd: "/test/path",
 				globalCustomInstructions: "Global instructions",
 				globalCustomInstructions: "Global instructions",
-				preferredLanguage: "en",
+				vscodeLanguage: "en",
 			}
 			}
 
 
 			await getFullModeDetails("debug", undefined, undefined, options)
 			await getFullModeDetails("debug", undefined, undefined, options)
@@ -412,7 +411,7 @@ describe("FileRestrictionError", () => {
 				"Global instructions",
 				"Global instructions",
 				"/test/path",
 				"/test/path",
 				"debug",
 				"debug",
-				{ preferredLanguage: "en" },
+				{ vscodeLanguage: "en" },
 			)
 			)
 		})
 		})
 
 

+ 0 - 1
src/shared/globalState.ts

@@ -82,7 +82,6 @@ export const GLOBAL_STATE_KEYS = [
 	"screenshotQuality",
 	"screenshotQuality",
 	"remoteBrowserHost",
 	"remoteBrowserHost",
 	"fuzzyMatchThreshold",
 	"fuzzyMatchThreshold",
-	"preferredLanguage", // Language setting for Cline's communication.
 	"writeDelayMs",
 	"writeDelayMs",
 	"terminalOutputLineLimit",
 	"terminalOutputLineLimit",
 	"mcpEnabled",
 	"mcpEnabled",

+ 7 - 4
src/shared/modes.ts

@@ -195,10 +195,13 @@ export function isToolAllowedForMode(
 	}
 	}
 
 
 	// Check tool requirements if any exist
 	// Check tool requirements if any exist
-	if (toolRequirements && tool in toolRequirements) {
-		if (!toolRequirements[tool]) {
+	if (toolRequirements && typeof toolRequirements === "object") {
+		if (tool in toolRequirements && !toolRequirements[tool]) {
 			return false
 			return false
 		}
 		}
+	} else if (toolRequirements === false) {
+		// If toolRequirements is a boolean false, all tools are disabled
+		return false
 	}
 	}
 
 
 	const mode = getModeBySlug(modeSlug, customModes)
 	const mode = getModeBySlug(modeSlug, customModes)
@@ -275,7 +278,7 @@ export async function getFullModeDetails(
 	options?: {
 	options?: {
 		cwd?: string
 		cwd?: string
 		globalCustomInstructions?: string
 		globalCustomInstructions?: string
-		preferredLanguage?: string
+		vscodeLanguage?: string
 	},
 	},
 ): Promise<ModeConfig> {
 ): Promise<ModeConfig> {
 	// First get the base mode config from custom modes or built-in modes
 	// First get the base mode config from custom modes or built-in modes
@@ -295,7 +298,7 @@ export async function getFullModeDetails(
 			options.globalCustomInstructions || "",
 			options.globalCustomInstructions || "",
 			options.cwd,
 			options.cwd,
 			modeSlug,
 			modeSlug,
-			{ preferredLanguage: options.preferredLanguage },
+			{ vscodeLanguage: options.vscodeLanguage },
 		)
 		)
 	}
 	}
 
 

+ 0 - 140
webview-ui/src/components/prompts/PromptsView.tsx

@@ -9,19 +9,6 @@ import {
 	VSCodeRadioGroup,
 	VSCodeRadioGroup,
 	VSCodeRadio,
 	VSCodeRadio,
 } from "@vscode/webview-ui-toolkit/react"
 } from "@vscode/webview-ui-toolkit/react"
-import { CaretSortIcon, CheckIcon } from "@radix-ui/react-icons"
-import {
-	Button,
-	Command,
-	CommandGroup,
-	CommandInput,
-	CommandItem,
-	CommandList,
-	Popover,
-	PopoverContent,
-	PopoverTrigger,
-} from "@/components/ui"
-import { cn } from "@/lib/utils"
 import { useExtensionState } from "../../context/ExtensionStateContext"
 import { useExtensionState } from "../../context/ExtensionStateContext"
 import {
 import {
 	Mode,
 	Mode,
@@ -69,8 +56,6 @@ const PromptsView = ({ onDone }: PromptsViewProps) => {
 		mode,
 		mode,
 		customInstructions,
 		customInstructions,
 		setCustomInstructions,
 		setCustomInstructions,
-		preferredLanguage,
-		setPreferredLanguage,
 		customModes,
 		customModes,
 		enableCustomModeCreation,
 		enableCustomModeCreation,
 		setEnableCustomModeCreation,
 		setEnableCustomModeCreation,
@@ -82,9 +67,6 @@ const PromptsView = ({ onDone }: PromptsViewProps) => {
 	const [testPrompt, setTestPrompt] = useState("")
 	const [testPrompt, setTestPrompt] = useState("")
 	const [isEnhancing, setIsEnhancing] = useState(false)
 	const [isEnhancing, setIsEnhancing] = useState(false)
 	const [isDialogOpen, setIsDialogOpen] = useState(false)
 	const [isDialogOpen, setIsDialogOpen] = useState(false)
-	const [open, setOpen] = useState(false)
-	const [isCustomLanguage, setIsCustomLanguage] = useState(false)
-	const [customLanguage, setCustomLanguage] = useState("")
 	const [selectedPromptContent, setSelectedPromptContent] = useState("")
 	const [selectedPromptContent, setSelectedPromptContent] = useState("")
 	const [selectedPromptTitle, setSelectedPromptTitle] = useState("")
 	const [selectedPromptTitle, setSelectedPromptTitle] = useState("")
 	const [isToolsEditMode, setIsToolsEditMode] = useState(false)
 	const [isToolsEditMode, setIsToolsEditMode] = useState(false)
@@ -428,93 +410,6 @@ const PromptsView = ({ onDone }: PromptsViewProps) => {
 
 
 			<TabContent>
 			<TabContent>
 				<div className="pb-5 border-b border-vscode-input-border">
 				<div className="pb-5 border-b border-vscode-input-border">
-					<div className="mb-5">
-						<div className="font-bold mb-1">Preferred Language</div>
-						<Popover open={open} onOpenChange={setOpen}>
-							<PopoverTrigger asChild>
-								<Button
-									variant="combobox"
-									role="combobox"
-									aria-expanded={open}
-									className="w-full justify-between">
-									{preferredLanguage ?? "Select language..."}
-									<CaretSortIcon className="opacity-50" />
-								</Button>
-							</PopoverTrigger>
-							<PopoverContent align="start" className="p-0">
-								<Command>
-									<CommandInput placeholder="Search language..." className="h-9" />
-									<CommandList>
-										<CommandGroup>
-											{[
-												{ value: "English", label: "English" },
-												{ value: "Arabic", label: "Arabic - العربية" },
-												{
-													value: "Brazilian Portuguese",
-													label: "Portuguese - Português (Brasil)",
-												},
-												{ value: "Catalan", label: "Catalan - Català" },
-												{ value: "Czech", label: "Czech - Čeština" },
-												{ value: "French", label: "French - Français" },
-												{ value: "German", label: "German - Deutsch" },
-												{ value: "Hindi", label: "Hindi - हिन्दी" },
-												{ value: "Hungarian", label: "Hungarian - Magyar" },
-												{ value: "Italian", label: "Italian - Italiano" },
-												{ value: "Japanese", label: "Japanese - 日本語" },
-												{ value: "Korean", label: "Korean - 한국어" },
-												{ value: "Polish", label: "Polish - Polski" },
-												{ value: "Portuguese", label: "Portuguese - Português (Portugal)" },
-												{ value: "Russian", label: "Russian - Русский" },
-												{ value: "Simplified Chinese", label: "Simplified Chinese - 简体中文" },
-												{ value: "Spanish", label: "Spanish - Español" },
-												{
-													value: "Traditional Chinese",
-													label: "Traditional Chinese - 繁體中文",
-												},
-												{ value: "Turkish", label: "Turkish - Türkçe" },
-											].map((language) => (
-												<CommandItem
-													key={language.value}
-													value={language.value}
-													onSelect={(value) => {
-														setPreferredLanguage(value)
-														vscode.postMessage({
-															type: "preferredLanguage",
-															text: value,
-														})
-														setOpen(false)
-													}}>
-													{language.label}
-													<CheckIcon
-														className={cn(
-															"ml-auto",
-															preferredLanguage === language.value
-																? "opacity-100"
-																: "opacity-0",
-														)}
-													/>
-												</CommandItem>
-											))}
-										</CommandGroup>
-									</CommandList>
-								</Command>
-								<div className="border-t border-[var(--vscode-input-border)]">
-									<button
-										className="w-full px-2 py-1.5 text-sm text-left hover:bg-[var(--vscode-list-hoverBackground)]"
-										onClick={() => {
-											setIsCustomLanguage(true)
-											setOpen(false)
-										}}>
-										+ Choose another language
-									</button>
-								</div>
-							</PopoverContent>
-						</Popover>
-						<p className="text-xs mt-1.5 text-vscode-descriptionForeground">
-							Select the language that Roo should use for communication.
-						</p>
-					</div>
-
 					<div className="font-bold mb-1">Custom Instructions for All Modes</div>
 					<div className="font-bold mb-1">Custom Instructions for All Modes</div>
 					<div className="text-sm text-vscode-descriptionForeground mb-2">
 					<div className="text-sm text-vscode-descriptionForeground mb-2">
 						These instructions apply to all modes. They provide a base set of behaviors that can be enhanced
 						These instructions apply to all modes. They provide a base set of behaviors that can be enhanced
@@ -1509,41 +1404,6 @@ const PromptsView = ({ onDone }: PromptsViewProps) => {
 					</div>
 					</div>
 				</div>
 				</div>
 			)}
 			)}
-
-			{isCustomLanguage && (
-				<div className="fixed inset-0 bg-black/50 flex items-center justify-center z-50">
-					<div className="bg-[var(--vscode-editor-background)] p-6 rounded-lg w-96">
-						<h3 className="text-lg font-semibold mb-4">Add Custom Language</h3>
-						<input
-							type="text"
-							className="w-full p-2 mb-4 bg-[var(--vscode-input-background)] text-[var(--vscode-input-foreground)] border border-[var(--vscode-input-border)] rounded"
-							placeholder="Enter language name"
-							value={customLanguage}
-							onChange={(e) => setCustomLanguage(e.target.value)}
-						/>
-						<div className="flex justify-end gap-2">
-							<Button variant="secondary" onClick={() => setIsCustomLanguage(false)}>
-								Cancel
-							</Button>
-							<Button
-								onClick={() => {
-									if (customLanguage.trim()) {
-										setPreferredLanguage(customLanguage.trim())
-										vscode.postMessage({
-											type: "preferredLanguage",
-											text: customLanguage.trim(),
-										})
-										setIsCustomLanguage(false)
-										setCustomLanguage("")
-									}
-								}}
-								disabled={!customLanguage.trim()}>
-								Add
-							</Button>
-						</div>
-					</div>
-				</div>
-			)}
 		</Tab>
 		</Tab>
 	)
 	)
 }
 }

+ 1 - 4
webview-ui/src/context/ExtensionStateContext.tsx

@@ -39,8 +39,6 @@ export interface ExtensionStateContextType extends ExtensionState {
 	setEnableCheckpoints: (value: boolean) => void
 	setEnableCheckpoints: (value: boolean) => void
 	setBrowserViewportSize: (value: string) => void
 	setBrowserViewportSize: (value: string) => void
 	setFuzzyMatchThreshold: (value: number) => void
 	setFuzzyMatchThreshold: (value: number) => void
-	preferredLanguage: string
-	setPreferredLanguage: (value: string) => void
 	setWriteDelayMs: (value: number) => void
 	setWriteDelayMs: (value: number) => void
 	screenshotQuality?: number
 	screenshotQuality?: number
 	setScreenshotQuality: (value: number) => void
 	setScreenshotQuality: (value: number) => void
@@ -118,7 +116,7 @@ export const ExtensionStateContextProvider: React.FC<{ children: React.ReactNode
 		enableCheckpoints: true,
 		enableCheckpoints: true,
 		checkpointStorage: "task",
 		checkpointStorage: "task",
 		fuzzyMatchThreshold: 1.0,
 		fuzzyMatchThreshold: 1.0,
-		preferredLanguage: "English",
+		vscodeLanguage: "en", // Default language code
 		enableCustomModeCreation: true,
 		enableCustomModeCreation: true,
 		writeDelayMs: 1000,
 		writeDelayMs: 1000,
 		browserViewportSize: "900x600",
 		browserViewportSize: "900x600",
@@ -260,7 +258,6 @@ export const ExtensionStateContextProvider: React.FC<{ children: React.ReactNode
 		setBrowserViewportSize: (value: string) =>
 		setBrowserViewportSize: (value: string) =>
 			setState((prevState) => ({ ...prevState, browserViewportSize: value })),
 			setState((prevState) => ({ ...prevState, browserViewportSize: value })),
 		setFuzzyMatchThreshold: (value) => setState((prevState) => ({ ...prevState, fuzzyMatchThreshold: value })),
 		setFuzzyMatchThreshold: (value) => setState((prevState) => ({ ...prevState, fuzzyMatchThreshold: value })),
-		setPreferredLanguage: (value) => setState((prevState) => ({ ...prevState, preferredLanguage: value })),
 		setWriteDelayMs: (value) => setState((prevState) => ({ ...prevState, writeDelayMs: value })),
 		setWriteDelayMs: (value) => setState((prevState) => ({ ...prevState, writeDelayMs: value })),
 		setScreenshotQuality: (value) => setState((prevState) => ({ ...prevState, screenshotQuality: value })),
 		setScreenshotQuality: (value) => setState((prevState) => ({ ...prevState, screenshotQuality: value })),
 		setTerminalOutputLineLimit: (value) =>
 		setTerminalOutputLineLimit: (value) =>

+ 0 - 1
webview-ui/src/context/__tests__/ExtensionStateContext.test.tsx

@@ -109,7 +109,6 @@ describe("mergeExtensionState", () => {
 			shouldShowAnnouncement: false,
 			shouldShowAnnouncement: false,
 			enableCheckpoints: true,
 			enableCheckpoints: true,
 			checkpointStorage: "task",
 			checkpointStorage: "task",
-			preferredLanguage: "English",
 			writeDelayMs: 1000,
 			writeDelayMs: 1000,
 			requestDelaySeconds: 5,
 			requestDelaySeconds: 5,
 			rateLimitSeconds: 0,
 			rateLimitSeconds: 0,

Certains fichiers n'ont pas été affichés car il y a eu trop de fichiers modifiés dans ce diff