Feat(i18n): add full Spanish (ES) language support#272
Feat(i18n): add full Spanish (ES) language support#272hqhq1025 merged 8 commits intoOpenCoworkAI:mainfrom
Conversation
There was a problem hiding this comment.
Review mode: initial
Findings
-
[Minor] Unrelated
.claude/settings.jsoncommitted — this PR is a Spanish i18n feature, but it also adds a personal Claude Code permissions file (apps/desktop/../.claude/settings.json). This file is a local agent configuration and should not be committed to the repository. If it's needed for development, consider adding it to.gitignoreor removing it from this PR.
Suggested fix:git rm --cached .claude/settings.json echo '.claude/' >> .gitignore
-
[Minor] Type narrowing regression in
packages/templates/src/index.ts:34— theREGISTRYvariable type was changed fromRecord<Locale, DemoTemplate[]>toRecord<string, DemoTemplate[]>. While this is not a runtime error (all keys are still valid locale strings), it removes the type-level restriction that prevents accidental key typos or unsupported locale keys. Consider keeping the stricterRecord<Locale, DemoTemplate[]>type and casting only where necessary, or adding a type assertion inREGISTRYto preserve the safety net.
Suggested fix:export const REGISTRY: Record<Locale, DemoTemplate[]> = { en: enDemos, 'zh-CN': zhCNDemos, 'pt-BR': ptBRDemos, es: esDemos, };
-
[Minor] No tests added for the Spanish locale — the i18n package currently runs
vitest run --passWithNoTests, so missing locale tests won't break CI, but there is no automated check that thees.jsonfile includes all keys present in the English base file or that theesExamplesandesDemosregistrations are complete. Adding a snapshot or key-comparison test (following the pattern of other locales if any) would catch future drift.
Suggested test:import es from '../src/locales/es.json'; import en from '../src/locales/en.json'; it('all English keys exist in Spanish', () => { const enKeys = Object.keys(flatten(en)); const esKeys = new Set(Object.keys(flatten(es))); const missing = enKeys.filter(k => !esKeys.has(k)); expect(missing).toEqual([]); });
Questions
- None.
Summary
This PR adds full Spanish (ES) language support with a comprehensive translation of 889 i18n keys, dashboard templates, and examples catalog. The integration follows the established patterns for zh-CN and pt-BR locales: registering the locale in availableLocales, adding the JSON resource, updating the UI component cycle, extending the IPC handler's recognition, and setting up the export alias. No new dependencies are introduced, and all license requirements remain satisfied.
The changeset bumps @open-codesign/desktop as minor and @open-codesign/i18n and @open-codesign/templates as patch — this is reasonable given the addition of a new user-facing locale.
Three minor issues should be addressed: 1) remove the unrelated .claude/settings.json from the commit, 2) preserve the strict Record<Locale, ...> type in the templates registry, and 3) consider adding a key-coverage test for the new locale to prevent silent drift.
Testing
- Not added for the new locale. Existing tests pass with
--passWithNoTests. Manual verification in the UI would be needed to confirm all translated strings render correctly.
Open-CoDesign Bot
There was a problem hiding this comment.
Review mode: follow-up after new commits
Findings
- [Minor] No tests added for the Spanish locale — this finding from the initial review remains unaddressed. The i18n package continues to run
vitest run --passWithNoTests, so missing locale tests won't break CI, but there is no automated check that thees.jsonfile includes all keys present in the English base file or that theesExamplesandesDemosregistrations are complete. Adding a snapshot or key-comparison test (following the pattern of other locales if any) would catch future drift.
Suggested test:import es from '../src/locales/es.json'; import en from '../src/locales/en.json'; it('all English keys exist in Spanish', () => { const enKeys = Object.keys(flatten(en)); const esKeys = new Set(Object.keys(flatten(es))); const missing = enKeys.filter(k => !esKeys.has(k)); expect(missing).toEqual([]); });
Resolved from previous review
- Unrelated
.claude/settings.jsonhas been removed from the commit. ✅ - The
REGISTRYtype inpackages/templates/src/index.tshas been restored toRecord<Locale, DemoTemplate[]>(narrowed back fromRecord<string, ...>). ✅
Summary
The previous two minor issues have been addressed. The remaining test gap is minor and non-blocking. The PR correctly adds Spanish language support following the established pattern for other locales. No new dependencies, no hardcoded UI values, no silent fallbacks, and no direct SDK imports.
Testing
- Not added for the new locale. Existing tests pass with
--passWithNoTests. Manual verification in the UI would be needed to confirm all translated strings render correctly.
Open-CoDesign Bot
There was a problem hiding this comment.
Review mode: follow-up after new commits
Findings
- [Minor] The test gap for the Spanish locale has been partially addressed by adding
es(andpt-BR) toerr-codes.test.ts, ensuring allERROR_CODESvalues have correspondingerr.*translations. This is a good improvement. However, there is still no broader key-coverage test (e.g., flatten-and-compare all keys betweenen.jsonandes.json). While the error-code test covers the most critical subset, a full key-comparison would catch future translation drift in the remaining ~850 keys. Consider adding a snapshot or key-coverage test as previously suggested.
Suggested test (from previous review):import es from '../src/locales/es.json'; import en from '../src/locales/en.json'; it('all English keys exist in Spanish', () => { const enKeys = Object.keys(flatten(en)); const esKeys = new Set(Object.keys(flatten(es))); const missing = enKeys.filter(k => !esKeys.has(k)); expect(missing).toEqual([]); });
Summary
This follow-up commit resolves the previous finding about missing locale test coverage by adding es (and incidentally pt-BR) to the existing err-codes.test.ts. The broader key-coverage test remains optional but recommended. All other aspects of the PR remain clean: no new dependencies, no hardcoded UI values, no silent fallbacks, no direct SDK imports, and the implementation follows the established locale pattern.
Testing
- Added locale entries to
err-codes.test.ts— error-code coverage now verified for all four locales. - No other tests added. Manual UI verification of the full translation set is still recommended.
Open-CoDesign Bot
There was a problem hiding this comment.
Review mode: follow-up after new commits
Findings
-
[Minor] Full key-coverage test still not added — the previous review suggested adding a flatten-and-compare test to ensure all keys from
en.jsonexist ines.json. This commit does not include such a test. While theerr-codes.test.tscoverage is adequate for error codes, a broader key-coverage test would catch future translation drift in the remaining ~850 keys. Consider adding it in a follow-up.
Suggested test (from previous review):import es from '../src/locales/es.json'; import en from '../src/locales/en.json'; it('all English keys exist in Spanish', () => { const enKeys = Object.keys(flatten(en)); const esKeys = new Set(Object.keys(flatten(es))); const missing = enKeys.filter(k => !esKeys.has(k)); expect(missing).toEqual([]); });
-
[Nit] Locale reordering — the changes to
LOCALE_CYCLE,resources,REGISTRY, and Settings dropdown order are cosmetic and have no behavioral impact. The addition ofpt-br/pt_br/pt-recognition inlocale-ipc.tsis a welcome bugfix for Portuguese locale detection.
Summary
This follow-up commit reorders locale arrays for consistency and adds missing Portuguese locale detection in the IPC handler (a bugfix from the previous iteration). No new dependencies, no hardcoded UI values, no silent fallbacks. The only remaining gap is the optional full key-coverage test, but the essential error-code test is already in place.
Testing
err-codes.test.tscovers all four locales for ERROR_CODES.- Manual UI verification of the full translation set is still recommended.
Open-CoDesign Bot
There was a problem hiding this comment.
Review mode: follow-up after new commits
This follow-up commit only reformats long string literals in packages/templates/src/examples/locales/es.ts to match Biome's preferred line length. No behavioral changes, no new issues introduced.
Residual observations:
- The minor finding from the previous review (missing full key-coverage test for all i18n keys) remains unaddressed. Consider adding a flatten-and-compare test in a follow-up PR — the suggestion is unchanged.
- The Biome formatting adjustments in this commit could have been caught by running
pnpm lint:fix. For future iterations, please run the linter before pushing to avoid formatting-only diffs.
Summary
No blockers or majors. The Portuguese locale-detection fix from the prior follow-up is preserved. The Spanish translation is complete and well-structured. This PR is ready to merge after CI passes.
Testing
err-codes.test.tscontinues to pass for all four locales.- No new tests needed for formatting-only changes.
Open-CoDesign Bot
There was a problem hiding this comment.
Review mode: follow-up after new commits
Findings
None. The follow-up commit removes internal .claude/ files that should not be in the repository and adds the missing PROVIDER_GATEWAY_INCOMPATIBLE error key to the Portuguese (pt-BR) locale, which was already present in the English and Spanish translations. This fix ensures the existing err-codes.test.ts will pass for pt-BR as well.
Summary
No blockers or majors. The Spanish localization is complete and well-structured. The pt-BR locale now has the same error coverage as the other locales. The removal of .claude/ files is a cleanup unrelated to the i18n feature. This PR is ready to merge after CI passes.
Testing
err-codes.test.tsnow validates all four locales againstERROR_CODES, including the newly addedPROVIDER_GATEWAY_INCOMPATIBLE.
Open-CoDesign Bot
Summary
This PR adds full Spanish (ES) language support to Open CoDesign. I have translated the core i18n keys (889 keys), dashboard templates, and the examples catalog into a natural, neutral Latin American Spanish. The implementation includes registering the 'es' locale in the i18n package, updating the UI components (LanguageToggle and Settings) to support the new locale, and ensuring persistence through the main-process IPC handlers.
Type of change
Linked issue
None.
Checklist
pnpm lint && pnpm typecheck && pnpm testpasses locally (Implementation follows existing patterns for 'zh-CN' and 'pt-BR')pnpm changeset)