From flex-workflow
하드코딩된 텍스트를 i18n 번역 키로 자동 변환합니다. 컴포넌트의 하드코딩된 텍스트를 식별하고 ko/en 번역 파일을 자동 업데이트합니다.
How this agent operates — its isolation, permissions, and tool access model
Agent reference
flex-workflow:agents/i18n-convertinheritThe summary Claude sees when deciding whether to delegate to this agent
This agent automates the conversion of hardcoded text to i18n translation keys, ensuring proper multilingual support across applications. When components have hardcoded text like `t('다운로드가 완료됐어요.')`, this subAgent: 1. Identifies all hardcoded text patterns 2. Determines appropriate translation key structures 3. Updates both Korean and English translation files 4. Updates component code to use t...This agent automates the conversion of hardcoded text to i18n translation keys, ensuring proper multilingual support across applications.
When components have hardcoded text like t('다운로드가 완료됐어요.'), this subAgent:
web-applications/
├── remotes-goal/
│ └── locales/
│ ├── ko/translation.json
│ └── en/translation.json
├── remotes-evaluation/
│ └── locales/
│ ├── ko/translation.json
│ └── en/translation.json
├── remotes-review/
│ └── locales/
│ ├── ko/translation.json
│ └── en/translation.json
├── remotes-people/
│ └── locales/
│ ├── ko/translation.json
│ └── en/translation.json
└── remotes-user-profile/
└── locales/
├── ko/translation.json
└── en/translation.json
{domain}.{feature}.{context}.{key}
Examples:
goal.manage_goal.excel.download.successevaluation.form.validation.requiredreview.comment.action.submitFor commonly used text across the application:
global.{key}
Examples:
global.재시도 (Retry)global.다운로드 (Download)global.취소 (Cancel)global.확인 (Confirm)global.저장 (Save)For text used across multiple features within a domain:
{domain}.common.{key}
Examples:
goal.common.save_successevaluation.common.loadingIdentify hardcoded text in components:
# Search for hardcoded text in t() function
grep -r "t\(['\"]" web-applications/remotes-goal/src/ -n
# Common patterns to find:
# - t('하드코딩된 텍스트')
# - t("hardcoded text")
# - <Button>{t('텍스트')}</Button>
# - toast.success(t('메시지'))
Target patterns:
For each hardcoded text:
Determine domain:
web-applications/remotes-goal/src/pages/ManageGoal.tsx → domain: goalDetermine feature:
.../pages/ManageGoal/ → feature: manage_goalDetermine context:
excel.downloadCheck for existing keys:
# Search in translation file
grep -i "다운로드" web-applications/remotes-goal/locales/ko/translation.json
# Check for global keys
grep "global\\.재시도" web-applications/remotes-goal/locales/ko/translation.json
Propose translation key:
goal.manage_goal.excel.download.successglobal.재시도// Before
{
"goal.manage_goal.excel.download.error": "요청이 실패했어요."
}
// After (alphabetically ordered)
{
"goal.manage_goal.excel.download.error": "요청이 실패했어요.",
"goal.manage_goal.excel.download.success": "다운로드가 완료됐어요."
}
Important:
// Before
{
"goal.manage_goal.excel.download.error": "The request failed."
}
// After
{
"goal.manage_goal.excel.download.error": "The request failed.",
"goal.manage_goal.excel.download.success": "Download completed."
}
// Before
toast.success(t("다운로드가 완료됐어요."));
toast.error(t("요청이 실패했어요."));
// After
toast.success(t("goal.manage_goal.excel.download.success"));
toast.error(t("goal.manage_goal.excel.download.error"));
// Before
<Button>{t("재시도")}</Button>
<Button>{t("다운로드")}</Button>
// After
<Button>{t("global.재시도")}</Button>
<Button>{t("global.다운로드")}</Button>
// Before
const schema = z.object({
name: z.string().min(1, t("이름을 입력해주세요"))
});
// After
const schema = z.object({
name: z.string().min(1, t("goal.form.validation.name_required"))
});
After making changes, validate:
# Type check
yarn turbo run type-check --filter=@flex-apps/remotes-goal
# Lint check
yarn turbo run lint --filter=@flex-apps/remotes-goal
Validation checklist:
goal.manage_goal.excel.download.success
global.재시도
evaluation.form.validation.required
review.common.save_success
goal.다운로드완료 // Don't mix Korean in keys (except global.* pattern)
DownloadSuccess // Use lowercase with underscores
goal.goal.success // Don't repeat domain
very.long.nested.key.structure.that.is.hard.to.read // Too deep
IMPORTANT: Use single braces {variable} only
This project uses single braces for variable interpolation. NEVER use double braces {{variable}}.
// ko/translation.json
{
"people.manage_people.count": "총 {count}명",
"people.setting.max_length": "{max}자 이내로 입력하세요.",
"people.template.year_month": "{year}년 {month}개월"
}
// en/translation.json
{
"people.manage_people.count": "Total {count}",
"people.setting.max_length": "Please enter up to {max} characters.",
"people.template.year_month": "{year} year {month} month"
}
{
"people.manage_people.count": "총 {{count}}명",
"people.setting.max_length": "{{max}}자 이내로 입력하세요."
}
Examples:
Examples:
Translation files can be large (3000+ lines). When editing:
Read specific sections:
# Read lines around a specific key
grep -A 5 -B 5 "key_name" locales/ko/translation.json
Use Edit tool carefully:
old_string is unique and exactTest after changes:
Always update both files: Korean and English translations must be in sync
Maintain alphabetical order: Makes it easier to find and manage keys
Avoid nested t() calls: Don't use t(t('key'))
Check for duplicates: Search existing keys before creating new ones
Use consistent naming: Follow the domain.feature.context.key pattern
Validate thoroughly: Run type-check and lint after changes
Test in browser: Verify translations display correctly
조건 분기 시 반드시 trans() 사용: 삼항 연산자, 변수 할당 등 조건식에서 번역 키를 사용할 때는 반드시 trans() 함수로 감싸야 한다. <Translation> 컴포넌트의 tKey에 조건식을 직접 넘기면 i18n 추출 도구가 키를 정적으로 인식하지 못해 번역이 누락된다.
// ❌ BAD — 추출 도구가 키를 인식하지 못함
<Translation tKey={isActive ? 'status.active' : 'status.inactive'} />
const label = isNew ? 'action.create' : 'action.edit';
<Translation tKey={label} />
// ✅ GOOD — trans()로 감싸서 추출 가능
{isActive ? trans('status.active') : trans('status.inactive')}
const label = isNew ? trans('action.create') : trans('action.edit');
For large-scale conversion:
This approach is more efficient than converting one text at a time.
Expert in strict POSIX sh scripting for portable Unix-like systems. Delegate for shell scripts compatible with dash, ash, sh, bash --posix, featuring safe argument parsing, error handling, and cross-platform ops.
Elite code reviewer for modern AI-powered code analysis, security vulnerability detection, performance optimization, and production reliability. Masters static analysis tools and security scanning.
Analyzes code comments for accuracy against actual code, completeness, and long-term maintainability. Delegated for post-doc verification, pre-PR comment sweeps, and detecting comment rot.
npx claudepluginhub flex-hyuntae/claude-plugins --plugin flex-workflow