Skip to content

Conversation

@KJ7LNW
Copy link
Contributor

@KJ7LNW KJ7LNW commented May 10, 2025

This PR introduces comprehensive improvements to the translation validation system and management tools.

Note to reviewers: this might look really big, but nothing in core was modified.

This is really just:

  1. fixed missing translations
  2. translation test clean up
  3. deleted unused translation keys
  4. added translation management tool (see below)

Easy translation updates:

node scripts/manage-translations.js --stdin webview-ui/src/i18n/locales/am/settings.json << 'EOF'
> {"terminal.advanced.description": "የሚከተሉት አማራጮች ቅንብሩን ለመተግበር የተርሚናል ዳግም ማስጀመር ሊያስፈልጋቸው ይችላል።"}
> {"terminal.advanced.label": "የተርሚናል ቅንብሮች: የላቀ"}
> {"terminal.basic.description": "መሰረታዊ የተርሚናል ቅንብሮች"}
...
> EOF

The only real risk is if I caused a problem with translations, but there were very few actual translation fixes/additions. Everything else was testing and tooling for translation management. See #3422

# git diff --stat origin/main... -- local/ src/i18n/ webview-ui/src/i18n/ locales/ 

# new far more comprehensive tests to replace scripts/find-*.js language linters
 locales/__tests__/find-missing-i18n-keys.test.ts | 221 ++++++++
 locales/__tests__/lint-translations.test.ts      | 669 +++++++++++++++++++++++
 locales/__tests__/utils.ts                       |  71 +++

# add missing privacy translations
 locales/ca/PRIVACY.md                            |  37 ++
 locales/de/PRIVACY.md                            |  37 ++
 locales/es/PRIVACY.md                            |  37 ++
 locales/fr/PRIVACY.md                            |  37 ++
 locales/hi/PRIVACY.md                            |  37 ++
 locales/it/PRIVACY.md                            |  37 ++
 locales/ja/PRIVACY.md                            |  37 ++
 locales/ko/PRIVACY.md                            |  37 ++
 locales/nl/PRIVACY.md                            |  37 ++
 locales/pl/PRIVACY.md                            |  37 ++
 locales/pt-BR/PRIVACY.md                         |  37 ++
 locales/ru/PRIVACY.md                            |  37 ++
 locales/tr/PRIVACY.md                            |  37 ++
 locales/vi/PRIVACY.md                            |  37 ++
 locales/zh-CN/PRIVACY.md                         |  37 ++
 locales/zh-TW/PRIVACY.md                         |  37 ++

# missing and extra key/value language fixes
 src/i18n/locales/ca/common.json                  |   6 -
 src/i18n/locales/de/common.json                  |   6 -
 src/i18n/locales/es/common.json                  |   6 -
 src/i18n/locales/fr/common.json                  |   6 -
 src/i18n/locales/hi/common.json                  |   6 -
 src/i18n/locales/it/common.json                  |   6 -
 src/i18n/locales/ja/common.json                  |   6 -
 src/i18n/locales/ko/common.json                  |   6 -
 src/i18n/locales/pl/common.json                  |   6 -
 src/i18n/locales/pt-BR/common.json               |   6 -
 src/i18n/locales/ru/common.json                  |   6 -
 src/i18n/locales/tr/common.json                  |   6 -
 src/i18n/locales/vi/common.json                  |   6 -
 src/i18n/locales/zh-CN/common.json               |   6 -
 src/i18n/locales/zh-TW/common.json               |   6 -
 webview-ui/src/i18n/locales/ca/prompts.json      |   3 +-
 webview-ui/src/i18n/locales/ca/settings.json     |   1 -
 webview-ui/src/i18n/locales/de/prompts.json      |   3 +-
 webview-ui/src/i18n/locales/de/settings.json     |   1 -
 webview-ui/src/i18n/locales/en/prompts.json      |   3 +-
 webview-ui/src/i18n/locales/es/prompts.json      |   3 +-
 webview-ui/src/i18n/locales/es/settings.json     |   1 -
 webview-ui/src/i18n/locales/fr/prompts.json      |   3 +-
 webview-ui/src/i18n/locales/fr/settings.json     |   1 -
 webview-ui/src/i18n/locales/hi/prompts.json      |   3 +-
 webview-ui/src/i18n/locales/hi/settings.json     |   1 -
 webview-ui/src/i18n/locales/it/prompts.json      |   3 +-
 webview-ui/src/i18n/locales/it/settings.json     |   1 -
 webview-ui/src/i18n/locales/ja/prompts.json      |   3 +-
 webview-ui/src/i18n/locales/ja/settings.json     |   1 -
 webview-ui/src/i18n/locales/ko/prompts.json      |   3 +-
 webview-ui/src/i18n/locales/ko/settings.json     |   1 -
 webview-ui/src/i18n/locales/nl/prompts.json      |   3 +-
 webview-ui/src/i18n/locales/pl/prompts.json      |   3 +-
 webview-ui/src/i18n/locales/pl/settings.json     |   1 -
 webview-ui/src/i18n/locales/pt-BR/prompts.json   |   3 +-
 webview-ui/src/i18n/locales/pt-BR/settings.json  |   1 -
 webview-ui/src/i18n/locales/ru/prompts.json      |   3 +-
 webview-ui/src/i18n/locales/tr/prompts.json      |   3 +-
 webview-ui/src/i18n/locales/tr/settings.json     |   1 -
 webview-ui/src/i18n/locales/vi/mcp.json          |   1 -
 webview-ui/src/i18n/locales/vi/prompts.json      |   3 +-
 webview-ui/src/i18n/locales/vi/settings.json     |   1 -
 webview-ui/src/i18n/locales/zh-CN/mcp.json       |   1 -
 webview-ui/src/i18n/locales/zh-CN/prompts.json   |   3 +-
 webview-ui/src/i18n/locales/zh-CN/settings.json  |   1 -
 webview-ui/src/i18n/locales/zh-TW/mcp.json       |   1 -
 webview-ui/src/i18n/locales/zh-TW/prompts.json   |   3 +-
 67 files changed, 1587 insertions(+), 123 deletions(-)

