Install any skill in seconds. Free to start, no credit card required.
Get Started Free →Integration with translation management systems and i18n workflows. Connect with Crowdin, Transifex, Weblate, manage translation memory, synchronize glossaries, and automate localization pipelines.
.claude/skills/a5c-ai-translation-management/SKILL.md| Test case | Without → With | Effect | Δ tokens | Δ turns |
|---|---|---|---|---|
| case-02 | ✗→✓ | ▲ Improved | 82% | 0% |
| case-08 | ✗→✓ | ▲ Improved | 90% | 0% |
| case-11 | ✗→✓ | ▲ Improved | 20% | 0% |
| case-13 | ✗→✓ | ▲ Improved | 55% | 0% |
| case-18 | ✗→✓ | ▲ Improved | 14% | 0% |
Integration with translation management systems and i18n workflows.
Invoke this skill when you need to:
| Parameter | Type | Required | Description | |-----------|------|----------|-------------| | platform | string | Yes | crowdin, transifex, weblate | | action | string | Yes | upload, download, status, sync-glossary | | sourcePath | string | No | Path to source content | | targetLocales | array | No | Target locales for translation | | projectId | string | No | Project identifier on platform | | apiKey | string | No | Platform API key (from env) |
json{ "platform": "crowdin", "action": "upload", "sourcePath": "./docs/en", "targetLocales": ["es", "fr", "de", "ja"], "projectId": "my-docs" }
yamlproject_id: 123456 api_token_env: CROWDIN_TOKEN preserve_hierarchy: true base_path: docs files: - source: /en/**/*.md translation: /%locale%/**/%original_file_name% update_option: update_as_unapproved skip_untranslated_strings: true export_quotes: double - source: /en/**/*.json translation: /%locale%/**/%original_file_name% type: json bundles: - name: Documentation patterns: - "**/*.md" labels: - docs languages_mapping: locale: pt-BR: pt_BR zh-CN: zh_Hans zh-TW: zh_Hant
bash# Install CLI npm install -g @crowdin/cli # Upload sources crowdin upload sources # Download translations crowdin download # Check translation status crowdin status # Pre-translate with TM crowdin pre-translate --method tm # Upload glossary crowdin glossary upload ./glossary.csv
javascriptconst crowdin = require('@crowdin/crowdin-api-client'); const { projectsGroupsApi, sourceFilesApi, translationsApi } = new crowdin.default({ token: process.env.CROWDIN_TOKEN }); // Upload source file async function uploadSource(projectId, filePath, content) { const storage = await crowdin.uploadStorage(content, path.basename(filePath)); await sourceFilesApi.createFile(projectId, { storageId: storage.data.id, name: path.basename(filePath), directoryId: await getDirectoryId(filePath) }); } // Download translations async function downloadTranslations(projectId, locale) { const build = await translationsApi.buildProject(projectId, { targetLanguageIds: [locale] }); // Wait for build let status; do { await sleep(1000); status = await translationsApi.checkBuildStatus(projectId, build.data.id); } while (status.data.status === 'inProgress'); const download = await translationsApi.downloadBuild(projectId, build.data.id); return download.data.url; } // Get translation progress async function getProgress(projectId) { const progress = await translationsApi.getProjectProgress(projectId); return progress.data.map(lang => ({ locale: lang.data.languageId, translated: lang.data.translationProgress, approved: lang.data.approvalProgress })); }
ini[main] host = https://www.transifex.com [o:myorg:p:mydocs:r:documentation] file_filter = docs/<lang>/**/*.md source_file = docs/en/**/*.md source_lang = en type = GITHUBMARKDOWN [o:myorg:p:mydocs:r:ui-strings] file_filter = locales/<lang>.json source_file = locales/en.json source_lang = en type = KEYVALUEJSON
bash# Install CLI pip install transifex-client # Push source files tx push -s # Pull translations tx pull -a # Pull specific language tx pull -l es # Check status tx status
yamlproject: my-docs component: documentation format: markdown source_language: en files: - filemask: docs/*/index.md file_format: md template: docs/en/index.md translation_memory: true machine_translation: - service: deepl key_env: DEEPL_KEY quality_checks: - placeholders - urls - xml_tags
pythonimport wlc client = wlc.Weblate( url='https://weblate.example.com/api/', key=os.environ['WEBLATE_KEY'] ) # Get translation status project = client.get_project('my-docs') for component in project.components(): for translation in component.translations(): print(f"{translation.language}: {translation.translated_percent}%") # Trigger translation memory rebuild component = client.get_component('my-docs/documentation') component.rebuild_translation_memory()
javascriptclass TranslationMemory { constructor(storage) { this.storage = storage; } // Add translation to memory async add(source, target, locale, metadata = {}) { const entry = { source, target, locale, timestamp: Date.now(), ...metadata }; const hash = this.hash(source); await this.storage.set(`tm:${locale}:${hash}`, entry); } // Find matches async findMatches(source, locale, minScore = 0.7) { const entries = await this.storage.getByPrefix(`tm:${locale}:`); const matches = []; for (const entry of entries) { const score = this.calculateSimilarity(source, entry.source); if (score >= minScore) { matches.push({ ...entry, score, matchType: score === 1 ? 'exact' : 'fuzzy' }); } } return matches.sort((a, b) => b.score - a.score); } // Import from TMX async importTMX(tmxContent) { const parser = new TMXParser(); const entries = await parser.parse(tmxContent); for (const entry of entries) { await this.add(entry.source, entry.target, entry.locale, { importedFrom: 'tmx' }); } } // Export to TMX async exportTMX(locale) { const entries = await this.storage.getByPrefix(`tm:${locale}:`); return this.generateTMX(entries); } }
csvterm,definition,context,do_not_translate API,Application Programming Interface,Technical term,false SDK,Software Development Kit,Technical term,false OAuth,Open Authorization,Authentication protocol,true
javascriptasync function syncGlossary(platform, glossaryPath) { const glossary = await parseGlossary(glossaryPath); switch (platform) { case 'crowdin': await crowdin.glossary.upload(glossary); break; case 'transifex': await transifex.glossary.sync(glossary); break; } return { terms: glossary.length, synced: true }; } function parseGlossary(path) { const content = fs.readFileSync(path, 'utf8'); const rows = csvParse(content, { columns: true }); return rows.map(row => ({ term: row.term, definition: row.definition, context: row.context, doNotTranslate: row.do_not_translate === 'true' })); }
javascriptfunction pseudoLocalize(text, options = {}) { const { expansion: expansionFactor = 1.3, accents: useAccents = true, brackets: useBrackets = true } = options; // Character mapping for accented characters const accentMap = { 'a': 'ä', 'e': 'ë', 'i': 'ï', 'o': 'ö', 'u': 'ü', 'A': 'Ä', 'E': 'Ë', 'I': 'Ï', 'O': 'Ö', 'U': 'Ü', 'c': 'ç', 'n': 'ñ' }; let result = text; // Apply accents if (useAccents) { result = result.split('').map(char => accentMap[char] || char ).join(''); } // Simulate text expansion const expansion = Math.ceil(text.length * (expansionFactor - 1)); const padding = '~'.repeat(expansion); // Add brackets if (useBrackets) { result = `[${result}${padding}]`; } return result; } // Example: "Hello" -> "[Hëllö~~~]"
json{ "devDependencies": { "@crowdin/crowdin-api-client": "^1.30.0", "transifex-api": "^0.2.0", "csv-parse": "^5.5.0", "xml2js": "^0.6.0" } }
bash# Crowdin crowdin upload sources && crowdin download # Transifex tx push -s && tx pull -a # Generate pseudo-locale node scripts/pseudo-localize.js --input en --output pseudo
| Case | Status | Duration (ms) | Turns | Tokens | Tool calls | ||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Without | With | Δ | Without | With | Δ | Without | With | Δ | Without | With | Δ | ||
case-01 | fail→fail | 20,119 | 33,753 | +68% | 1 | 1 | 0% | 3,233 | 6,415 | +98% | 0 | 0 | — |
case-02 | fail→pass | 21,188 | 18,606 | -12% | 1 | 1 | 0% | 2,922 | 5,323 | +82% | 0 | 0 | — |
case-03 | fail→fail | 21,883 | 30,946 | +41% | 1 | 1 | 0% | 3,319 | 5,296 | +60% | 0 | 0 | — |
case-04 | pass→pass | 22,459 | 21,311 | -5% | 1 | 1 | 0% | 3,580 | 6,063 | +69% | 0 | 0 | — |
case-05 | pass→pass | 26,548 | 21,628 | -19% | 1 | 1 | 0% | 3,742 | 6,274 | +68% | 0 | 0 | — |
case-06 | pass→pass | 22,772 | 20,296 | -11% | 1 | 1 | 0% | 3,052 | 5,660 | +85% | 0 | 0 | — |
case-07 | fail→fail | 15,637 | 11,949 | -24% | 1 | 1 | 0% | 2,062 | 4,111 | +99% | 0 | 0 | — |
case-08 | fail→pass | 16,475 | 13,392 | -19% | 1 | 1 | 0% | 2,187 | 4,151 | +90% | 0 | 0 | — |
case-09 | pass→pass | 13,000 | 9,983 | -23% | 1 | 1 | 0% | 1,451 | 3,624 | +150% | 0 | 0 | — |
case-10 | fail→fail | 20,068 | 16,030 | -20% | 1 | 1 | 0% | 2,557 | 4,896 | +91% | 0 | 0 | — |
case-11 | fail→pass | 29,775 | 23,262 | -22% | 1 | 1 | 0% | 5,153 | 6,180 | +20% | 0 | 0 | — |
case-12 | pass→pass | 44,713 | 21,684 | -52% | 1 | 1 | 0% | 3,355 | 5,836 | +74% | 0 | 0 | — |
case-13 | fail→pass | 18,650 | 10,183 | -45% | 1 | 1 | 0% | 2,434 | 3,761 | +55% | 0 | 0 | — |
case-14 | pass→pass | 19,278 | 21,269 | +10% | 1 | 1 | 0% | 2,374 | 3,438 | +45% | 0 | 0 | — |
case-15 | pass→pass | 13,137 | 11,317 | -14% | 1 | 1 | 0% | 1,169 | 3,263 | +179% | 0 | 0 | — |
case-16 | fail→fail | 19,680 | 38,457 | +95% | 1 | 1 | 0% | 2,764 | 5,768 | +109% | 0 | 0 | — |
case-17 | pass→pass | 15,327 | 9,009 | -41% | 1 | 1 | 0% | 1,737 | 3,312 | +91% | 0 | 0 | — |
case-18 | fail→pass | 20,707 | 11,894 | -43% | 1 | 1 | 0% | 2,891 | 3,287 | +14% | 0 | 0 | — |
case-19 | fail→pass | 19,778 | 12,641 | -36% | 1 | 1 | 0% | 2,809 | 4,204 | +50% | 0 | 0 | — |
case-20 | pass→pass | 11,499 | 8,390 | -27% | 1 | 1 | 0% | 1,107 | 3,392 | +206% | 0 | 0 | — |
case-21 | pass→pass | 10,928 | 6,916 | -37% | 1 | 1 | 0% | 1,001 | 3,105 | +210% | 0 | 0 | — |
case-22 | pass→pass | 27,217 | 20,336 | -25% | 1 | 1 | 0% | 3,553 | 5,298 | +49% | 0 | 0 | — |
DecimalAI ran this skill against gemini-3.6-flash twice over the same eval suite — once with the skill loaded and once without — and compared the two runs case by case. 22 cases were attempted. The headline lift of +27 percentage points is the difference between those two pass rates over the 22 comparable cases.
Without the skill loaded, the model failed this case. With it loaded, the same prompt on the same model passed. This is one improved case from the latest verified run; every case, including any that regressed, is in the table above.
Other measured skills in the registry, with their headline benchmark lift.