i18n — independently scanned and version-tracked by SaferSkills.
SaferSkills independently audited i18n (Agent Skill) and scored it 92/100 (green). The audit ran 55 deterministic rules across Security, Supply Chain, Maintenance, Transparency, and Community; it found 0 high-severity and 2 lower-severity findings. The full rule-by-rule trace and per-finding evidence are below. Free, methodology-open.
Findings & checks · 2 flagged
The text {match} tells the agent to skip the normal "ask the user first" gate. Used adversarially it removes the human-in-the-loop check before destructive or sensitive actions, turning a normally-gated agent into a fire-and-forget executor.
The text {match} tells the agent to skip the normal "ask the user first" gate. Used adversarially it removes the human-in-the-loop check before destructive or sensitive actions, turning a normally-gated agent into a fire-and-forget executor.
Every scanned point with the score it earned and what moved between them.
First recorded scan — no prior version to compare against.
The primary manifest — the file an agent reads to learn what this artifact does.
You are in AUTONOMOUS MODE. Do NOT ask questions. Execute the full pipeline below without pausing for user input. Make reasonable decisions using sensible defaults.
PURPOSE: Set up complete internationalization (i18n) for the current project. Auto-detect the framework, scan for all hardcoded user-facing strings, extract them to locale files, install and configure the appropriate i18n library, and handle pluralization, interpolation, date/number formatting, and RTL layout support.
INPUT: $ARGUMENTS
The user may specify:
If no arguments, set up English as the base locale with extraction of all hardcoded strings.
============================================================ PHASE 1 -- FRAMEWORK AND I18N LIBRARY DETECTION ============================================================
Detect the framework and determine the appropriate i18n library:
| Indicator | Framework | I18n Library |
|---|---|---|
| pubspec.yaml | Flutter | flutter_localizations + intl / easy_localization |
| next.config.* with i18n or package.json with "next" | Next.js | next-intl or next-i18next |
| package.json with "react" (no next) | React | react-intl (FormatJS) or react-i18next |
| package.json with "vue" | Vue | vue-i18n |
| package.json with "@angular/core" | Angular | @angular/localize or ngx-translate |
| package.json with "svelte" | Svelte | svelte-i18n |
| Podfile or *.xcodeproj | iOS (Swift) | NSLocalizedString + Localizable.strings |
| build.gradle with android | Android (Kotlin) | strings.xml resources |
Check for existing i18n setup:
If an i18n library is already configured, extend it rather than replacing it.
Record: FRAMEWORK, I18N_LIBRARY, LOCALE_DIR, BASE_LOCALE, TARGET_LOCALES
============================================================ PHASE 2 -- STRING EXTRACTION SCAN ============================================================
Scan the entire source tree for hardcoded user-facing strings.
Step 2.1 -- Identify User-Facing Strings
Search for strings that are displayed to users:
placeholder, title, aria-label, alt text, tooltip, snackbar, toast, dialog content
For each string found, record:
Step 2.2 -- Exclude Non-User-Facing Strings
Do NOT extract:
Step 2.3 -- Generate Translation Key Map
For each extracted string, generate a namespaced translation key:
screen.section.elementprofile.actions.saveitems.empty.titlecommon.dialog.confirmDeleteitems.selectedCount (with interpolation)Group keys by screen/feature for maintainability. Use a common namespace for strings reused across screens (OK, Cancel, Save, Delete, etc.).
Produce the key map:
| Key | English Value | Context | Interpolation | File |
|---|
============================================================ PHASE 3 -- LOCALE FILE GENERATION ============================================================
Step 3.1 -- Create Base Locale File
Generate the locale file in the format appropriate for the detected library:
JSON format (react-intl, next-intl, vue-i18n, svelte-i18n): Create src/locales/en.json or messages/en.json:
{
"common": {
"actions": {
"save": "Save",
"cancel": "Cancel",
"delete": "Delete"
}
},
"profile": {
"title": "My Profile",
"actions": {
"save": "Save Changes"
}
}
}ARB format (Flutter): Create lib/l10n/app_en.arb:
{
"@@locale": "en",
"commonSave": "Save",
"@commonSave": { "description": "Save action button" },
"itemCount": "{count, plural, =0{No items} =1{1 item} other{{count} items}}",
"@itemCount": { "description": "Item count with pluralization", "placeholders": { "count": { "type": "int" } } }
}Localizable.strings (iOS): Create en.lproj/Localizable.strings.
strings.xml (Android): Create res/values/strings.xml.
Step 3.2 -- Handle Interpolation
Convert strings with dynamic values to use the library's interpolation syntax:
{count} items or ICU format {count, plural, one {# item} other {# items}}{count} items{count} items or @:common.save{count, plural, =0{No items} =1{1 item} other{{count} items}}{{count}} items with count optionStep 3.3 -- Handle Pluralization
Identify strings that represent countable items and apply plural rules:
Use ICU MessageFormat where the library supports it.
Step 3.4 -- Generate Target Locale Files
For each target locale beyond the base:
[TRANSLATE] prefix.Example: src/locales/es.json with "commonSave": "[TRANSLATE] Save".
Commit: "feat(i18n): generate locale files with extracted strings"
============================================================ PHASE 4 -- I18N LIBRARY SETUP ============================================================
Step 4.1 -- Install Dependencies
Install the i18n library and any required dependencies:
npm install react-intlnpm install next-intlnpm install vue-i18nng add @angular/localizeflutter_localizations, intl to pubspec.yamlnpm install i18next react-i18nextUse the project's package manager (npm/yarn/pnpm based on lockfile).
Step 4.2 -- Configure Provider/Plugin
Set up the i18n provider at the application root:
React/Next.js (react-intl):
src/i18n/config.ts with locale detection and message loading<IntlProvider>Next.js (next-intl):
next.config.* with i18n locale configurationNextIntlClientProvider in root layoutVue:
src/i18n/index.ts with createI18n configurationFlutter:
localizationsDelegates and supportedLocales to MaterialAppflutter gen-l10nl10n.yaml configuration fileAngular:
angular.json with i18n localesStep 4.3 -- Configure Date and Number Formatting
Set up locale-aware formatting:
Step 4.4 -- RTL Layout Support (if Arabic, Hebrew, or Urdu in target locales)
If any RTL locale is requested:
[dir="rtl"] selectors or use logical properties (margin-inline-start instead of margin-left)Directionality or use TextDirection.rtldir attribute on <html> based on localestart/end instead of left/rightCommit: "feat(i18n): configure i18n library with locale detection and formatting"
============================================================ PHASE 5 -- STRING REPLACEMENT ============================================================
Replace all hardcoded strings in the codebase with translation function calls:
Step 5.1 -- Replace Strings
For each extracted string, replace the hardcoded value with the i18n function:
<FormattedMessage id="key" /> or intl.formatMessage({ id: 'key' })t('key') or <NextIntlClientProvider>{{ $t('key') }} or t('key') in setupAppLocalizations.of(context)!.keyNamet('key') or <Trans i18nKey="key" />{{ 'key' | translate }} or $localizeStep 5.2 -- Handle Interpolated Strings
Replace strings with dynamic values:
// Before
`Welcome, ${user.name}!`
// After (react-intl)
intl.formatMessage({ id: 'greeting.welcome' }, { name: user.name })
// After (Flutter)
AppLocalizations.of(context)!.greetingWelcome(user.name)Step 5.3 -- Handle Conditional Strings
Replace pluralized or conditional strings:
// Before
`${count} item${count !== 1 ? 's' : ''}`
// After (react-intl with ICU)
intl.formatMessage({ id: 'items.count' }, { count })
// In locale file: "{count, plural, one {# item} other {# items}}"Commit per screen or feature module:
============================================================ PHASE 6 -- VERIFICATION ============================================================
Step 6.1 -- Static Analysis
Run the appropriate linter/analyzer:
flutter analyze and flutter gen-l10ntsc --noEmitFix all errors introduced by the i18n integration.
Step 6.2 -- String Coverage Audit
Re-scan the codebase for any remaining hardcoded user-facing strings:
Step 6.3 -- Locale File Validation
Verify locale files:
============================================================ SELF-HEALING VALIDATION (max 3 iterations) ============================================================
After completing fixes, re-validate:
STOP when:
IF STILL FAILING after 3 iterations:
============================================================ OUTPUT ============================================================
## I18n Setup Complete
### Framework: [detected]
### I18n Library: [library]
### Base Locale: [locale]
### Target Locales: [list]
### Files Created/Modified
| File | Purpose |
|------|---------|
| [path] | [description] |
### String Extraction Summary
| Category | Count |
|----------|-------|
| Total strings found | N |
| Strings extracted | N |
| Strings skipped (non-user-facing) | N |
| Unique translation keys | N |
| Common/shared keys | N |
| Keys with interpolation | N |
| Keys with pluralization | N |
### Locale File Status
| Locale | Keys | Translated | Needs Translation |
|--------|------|-----------|-------------------|
| en | N | N (base) | 0 |
| es | N | N | N |
### Coverage
- Screens processed: N/N
- Strings replaced: N/N (N%)
- Remaining hardcoded: N (with rationale)============================================================ NEXT STEPS ============================================================
After i18n setup:
[TRANSLATE]-prefixed values in each target locale file./ux to audit UX quality including localized content."/responsive to verify layouts do not break with longer translated strings."/design-system to ensure text styles accommodate variable-length translations."============================================================ SELF-EVOLUTION TELEMETRY ============================================================
After producing output, record execution metadata for the /evolve pipeline.
Check if a project memory directory exists:
~/.claude/projects/skill-telemetry.md in that memory directoryEntry format:
### /i18n — {{YYYY-MM-DD}}
- Outcome: {{SUCCESS | PARTIAL | FAILED}}
- Self-healed: {{yes — what was healed | no}}
- Iterations used: {{N}} / {{N max}}
- Bottleneck: {{phase that struggled or "none"}}
- Suggestion: {{one-line improvement idea for /evolve, or "none"}}Only log if the memory directory exists. Skip silently if not found. Keep entries concise — /evolve will parse these for skill improvement signals.
============================================================ DO NOT ============================================================
~30 seconds. Free. No account. Every finding cites a rule and a line of evidence.