Major Changes

  • Migrated translation validation from scripts to Jest test suite
  • Added comprehensive linting for missing and extra translations
  • Improved translation management tooling
  • Enhanced error reporting and documentation

Translation Management

The improved manage-translations.js script provides powerful translation management capabilities:

Command Line Usage

# Add/update translations
node scripts/manage-translations.js [-v] TRANSLATION_FILE KEY_PATH VALUE [KEY_PATH VALUE...]

# Delete translations
node scripts/manage-translations.js [-v] -d TRANSLATION_FILE1 [TRANSLATION_FILE2 ...] [ -- KEY1 ...]

Key Path Format

  • Single dot (.) for nested paths: command.newTask.title
  • Double dots (..) for literal dots: settings..path{ "settings.path": "value" }

Batch Processing

Support for line-by-line JSON input via stdin:

# Add multiple translations
echo '{"command.newTask.title": "New Task"}' | \
  node scripts/manage-translations.js --stdin package.nls.json

# Delete multiple keys
echo '["command.newTask.title"]' | \
  node scripts/manage-translations.js -d --stdin package.nls.json

Here Document Support

node scripts/manage-translations.js --stdin package.nls.json << 'EOF'
{"command.newTask.title": "New Task"}
{"settings..path": "Custom Path"}
EOF

Technical Details

  • Replaced find-missing-translations.js and find-missing-i18n-keys.js with Jest-based tests
  • Added support for escaped dots in translation paths
  • Enhanced empty object key detection
  • Unified file existence checking
  • Improved error grouping and reporting

Test Coverage

The new system provides better validation across:

  • Core translations
  • Webview translations
  • Documentation files
  • Package NLS files

This change improves our ability to maintain translation quality and consistency.

Fixes: #3422


Important

Improves translation validation and management by migrating to Jest, enhancing error reporting, and introducing a new script for managing translations.

  • Behavior:
    • Migrated translation validation to Jest test suite in code-qa.yml and jest.config.js.
    • Added lint-translations.test.ts and find-missing-i18n-keys.test.ts for comprehensive translation checks.
    • Enhanced error reporting and documentation in 001-general-rules.md.
  • Translation Management:
    • Introduced manage-translations.js for managing translations with command line and stdin support.
    • Supports batch processing and here document input for adding and deleting translations.
    • Updated manage-translations.test.ts for testing new functionalities.
  • Misc:
    • Removed find-missing-translations.js and find-missing-i18n-key.js scripts.
    • Updated translation files in locales and webview-ui/src/i18n/locales for various languages.
    • Updated README.md for new translation management instructions.

This description was created by Ellipsis for 9a70cdc. You can customize this summary. It will automatically update as commits are pushed.

Eric Wheeler added 21 commits May 9, 2025 16:16
Implement a full translation linting system in Jest that:
- Checks both missing and extra translations
- Supports all translation areas (core, webview, docs, package-nls)
- Provides detailed reporting and error grouping
- Includes type safety and modular design
- Adds unit tests for linting functions

This extends and improves upon the functionality from
find-extra-translations.js script, adding more comprehensive
checking and test coverage.

