cm-autopilot
Easy-to-use conversational CLI (Claude Code style) for non-technical users to spawn parallel AI tasks supervised by a visual web dashboard.
Safe i18n: multi-pass batching, parallel-per-language dispatch, 8 audit gates, HTML integrity. Use for translating or mass-converting hardcoded strings to t() calls.
$ npx -y skills add tody-agent/codymaster --skill cm-safe-i18n --agent claude-codeHow it fires
How this skill gets triggered: by you, by Claude, or both.
/cm-safe-i18nContext preview
The summary Claude sees to decide when to auto-load this skill.
Safe i18n: multi-pass batching, parallel-per-language dispatch, 8 audit gates, HTML integrity. Use for translating or mass-converting hardcoded strings to t() calls.
name: cm-safe-i18n description: "Safe i18n: multi-pass batching, parallel-per-language dispatch, 8 audit gates, HTML integrity. Use for translating or mass-converting hardcoded strings to t() calls."
Mass i18n conversion is the most dangerous code transformation in a frontend monolith. A single-pass conversion of 600+ strings corrupted `app.js` beyond repair while 572 backend tests passed green. Additional incidents include HTML tag corruption, variable shadowing, and placeholder translation errors.
**Core principle:** Every batch of i18n changes MUST pass ALL 8 audit gates before proceeding. No exceptions.
**Violating the letter of this rule is violating the spirit of this rule.**
NO BATCH WITHOUT PASSING ALL 8 AUDIT GATES. NO LANGUAGE FILE WITHOUT KEY PARITY. NO DEPLOY WITHOUT FULL SYNTAX VALIDATION. NO HTML TAG MODIFICATION — TEXT CONTENT ONLY. NO REGEX TO FIX REGEX ERRORS — USE LEXICAL SCANNER.
**ALWAYS** when any of these happen:
**Don't use for:**
digraph i18n_flow {
rankdir=TB;
"0. Pre-flight" [shape=box];
"1. Scan ALL files" [shape=box];
">10 strings?" [shape=diamond];
"Manual add + test" [shape=box];
"2. Plan passes" [shape=box];
"3. Extract batch (max 30)" [shape=box];
"4. 8-Gate Audit" [shape=box, style=filled, fillcolor="#ffffcc"];
"All 8 pass?" [shape=diamond];
"FIX or ROLLBACK" [shape=box, style=filled, fillcolor="#ffcccc"];
"More batches?" [shape=diamond];
"5. Parallel language sync" [shape=box];
"6. Final validation" [shape=box];
"0. Pre-flight" -> "1. Scan ALL files";
"1. Scan ALL files" -> ">10 strings?";
">10 strings?" -> "Manual add + test" [label="no"];
">10 strings?" -> "2. Plan passes" [label="yes"];
"2. Plan passes" -> "3. Extract batch (max 30)";
"3. Extract batch (max 30)" -> "4. 8-Gate Audit";
"4. 8-Gate Audit" -> "All 8 pass?";
"All 8 pass?" -> "FIX or ROLLBACK" [label="no"];
"FIX or ROLLBACK" -> "4. 8-Gate Audit";
"All 8 pass?" -> "More batches?" [label="yes"];
"More batches?" -> "3. Extract batch (max 30)" [label="yes"];
"More batches?" -> "5. Parallel language sync" [label="no"];
"5. Parallel language sync" -> "6. Final validation";
}---
Before ANY i18n work:
# NEVER work on main git checkout -b i18n/$(date +%Y%m%d)-target-description # Verify baseline is clean node -c public/static/app.js npm run test:gate
If either fails, DO NOT PROCEED. Fix the baseline first.
---
> [!CAUTION] > **Lesson #11:** `import-adapters.js` and `import-engine.js` had 60+ hardcoded strings that were initially missed because only `app.js` was scanned.
Scan EVERY file that produces user-visible UI text:
# Scan ALL .js files for Vietnamese strings node scripts/i18n-lint.js # Also check non-app.js files grep -rnP '[àáạảãâầấậẩẫăằắặẳẵ]' public/static/*.js --include="*.js" | grep -v "\.backup" | grep -v "i18n"
Group strings by **functional domain** — never by file position:
| Pass | Domain | Example Keys | |------|--------|-------------| | 1 | Core UI | `sidebar.*`, `common.*`, `login.*` | | 2 | Primary Feature | `vio.*`, `emp.*`, `scores.*` | | 3 | Config & Settings | `config.*`, `benconf.*` | | 4 | Reports & Export | `report.*`, `export.*` | | 5 | Secondary Files | `import-adapters.js`, `import-engine.js` | | 6 | Edge cases | Tooltips, error messages, dynamic labels |
**Output:** A numbered list of passes with estimated string count per pass per FILE.
---
> [!CAUTION] > **MAX 30 strings per batch. Not 31. Not "about 30". Exactly 30 or fewer.** > The i18n crash happened because 600+ strings were done in one pass.
For each batch:
1. **Identify** up to 30 hardcoded strings in the current pass domain 2. **Generate** namespace-compliant keys: `domain.descriptive_key` 3. **Replace** strings with `t('domain.key')` calls 4. **Add** keys to the **primary** language JSON (usually `vi.json`)
// ✅ CORRECT — backtick template with t() inside
`<div>${t('login.welcome')}</div>`
// ✅ CORRECT — concatenation
'<div>' + t('login.welcome') + '</div>'
// ❌ BUG #1 (FATAL) — single-quote wrapping template expression
'${t("login.welcome")}' // ← THIS DESTROYED APP.JS
// ❌ BUG #4 — mismatched delimiters
t('login.welcome`) // ← quote/backtick mismatch
t(`login.welcome') // ← backtick/quote mismatch// ❌ BROKEN — single-quote ternary result with template expression
${ canDo ? '...${t('key')}...' : '' }
// ✅ CORRECT — backtick ternary result
${ canDo ? `...${t('key')}...` : '' }// ❌ BROKEN — shadows global t() translation function
items.map((t, i) => `<div>${t('key')}</div>`)
// ✅ CORRECT — use different variable name
items.map((item, i) => `<div>${t('key')}</div>`)// ❌ NEVER modify content inside HTML tags
`< div class="card" >` // spaces inside tags = broken rendering
`style = "color: red"` // space around = breaks attributes
`<!-- text-- >` // broken comment closers
// ✅ ONLY replace text content between tags
`<div class="card">${t('card.title')}</div>`// ❌ FORBIDDEN — dynamic keys can't be statically validated
t('nav.' + pageName)
t(`messages.${type}`)
// ✅ REQ"I can't write code. But in 6 months, I shipped 12 real products using AI. CodyMaster is everything I learned — so you don't have to repeat my mistakes." — Tody Le, Head of Product, Creator of CodyMaster 50+ skills. One install.
Repo: tody-agent/codymaster
Easy-to-use conversational CLI (Claude Code style) for non-technical users to spawn parallel AI tasks supervised by a visual web dashboard.
Strategic analysis gate for existing products — multi-dimensional evaluation (tech, product, design, business) using Design Thinking + 9 Windows (TRIZ) +…
Fallback local Playwright daemon for real-browser visual QA / screenshots / smoke. Use ONLY when the host platform has no native browser mode — prefer the host…
Code hygiene gate — detect and eliminate dead code, duplicates, naming mess, and code smells. TRIZ-powered. Run after features, before PRs, during debt sprints.
Full review lifecycle — request reviews, handle feedback with technical rigor, and complete branch integration. Use when completing tasks, receiving feedback,…
Unified code intelligence — routes to Skeleton Index, CodeGraph, Architecture Diagram, or Smart Context Builder based on task shape. Loads deep refs on demand.