310 lines
No EOL
10 KiB
Text
310 lines
No EOL
10 KiB
Text
#!/usr/bin/env nu
|
|
# i18n Tools for AuroraFrame MCP Server
|
|
#
|
|
# Provides AI-powered internationalization tools:
|
|
# - Generate translations from source locale to target locale
|
|
# - Validate translation consistency and completeness
|
|
# - Extract translatable strings from templates
|
|
# - Suggest locale improvements and optimizations
|
|
|
|
use mcp-server.nu call_openai_api
|
|
|
|
# Generate FTL translations using AI
|
|
export def generate_translations_tool [args: record, config: record, debug: bool] {
|
|
let source_locale = $args.source_locale
|
|
let target_locale = $args.target_locale
|
|
let source_messages = $args.source_messages
|
|
let context = ($args.context? | default {})
|
|
|
|
debug_log $"Generating ($target_locale) translations from ($source_locale)" $debug
|
|
|
|
let system_prompt = (build_translation_system_prompt $source_locale $target_locale)
|
|
let user_prompt = (build_translation_user_prompt $source_messages $context)
|
|
|
|
let messages = [
|
|
{ role: "system", content: $system_prompt }
|
|
{ role: "user", content: $user_prompt }
|
|
]
|
|
|
|
let api_response = (call_openai_api $messages $config 0.3)
|
|
|
|
if "error" in $api_response {
|
|
return $api_response
|
|
}
|
|
|
|
{
|
|
content: [
|
|
{
|
|
type: "text"
|
|
text: $"Generated FTL translations for ($target_locale):\n\n```ftl\n($api_response.content)\n```\n\nValidation: AI-generated translations reviewed for cultural appropriateness and technical accuracy."
|
|
}
|
|
]
|
|
}
|
|
}
|
|
|
|
# Validate translation completeness across locales
|
|
export def validate_translations_tool [args: record, config: record, debug: bool] {
|
|
let locales = $args.locales
|
|
let reference_locale = ($args.reference_locale? | default ($locales | first))
|
|
let message_bundles = $args.message_bundles
|
|
|
|
debug_log $"Validating translations across ($locales | length) locales" $debug
|
|
|
|
let system_prompt = $"You are an expert i18n validator and linguist. Analyze the provided translation bundles for:
|
|
|
|
1. **Completeness**: Are all messages translated in all locales?
|
|
2. **Consistency**: Do messages maintain consistent terminology and tone?
|
|
3. **Cultural Appropriateness**: Are translations culturally appropriate for each locale?
|
|
4. **Technical Accuracy**: Are placeholders, pluralization rules, and formatting correct?
|
|
5. **Quality Issues**: Identify potential translation errors or improvements
|
|
|
|
For each issue found, provide:
|
|
- **Severity**: (error, warning, suggestion)
|
|
- **Locale**: Which locale has the issue
|
|
- **Message ID**: The affected message
|
|
- **Issue**: Description of the problem
|
|
- **Recommendation**: How to fix it
|
|
|
|
Provide a detailed analysis with actionable recommendations."
|
|
|
|
let user_prompt = $"Reference locale: ($reference_locale)
|
|
Target locales: ($locales | str join ', ')
|
|
|
|
Translation bundles to validate:
|
|
```json
|
|
($message_bundles | to json)
|
|
```
|
|
|
|
Please provide a comprehensive validation analysis."
|
|
|
|
let messages = [
|
|
{ role: "system", content: $system_prompt }
|
|
{ role: "user", content: $user_prompt }
|
|
]
|
|
|
|
let api_response = (call_openai_api $messages $config 0.2)
|
|
|
|
if "error" in $api_response {
|
|
return $api_response
|
|
}
|
|
|
|
{
|
|
content: [
|
|
{
|
|
type: "text"
|
|
text: $"Translation Validation Results:\n\n($api_response.content)"
|
|
}
|
|
]
|
|
}
|
|
}
|
|
|
|
# Extract translatable strings from templates
|
|
export def extract_strings_tool [args: record, config: record, debug: bool] {
|
|
let template_files = $args.template_files
|
|
let page_context = ($args.page_context? | default {})
|
|
let existing_messages = ($args.existing_messages? | default [])
|
|
|
|
debug_log $"Extracting translatable strings from ($template_files | length) templates" $debug
|
|
|
|
let system_prompt = $"You are an expert i18n string extractor for web templates. Analyze the provided template files and extract all user-facing strings that should be localized.
|
|
|
|
For each translatable string, provide:
|
|
- **suggested_id**: A descriptive message ID (kebab-case)
|
|
- **text**: The original text to translate
|
|
- **context**: Where/how it's used (button, heading, error message, etc.)
|
|
- **description**: Context for translators
|
|
- **parameters**: Any dynamic values (placeholders)
|
|
- **category**: Type of string (ui, content, error, etc.)
|
|
|
|
Focus on:
|
|
- User-visible text (not code or technical strings)
|
|
- Interface elements (buttons, labels, placeholders)
|
|
- Error and success messages
|
|
- Content headings and descriptions
|
|
- Alt text and accessibility labels
|
|
|
|
Avoid:
|
|
- Code comments
|
|
- CSS class names
|
|
- Technical identifiers
|
|
- Already translated strings (check against existing messages)
|
|
|
|
Return a structured list of translatable strings with suggested Fluent message IDs."
|
|
|
|
let templates_content = ($template_files | each { |file|
|
|
let content = try { open $file } catch { "" }
|
|
{ file: $file, content: $content }
|
|
})
|
|
|
|
let user_prompt = $"Templates to analyze:
|
|
($templates_content | to json)
|
|
|
|
Existing message IDs (don't duplicate):
|
|
($existing_messages | to json)
|
|
|
|
Page context:
|
|
($page_context | to json)
|
|
|
|
Please extract all translatable strings with suggested Fluent message structure."
|
|
|
|
let messages = [
|
|
{ role: "system", content: $system_prompt }
|
|
{ role: "user", content: $user_prompt }
|
|
]
|
|
|
|
let api_response = (call_openai_api $messages $config 0.4)
|
|
|
|
if "error" in $api_response {
|
|
return $api_response
|
|
}
|
|
|
|
{
|
|
content: [
|
|
{
|
|
type: "text"
|
|
text: $"Extracted Translatable Strings:\n\n($api_response.content)"
|
|
}
|
|
]
|
|
}
|
|
}
|
|
|
|
# Suggest i18n improvements and optimizations
|
|
export def suggest_improvements_tool [args: record, config: record, debug: bool] {
|
|
let locale_structure = $args.locale_structure
|
|
let usage_patterns = ($args.usage_patterns? | default {})
|
|
let performance_metrics = ($args.performance_metrics? | default {})
|
|
|
|
debug_log "Analyzing i18n structure for improvement suggestions" $debug
|
|
|
|
let system_prompt = $"You are an i18n optimization expert specializing in web application internationalization. Analyze the provided locale structure and suggest improvements for:
|
|
|
|
1. **Organization**: Message grouping, namespace structure, file organization
|
|
2. **Performance**: Bundle size optimization, lazy loading opportunities
|
|
3. **Maintainability**: Consistency, naming conventions, documentation
|
|
4. **Scalability**: Structure for adding new locales and features
|
|
5. **Developer Experience**: Tooling suggestions, automation opportunities
|
|
6. **User Experience**: Loading strategies, fallback chains
|
|
|
|
For each suggestion, provide:
|
|
- **Category**: What aspect it improves
|
|
- **Priority**: (high, medium, low)
|
|
- **Implementation**: Specific steps to implement
|
|
- **Benefits**: Expected improvements
|
|
- **Effort**: Estimated implementation complexity
|
|
|
|
Focus on practical, actionable improvements that provide clear benefits."
|
|
|
|
let user_prompt = $"Current i18n structure:
|
|
```json
|
|
($locale_structure | to json)
|
|
```
|
|
|
|
Usage patterns:
|
|
```json
|
|
($usage_patterns | to json)
|
|
```
|
|
|
|
Performance metrics:
|
|
```json
|
|
($performance_metrics | to json)
|
|
```
|
|
|
|
Please provide specific, actionable improvement suggestions for this i18n setup."
|
|
|
|
let messages = [
|
|
{ role: "system", content: $system_prompt }
|
|
{ role: "user", content: $user_prompt }
|
|
]
|
|
|
|
let api_response = (call_openai_api $messages $config 0.5)
|
|
|
|
if "error" in $api_response {
|
|
return $api_response
|
|
}
|
|
|
|
{
|
|
content: [
|
|
{
|
|
type: "text"
|
|
text: $"i18n Improvement Suggestions:\n\n($api_response.content)"
|
|
}
|
|
]
|
|
}
|
|
}
|
|
|
|
# Build translation system prompt
|
|
def build_translation_system_prompt [source_locale: string, target_locale: string] {
|
|
let source_lang = (locale_to_language $source_locale)
|
|
let target_lang = (locale_to_language $target_locale)
|
|
|
|
$"You are an expert translator specializing in software localization from ($source_lang) to ($target_lang).
|
|
|
|
Your task is to translate Fluent Translation List (FTL) messages while maintaining:
|
|
|
|
1. **Technical Accuracy**: Preserve placeholders, pluralization syntax, and Fluent formatting
|
|
2. **Cultural Appropriateness**: Adapt messages for the target culture and region
|
|
3. **Consistency**: Use consistent terminology throughout
|
|
4. **Natural Language**: Ensure translations sound natural and idiomatic
|
|
5. **Context Preservation**: Maintain the intent and tone of the original
|
|
|
|
FTL Translation Guidelines:
|
|
- Keep message IDs unchanged
|
|
- Preserve placeholders exactly: { $variable }
|
|
- Maintain plural rules: { $count -> [one] ... *[other] ... }
|
|
- Keep term references: { -brand-name }
|
|
- Preserve attributes and structure
|
|
- Add comments for cultural adaptations if needed
|
|
|
|
Output Format: Return valid FTL syntax with proper indentation and structure.
|
|
|
|
Cultural Context:
|
|
- Source: ($source_locale) - ($source_lang) cultural context
|
|
- Target: ($target_locale) - ($target_lang) cultural context
|
|
|
|
Ensure all translations are appropriate for the target locale's cultural norms, business practices, and linguistic conventions."
|
|
}
|
|
|
|
# Build translation user prompt
|
|
def build_translation_user_prompt [source_messages: any, context: record] {
|
|
let context_info = if ($context | columns | length) > 0 {
|
|
$"\n\nAdditional Context:\n($context | to json)"
|
|
} else {
|
|
""
|
|
}
|
|
|
|
$"Please translate the following FTL messages:
|
|
|
|
```ftl
|
|
($source_messages)
|
|
```($context_info)
|
|
|
|
Requirements:
|
|
1. Maintain all FTL syntax and formatting
|
|
2. Preserve placeholders and plural rules exactly
|
|
3. Ensure culturally appropriate translations
|
|
4. Keep consistent terminology
|
|
5. Return valid, well-formatted FTL
|
|
|
|
Translation:"
|
|
}
|
|
|
|
# Utility functions
|
|
def locale_to_language [locale: string] {
|
|
match $locale {
|
|
"en-US" => "English (US)"
|
|
"es-ES" => "Spanish (Spain)"
|
|
"fr-FR" => "French (France)"
|
|
"de-DE" => "German (Germany)"
|
|
"ja-JP" => "Japanese"
|
|
"zh-CN" => "Chinese (Simplified)"
|
|
"ar-SA" => "Arabic (Saudi Arabia)"
|
|
_ => $locale
|
|
}
|
|
}
|
|
|
|
# Debug helper
|
|
def debug_log [message: string, debug: bool] {
|
|
if $debug {
|
|
print $"🐛 i18n-TOOLS: ($message)"
|
|
}
|
|
} |