Signed-off-by: Eric Wheeler <[email protected]>
- Only check existence for non-JSON files
- Add proper indentation for extra translations output
- Make test fail when translation issues are found

Signed-off-by: Eric Wheeler <[email protected]>
- Change getFilteredLocales to throw error for invalid locales
- Remove dead code in resolveTargetPath for '/' template
- Return structured output from lintTranslations with exitCode and message
- Remove unused getAllLocalesForMapping export
- Fix sourceContent type handling
- Improve test assertions to verify output content

Signed-off-by: Eric Wheeler <[email protected]>
Corrected translation validation to properly detect existing translations and improved output readability

Signed-off-by: Eric Wheeler <[email protected]>
Add manage-translations.js CLI tool that provides utilities for:
- Adding/updating translations with nested key paths
- Deleting translation keys
- Batch operations via stdin/JSON input
- Verbose output mode for debugging

The script supports both direct command line usage and line-by-line
JSON input for bulk operations, making translation management more
efficient.

Signed-off-by: Eric Wheeler <[email protected]>
- Track and display missing markdown files in docs area
- Group missing files by locale with full target paths
- Show each missing file on its own line
- Update example paths to use relative paths in help text

Signed-off-by: Eric Wheeler <[email protected]>
Standardize how missing files are reported across all file types:
- Remove special case for markdown files
- Report all missing files consistently in missing array
- Keep JSON-specific parsing as the only special case
- Improve error messages for translation tasks

Signed-off-by: Eric Wheeler <[email protected]>
Remove exitCode from lintTranslations return type and test since it was not being used meaningfully. Add 'All translations are complete' message when there are no issues.

Signed-off-by: Eric Wheeler <[email protected]>
Created PRIVACY.md translations for:
ca, de, es, fr, hi, it, ja, ko, nl, pl, pt-BR, ru, tr, vi, zh-CN, zh-TW

Each translation maintains consistent structure and terminology while adapting to language-specific conventions.

Signed-off-by: Eric Wheeler <[email protected]>
- Add support for escaped dots (\.) in translation paths
- Allow keys to contain dots by escaping them
- Add comprehensive tests for dot escaping functionality
- Improve error handling and exports for testing
- Update jest config to include scripts directory

Example:
  settings\.customStoragePath\.description -> settings.customStoragePath.description
Signed-off-by: Eric Wheeler <[email protected]>
Modified findKeys() to include empty object keys in translation checks,
allowing detection of extra object keys like settings.providers that
exist in translations but not in English source.

Signed-off-by: Eric Wheeler <[email protected]>
Change key escaping format to use double dots, similar to SMTP byte stuffing:
- Replace \. with .. for escaping dots in key paths
- Update documentation with new format and clearer examples
- Update test cases to use new escaping format
- Fix delete mode tests to use -- separator
- Maintain all existing functionality

Example:
  Old: settings\.path -> settings.path
  New: settings..path -> settings.path

The new format is more readable and follows the SMTP byte stuffing pattern
for escaping dots.

Signed-off-by: Eric Wheeler <[email protected]>
Update error output in lint-translations.test.ts to match manage-translations.js:
- Add key path format documentation (single/double dots)
- Include realistic examples matching actual usage patterns
- Document -v flag for verbose output
- Show multiple ways to use the script (here-doc and direct)
- Improve help text organization and clarity

Signed-off-by: Eric Wheeler <[email protected]>
Remove translations not present in English source:
- settings.providers.groqApiKey and getGroqApiKey from common.json
- footer.version from settings.json
- editSettings from mcp.json

This ensures translation files only contain keys that exist in English source files.

Signed-off-by: Eric Wheeler <[email protected]>
Move missing i18n key detection from scripts/ to test suite.
Export helper functions from lint-translations for reuse.

The migrated test:
- Maintains existing scanning functionality
- Groups and reports missing keys by file
- Provides command line example for adding translations

Signed-off-by: Eric Wheeler <[email protected]>
Remove scripts that were migrated to test suite:
- scripts/find-missing-i18n-key.js -> locales/__tests__/find-missing-i18n-keys.test.ts
- scripts/find-missing-translations.js -> locales/__tests__/lint-translations.test.ts

Signed-off-by: Eric Wheeler <[email protected]>
Move common utilities used by i18n test files into utils.ts:
- File operations (fileExists, loadFileContent)
- JSON parsing and path handling
- Logging utilities

Replace direct logBuffer access with clearLogs() function
Remove duplicate code between test files

Signed-off-by: Eric Wheeler <[email protected]>
Include English locale when checking for missing translations to ensure
completeness across all language files.

