Skip to content
Merged

I18n #1584

Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 29 additions & 0 deletions .roomodes
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
{
"customModes": [
{
"slug": "translate",
"name": "Translate",
"roleDefinition": "You are Roo, a linguistic specialist focused on translating and managing localization files. Your responsibility is to help maintain and update translation files for the application, ensuring consistency and accuracy across all language resources.",
"groups": [
"read",
["edit", { "fileRegex": "src/i18n/locales/", "description": "Translation files only" }]
],
"customInstructions": "When translating content:\n- Maintain consistent terminology across all translations\n- Respect the JSON structure of translation files\n- Consider context when translating UI strings\n- Watch for placeholders (like {{variable}}) and preserve them in translations\n- Be mindful of text length in UI elements when translating to languages that might require more characters\n- If you need context for a translation, use read_file to examine the components using these strings"
},
{
"slug": "test",
"name": "Test",
"roleDefinition": "You are Roo, a Jest testing specialist with deep expertise in:\n- Writing and maintaining Jest test suites\n- Test-driven development (TDD) practices\n- Mocking and stubbing with Jest\n- Integration testing strategies\n- TypeScript testing patterns\n- Code coverage analysis\n- Test performance optimization\n\nYour focus is on maintaining high test quality and coverage across the codebase, working primarily with:\n- Test files in __tests__ directories\n- Mock implementations in __mocks__\n- Test utilities and helpers\n- Jest configuration and setup\n\nYou ensure tests are:\n- Well-structured and maintainable\n- Following Jest best practices\n- Properly typed with TypeScript\n- Providing meaningful coverage\n- Using appropriate mocking strategies",
"groups": [
"read",
"browser",
"command",
["edit", {
"fileRegex": "(__tests__/.*|__mocks__/.*|\\.test\\.(ts|tsx|js|jsx)$|/test/.*|jest\\.config\\.(js|ts)$)",
"description": "Test files, mocks, and Jest configuration"
}]
],
"customInstructions": "When writing tests:\n- Always use describe/it blocks for clear test organization\n- Include meaningful test descriptions\n- Use beforeEach/afterEach for proper test isolation\n- Implement proper error cases\n- Add JSDoc comments for complex test scenarios\n- Ensure mocks are properly typed\n- Verify both positive and negative test cases"
}
]
}
9 changes: 9 additions & 0 deletions src/__mocks__/vscode.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,13 @@
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: {
showInformationMessage: jest.fn(),
showErrorMessage: jest.fn(),
Expand Down
6 changes: 2 additions & 4 deletions src/core/Cline.ts
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@ import { truncateConversationIfNeeded } from "./sliding-window"
import { ClineProvider } from "./webview/ClineProvider"
import { detectCodeOmission } from "../integrations/editor/detect-omission"
import { BrowserSession } from "../services/browser/BrowserSession"
import { formatLanguage } from "../shared/language"
import { McpHub } from "../services/mcp/McpHub"
import crypto from "crypto"
import { insertGroups } from "./diff/insert-groups"
Expand Down Expand Up @@ -1102,7 +1103,6 @@ export class Cline {
browserViewportSize,
mode,
customModePrompts,
preferredLanguage,
experiments,
enableMcpServerCreation,
browserToolEnabled,
Expand All @@ -1124,7 +1124,6 @@ export class Cline {
customModePrompts,
customModes,
this.customInstructions,
preferredLanguage,
this.diffEnabled,
experiments,
enableMcpServerCreation,
Expand Down Expand Up @@ -3665,13 +3664,12 @@ export class Cline {
customModePrompts,
experiments = {} as Record<ExperimentId, boolean>,
customInstructions: globalCustomInstructions,
preferredLanguage,
} = (await this.providerRef.deref()?.getState()) ?? {}
const currentMode = mode ?? defaultModeSlug
const modeDetails = await getFullModeDetails(currentMode, customModes, customModePrompts, {
cwd,
globalCustomInstructions,
preferredLanguage,
language: formatLanguage(vscode.env.language),
})
details += `\n\n# Current Mode\n`
details += `<slug>${currentMode}</slug>\n`
Expand Down
1,439 changes: 1,437 additions & 2 deletions src/core/prompts/__tests__/__snapshots__/system.test.ts.snap

Large diffs are not rendered by default.

73 changes: 33 additions & 40 deletions src/core/prompts/__tests__/custom-system-prompt.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -46,8 +46,6 @@ const mockContext = {
} as unknown as vscode.ExtensionContext

describe("File-Based Custom System Prompt", () => {
const experiments = {}

beforeEach(() => {
// Reset mocks before each test
jest.clearAllMocks()
Expand All @@ -66,18 +64,17 @@ describe("File-Based Custom System Prompt", () => {
const prompt = await SYSTEM_PROMPT(
mockContext,
"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
Expand All @@ -101,26 +98,24 @@ describe("File-Based Custom System Prompt", () => {
const prompt = await SYSTEM_PROMPT(
mockContext,
"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
expect(prompt).toContain(modes[0].roleDefinition)
expect(prompt).toContain(fileCustomSystemPrompt)

// Should not contain any of the default sections
expect(prompt).not.toContain("TOOL USE")
expect(prompt).not.toContain("CAPABILITIES")
expect(prompt).not.toContain("MODES")
})
Expand All @@ -146,26 +141,24 @@ describe("File-Based Custom System Prompt", () => {
const prompt = await SYSTEM_PROMPT(
mockContext,
"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
expect(prompt).toContain(customRoleDefinition)
expect(prompt).toContain(fileCustomSystemPrompt)

// Should not contain any of the default sections
expect(prompt).not.toContain("TOOL USE")
expect(prompt).not.toContain("CAPABILITIES")
expect(prompt).not.toContain("MODES")
})
Expand Down
8 changes: 4 additions & 4 deletions src/core/prompts/__tests__/sections.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,20 +3,20 @@ import { getCapabilitiesSection } from "../sections/capabilities"
import { DiffStrategy, DiffResult } from "../../diff/types"

describe("addCustomInstructions", () => {
test("adds preferred language to custom instructions", async () => {
test("adds vscode language to custom instructions", async () => {
const result = await addCustomInstructions(
"mode instructions",
"global instructions",
"/test/path",
"test-mode",
{ preferredLanguage: "French" },
{ language: "fr" },
)

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(
"mode instructions",
"global instructions",
Expand Down
Loading
Loading