Skip to content

Commit b09c260

Browse files
committed
Extension-side internationalization
1 parent eb74f02 commit b09c260

File tree

25 files changed

+1451
-69
lines changed

25 files changed

+1451
-69
lines changed

.roomodes

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@
2222
"slug": "translate",
2323
"name": "Translate",
2424
"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.",
25-
"customInstructions": "When internationalizing and translating content:\n\n# Translation Style and Tone\n- Maintain a direct and concise style that mirrors the tone of the original text\n- Carefully account for colloquialisms and idiomatic expressions in both source and target languages\n- Aim for culturally relevant and meaningful translations rather than literal translations\n- Adapt the formality level to match the original content (whether formal or informal)\n- Preserve the personality and voice of the original content\n- Use natural-sounding language that feels native to speakers of the target language\n- Don't translate the word \"token\" as it means something specific in English that all languages will understand\n\n# Technical Implementation\n- Use namespaces to organize translations logically\n- Handle pluralization using i18next's built-in capabilities\n- Implement proper interpolation for variables using {{variable}} syntax\n- Don't include defaultValue. The `en` translations are the fallback.\n- Always use apply_diff instead of write_to_file when editing existing translation files as it's much faster and more reliable\n- When using apply_diff, make sure to carefully identify the exact JSON structure to edit to avoid syntax errors\n- Always use the Trans component for text with embedded components\n- Internationalize and add English strings first, and then ask the user to confirm the approach before translating into all other languages\n\n# Quality Assurance\n- Maintain consistent terminology across all translations\n- Respect the JSON structure of translation files\n- Watch for placeholders and preserve them in translations\n- Be mindful of text length in UI elements when translating to languages that might require more characters\n- Use context-aware translations when the same string has different meanings\n- Always validate your translation work by running the missing translations script:\n ```\n node scripts/find-missing-translations.js\n ```\n- Before completing any translation task, ensure there are no missing translations by running the script with the target locale(s):\n ```\n node scripts/find-missing-translations.js --locale=<locale-code>\n ```\n- Address any missing translations identified by the script to ensure complete coverage across all locales\n\n# Supported Languages\n- Localize all strings into the following locale files: ca, de, en, es, fr, hi, it, ja, ko, pl, pt-BR, tr, vi, zh-CN, zh-TW\n- The translation files are under webview-ui/src/i18n/locales/",
25+
"customInstructions": "# 1. SUPPORTED LANGUAGES AND LOCATION\n- Localize all strings into the following locale files: ca, de, en, es, fr, hi, it, ja, ko, pl, pt-BR, tr, vi, zh-CN, zh-TW\n- The VSCode extension has two main areas that require localization:\n * Core Extension: src/i18n/locales/ (extension backend)\n * WebView UI: webview-ui/src/i18n/locales/ (user interface)\n\n# 2. VOICE, STYLE AND TONE\n- Maintain a direct and concise style that mirrors the tone of the original text\n- Carefully account for colloquialisms and idiomatic expressions in both source and target languages\n- Aim for culturally relevant and meaningful translations rather than literal translations\n- Adapt the formality level to match the original content (whether formal or informal)\n- Preserve the personality and voice of the original content\n- Use natural-sounding language that feels native to speakers of the target language\n- Don't translate the word \"token\" as it means something specific in English that all languages will understand\n\n# 3. CORE EXTENSION LOCALIZATION (src/)\n- Located in src/i18n/locales/\n- NOT ALL strings in core source need internationalization - only user-facing messages\n- Internal error messages, debugging logs, and developer-facing messages should remain in English\n- The t() function is used with namespaces like 'core:errors.missingToolParameter'\n- Be careful when modifying interpolation variables; they must remain consistent across all translations\n- Some strings in formatResponse.ts are intentionally not internationalized since they're internal\n- When updating strings in core.json, maintain all existing interpolation variables\n- Check string usages in the codebase before making changes to ensure you're not breaking functionality\n\n# 4. WEBVIEW UI LOCALIZATION (webview-ui/src/)\n- Located in webview-ui/src/i18n/locales/\n- Uses standard React i18next patterns with the useTranslation hook\n- All user interface strings should be internationalized\n- Always use the Trans component for text with embedded components\n\n# 5. TECHNICAL IMPLEMENTATION\n- Use namespaces to organize translations logically\n- Handle pluralization using i18next's built-in capabilities\n- Implement proper interpolation for variables using {{variable}} syntax\n- Don't include defaultValue. The `en` translations are the fallback\n- Always use apply_diff instead of write_to_file when editing existing translation files (much faster and more reliable)\n- When using apply_diff, carefully identify the exact JSON structure to edit to avoid syntax errors\n\n# 6. WORKFLOW AND APPROACH\n- First add or modify English strings, then ask for confirmation before translating to all other languages\n- Use this process for each localization task:\n 1. Identify where the string appears in the UI/codebase\n 2. Understand the context and purpose of the string\n 3. Update English translation first\n 4. Create appropriate translations for all other supported languages\n 5. Validate your changes with the missing translations script\n\n# 7. QUALITY ASSURANCE\n- Maintain consistent terminology across all translations\n- Respect the JSON structure of translation files\n- Watch for placeholders and preserve them in translations\n- Be mindful of text length in UI elements when translating to languages that might require more characters\n- Use context-aware translations when the same string has different meanings\n- Always validate your translation work by running the missing translations script:\n ```\n node scripts/find-missing-translations.js\n ```\n- Address any missing translations identified by the script to ensure complete coverage across all locales",
2626
"groups": [
2727
"read",
2828
"command",

esbuild.js

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,13 +63,78 @@ const copyWasmFiles = {
6363
},
6464
}
6565