Signed-off-by: Eric Wheeler <[email protected]>
Restore original implementations that were incorrectly refactored:
- Add ./ prefix in fileExists for proper path resolution
- Restore error deduplication tracking in parseJsonContent
- Restore direct property access optimization in getValueAtPath

Signed-off-by: Eric Wheeler <[email protected]>
Replace find-missing-translations.js script with Jest tests for improved:
- Test organization and reporting
- Error handling and validation
- Integration with existing test infrastructure

Added detailed documentation for translation management script usage
with examples for adding/updating/deleting translations

Signed-off-by: Eric Wheeler <[email protected]>
Add missing 'No matching modes found' translation key across all locales
to fix failing translation tests.

Fixes: #3422
Signed-off-by: Eric Wheeler <[email protected]>
@changeset-bot
Copy link

changeset-bot bot commented May 10, 2025

⚠️ No Changeset found

Latest commit: 4f21bb5

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

This PR includes no changesets

When changesets are added to this PR, you'll see the packages that this PR includes changesets for and the associated semver types

Click here to learn what changesets are, and how to add one.

Click here if you're a maintainer who wants to add a changeset to this PR

@dosubot dosubot bot added size:XXL This PR changes 1000+ lines, ignoring generated files. enhancement New feature or request labels May 10, 2025
@ellipsis-dev
Copy link
Contributor

ellipsis-dev bot commented May 10, 2025

Hi @KJ7LNW, thanks for the comprehensive improvements to the translation validation, linting, and management system! This is a substantial pull request with a lot of valuable work.

To help with review and maintainability, could you please consider splitting out the changes related to privacy policy documentation (the new/updated PRIVACY.md files in each locale) into a separate pull request? These documentation updates are independent of the translation validation/linting/tooling overhaul and can be reviewed and merged on their own.

The translation validation/linting/tooling changes and the locale JSON updates are closely related and make sense to keep together, but separating the privacy policy markdowns will make it easier for reviewers to focus on each area.

Thank you for your efforts and for helping keep the codebase organized!

@KJ7LNW KJ7LNW marked this pull request as draft May 11, 2025 09:07
@KJ7LNW
Copy link
Contributor Author

KJ7LNW commented May 11, 2025

Found some more lint: lots of language keys not in Roo's source.

switching to draft mode and adding some more tests.

@KJ7LNW KJ7LNW added Issue - In Progress Someone is actively working on this. Should link to a PR soon. and removed bug Something isn't working UI/UX UI/UX related or focused labels May 11, 2025
Eric Wheeler added 4 commits May 12, 2025 21:29
When a translation file is missing, now properly shows:
- For JSON files: 'Missing keys: ALL KEYS (N total)'
- For non-JSON files: 'Missing file: ALL CONTENT (entire file)'

This makes it clearer that all content is missing when a file doesn't exist.

Signed-off-by: Eric Wheeler <[email protected]>
Added a new pattern to match i18n keys used with parameters, which fixes
detection of keys like common:errors.invalid_mcp_settings_validation.

Refactored the code to split it into 4 functions:
- accumulateSourceKeys(): Collects all keys used in source code
- accumulateTranslationKeys(): Collects all keys found in translation files
- getKeysInSourceNotInTranslation(): Returns keys in source not in translations
- getKeysInTranslationNotInSource(): Returns keys in translations not in source

Added tests to validate that there are no keys in source not in translations
and no keys in translations not in source.

Signed-off-by: Eric Wheeler <[email protected]>
Enhance i18n key test error reporting with file:line information to help
locate problematic keys in the codebase.

- Track line numbers for i18n keys
- Handle multi-line t() calls
- Show file:line in test output

Signed-off-by: Eric Wheeler <[email protected]>
Improve i18n key detection by adding path segment matching to handle dynamic keys like:
- chat:codeblock.tooltips.${windowShade ? "expand" : "collapse"}
- prompts:supportPrompts.types.${type}.label

This reduces false positives by recognizing that static keys in translation files
(like chat:codeblock.tooltips.expand) are actually used via dynamic keys in the
source code.

The solution:
- Splits keys into segments and marks dynamic parts as wildcards
- Matches static keys against these patterns
- Reduces reported unused keys from 108 to 78

Signed-off-by: Eric Wheeler <[email protected]>
@KJ7LNW KJ7LNW force-pushed the test-translation-linting branch from c7a97d1 to 4f21bb5 Compare May 13, 2025 04:57
Eric Wheeler added 2 commits May 14, 2025 14:46
Enhance the translation linting tool to better handle and display missing translations:

