diff options
| author | Adam <[email protected]> | 2026-02-08 16:21:59 -0600 |
|---|---|---|
| committer | Adam <[email protected]> | 2026-02-08 16:22:39 -0600 |
| commit | 6490fb01489bfa5644349d650f978c80d0ab7365 (patch) | |
| tree | 3cf4a2fc9949f26b6802b3fa9451111ca1dfca1e /specs | |
| parent | 43811b62d2940cf025745cf470beafac820e98b1 (diff) | |
| download | opencode-6490fb01489bfa5644349d650f978c80d0ab7365.tar.gz opencode-6490fb01489bfa5644349d650f978c80d0ab7365.zip | |
fix(console): zen workspace translation cleanup
Diffstat (limited to 'specs')
| -rw-r--r-- | specs/19-workspace-i18n-audit-overview.md | 76 | ||||
| -rw-r--r-- | specs/20-workspace-i18n-audit-ar.md | 99 | ||||
| -rw-r--r-- | specs/21-workspace-i18n-audit-da.md | 103 | ||||
| -rw-r--r-- | specs/22-workspace-i18n-audit-de.md | 95 | ||||
| -rw-r--r-- | specs/23-workspace-i18n-audit-it.md | 86 |
5 files changed, 459 insertions, 0 deletions
diff --git a/specs/19-workspace-i18n-audit-overview.md b/specs/19-workspace-i18n-audit-overview.md new file mode 100644 index 000000000..42599a2f6 --- /dev/null +++ b/specs/19-workspace-i18n-audit-overview.md @@ -0,0 +1,76 @@ +## workspace i18n audit overview (zen workspace routes) + +Audit objective: verify translation accuracy for customer-facing workspace management pages used to manage Zen (AI inference provider) usage, with strict terminology and brand integrity. + +--- + +### scope + +- Routes audited: `packages/console/app/src/routes/workspace/**` (all workspace TSX routes, including billing/keys/members/settings) +- Locale files audited: `packages/console/app/src/i18n/ar.ts`, `packages/console/app/src/i18n/da.ts`, `packages/console/app/src/i18n/de.ts`, `packages/console/app/src/i18n/it.ts` +- Source-of-truth copy: `packages/console/app/src/i18n/en.ts` +- Total unique translation keys used by workspace routes: **181** + +--- + +### deliverables + +- Arabic audit and fix spec: `specs/20-workspace-i18n-audit-ar.md` +- Danish audit and fix spec: `specs/21-workspace-i18n-audit-da.md` +- German audit and fix spec: `specs/22-workspace-i18n-audit-de.md` +- Italian audit and fix spec: `specs/23-workspace-i18n-audit-it.md` + +These files are intentionally execution-ready so follow-up agents can apply string fixes without re-auditing. + +--- + +### non-negotiable terminology contract + +1. Product names and brands: + - `Zen` must remain exactly `Zen` (never translated, never lowercased). + - `Stripe`, `OpenCode Black`, `opencode`, `API`, `/models` remain literal. +2. AI domain terms must preserve technical meaning: + - `model` = AI model, not fashion/product model. + - `provider` = AI provider/vendor. + - `Bring Your Own Key` = BYOK concept (user-provided API credential). +3. Billing/top-up language must stay financial: + - `reload` in billing pages means balance top-up/recharge, not page refresh. + - `amount`, `cost`, `usage`, `monthly spending limit` must map to metering/billing context. +4. Placeholder and interpolation safety: + - Keep placeholders unchanged (`{{provider}}`, `{{prefix}}`, `{{amount}}`, etc). + - Keep currency symbols and key ordering intact. + +--- + +### cross-locale risk summary + +- Critical risk focus across locales: billing `reload` text must consistently mean balance top-up/recharge (not page refresh), while product literals and CLI command verbs remain exact. +- `ar` (Arabic): **31** flagged keys (critical: 4, major: 23, minor: 4), with critical literals broken for `Zen`, `Stripe`, and `OpenCode Black` waitlist strings. +- `da` (Danish): **33** flagged keys (critical: 8, major: 18, minor: 7), concentrated in reload/top-up semantics plus onboarding/default-label blockers. +- `de` (German): **34** flagged keys (critical: 6, major: 27, minor: 1), centered on reload/top-up semantics, onboarding command phrasing, and usage metric wording. +- `it` (Italian): **25** flagged keys (critical: 2, major: 18, minor: 5), led by `Zen` casing and waitlist status semantics with broader API/billing wording drift. + +--- + +### remediation workflow for follow-up agents + +1. Pick one locale spec (`20`/`21`/`22`/`23`) and apply only mapped key updates in that locale file. +2. Do not add/remove keys; only edit string values. +3. Preserve placeholders and punctuation contracts. +4. Run app typecheck: + - `bun run typecheck` in `packages/console/app` +5. Run post-fix terminology sanity checks: + - Literal checks in locale files: `Zen`, `Stripe`, `OpenCode Black`, `opencode`, `API`, `/models`. + - `workspace.reload.*` language matches top-up/recharge semantics. + - `API key` labels are ordered naturally in target language. + - Placeholders remain unchanged (`{{provider}}`, `{{prefix}}`, `{{plan}}`, `{{amount}}`, etc). + +--- + +### acceptance criteria + +- All mapped critical and major issues in locale specs are fixed. +- `workspace.nav.zen` is exactly `Zen` in all locales. +- `workspace.billing.linkedToStripe` preserves `Stripe` literal in all locales. +- Workspace billing and usage terminology is technically accurate for AI inference workflows. +- No placeholder regressions. diff --git a/specs/20-workspace-i18n-audit-ar.md b/specs/20-workspace-i18n-audit-ar.md new file mode 100644 index 000000000..5eab6fed9 --- /dev/null +++ b/specs/20-workspace-i18n-audit-ar.md @@ -0,0 +1,99 @@ +## workspace i18n audit - ar + +Arabic translation audit for workspace routes with focus on Zen/AI/billing terminology accuracy. + +--- + +### coverage + +- Route scope: `packages/console/app/src/routes/workspace/**` +- Locale file: `packages/console/app/src/i18n/ar.ts` +- Source reference: `packages/console/app/src/i18n/en.ts` +- Unique keys in scope: **181** +- Flagged keys: **31** (critical: 4, major: 23, minor: 4) + +--- + +### glossary decisions (ar) + +- `Zen`: keep exactly `Zen` +- `OpenCode Black`: keep exactly `OpenCode Black` +- `Stripe`: keep exactly `Stripe` +- `opencode`: keep exactly `opencode` +- `API`: keep exactly `API` +- `/models`: keep exactly `/models` +- `model`: `نموذج` / `نماذج` +- `provider`: `مزوّد` +- `API key`: `مفتاح API` +- `Bring Your Own Key`: `استخدم مفتاحك الخاص` +- `usage`: `الاستخدام` +- `cost`: `التكلفة` +- `billing`: `الفوترة` +- `monthly spending limit`: `حد الإنفاق الشهري` +- `auto reload` (billing context): `إعادة الشحن التلقائي` +- Keep placeholders exactly as-is: `{{provider}}`, `{{prefix}}`, `{{plan}}`, `{{amount}}`. + +--- + +### required key updates + +| key | replace with | severity | reason | +| -------------------------------------- | ------------------------------------------------------------------ | -------- | ---------------------------------------------------- | +| workspace.nav.zen | Zen | critical | Product literal must not be translated. | +| workspace.billing.linkedToStripe | مرتبط بـ Stripe | critical | Keep payment brand literal `Stripe`. | +| workspace.black.waitlist.joined | أنت على قائمة الانتظار لخطة OpenCode Black بقيمة ${{plan}} شهريًا. | critical | Preserve exact literal `OpenCode Black`. | +| workspace.black.waitlist.ready | نحن مستعدون لتسجيلك في خطة OpenCode Black بقيمة ${{plan}} شهريًا. | critical | Preserve exact literal `OpenCode Black`. | +| workspace.nav.apiKeys | مفاتيح API | major | Correct `API` key word order. | +| workspace.keys.title | مفاتيح API | major | Correct `API` key word order. | +| workspace.providers.table.apiKey | مفتاح API | major | Correct `API` key word order. | +| workspace.cost.title | التكلفة | major | `Cost` mistranslated as verb. | +| workspace.usage.table.cost | التكلفة | major | `Cost` mistranslated as verb. | +| workspace.cost.allModels | جميع النماذج | major | Prefer standard AI term `نماذج`. | +| workspace.cost.subscriptionShort | اشتراك | major | Current value is semantically wrong. | +| workspace.payments.table.amount | المبلغ | major | Financial amount mistranslated as quantity. | +| workspace.payments.view | عرض | major | CTA mistranslated as noun “scenery”. | +| workspace.monthlyLimit.setting | جارٍ التعيين... | major | Progress state mistranslated. | +| workspace.settings.defaultName | الافتراضي | major | Default label mistranslated. | +| workspace.newUser.step.login.before | شغّل | major | CLI imperative “Run” mistranslated. | +| workspace.members.role.admin | مسؤول | major | Spelling error. | +| workspace.reload.title | إعادة الشحن التلقائي | major | Billing `reload` means top-up/recharge, not refresh. | +| workspace.reload.enableAutoReload | تفعيل إعادة الشحن التلقائي | major | Must reflect top-up semantics. | +| workspace.reload.reloadAmount | مبلغ إعادة الشحن $ | major | Must reflect recharge amount. | +| workspace.reload.failedAt | فشلت إعادة الشحن في | major | Must reflect recharge failure. | +| workspace.reload.disabled.state | معطّل | major | Incorrect toggle state term. | +| workspace.reload.enabled.after | عندما يصل الرصيد إلى | major | `balance` mistranslated as “equilibrium”. | +| workspace.reload.enable | تفعيل | major | CTA form mistranslated. | +| workspace.reload.disabled.before | إعادة الشحن التلقائي | major | Align phrase with recharge semantics. | +| workspace.reload.enabled.before | إعادة الشحن التلقائي | major | Align phrase with recharge semantics. | +| workspace.reload.enabled.middle | سنعيد شحن رصيدك بمبلغ | major | Must explicitly mean topping up balance. | +| workspace.billing.addAction | إضافة | minor | CTA grammatical form fix. | +| workspace.billing.manage | إدارة | minor | CTA grammatical form fix. | +| workspace.keys.empty | أنشئ مفتاح API لبوابة opencode | minor | Improve technical clarity and ordering. | +| workspace.newUser.feature.lockin.title | بدون احتجاز بمزوّد واحد | minor | Better conveys “No Lock-in”. | + +--- + +### implementation batches + +1. **Brand literals first (critical)** + - `workspace.nav.zen`, `workspace.billing.linkedToStripe`, `workspace.black.waitlist.joined`, `workspace.black.waitlist.ready` +2. **Reload/recharge semantics** + - `workspace.reload.*` flagged keys to ensure top-up meaning (not page refresh) +3. **Billing/payment terminology** + - `workspace.cost.title`, `workspace.usage.table.cost`, `workspace.payments.table.amount`, `workspace.payments.view`, `workspace.monthlyLimit.setting` +4. **API/workspace wording fixes** + - API-key ordering keys, `workspace.settings.defaultName`, `workspace.members.role.admin`, `workspace.newUser.step.login.before` +5. **Minor CTA/clarity polish** + - `workspace.billing.addAction`, `workspace.billing.manage`, `workspace.keys.empty`, `workspace.newUser.feature.lockin.title` + +--- + +### acceptance checks for follow-up fix agent + +- `workspace.nav.zen` value is exactly `Zen`. +- `workspace.billing.linkedToStripe` contains `Stripe` literal. +- `workspace.black.waitlist.joined` and `workspace.black.waitlist.ready` keep `OpenCode Black` exactly. +- No `workspace.reload.*` string implies page refresh; all imply balance top-up/recharge. +- API key labels use `مفتاح API` / `مفاتيح API` ordering. +- Preserve literals exactly: `Zen`, `Stripe`, `OpenCode Black`, `opencode`, `API`, `/models`. +- All placeholders remain unchanged (`{{provider}}`, `{{prefix}}`, `{{plan}}`, `{{amount}}`). diff --git a/specs/21-workspace-i18n-audit-da.md b/specs/21-workspace-i18n-audit-da.md new file mode 100644 index 000000000..c0c0ef0c0 --- /dev/null +++ b/specs/21-workspace-i18n-audit-da.md @@ -0,0 +1,103 @@ +## workspace i18n audit - da + +Danish translation audit for workspace routes with emphasis on AI-provider, billing, and workspace-management accuracy. + +--- + +### coverage + +- Route scope: `packages/console/app/src/routes/workspace/**` +- Locale file: `packages/console/app/src/i18n/da.ts` +- Source reference: `packages/console/app/src/i18n/en.ts` +- Unique locale keys used in scope: **181** +- Flagged keys: **33** (critical: 8, major: 18, minor: 7) + +--- + +### glossary decisions (da) + +- `Zen`: keep exactly `Zen` +- `Stripe`: keep exactly `Stripe` +- `OpenCode Black`: keep exactly `OpenCode Black` +- `opencode`: keep exactly `opencode` +- `API`: keep exactly `API` +- `/models`: keep exactly `/models` +- `API key`: `API-nøgle` +- `billing`: `fakturering` +- `reload` in wallet context: `genopfyldning` (top-up), never page refresh wording + +--- + +### required key updates + +| key | current da | replace with | severity | reason | +| ------------------------------------- | --------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------- | -------- | ---------------------------------------------------------------------- | +| workspace.newUser.step.login.before | Løbe | Kør | critical | Wrong verb for CLI instruction (`opencode auth login`). | +| workspace.settings.defaultName | Misligholdelse | Standard | critical | Wrong meaning for default-label UI text. | +| workspace.reload.title | Automatisk genindlæsning | Automatisk genopfyldning | critical | `reload` here is balance top-up, not page reload. | +| workspace.reload.disabled.before | Automatisk genindlæsning er | Automatisk genopfyldning er | critical | Same billing top-up semantic issue. | +| workspace.reload.enabled.before | Automatisk genindlæsning er | Automatisk genopfyldning er | critical | Same billing top-up semantic issue. | +| workspace.reload.enableAutoReload | Aktiver automatisk genindlæsning | Aktiver automatisk genopfyldning | critical | Same billing top-up semantic issue. | +| workspace.reload.reloadAmount | Genindlæs $ | Genopfyld $ | critical | Top-up amount label, not page reload action. | +| workspace.reload.failedAt | Genindlæsning mislykkedes kl | Genopfyldning mislykkedes kl | critical | Error refers to failed recharge event. | +| workspace.reload.disabled.after | Aktiver for automatisk at genindlæse, når balancen er lav. | Aktiver for automatisk at genopfylde, når saldoen er lav. | major | Must describe low-balance auto top-up behavior. | +| workspace.reload.enabled.middle | Vi genindlæser | Vi genopfylder | major | Must describe automatic recharge action. | +| workspace.reload.disabled.state | handicappet | deaktiveret | major | Wrong/off-tone toggle-state wording. | +| workspace.members.save | Spare | Gem | major | Current word means monetary savings, not save changes. | +| workspace.providers.save | Spare | Gem | major | Current word means monetary savings, not save changes. | +| workspace.reload.save | Spare | Gem | major | Current word means monetary savings, not save changes. | +| workspace.settings.save | Spare | Gem | major | Current word means monetary savings, not save changes. | +| workspace.keys.copyApiKey | Kopiér nøglen API | Kopiér API-nøgle | major | Incorrect technical phrase order. | +| workspace.newUser.copyApiKey | Kopiér nøglen API | Kopiér API-nøgle | major | Incorrect technical phrase order. | +| workspace.providers.placeholder | Indtast nøglen {{provider}} API ({{prefix}}...) | Indtast {{provider}} API-nøgle ({{prefix}}...) | major | Technical phrase is malformed; placeholders must be preserved exactly. | +| workspace.newUser.feature.tested.body | Vi har benchmarket og testet modeller specifikt til kodningsmidler for at sikre den bedste ydeevne. | Vi har benchmarket og testet modeller specifikt til kodningsagenter for at sikre den bedste ydeevne. | major | Wrong domain noun (`kodningsmidler` != coding agents). | +| workspace.payments.table.receipt | Modtagelse | Kvittering | major | Wrong payment term for receipt column. | +| workspace.payments.view | Udsigt | Vis | major | Wrong CTA meaning for “View” action. | +| workspace.black.waitlist.left | Venstre | Forladt | major | Wrong meaning (“left” direction vs status). | +| workspace.usage.table.output | Produktion | Output | major | Wrong AI metering term in token table. | +| workspace.usage.breakdown.output | Produktion | Output | major | Wrong AI metering term in token breakdown. | +| workspace.usage.table.cost | Koste | Omkostning | major | Wrong part of speech for metric label. | +| workspace.cost.title | Koste | Omkostninger | major | Wrong part of speech for section heading. | +| workspace.members.edit | Redigere | Rediger | minor | Use imperative CTA form. | +| workspace.providers.edit | Redigere | Rediger | minor | Use imperative CTA form. | +| workspace.reload.edit | Redigere | Rediger | minor | Use imperative CTA form. | +| workspace.settings.edit | Redigere | Rediger | minor | Use imperative CTA form. | +| workspace.billing.addAction | Tilføje | Tilføj | minor | Use imperative CTA form. | +| workspace.billing.manage | Styre | Administrer | minor | Better management CTA wording in product UI. | +| workspace.black.waitlist.enroll | Indskrive | Tilmeld | minor | Better enrollment CTA for subscription/waitlist flow. | + +--- + +### implementation batches + +1. **Critical blockers: onboarding + default + reload semantics** + - `workspace.newUser.step.login.before` + - `workspace.settings.defaultName` + - `workspace.reload.title` + - `workspace.reload.disabled.before` + - `workspace.reload.enabled.before` + - `workspace.reload.enableAutoReload` + - `workspace.reload.reloadAmount` + - `workspace.reload.failedAt` +2. **Billing top-up and save-action correctness** + - Remaining `workspace.reload.*` in table + - `workspace.members.save`, `workspace.providers.save`, `workspace.reload.save`, `workspace.settings.save` +3. **API and provider terminology cleanup** + - `workspace.keys.copyApiKey`, `workspace.newUser.copyApiKey`, `workspace.providers.placeholder` +4. **Usage/payments/workspace label fixes** + - `workspace.newUser.feature.tested.body` + - `workspace.payments.table.receipt`, `workspace.payments.view` + - `workspace.black.waitlist.left` + - `workspace.usage.table.output`, `workspace.usage.breakdown.output`, `workspace.usage.table.cost`, `workspace.cost.title` +5. **CTA polish (minor imperative consistency)** + - all `*.edit`, `workspace.billing.addAction`, `workspace.billing.manage`, `workspace.black.waitlist.enroll` + +--- + +### acceptance checks for follow-up fix agent + +- Preserve literals exactly: `Zen`, `Stripe`, `OpenCode Black`, `opencode`, `API`, `/models`. +- Preserve placeholders exactly (eg `{{provider}}`, `{{prefix}}`, `{{plan}}`, `{{amount}}`). +- All `workspace.reload.*` labels must mean balance top-up/recharge (`genopfyld*`), never page refresh (`genindlæs*`). +- Save CTAs must reflect saving changes (`Gem` / `Gemmer...`), not savings-money wording. +- AI metering labels in usage tables remain technically correct (`Input`, `Output`, cost nouns). diff --git a/specs/22-workspace-i18n-audit-de.md b/specs/22-workspace-i18n-audit-de.md new file mode 100644 index 000000000..cfc782008 --- /dev/null +++ b/specs/22-workspace-i18n-audit-de.md @@ -0,0 +1,95 @@ +## workspace i18n audit - de + +German translation audit for workspace routes with focus on CLI onboarding clarity, AI metric terminology, and billing top-up semantics. + +--- + +### coverage + +- Route scope: `packages/console/app/src/routes/workspace/**` +- Locale file: `packages/console/app/src/i18n/de.ts` +- Source reference: `packages/console/app/src/i18n/en.ts` +- Unique keys in scope: **181** +- Flagged keys: **34** (critical: 6, major: 27, minor: 1) + +--- + +### glossary decisions (de) + +- Preserve literals exactly: `Zen`, `Stripe`, `OpenCode Black`, `opencode`, `API`, `/models` +- Preserve placeholders exactly (`{{provider}}`, `{{amount}}`, `{{plan}}`, `{{prefix}}`, etc.) +- `API key`: `API-Schlüssel` +- `usage`: `Nutzung` +- `cost`: `Kosten`; payments column `Betrag` +- `billing`: `Abrechnung` +- Billing `reload` semantics: `Aufladung` / `aufladen` (never `Neuladen`) +- AI cost metrics: keep `Input`, `Output`, `Reasoning` + +--- + +### required key updates + +| key | replace with | severity | reason | +| ------------------------------------- | ---------------------------------------------------------------------------------------- | -------- | ----------------------------------------------------- | +| workspace.newUser.step.login.before | Führe | critical | Wrong CLI verb in onboarding instruction. | +| workspace.monthlyLimit.set | Festlegen | critical | CTA mistranslated as noun (`Satz`). | +| workspace.reload.title | Automatische Aufladung | critical | Billing top-up semantics, not page reload. | +| workspace.reload.disabled.after | Aktivieren Sie diese Option, damit bei niedrigem Kontostand automatisch aufgeladen wird. | critical | Uses `neu laden`; must use billing top-up phrasing. | +| workspace.reload.enableAutoReload | Automatische Aufladung aktivieren | critical | Primary toggle must follow billing top-up semantics. | +| workspace.black.subscription.message | Sie haben OpenCode Black für ${{plan}} pro Monat abonniert. | critical | Missing `$` before `{{plan}}`. | +| workspace.newUser.step.models.before | Starte opencode und führe | major | Unidiomatic command phrasing before `/models`. | +| workspace.newUser.copyApiKey | API-Schlüssel kopieren | major | Broken technical term word order. | +| workspace.keys.copyApiKey | API-Schlüssel kopieren | major | Broken technical term word order. | +| workspace.models.table.enabled | Aktiviert | major | Wrong toggle-state label. | +| workspace.providers.saving | Wird gespeichert... | major | `Sparen...` means saving money, not save state. | +| workspace.members.inviting | Wird eingeladen... | major | Incorrect invite loading state wording. | +| workspace.members.saving | Wird gespeichert... | major | `Sparen...` means saving money, not save state. | +| workspace.monthlyLimit.setting | Wird gesetzt... | major | In-progress state should be verbal action. | +| workspace.payments.table.amount | Betrag | major | Financial column mistranslated as quantity. | +| workspace.payments.view | Anzeigen | major | CTA mistranslated as noun (`Sicht`). | +| workspace.usage.table.input | Input | major | AI billing metric should remain technical term. | +| workspace.usage.table.output | Output | major | AI billing metric should remain technical term. | +| workspace.usage.breakdown.input | Input | major | AI billing metric should remain technical term. | +| workspace.usage.breakdown.output | Output | major | AI billing metric should remain technical term. | +| workspace.usage.breakdown.reasoning | Reasoning | major | AI billing metric should remain technical term. | +| workspace.reload.disabled.before | Automatische Aufladung ist | major | Should use top-up semantics instead of `Nachladen`. | +| workspace.reload.enabled.before | Automatische Aufladung ist | major | Should use top-up semantics instead of `Nachladen`. | +| workspace.reload.enabled.state | aktiviert | major | `ermöglicht` is wrong state adjective for toggle. | +| workspace.reload.enabled.middle | Wir laden auf | major | Should be account top-up verb (`aufladen`). | +| workspace.reload.enabled.after | sobald der Kontostand | major | `Gleichgewicht` is wrong meaning for account balance. | +| workspace.reload.reloadAmount | Aufladebetrag $ | major | Label should reflect top-up amount semantics. | +| workspace.reload.whenBalanceReaches | Wenn der Kontostand $ erreicht | major | Use account-balance term `Kontostand`. | +| workspace.reload.failedAt | Aufladung fehlgeschlagen am | major | Error copy should use top-up semantics. | +| workspace.reload.saving | Wird gespeichert... | major | `Sparen...` means saving money, not save state. | +| workspace.black.waitlist.left | Verlassen | major | `Links` is incorrect meaning. | +| workspace.black.waitlist.joined | Sie stehen auf der Warteliste für den OpenCode Black Tarif für ${{plan}} pro Monat. | major | Product name order/phrase is broken. | +| workspace.black.waitlist.ready | Wir können Sie jetzt in den OpenCode Black Tarif für ${{plan}} pro Monat aufnehmen. | major | Product name order/phrase is broken. | +| workspace.black.subscription.resetsIn | Zurückgesetzt in | minor | Improve pre-duration label grammar. | + +--- + +### implementation batches + +1. **Critical blockers first** + - `workspace.newUser.step.login.before`, `workspace.monthlyLimit.set`, `workspace.reload.title`, `workspace.reload.disabled.after`, `workspace.reload.enableAutoReload`, `workspace.black.subscription.message` +2. **Reload semantics sweep** + - All `workspace.reload.*` keys listed above (state labels, helper text, error text, amount labels) +3. **Onboarding + API key wording** + - `workspace.newUser.step.models.before`, `workspace.newUser.copyApiKey`, `workspace.keys.copyApiKey` +4. **Async/CTA quality fixes** + - `workspace.providers.saving`, `workspace.members.inviting`, `workspace.members.saving`, `workspace.monthlyLimit.setting`, `workspace.payments.view`, `workspace.reload.saving` +5. **AI usage/payments terminology** + - usage `Input/Output/Reasoning` keys + `workspace.payments.table.amount` +6. **OpenCode Black waitlist copy** + - `workspace.black.waitlist.left`, `workspace.black.waitlist.joined`, `workspace.black.waitlist.ready`, `workspace.black.subscription.resetsIn` + +--- + +### acceptance checks for follow-up fix agent + +- Flagged totals align with this spec: **34** (`critical` 6, `major` 27, `minor` 1). +- `workspace.nav.zen` remains exactly `Zen`. +- Literals remain exact where present: `Stripe`, `OpenCode Black`, `opencode`, `API`, `/models`. +- Billing top-up copy consistently uses `Aufladung` / `aufladen` (not `Neuladen`/`Nachladen`). +- Usage metrics remain technical terms: `Input`, `Output`, `Reasoning`. +- Placeholders remain unchanged in all updated strings. diff --git a/specs/23-workspace-i18n-audit-it.md b/specs/23-workspace-i18n-audit-it.md new file mode 100644 index 000000000..da1b72826 --- /dev/null +++ b/specs/23-workspace-i18n-audit-it.md @@ -0,0 +1,86 @@ +## workspace i18n audit - it + +Italian translation audit for workspace routes with focus on Zen brand integrity and AI/billing term precision. + +--- + +### coverage + +- Route scope: `packages/console/app/src/routes/workspace/**` +- Locale file: `packages/console/app/src/i18n/it.ts` +- Source reference: `packages/console/app/src/i18n/en.ts` +- Unique keys in scope: **181** (`177` `workspace.*` + `4` `common.*`) +- Flagged keys: **25** (critical: 2, major: 18, minor: 5) + +--- + +### glossary decisions (it) + +- `Zen`: keep exactly `Zen` +- `Stripe`: keep exactly `Stripe` +- `OpenCode Black`: keep exactly `OpenCode Black` +- `opencode`: keep exactly `opencode` +- `API`: keep exactly `API` +- `/models`: keep exactly `/models` +- `API key`: `chiave API` / `chiavi API` +- `billing`: `fatturazione` +- `auto reload` (billing): `ricarica automatica` +- `reload` in billing context: top-up/recharge semantics (never page refresh) + +--- + +### required key updates + +| key | current_it | replace with | severity | reason | +| -------------------------------------- | ------------------------------------------------------------------- | ----------------------------------------------------------------------- | -------- | --------------------------------------------------------- | +| workspace.nav.zen | zen | Zen | critical | Brand literal must match exactly. | +| workspace.black.waitlist.left | Sinistra | Uscito dalla lista d'attesa | critical | `Left` is waitlist status, not direction. | +| workspace.billing.manage | Maneggio | Gestisci | major | Wrong lexical meaning for CTA. | +| workspace.billing.subtitle.beforeLink | Gestire i metodi di pagamento. | Gestisci i metodi di pagamento. | major | UI copy should be imperative, not infinitive. | +| workspace.black.waitlist.joined | Sei in lista d'attesa per il piano nero ${{plan}} al mese OpenCode. | Sei in lista d'attesa per il piano OpenCode Black da ${{plan}} al mese. | major | Preserve exact product naming and natural billing phrase. | +| workspace.black.waitlist.leaving | In partenza... | Uscita in corso... | major | Wrong async action meaning for waitlist exit. | +| workspace.black.subscription.resetsIn | Si reimposta | Si reimposta tra | major | Missing connector for duration composition. | +| workspace.members.inviting | Invitante... | Invito in corso... | major | Incorrect grammar for in-progress invite state. | +| workspace.members.role.admin | Ammin | Admin | major | Role label typo / non-standard abbreviation. | +| workspace.members.saving | Risparmio... | Salvataggio in corso... | major | Persistence action mistranslated as money saving. | +| workspace.providers.saving | Risparmio... | Salvataggio in corso... | major | Persistence action mistranslated as money saving. | +| workspace.reload.saving | Risparmio... | Salvataggio in corso... | major | Persistence action mistranslated as money saving. | +| workspace.monthlyLimit.setting | Collocamento... | Impostazione in corso... | major | Wrong lexical meaning for `Setting...`. | +| workspace.newUser.step.login.before | Correre | Esegui | major | CLI instruction must convey `Run`. | +| workspace.payments.table.amount | Quantità | Importo | major | Financial amount requires `Importo`. | +| workspace.keys.title | API Chiavi | Chiavi API | major | Technical term order is incorrect. | +| workspace.nav.apiKeys | API Chiavi | Chiavi API | major | Technical term order is incorrect. | +| workspace.providers.table.apiKey | API Chiave | Chiave API | major | Technical term order is incorrect. | +| workspace.providers.title | Porta la tua chiave | Bring Your Own Key (BYOK) | major | Preserve BYOK concept explicitly in AI-provider context. | +| workspace.reload.enabled.after | quando l'equilibrio raggiunge | quando il saldo raggiunge | major | Billing semantic error (`saldo`, not physical balance). | +| workspace.billing.addAction | Aggiungere | Aggiungi | minor | CTA should be imperative form. | +| workspace.payments.view | Visualizzazione | Visualizza | minor | CTA should be verb, not noun. | +| workspace.reload.disabled.before | La ricarica automatica lo è | La ricarica automatica è | minor | Remove incorrect pronoun for grammatical sentence. | +| workspace.reload.enabled.before | La ricarica automatica lo è | La ricarica automatica è | minor | Remove incorrect pronoun for grammatical sentence. | +| workspace.newUser.feature.lockin.title | Nessun blocco | Nessun lock-in | minor | Prefer established product/industry term. | + +--- + +### implementation batches + +1. **Critical brand/status fixes** + - `workspace.nav.zen`, `workspace.black.waitlist.left` +2. **Billing and waitlist semantics** + - `workspace.billing.manage`, `workspace.billing.subtitle.beforeLink`, `workspace.black.waitlist.joined`, `workspace.black.waitlist.leaving`, `workspace.black.subscription.resetsIn`, `workspace.reload.enabled.after`, `workspace.payments.table.amount` +3. **Async/action grammar correctness** + - `workspace.members.inviting`, all `*.saving` keys, `workspace.monthlyLimit.setting`, `workspace.newUser.step.login.before` +4. **AI/API terminology consistency** + - `workspace.keys.title`, `workspace.nav.apiKeys`, `workspace.providers.table.apiKey`, `workspace.providers.title` +5. **Minor CTA/style normalizations** + - `workspace.billing.addAction`, `workspace.payments.view`, `workspace.reload.disabled.before`, `workspace.reload.enabled.before`, `workspace.newUser.feature.lockin.title` + +--- + +### acceptance checks for follow-up fix agent + +- `workspace.nav.zen` is exactly `Zen`. +- Waitlist status strings use state semantics (`joined`, `leaving`, `left`) and preserve `OpenCode Black`. +- Billing `reload` copy clearly means balance top-up/recharge. +- `Chiave API` / `Chiavi API` ordering is consistent across workspace UI. +- BYOK meaning remains explicit in provider setup title. +- All placeholders are preserved exactly (`{{plan}}`, `{{provider}}`, `{{prefix}}`, `{{amount}}`, etc.). |
