Skip to content
Merged
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
176 changes: 176 additions & 0 deletions scripts/find-missing-i18n-key.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,176 @@
const fs = require("fs")
const path = require("path")

// Parse command-line arguments
const args = process.argv.slice(2).reduce((acc, arg) => {
if (arg === "--help") {
acc.help = true
} else if (arg.startsWith("--locale=")) {
acc.locale = arg.split("=")[1]
} else if (arg.startsWith("--file=")) {
acc.file = arg.split("=")[1]
}
return acc
}, {})

// Display help information
if (args.help) {
console.log(`
Find missing i18n translations

A useful script to identify whether the i18n keys used in component files exist in all language files.

Usage:
node scripts/find-missing-i18n-key.js [options]

Options:
--locale=<locale> Only check a specific language (e.g., --locale=de)
--file=<file> Only check a specific file (e.g., --file=chat.json)
--help Display help information

Output:
- Generate a report of missing translations
`)
process.exit(0)
}

// Directory to traverse
const TARGET_DIR = path.join(__dirname, "../webview-ui/src/components")
const LOCALES_DIR = path.join(__dirname, "../webview-ui/src/i18n/locales")

// Regular expressions to match i18n keys
const i18nPatterns = [
/{t\("([^"]+)"\)}/g, // Match {t("key")} format
/i18nKey="([^"]+)"/g, // Match i18nKey="key" format
/t\("([a-zA-Z][a-zA-Z0-9_]*[:.][a-zA-Z0-9_.]+)"\)/g, // Match t("key") format, where key contains a colon or dot
]

// Get all language directories
function getLocaleDirs() {
const allLocales = fs.readdirSync(LOCALES_DIR).filter((file) => {
const stats = fs.statSync(path.join(LOCALES_DIR, file))
return stats.isDirectory() // Do not exclude any language directories
})

// Filter to a specific language if specified
return args.locale ? allLocales.filter((locale) => locale === args.locale) : allLocales
}

// Get the value from JSON by path
function getValueByPath(obj, path) {
const parts = path.split(".")
let current = obj

for (const part of parts) {
if (current === undefined || current === null) {
return undefined
}
current = current[part]
}

return current
}

// Check if the key exists in all language files, return a list of missing language files
function checkKeyInLocales(key, localeDirs) {
const [file, ...pathParts] = key.split(":")
const jsonPath = pathParts.join(".")

const missingLocales = []

localeDirs.forEach((locale) => {
const filePath = path.join(LOCALES_DIR, locale, `${file}.json`)
if (!fs.existsSync(filePath)) {
missingLocales.push(`${locale}/${file}.json`)
return
}

const json = JSON.parse(fs.readFileSync(filePath, "utf8"))
if (getValueByPath(json, jsonPath) === undefined) {
missingLocales.push(`${locale}/${file}.json`)
}
})

return missingLocales
}

// Recursively traverse the directory
function findMissingI18nKeys() {
const localeDirs = getLocaleDirs()
const results = []

function walk(dir) {
const files = fs.readdirSync(dir)

for (const file of files) {
const filePath = path.join(dir, file)
const stat = fs.statSync(filePath)

// Exclude test files
if (filePath.includes(".test.")) continue

if (stat.isDirectory()) {
walk(filePath) // Recursively traverse subdirectories
} else if (stat.isFile() && [".ts", ".tsx", ".js", ".jsx"].includes(path.extname(filePath))) {
const content = fs.readFileSync(filePath, "utf8")

// Match all i18n keys
for (const pattern of i18nPatterns) {
let match
while ((match = pattern.exec(content)) !== null) {
const key = match[1]
const missingLocales = checkKeyInLocales(key, localeDirs)
if (missingLocales.length > 0) {
results.push({
key,
missingLocales,
file: path.relative(TARGET_DIR, filePath),
})
}
}
}
}
}
}

walk(TARGET_DIR)
return results
}