- Add escapeDotsForDisplay utility function to properly handle dots in key names
- Move utility function to utils.ts for better code organization
- Use source values captured during scan time when displaying missing keys
- Update property name from englishValue to sourceValue for consistency
- Improve display of missing keys by using stored translation issues

Signed-off-by: Eric Wheeler <[email protected]>
Refactors the translation linting script to more accurately handle and display translation keys.

- Uses direct object comparison instead of key flattening
- Changes internal key representation to path arrays for clearer structure
- Fixes display of keys with literal dots versus nested keys
- Prevents [object Object] from appearing in extra translations list
- Adds configuration-driven namespace prefix for displayed keys
- Introduces useFilenameAsNamespace property in PATH_MAPPINGS
- Removes findKeys utility and cleans up related code

Signed-off-by: Eric Wheeler <[email protected]>
@hannesrudolph hannesrudolph moved this from New to PR [Draft/WIP] in Roo Code Roadmap May 20, 2025
Eric Wheeler added 4 commits May 20, 2025 16:18
…reporting

Enhance the translation linting script with configuration-driven behavior:
- Update PathMapping interface with displayNamespace and reportFileLevelOnly attributes
- Make namespace prefixing configurable via PathMapping attributes
- Implement recursive object comparison for accurate key detection
- Add file size checking for documentation translations
- Add detection of extra files in translation directories
- Refine display of translation issues with appropriate namespacing

These changes allow for more accurate reporting of translation issues
while maintaining a clean and consistent output format across different
types of translation files (JSON, Markdown).

Signed-off-by: Eric Wheeler <[email protected]>
Refactor `lint-translations.test.ts` to improve testability:

- Extracted `checkIfFileMissing` to centralize file existence checks.
- Extracted `checkFileSizeDifference` to isolate file size comparison logic.
- Renamed `checkExtraFiles` to `identifyExtraFiles` and modified it to return a list of issues instead of directly mutating the results object.
- Updated `processFileLocale` and the main `lintTranslations` loop to use these new/refactored helper functions.

These changes make the logic for these specific checks more isolated and prepare the codebase for adding more focused unit tests.

Signed-off-by: Eric Wheeler <[email protected]>
Modify translation linting to ignore dotfiles in both source and target directories:
- Update enumerateSourceFiles to skip dotfiles when scanning source directories
- Update identifyExtraFiles to skip dotfiles when scanning target directories

This prevents .gitkeep files from being reported as missing or extra translations.

Also updates the file size warning threshold from 2x to 3x to reduce false positives
for languages that naturally require more characters than English.

Signed-off-by: Eric Wheeler <[email protected]>
Filter out keys with object values when reporting 'ALL KEYS' for
a missing JSON file. This prevents parent keys of nested objects
from being incorrectly displayed as missing individual translations.

Signed-off-by: Eric Wheeler <[email protected]>
@hannesrudolph hannesrudolph moved this from PR [Draft / In Progress] to TEMP in Roo Code Roadmap May 26, 2025
@daniel-lxs daniel-lxs moved this from TEMP to PR [Draft / In Progress] in Roo Code Roadmap May 26, 2025
@hannesrudolph hannesrudolph removed Issue - Unassigned / Actionable Clear and approved. Available for contributors to pick up. Issue - In Progress Someone is actively working on this. Should link to a PR soon. labels May 27, 2025
Eric Wheeler added 2 commits June 5, 2025 00:18
Modified the translation linting script to no longer display English source text
when reporting missing translation keys. This makes the output cleaner and
focuses only on the missing key paths rather than showing both the path and
the untranslated English text.

The changes remove the display of "[en]" source values while preserving the
key path information needed to identify missing translations.

Signed-off-by: Eric Wheeler <[email protected]>
Create separate functions for rendering missing and extra translations:
- renderMissingFilesSection: For completely missing files
- renderMissingKeysSection: For files with missing keys
- renderExtraTranslationsSection: For extra translations

These functions ensure consistent formatting across the codebase
and fix the issue of showing translation values for extra keys.

Signed-off-by: Eric Wheeler <[email protected]>
@hannesrudolph
Copy link
Collaborator

Stale

@github-project-automation github-project-automation bot moved this from PR [Pre Approval Review] to Done in Roo Code Roadmap Jul 7, 2025
@github-project-automation github-project-automation bot moved this from PR [Draft / In Progress] to Done in Roo Code Roadmap Jul 7, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request PR - Draft / In Progress size:XXL This PR changes 1000+ lines, ignoring generated files.

Projects

Archived in project

Development

Successfully merging this pull request may close these issues.

fix: Translation linting failures need resolution

3 participants