Repository navigation
feat(i18n): spec 019 language packs: catalog, checker, backend, module translations and designs - #668
ValgulNecron wants to merge 44 commits into
Conversation
… and i18n-check Spec 019 T001-T004, T007-T019: new Go module i18n/ (go.work, GO_MODULES, CI matrices, dependabot, coverage gate 90), ICU MessageFormat subset parser/formatter with CLDR plurals, pack load/validate/completeness, embedded catalog with regional -> base -> en fallback, the i18n-check CLI and one seeded defective fixture per finding code. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Signed-off-by: Claude <noreply@anthropic.com>
Spec 019 T005, T006 (web), T024-T033: react-intl provider with language resolution, storage and no-flash boot snippet; locale-aware formatting helpers replacing hard-coded en-US; problem+json parsing in APIError with err.body kept as the English detail; extract/compile/manifest scripts; formatjs ESLint rules on migrated paths. No visible UI change. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Signed-off-by: Claude <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Signed-off-by: Claude <noreply@anthropic.com>
Spec 019 T006 (api/operator), T020-T023: api/internal/messages registry (server.* ids with translator notes), httperr.Message and WriteMessage, RFC 9457 problem details only when Accept lists application/problem+json with q > 0 (plain-text bodies stay byte-identical), 5xx never echo error text or args, messages-export command and make i18n-sync writing the server.* entries into i18n/locales/en/app.json. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Signed-off-by: Claude <noreply@anthropic.com>
Spec 019 T034, T048: the web job builds the language manifest, runs i18n-check (extraction drift, server-message drift, before/after completeness in the job summary) and self-tests the checker on the seeded defective packs; make check-i18n joins make lint. i18n-check now creates the manifest's directory. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Signed-off-by: Claude <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Signed-off-by: Claude <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Signed-off-by: Claude <noreply@anthropic.com>
|
Important Review skippedToo many files! This PR contains 295 files, which is 195 over the limit of 100. To get a review, reduce the PR to 100 files or fewer by splitting it into smaller PRs or changing its base branch. Upgrade to a paid plan to raise the limit. This review couldn't start because sufficient usage credits or metered capacity aren't available. Add credits or update usage-based reviews in the billing tab, then retry. ⚙️ Run configuration
⛔ Files ignored due to path filters: 27
📒 Files selected for processing: 295
You can disable this status message by setting the
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
…tions golangci-lint (gosec G703, staticcheck QF1001) on the new i18n module. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Signed-off-by: Claude <noreply@anthropic.com>
eslint formatjs/enforce-description on src/lib/i18n/serverMessage.ts. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Signed-off-by: Claude <noreply@anthropic.com>
CI Report - 0107fderun 38640625972 - attempt 1 0 failed - 32 passed - 0 skipped - 70m34s elapsed Coverage
Changed
Slowest jobs
e2e buckets run
|
|
Generated by Claude Code |
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Signed-off-by: Claude <noreply@anthropic.com>
…guage Spec 019 T036, T038-T041, T093: migration 016 adds user_preferences.language; PUT /users/me/language (listed languages only, server.i18n.unknown_language); language in GET /users/me/preferences; unauthenticated GET /auth/locale exposing only defaultLanguage; admin config section i18n validated against the listed languages (server.i18n.unlisted_language). E2E for /auth/locale in the api-auth bucket. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Signed-off-by: Claude <noreply@anthropic.com>
…ider Spec 019 T042, T046, T047: Users.setLanguage and Auth.locale endpoints, AppI18nProvider reading the cached /users/me language and /auth/locale default, and the 0% fixture language behind VITE_I18N_FIXTURES=1. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Signed-off-by: Claude <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Signed-off-by: Claude <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> GameServerStatus gains conditionArgs (map of condition type to the values interpolated into its English message), set after each status pass and cleared when the reason carries no values. The condition-ids generator writes condition.<type>.<reason> English entries into the reference pack and has a -check mode for drift. Signed-off-by: Claude <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Sinks take an optional language (validated against the listed languages). Titles, details and test text come from notify.* catalog entries in the sink language, then the instance default, then English. Webhook payloads add language, title and text and keep every existing field. English output is unchanged. Signed-off-by: Claude <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Every 4xx http.Error in handlers, auth, ws and rbac now goes through httperr.WriteMessage (registry id) or httperr.WriteCode (generic id). Plain-text bodies stay byte-identical; 5xx stays http.Error. Unauthenticated login and OIDC paths only use server.auth.invalid_credentials or generic ids. make i18n-sync also syncs notify.* and condition.* ids, and i18n-check covers notify.* drift. Adds the problem+json E2E and ticks the 019 US5 backend tasks. Signed-off-by: Claude <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> i18n-check gains --valid-out, which writes each pack's usable entries. The compile script and the web image use it, so a broken translation shows the English text instead (FR-018). Signed-off-by: Claude <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Signed-off-by: Claude <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Signed-off-by: Claude <noreply@anthropic.com>
valgul approved this expectation change on the spec 019 decision card. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Signed-off-by: Claude <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> New i18n/modlocale derives module ids from module.yaml and template.yaml with reversible ~0/~1 escaping. gp-module gains i18n extract and i18n stamp, validate checks locales/*.json, and package adds one OCI layer per language and includes locales/ in --output tarballs. i18n-check --module checks en.json drift and validates translations. Signed-off-by: Claude <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> valgul ruled on OD-007 (report in validate), OD-009 (WriteFailed ranks first) and OD-013 (i18n-check --module --stamp stays an error). Signed-off-by: Claude <noreply@anthropic.com>
The locale check needs GameplanePanel/Gameplane#668 on master; running it last keeps the build.sh and validate.py tests visible meanwhile. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Signed-off-by: Claude <noreply@anthropic.com>
Design for T043, T072 and T094 of spec 019, with exports. - Personal settings: a Language card is the first card of Theme & Appearance (also on the Warnings variant), plus a mobile screen. - Login and share pages: a compact picker in the top-right corner of the card on every state, and a screen with its menu open. It shows language names only. - Notifications: a Language select on each sink row and a new screen for the Add sink form, which the design did not have. - Admin settings: a Language card with the Default language field. Records the placement rulings as OD-015 to OD-017 and ticks the three design tasks. loginCard (J14ME) is unchanged: Pencil cannot insert a child into it, so the login screens use a wrapper component (see assets/design-export/MANIFEST.md). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Signed-off-by: valgulnecron <39313199+ValgulNecron@users.noreply.github.com>
PR #668 conflicted with master, so no CI run started. Four conflicts, one hunk each, resolved by keeping both sides: - Makefile: lint runs check-i18n and check-coverage-gaps. - api/go.mod: golang.org/x/sys v0.49.0 from master; golang.org/x/text stays a direct requirement. - web/package.json and web/package-lock.json: the @formatjs dev dependencies from the branch, @playwright/test ^1.64.0 from master. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Signed-off-by: valgulnecron <39313199+ValgulNecron@users.noreply.github.com>
|
Cause: this PR's Generated by Claude Code |
…lgul) The dashboard asks for the instance default language on every page load. Without a mock route the request reached the dev proxy and returned 502, which failed the console-error checks in serverDetail.spec.ts and settingsSubTabs.spec.ts. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Signed-off-by: Claude <noreply@anthropic.com>
…approved by valgul) --module now checks en.json against the ids the template derives (OD Q4), so the fixture template declares spec.displayName and the packs use the derived id template.displayName. Both cases and exit codes are unchanged. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Signed-off-by: Claude <noreply@anthropic.com>
hadolint DL3062 flags go run without a version; building the local package and running the binary does the same work. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Signed-off-by: Claude <noreply@anthropic.com>
…ad-awjqv0 Signed-off-by: Claude <noreply@anthropic.com>
Codegen drift gate (make tidy) expects the tidied i18n/go.sum. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Signed-off-by: Claude <noreply@anthropic.com>
|
This isn't caused by this PR: it doesn't touch that file, and master 2155568 has the same mismatch. #672 and #674 each flipped a gap against the same old summary line. No fix exists yet. I've asked the spec 013 thread, which owns the file, to fix it on master. I'll merge master here once the fix lands. Generated by Claude Code |
golangci-lint: errcheck on the i18n command's output writes, gosec G602 on the --output value read, and G703 on the stamp write. Translations are now written through an os.Root on the locales directory. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Signed-off-by: Claude <noreply@anthropic.com>
gosec G703 on the condition-ids generator's write of app.json. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Signed-off-by: Claude <noreply@anthropic.com>
|
The test races the capabilities query. It asserts the Completed row's download button is enabled right after the list renders, but A fix already exists on #677 (a8ffe53, which wraps the assertion in Generated by Claude Code |
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Signed-off-by: Claude <noreply@anthropic.com>
- gp-module: locale archive fixture includes the required README.md - api/db: theme migration test applies the remaining migrations before reading preferences (016 adds language) - api/handlers: TestValidateI18n checks the canonical JSON; the locales test path-escapes its invalid tag so the request reaches the handler - e2e: close the locales response body; drop two unused ct assignments Each change approved by valgul on its decision card. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Signed-off-by: Claude <noreply@anthropic.com>
misspell flags the French "Exemple" as a typo of "Example". The fixture pair becomes Template/Modèle; the test still compares message ids only. Approved by valgul. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Signed-off-by: Claude <noreply@anthropic.com>
|
The cause is in this PR. The new Fixing it means editing the new test. This repo needs explicit sign-off for test edits, and one option (a different IP) was declined. The fix is waiting on a decision in the project thread. Generated by Claude Code |
The holder kept 203.0.113.20 after the test, and address conflicts are cluster-wide, so TestGameServer_ReleasedAddressBecomesAvailable saw the address as still in use. Both servers are now deleted on cleanup. Approved by valgul. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Signed-off-by: Claude <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Signed-off-by: Claude <noreply@anthropic.com>
|
I don't think this PR caused it:
No fix exists for this yet. I'll re-run the failed job once, after the rest of the run finishes, because GitHub won't re-run a job while its workflow is still running. If it fails a second time, I'll treat it as real. Generated by Claude Code |
Brings in PRs #630, #690, #691 and #696. Conflicts resolved: - api/internal/notify/format.go: master's remote-cluster headline is kept through a new notify.title.cluster message, so "[prod] server unhealthy: remote-1/games/mc" is unchanged in English; app.json regenerated with make i18n-sync. - web/src/lib/endpoints.ts: master's cluster parameter on Modules, and Modules.locales takes the same parameter. - web/src/components/ui/NotificationsPanel.tsx: both the formatter ref effect and master's enabled guard. - docs/architecture.md: master's standalone-panel paragraph, then the Internationalization section. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Signed-off-by: Claude <noreply@anthropic.com>
Master added 016_standalone_management.sql and 017_standalone_key_state.sql, so 016_user_language.sql collided on version 016 and Migrate refused to run. The language column moves to the next free version; spec 019 docs and api/specs.md follow. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Signed-off-by: Claude <noreply@anthropic.com>
Before: Gameplane has no translation system. Dashboard text, API errors, notifications and operator conditions are English-only, dates and numbers are hard-coded to
en-US, and game modules can't ship translations.After: Gameplane has a shared language catalog, a checker that runs in CI, and a backend that knows each user's language. The API saves each user's language and an instance default language. It returns localizable 4xx errors as RFC 9457 problem details to clients that ask for them. Notifications render in each destination's language, and the operator publishes condition message ids with their arguments. Modules can ship
locales/*.json, which the operator publishes and the API serves. The dashboard has the i18n runtime and anen-XApseudo-language for spotting untranslated text. The language picker and settings designs are indesign.pen. Nothing visible changes in English yet, and plain-text API error bodies stay byte-identical.This PR carries the cloud-built part of spec 019: 71 of 105 tasks in
specs/019-localization-language-packs/tasks.md. The rest goes in follow-up PRs:How
i18n/(new Go module, coverage gate 90):icuis an ICU MessageFormat subset with CLDR plurals.packloads and validates packs and applies the 80% listing rule.catalogholds the embedded packs and falls back regional → base → English.modlocalederives module translation ids.cmd/i18n-checkchecks extraction drift, server-message drift and module drift (--module), with one seeded defective fixture per finding code.internal/messagesregistry andhttperr.WriteMessage. Problem details are returned only whenAcceptasks forapplication/problem+json(wildcards never select them), and 5xx responses never echo error text.PUT /users/me/language, the instance default in/admin/config/i18n, and a per-sink language for notifications./modules/{name}/locales/{tag}.status.conditionArgsandcondition.*message ids.<template>-localesConfigMap in the operator namespace, with aLocalesValidcondition (LocalesTooLarge,InvalidEntries,WriteFailed) and a 4 MiB total read cap.sourceHash) and packages module translations, and reports YAML names that cannot become translation ids.src/lib/i18n/(provider, FR-004 resolution order, format helpers, server-message mapping), the user's and instance's language fed into the provider, invalid pack entries dropped at build time, anden-XAbehindVITE_I18N_PSEUDO.webjob builds the manifest and runsi18n-check, and translation-only PRs are labelled docs.make check-i18njoinsmake lint.Test fixes that valgul approved on decision cards: the api-cache Accept header, the
/auth/localemock, the TestModulePacks fixture, the gp-module README fixture, theMigratecall in the preferences test, the validator canonical check, the escaped locale tag, the e2e lint fixes, the Template/Modèle fixture words and the AddressInUse envtest cleanup.Only compile checks and the generators were run locally. Tests and lint run here in CI, and the latest head is green.
🤖 Generated with Claude Code