66+
const copyLocalesFiles = {
67+
name: "copy-locales-files",
68+
setup(build) {
69+
build.onEnd(() => {
70+
// Source directory for translations
71+
const srcDir = path.join(__dirname, "src", "i18n", "locales")
72+
73+
// Two destination directories to handle different import paths
74+
const destDirNested = path.join(__dirname, "dist", "i18n", "locales")
75+
const destDirFlat = path.join(__dirname, "dist", "locales")
76+
77+
// Create the destination directories if they don't exist
78+
fs.mkdirSync(destDirNested, { recursive: true })
79+
fs.mkdirSync(destDirFlat, { recursive: true })
80+
81+
// Function to copy directory recursively
82+
function copyDirRecursively(src, dest) {
83+
// Read the source directory
84+
const entries = fs.readdirSync(src, { withFileTypes: true })
85+
86+
// Process each entry
87+
entries.forEach((entry) => {
88+
const srcPath = path.join(src, entry.name)
89+
const destPath = path.join(dest, entry.name)
90+
91+
if (entry.isDirectory()) {
92+
// Create directory if it doesn't exist
93+
fs.mkdirSync(destPath, { recursive: true })
94+
// Recursively copy contents
95+
copyDirRecursively(srcPath, destPath)
96+
} else {
97+
// Copy the file
98+
fs.copyFileSync(srcPath, destPath)
99+
}
100+
})
101+
}
102+
103+
// Copy all locales recursively if the directory exists
104+
if (fs.existsSync(srcDir)) {
105+
// Copy to both locations for maximum compatibility
106+
copyDirRecursively(srcDir, destDirNested)
107+
copyDirRecursively(srcDir, destDirFlat)
108+
console.log("Copied translation files to dist/i18n/locales and dist/locales")
109+
110+
// Also copy to out directory for debugging (if it exists)
111+
const outDirNested = path.join(__dirname, "out", "i18n", "locales")
112+
const outDirFlat = path.join(__dirname, "out", "locales")
113+
114+
try {
115+
fs.mkdirSync(outDirNested, { recursive: true })
116+
fs.mkdirSync(outDirFlat, { recursive: true })
117+
copyDirRecursively(srcDir, outDirNested)
118+
copyDirRecursively(srcDir, outDirFlat)
119+
console.log("Copied translation files to out/i18n/locales and out/locales")
120+
} catch (err) {
121+
console.warn("Warning: Could not copy to out directory", err.message)
122+
}
123+
} else {
124+
console.warn("Warning: locales directory not found in src/i18n")
125+
}
126+
})
127+
},
128+
}
129+
66130
const extensionConfig = {
67131
bundle: true,
68132
minify: production,
69133
sourcemap: !production,
70134
logLevel: "silent",
71135
plugins: [
72136
copyWasmFiles,
137+
copyLocalesFiles,
73138
/* add to the end of plugins array */
74139
esbuildProblemMatcherPlugin,
75140
{

package-lock.json

Lines changed: 36 additions & 7 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -345,6 +345,7 @@
345345
"fastest-levenshtein": "^1.0.16",
346346
"get-folder-size": "^5.0.0",
347347
"globby": "^14.0.2",
348+
"i18next": "^24.2.2",
348349
"isbinaryfile": "^5.0.2",
349350
"js-tiktoken": "^1.0.19",
350351
"mammoth": "^1.8.0",

src/activate/registerTerminalActions.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import * as vscode from "vscode"
22
import { ClineProvider } from "../core/webview/ClineProvider"
33
import { Terminal } from "../integrations/terminal/Terminal"
4+
import { t } from "../i18n"
45

56
const TERMINAL_COMMAND_IDS = {
67
ADD_TO_CONTEXT: "roo-cline.terminalAddToContext",
@@ -37,7 +38,7 @@ const registerTerminalAction = (
3738
}
3839

3940
if (!content) {
40-
vscode.window.showWarningMessage("No terminal content selected")
41+
vscode.window.showWarningMessage(t("common:warnings.no_terminal_content"))
4142
return
4243
}
4344

0 commit comments

Comments
 (0)