// Execute and output the results
function main() {
try {
const localeDirs = getLocaleDirs()
if (args.locale && localeDirs.length === 0) {
console.error(`Error: Language '${args.locale}' not found in ${LOCALES_DIR}`)
process.exit(1)
}

console.log(`Checking ${localeDirs.length} non-English languages: ${localeDirs.join(", ")}`)

const missingKeys = findMissingI18nKeys()

if (missingKeys.length === 0) {
console.log("\n✅ All i18n keys are present!")
return
}

console.log("\nMissing i18n keys:\n")
missingKeys.forEach(({ key, missingLocales, file }) => {
console.log(`File: ${file}`)
console.log(`Key: ${key}`)
console.log("Missing in:")
missingLocales.forEach((file) => console.log(` - ${file}`))
console.log("-------------------")
})

// Exit code 1 indicates missing keys
process.exit(1)
} catch (error) {
console.error("Error:", error.message)
console.error(error.stack)
process.exit(1)
}
}

main()
2 changes: 1 addition & 1 deletion webview-ui/src/components/chat/ChatView.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -152,7 +152,7 @@ const ChatView = ({ isHidden, showAnnouncement, hideAnnouncement, showHistoryVie
setSecondaryButtonText(t("chat:reject.title"))
break
case "finishTask":
setPrimaryButtonText(t("chat:completeSubtaskAndReturn.title"))
setPrimaryButtonText(t("chat:completeSubtaskAndReturn"))
setSecondaryButtonText(undefined)
break
default:
Expand Down
12 changes: 12 additions & 0 deletions webview-ui/src/components/settings/ApiOptions.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -1448,6 +1448,18 @@ const ApiOptions = ({
<span className="font-medium">Custom ARN</span>
</VSCodeTextField>
<div className="text-sm text-vscode-descriptionForeground -mt-2">
{t("settings:providers.awsCustomArnUse")}
<ul className="list-disc pl-5 mt-1">
<li>
arn:aws:bedrock:us-east-1:123456789012:foundation-model/anthropic.claude-3-sonnet-20240229-v1:0
</li>
<li>
arn:aws:bedrock:us-west-2:123456789012:provisioned-model/my-provisioned-model
</li>
<li>
arn:aws:bedrock:us-east-1:123456789012:default-prompt-router/anthropic.claude:1
</li>
</ul>
{t("settings:providers.awsCustomArnDesc")}
</div>
{apiConfiguration?.awsCustomArn &&
Expand Down
16 changes: 16 additions & 0 deletions webview-ui/src/i18n/locales/ca/settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,20 @@
"description": "Descripció",
"apiProvider": "Proveïdor d'API",
"openRouterApiKey": "Clau API d'OpenRouter",
"nameEmpty": "El nom no pot estar buit",
"nameExists": "Ja existeix un perfil amb aquest nom",
"deleteProfile": "Esborrar perfil",
"invalidArnFormat": "Format ARN no vàlid. Comprova els exemples anteriors.",
"enterNewName": "Introduïu un nou nom",
"addProfile": "Afegeix perfil",
"renameProfile": "Canvia el nom del perfil",
"newProfile": "Nou perfil de configuració",
"enterProfileName": "Introduïu el nom del perfil",
"createProfile": "Crea perfil",
"cannotDeleteOnlyProfile": "No es pot eliminar l'únic perfil",
"vscodeLmDescription": "L'API del model de llenguatge de VS Code us permet executar models proporcionats per altres extensions de VS Code (incloent-hi, però no limitat a, GitHub Copilot). La manera més senzilla de començar és instal·lar les extensions Copilot i Copilot Chat des del VS Code Marketplace.",
"awsCustomArnUse": "Introduïu un ARN vàlid d'AWS Bedrock per al model que voleu utilitzar. Exemples de format:",
"awsCustomArnDesc": "Assegureu-vos que la regió a l'ARN coincideix amb la regió d'AWS seleccionada anteriorment.",
"apiKeyStorageNotice": "Les claus API s'emmagatzemen de forma segura a l'Emmagatzematge Secret de VSCode",
"useCustomBaseUrl": "Utilitzar URL base personalitzada",
"openRouterTransformsText": "Comprimir prompts i cadenes de missatges a la mida del context (<a>Transformacions d'OpenRouter</a>)",
Expand Down Expand Up @@ -104,6 +118,8 @@
"awsSessionToken": "Token de sessió d'AWS",
"awsRegion": "Regió d'AWS",
"awsCrossRegion": "Utilitzar inferència entre regions",
"vscodeLmModel": "Model de llenguatge",
"vscodeLmWarning": "Nota: Aquesta és una integració molt experimental i el suport del proveïdor variarà. Si rebeu un error sobre un model no compatible, és un problema del proveïdor.",
"googleCloudSetup": {
"title": "Per utilitzar Google Cloud Vertex AI, necessiteu:",
"step1": "1. Crear un compte de Google Cloud, habilitar l'API de Vertex AI i habilitar els models Claude necessaris.",
Expand Down
16 changes: 16 additions & 0 deletions webview-ui/src/i18n/locales/de/settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,20 @@
"description": "Beschreibung",
"apiProvider": "API-Anbieter",
"model": "Modell",
"nameEmpty": "Name darf nicht leer sein",
"nameExists": "Ein Profil mit diesem Namen existiert bereits",
"deleteProfile": "Profil löschen",
"invalidArnFormat": "Ungültiges ARN-Format. Überprüfen Sie die obigen Beispiele.",
"enterNewName": "Neuen Namen eingeben",
"addProfile": "Profil hinzufügen",
"renameProfile": "Profil umbenennen",
"newProfile": "Neues Konfigurationsprofil",
"enterProfileName": "Profilnamen eingeben",
"createProfile": "Profil erstellen",
"cannotDeleteOnlyProfile": "Das einzige Profil kann nicht gelöscht werden",
"vscodeLmDescription": "Die VS Code Language Model API ermöglicht das Ausführen von Modellen, die von anderen VS Code-Erweiterungen bereitgestellt werden (einschließlich, aber nicht beschränkt auf GitHub Copilot). Der einfachste Weg, um zu starten, besteht darin, die Erweiterungen Copilot und Copilot Chat aus dem VS Code Marketplace zu installieren.",
"awsCustomArnUse": "Geben Sie eine gültige AWS Bedrock ARN für das Modell ein, das Sie verwenden möchten. Formatbeispiele:",
"awsCustomArnDesc": "Stellen Sie sicher, dass die Region in der ARN mit Ihrer oben ausgewählten AWS-Region übereinstimmt.",
"openRouterApiKey": "OpenRouter API-Schlüssel",
"getOpenRouterApiKey": "OpenRouter API-Schlüssel erhalten",
"apiKeyStorageNotice": "API-Schlüssel werden sicher im VSCode Secret Storage gespeichert",
Expand Down Expand Up @@ -104,6 +118,8 @@
"awsSessionToken": "AWS Sitzungstoken",
"awsRegion": "AWS Region",
"awsCrossRegion": "Regionsübergreifende Inferenz verwenden",
"vscodeLmModel": "Sprachmodell",
"vscodeLmWarning": "Hinweis: Dies ist eine sehr experimentelle Integration und die Anbieterunterstützung variiert. Wenn Sie einen Fehler über ein nicht unterstütztes Modell erhalten, liegt das Problem auf Anbieterseite.",
"googleCloudSetup": {
"title": "Um Google Cloud Vertex AI zu verwenden, müssen Sie:",
"step1": "1. Ein Google Cloud-Konto erstellen, die Vertex AI API aktivieren & die gewünschten Claude-Modelle aktivieren.",
Expand Down
16 changes: 16 additions & 0 deletions webview-ui/src/i18n/locales/en/settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,20 @@
"description": "Description",
"apiProvider": "API Provider",
"model": "Model",
"nameEmpty": "Name cannot be empty",
"nameExists": "A profile with this name already exists",
"deleteProfile": "Delete Profile",
"invalidArnFormat": "Invalid ARN format. Please check the examples above.",
"enterNewName": "Enter new name",
"addProfile": "Add Profile",
"renameProfile": "Rename Profile",
"newProfile": "New Configuration Profile",
"enterProfileName": "Enter profile name",
"createProfile": "Create Profile",
"cannotDeleteOnlyProfile": "Cannot delete the only profile",
"vscodeLmDescription": " The VS Code Language Model API allows you to run models provided by other VS Code extensions (including but not limited to GitHub Copilot). The easiest way to get started is to install the Copilot and Copilot Chat extensions from the VS Code Marketplace.",
"awsCustomArnUse": "Enter a valid AWS Bedrock ARN for the model you want to use. Format examples:",
"awsCustomArnDesc": "Make sure the region in the ARN matches your selected AWS Region above.",
"openRouterApiKey": "OpenRouter API Key",
"getOpenRouterApiKey": "Get OpenRouter API Key",
"apiKeyStorageNotice": "API keys are stored securely in VSCode's Secret Storage",
Expand Down Expand Up @@ -104,6 +118,8 @@
"awsSessionToken": "AWS Session Token",
"awsRegion": "AWS Region",
"awsCrossRegion": "Use cross-region inference",
"vscodeLmModel": "Language Model",
"vscodeLmWarning": "Note: This is a very experimental integration and provider support will vary. If you get an error about a model not being supported, that's an issue on the provider's end.",
"googleCloudSetup": {
"title": "To use Google Cloud Vertex AI, you need to:",
"step1": "1. Create a Google Cloud account, enable the Vertex AI API & enable the desired Claude models.",
Expand Down
16 changes: 16 additions & 0 deletions webview-ui/src/i18n/locales/es/settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,20 @@
"description": "Descripción",
"apiProvider": "Proveedor de API",
"model": "Modelo",
"nameEmpty": "El nombre no puede estar vacío",
"nameExists": "Ya existe un perfil con este nombre",
"deleteProfile": "Eliminar perfil",
"invalidArnFormat": "Formato de ARN no válido. Verifica los ejemplos anteriores.",
"enterNewName": "Ingrese un nuevo nombre",
"addProfile": "Agregar perfil",
"renameProfile": "Renombrar perfil",
"newProfile": "Nuevo perfil de configuración",
"enterProfileName": "Ingrese el nombre del perfil",
"createProfile": "Crear perfil",
"cannotDeleteOnlyProfile": "No se puede eliminar el único perfil",
"vscodeLmDescription": "La API del Modelo de Lenguaje de VS Code le permite ejecutar modelos proporcionados por otras extensiones de VS Code (incluido, entre otros, GitHub Copilot). La forma más sencilla de empezar es instalar las extensiones Copilot y Copilot Chat desde el VS Code Marketplace.",
"awsCustomArnUse": "Ingrese un ARN de AWS Bedrock válido para el modelo que desea utilizar. Ejemplos de formato:",
"awsCustomArnDesc": "Asegúrese de que la región en el ARN coincida con la región de AWS seleccionada anteriormente.",
"openRouterApiKey": "Clave API de OpenRouter",
"getOpenRouterApiKey": "Obtener clave API de OpenRouter",
"apiKeyStorageNotice": "Las claves API se almacenan de forma segura en el Almacenamiento Secreto de VSCode",
Expand Down Expand Up @@ -104,6 +118,8 @@
"awsSessionToken": "Token de sesión de AWS",
"awsRegion": "Región de AWS",
"awsCrossRegion": "Usar inferencia entre regiones",
"vscodeLmModel": "Modelo de lenguaje",
"vscodeLmWarning": "Nota: Esta es una integración muy experimental y el soporte del proveedor variará. Si recibe un error sobre un modelo no compatible, es un problema del proveedor.",
"googleCloudSetup": {
"title": "Para usar Google Cloud Vertex AI, necesita:",
"step1": "1. Crear una cuenta de Google Cloud, habilitar la API de Vertex AI y habilitar los modelos Claude deseados.",
Expand Down
16 changes: 16 additions & 0 deletions webview-ui/src/i18n/locales/fr/settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,20 @@
"description": "Description",
"apiProvider": "Fournisseur d'API",
"model": "Modèle",
"nameEmpty": "Le nom ne peut pas être vide",
"nameExists": "Un profil avec ce nom existe déjà",
"deleteProfile": "Supprimer le profil",
"invalidArnFormat": "Format ARN invalide. Veuillez vérifier les exemples ci-dessus.",
"enterNewName": "Entrez un nouveau nom",
"addProfile": "Ajouter un profil",
"renameProfile": "Renommer le profil",
"newProfile": "Nouveau profil de configuration",
"enterProfileName": "Entrez le nom du profil",
"createProfile": "Créer un profil",
"cannotDeleteOnlyProfile": "Impossible de supprimer le seul profil",
"vscodeLmDescription": "L'API du modèle de langage VS Code vous permet d'exécuter des modèles fournis par d'autres extensions VS Code (y compris, mais sans s'y limiter, GitHub Copilot). Le moyen le plus simple de commencer est d'installer les extensions Copilot et Copilot Chat depuis le VS Code Marketplace.",
"awsCustomArnUse": "Entrez un ARN AWS Bedrock valide pour le modèle que vous souhaitez utiliser. Exemples de format :",
"awsCustomArnDesc": "Assurez-vous que la région dans l'ARN correspond à la région AWS sélectionnée ci-dessus.",
"openRouterApiKey": "Clé API OpenRouter",
"getOpenRouterApiKey": "Obtenir la clé API OpenRouter",
"apiKeyStorageNotice": "Les clés API sont stockées en toute sécurité dans le stockage sécurisé de VSCode",
Expand Down Expand Up @@ -104,6 +118,8 @@
"awsSessionToken": "Jeton de session AWS",
"awsRegion": "Région AWS",
"awsCrossRegion": "Utiliser l'inférence inter-régions",
"vscodeLmModel": "Modèle de langage",
"vscodeLmWarning": "Remarque : Il s'agit d'une intégration très expérimentale et le support des fournisseurs variera. Si vous recevez une erreur concernant un modèle non pris en charge, c'est un problème du côté du fournisseur.",
"googleCloudSetup": {
"title": "Pour utiliser Google Cloud Vertex AI, vous devez :",
"step1": "1. Créer un compte Google Cloud, activer l'API Vertex AI et activer les modèles Claude souhaités.",
Expand Down
16 changes: 16 additions & 0 deletions webview-ui/src/i18n/locales/hi/settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,20 @@
"description": "विवरण",
"apiProvider": "API प्रदाता",
"model": "मॉडल",
"nameEmpty": "नाम खाली नहीं हो सकता",
"nameExists": "इस नाम वाला प्रोफ़ाइल पहले से मौजूद है",
"deleteProfile": "प्रोफ़ाइल हटाएं",
"invalidArnFormat": "अमान्य ARN प्रारूप। कृपया ऊपर दिए गए उदाहरण देखें।",
"enterNewName": "नया नाम दर्ज करें",
"addProfile": "प्रोफ़ाइल जोड़ें",
"renameProfile": "प्रोफ़ाइल का नाम बदलें",
"newProfile": "नया कॉन्फ़िगरेशन प्रोफ़ाइल",
"enterProfileName": "प्रोफ़ाइल नाम दर्ज करें",
"createProfile": "प्रोफ़ाइल बनाएं",
"cannotDeleteOnlyProfile": "केवल एकमात्र प्रोफ़ाइल को हटाया नहीं जा सकता",
"vscodeLmDescription": "VS कोड भाषा मॉडल API आपको अन्य VS कोड एक्सटेंशन (जैसे GitHub Copilot) द्वारा प्रदान किए गए मॉडल चलाने की अनुमति देता है। शुरू करने का सबसे आसान तरीका VS कोड मार्केटप्लेस से Copilot और Copilot चैट एक्सटेंशन इंस्टॉल करना है।",
"awsCustomArnUse": "आप जिस मॉडल का उपयोग करना चाहते हैं, उसके लिए एक वैध AWS बेडरॉक ARN दर्ज करें। प्रारूप उदाहरण:",
"awsCustomArnDesc": "सुनिश्चित करें कि ARN में क्षेत्र ऊपर चयनित AWS क्षेत्र से मेल खाता है।",
"openRouterApiKey": "OpenRouter API कुंजी",
"getOpenRouterApiKey": "OpenRouter API कुंजी प्राप्त करें",
"apiKeyStorageNotice": "API कुंजियाँ VSCode के सुरक्षित स्टोरेज में सुरक्षित रूप से संग्रहीत हैं",
Expand Down Expand Up @@ -104,6 +118,8 @@
"awsSessionToken": "AWS सत्र टोकन",
"awsRegion": "AWS क्षेत्र",
"awsCrossRegion": "क्रॉस-क्षेत्र अनुमान का उपयोग करें",
"vscodeLmModel": "भाषा मॉडल",
"vscodeLmWarning": "नोट: यह एक बहुत ही प्रायोगिक एकीकरण है और प्रदाता समर्थन भिन्न होगा। यदि आपको किसी मॉडल के समर्थित न होने की त्रुटि मिलती है, तो यह प्रदाता की ओर से एक समस्या है।",
"googleCloudSetup": {
"title": "Google Cloud Vertex AI का उपयोग करने के लिए, आपको आवश्यकता है:",
"step1": "1. Google Cloud खाता बनाएं, Vertex AI API सक्षम करें और वांछित Claude मॉडल सक्षम करें।",
Expand Down
Loading