feat(il): P11 i18n — full 10-locale set (es/fr/ja/ko/pt/ru/zh-CN/zh-TW)#452
Conversation
Cut feature/i18n-locales off next (P0-P10 merged). Scope = parity-charter §3.9 — add the 8 missing locales (es/fr/ja/ko/pt/ru/zh-CN/zh-TW) matching en's keyset exactly; widen SupportedLocale/SUPPORTED_LOCALES/messages/toSupportedLocale to 10; generalise the en↔de key-parity test to all-10-against-en. Translate from our en.ts (claudian JSONs = wording reference). Largely mechanical + additive. Autonomous; SPLIT the locale impl into 2-3-locale chunks (timeout lesson). Next: /spec:requirements. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
12 REQ-IL + 9 NFR-IL (concise — mechanical phase). 10 locales registered/selectable; all-10 leaf-keyset parity against en (generalise the en↔de test); toSupportedLocale narrows the 10 incl. zh-CN/zh-TW (unknown→en, fallback en); placeholder multiset preserved (CLAR-IL-001 → dedicated test); forbidden-terms guard green for all locales; en/de byte-identical; missing key → en fallback no crash; build succeeds (note bundle delta). Keyset = our en.ts; claudian JSONs = wording reference only. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Additive 2→10 widening: SupportedLocale union + SUPPORTED_LOCALES + messages registration to all 10; toSupportedLocale body UNCHANGED (membership test auto-extends, covers zh-CN/zh-TW, unknown→en). 8 new locales/<code>.ts mirror de.ts (en's exact keyset, placeholders preserved, claudian wording). All-10 key-parity test (snapshot-at-load) + placeholder-multiset test + forbidden-terms-all-10. en/de byte-identical; fallback→en. EC-IL-001..010. Chunks: es/fr/pt · ja/ko · zh-CN/zh-TW/ru · wiring+tests. No new ADR/port. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
T-IL-001 baseline+guard-verify (NO new key/port — additive string-union widen); locale-file chunks es/fr/pt · ja/ko · zh-CN/zh-TW/ru; wiring widen index.ts (4 sites); test tasks all-10 key-parity (snapshot-at-load) + placeholder-multiset + forbidden-terms- all-10 + narrowing/fallback; gate (full verify + bundle delta + draft PR). Native-speaker polish deferred (non-gating). Orchestrator note: land the 8 locale FILES before the index widen so typecheck stays green (importing absent files would break it), then wiring+tests, then gate. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Add Spanish (es) translation of en.ts under src/ui/i18n/locales/es.ts —
exact en keyset (226 leaves, 0 missing / 0 extra), every leaf an idiomatic
Spanish string, every {token} interpolation placeholder preserved verbatim.
Mirrors de.ts file shape; index.ts wiring deferred to T-IL-002.
SPEC-IL-002, SPEC-IL-003, REQ-IL-002, REQ-IL-007, REQ-IL-008. Language: Spanish.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Add French (fr) translation of en.ts under src/ui/i18n/locales/fr.ts —
exact en keyset (226 leaves, 0 missing / 0 extra), every leaf an idiomatic
French string, every {token} interpolation placeholder preserved verbatim.
Mirrors de.ts file shape; index.ts wiring deferred to T-IL-002.
SPEC-IL-002, SPEC-IL-003, REQ-IL-002, REQ-IL-007, REQ-IL-008. Language: French.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Add Portuguese (pt) translation of en.ts under src/ui/i18n/locales/pt.ts —
exact en keyset (226 leaves, 0 missing / 0 extra), every leaf an idiomatic
Portuguese string, every {token} interpolation placeholder preserved verbatim.
Mirrors de.ts file shape; index.ts wiring deferred to T-IL-002.
SPEC-IL-002, SPEC-IL-003, REQ-IL-002, REQ-IL-007, REQ-IL-008. Language: Portuguese.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Create specs/i18n-locales/implementation-log.md with the Romance-chunk entry (es/fr/pt): 226-leaf parity vs en.ts, 0 placeholder mismatches, 0 forbidden-term offenders, claudian wording reference, per-locale commit SHAs. SPEC-IL-003, REQ-IL-002. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Add the Japanese (ja) locale catalogue: a full `export default {…} as const`
mirror of `en.ts` with all 226 leaves translated. Placeholders preserved
verbatim per key; brand tokens (Specorator/Claude/Codex/Opencode/MCP) carried
through; "API キー" confined to the whitelisted settings./provider secret keys.
Trace: SPEC-IL-002, REQ-IL-002.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Add the Korean (ko) locale catalogue: a full `export default {…} as const`
mirror of `en.ts` with all 226 leaves translated. Placeholders preserved
verbatim per key; brand tokens (Specorator/Claude/Codex/Opencode/MCP) carried
through; "API 키" confined to the whitelisted settings./provider secret keys.
Trace: SPEC-IL-002, REQ-IL-002.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Append the T-IL-008 CJK section to the implementation log: per-locale commit SHAs, 226-leaf parity, placeholder/forbidden-terms verification, claudian wording reference. Trace: SPEC-IL-002, REQ-IL-002. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Full Simplified Chinese (zh-Hans) translation of en.ts: 226-leaf keyset
exact match, every {placeholder} preserved verbatim, brand tokens and the
whitelisted "API key" strings carried per en.
Implements SPEC-IL-002. Traces REQ-IL-002.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Full Traditional Chinese (zh-Hant) translation of en.ts: 226-leaf keyset
exact match, every {placeholder} preserved verbatim, brand tokens and the
whitelisted "API key" strings carried per en. Diverges from zh-CN where
Simplified/Traditional and Taiwan UI idiom differ.
Implements SPEC-IL-002. Traces REQ-IL-002.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Full Russian translation of en.ts: 226-leaf keyset exact match, every
{placeholder} preserved verbatim, brand tokens and the whitelisted
"API key" strings carried per en.
Implements SPEC-IL-002. Traces REQ-IL-002.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Records the three CJK + Cyrillic catalogue commits with keyset-parity, placeholder, forbidden-terms, and zh-CN/zh-TW divergence evidence. Implements SPEC-IL-002. Traces REQ-IL-002. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Record the en.ts keyset (226 leaves), the placeholder inventory (35 interpolating leaves, 17 distinct tokens), the all-9-non-en parity + placeholder + forbidden-terms baseline (0 missing/extra/mismatch/offenders), the claudian WORDING-only reference + the deferred native-speaker-polish leg (T-IL-012, P12), the two-locale bundle-baseline note (delta recorded by T-IL-013), and the guard verdict: NO new InjectionKey/port, NO guard-relax, en/de/manifest untouched. No src/ change. Implements TEST-IL targets. SPEC-IL-003/004/005/006/007/009 §1-7. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Widen the four declaration sites in src/ui/i18n/index.ts from 2 → 10:
SupportedLocale union ('en'|'de'|'es'|'fr'|'ja'|'ko'|'pt'|'ru'|'zh-CN'|
'zh-TW'); SUPPORTED_LOCALES array (en first, de second, alphabetical, zh-*
last); the eight catalogue imports; the ten-entry messages map (quoted
'zh-CN'/'zh-TW' keys), keeping the `as unknown as Record<SupportedLocale,
MessageSchema>` cast and fallbackLocale: 'en'. toSupportedLocale body
byte-unchanged (narrows via SUPPORTED_LOCALES → auto-extends to all ten incl.
the regional tags; unknown → 'en'); the stale doc-comment example fr → it.
No new function/port/InjectionKey/composable; no obsidian/node:* import.
Implements SPEC-IL-001, SPEC-IL-002. REQ-IL-001/005/006, NFR-IL-005.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…ests
Generalise tests/ui/i18n/index.test.ts from en↔de to all ten locales — these
three test legs are co-located in the one shared file per SPEC-IL spec:
- T-IL-003 (TEST-IL-003/004, SPEC-IL-004): replace the en↔de key-parity block
with a table-driven all-ten-against-en assertion over
SUPPORTED_LOCALES.filter(c => c !== 'en'); snapshot each locale's leafKeys at
module load (dodging the i18nMerge mutation); assert missing/extra both [] with
a locale+keys failure message.
- T-IL-004 (TEST-IL-008, SPEC-IL-005): placeholder-multiset test — per non-en
locale, per en leaf key, value.match(/\{[^}]+\}/g) multiset === en's; failure
names locale+key+diff; no-placeholder leaf passes trivially.
- T-IL-006 (TEST-IL-001/002/005/006/011, SPEC-IL-001/002/008): registration
completeness (length 10 + SUPPORTED_LOCALES set deep-equals the messages-map
key set + every entry non-empty), per-catalogue import shape, narrows-the-ten
round-trip (incl. zh-CN/zh-TW), unknown→en (it/zh/''/EN/de-DE), and the
synthetic missing-key fallback (en string, no throw).
The existing i18nMerge/flatToNested + agent.empty.placeholder tests are
unchanged. 51 tests green. REQ-IL-001..006/008/011, NFR-IL-001/002/004,
EC-IL-001..004/006..009.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Generalise tests/i18n/forbidden-terms.test.ts from the en-only scan to a table-driven scan over all ten catalogues (SUPPORTED_LOCALES). Reuse the unchanged FORBIDDEN (/\bAPI key\b/i, /\bsubprocess\b/i, /\bSDK\b/i), flatten, and isAllowed helpers; ALLOWED_PREFIXES is byte-unchanged from P9. Each locale asserts zero offenders outside the allow-list with a locale+key+value+pattern failure message; a note records that any ALLOWED_PREFIXES extension is a defect-escalation (EC-IL-005), not a default. 10 locales scanned, 0 offenders. Implements TEST-IL-009. SPEC-IL-006, REQ-IL-009, NFR-IL-003, EC-IL-005. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Append Layer A implementation-log entries for T-IL-001 (baseline + guard verdict), T-IL-002 (index widen), T-IL-003/004/006 (all-ten parity + placeholder + registration/narrowing/fallback), T-IL-005 (forbidden-terms all-ten) with their real commit SHAs; mark the prior catalogue entries' "all-ten parity test does not exist yet" deviation note superseded. Tick the T-IL-001..006 DoD boxes (the two-locale bundle baseline deferred to T-IL-013; the RED-first boxes annotated GREEN-after-catalogues since T-IL-007..009 landed first). Update workflow-state.md artifacts (implementation-log.md / test-plan.md in-progress) + a Stage 7 hand-off note: vue-tsc 0, lint 0 errors, 61 i18n tests green; gate chunk T-IL-010..013 remain. SPEC-IL-001..009 §wiring+tests chunk. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
REVIEW-IL-001 verdict APPROVE (0 blockers). All-10 automated gates green (key-parity + placeholder-multiset + forbidden-terms-all-10 + narrowing/fallback, 61 tests). Additivity confirmed (en/de/manifest byte-identical; index widen = the 4 specced sites; toSupportedLocale body unchanged). Spot-checked fr/zh-CN genuinely translated, brand tokens intact, zh-CN≠zh-TW. permission.plan CJK-badge rendering non-blocking → native-polish (T-IL-012, deferred). TRACE-IL-001 all 12 REQ-IL chained. Native-speaker polish pending for the final epic gate. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: e06984ccce
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| export const SUPPORTED_LOCALES: SupportedLocale[] = [ | ||
| 'en', | ||
| 'de', | ||
| 'es', | ||
| 'fr', |
There was a problem hiding this comment.
Wire new locales into the settings selector
This commit registers eight additional locales in SUPPORTED_LOCALES, but users still cannot choose them from the plugin UI because the locale dropdown is still driven by the hard-coded settingsSchema options (en/de only in src/core/core-settings.ts) and rendered directly from those options in SpecoratorSettingTab.addControl (src/plugin/settings.ts). In practice, the new locales are only reachable by manually editing persisted settings, so the feature is incomplete for normal users.
Useful? React with 👍 / 👎.
P11 — i18n full locale set (claudian-reboot)
Adds the 8 missing locales to reach the charter §3.9 ten (de/en/es/fr/ja/ko/pt/ru/zh-CN/zh-TW). Spec:
specs/i18n-locales/(PRD-IL-001, DESIGN-IL-001, SPEC-IL-001..009, no new ADR, TASKS-IL-001 = 13 tasks). Mechanical + additive.Delivered (T-IL-001..011)
src/ui/i18n/locales/{es,fr,ja,ko,pt,ru,zh-CN,zh-TW}.ts— each a full translation ofen.ts, structurally matching en's 226-leaf keyset exactly, placeholders preserved verbatim, brand tokens intact, claudian wording reference. zh-CN ≠ zh-TW (Simplified vs Traditional).SupportedLocale/SUPPORTED_LOCALES/messagesto the 10;toSupportedLocalebody unchanged (auto-extends; narrows the 10 incl.zh-CN/zh-TW, unknown→en, fallback en).Gate (local, green)
vue-tsc0 ·eslint0 · vitest 286 files / 2179 passed (0 errors) (incl. the all-10 parity/placeholder/forbidden-terms gates) ·build+build:web+docs:apiclean ·npm audit --audit-level=highclean. Bundle: pluginmain.js1.91 MB (+~92 KB / gzip +~22 KB for the 8 catalogs); standalone 428 KB. Acceptable for the locale data (app-bundled, not externalized).Parity self-review (Stage 9)
review.mdAPPROVE (0 blockers). All-10 automated gates green (reviewer-confirmed); additivity confirmed (en/de/manifest byte-identical; theindex.tswiden = the 4 specced sites); fr/zh-CN spot-checked genuinely translated. Thepermission.planall-caps-badge CJK rendering is a non-blocking script fact → folded into the deferred native-speaker polish.Deferred — final epic gate
T-IL-012 — native-speaker / professional linguistic polish of the 8 machine-assisted translations (non-gating; accumulates for the final review).
🤖 Generated with Claude Code