Skip to content

Add refresh-keys command and update all language packs - #74

Merged
rockstardev merged 8 commits into
mainfrom
feat/newkeys-no-openrouter
Jun 9, 2026
Merged

Add refresh-keys command and update all language packs#74
rockstardev merged 8 commits into
mainfrom
feat/newkeys-no-openrouter

Conversation

@rockstardev

@rockstardev rockstardev commented Jun 9, 2026

Copy link
Copy Markdown
Member

Two changes here.

  1. New refresh-keys command

Pulls the current English strings and inserts any that are missing into the translation files as placeholders. Unlike update, it doesn't use OpenRouter (no API key needed), it's insert-only (never deletes keys, so DI-registered strings stay), and it leaves existing lines untouched. Pass --source-file to read a local Translations.Default.cs instead of downloading from GitHub.

dotnet run -- refresh-keys --source-file ./Translations.Default.cs
dotnet run -- generate-manifest
  1. Brought all 16 language packs up to date

Added the ~250 new strings (passkeys, multisig signing, subscriptions/monetization, store quotas, translation management) and translated them for each language, following each file's existing tone and terminology. Only the
new strings changed - existing translations and key ordering are untouched. manifest.json regenerated to match.

Tests: added unit + CLI coverage for refresh-keys; validate-packs reports no new issues.

Note: the new translations are machine-generated, so native-speaker review will be needed.

@coderabbitai

coderabbitai Bot commented Jun 9, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

Warning

Review limit reached

@rockstardev, we couldn't start this review because you've reached your PR review rate limit.

More reviews will be available in 20 minutes and 40 seconds. Learn how PR review limits work.

Your organization has run out of usage credits. Purchase more in the billing tab.

⌛ How to resolve this issue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans include higher PR review limits than trial, open-source, and free plans. In all cases, reviews become available again over time. During sustained high-volume PR review activity, CodeRabbit may temporarily slow when the next review becomes available.

Please see our Fair Usage Limits Policy for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 29fa9765-9bda-4b39-b2a5-b68b7074545e

📥 Commits

Reviewing files that changed from the base of the PR and between 0030e6c and f2dd783.

📒 Files selected for processing (4)
  • Translator/Services/TranslationOrchestrator.cs
  • translations/italian.json
  • translations/korean.json
  • translations/romanian.json
📝 Walkthrough

Walkthrough

This PR introduces a refresh-keys command that inserts newly-added English source keys as placeholders into existing translation files without requiring an OpenRouter API key. The feature spans optional API key handling, byte-preserving JSON key insertion with formatting preservation, CLI command wiring, comprehensive tests, documentation, and bulk translation updates across ten languages.

Changes

Refresh Keys Without Translation

Layer / File(s) Summary
Optional API Key Enforcement
Translator/Services/BaseTranslationService.cs
API key changed to nullable; constructor no longer throws when missing; new EnsureApiKeyConfigured() enforces requirement only at translation time in TranslateAsync and TranslateBatchAsync.
FileWriter Key Insertion with Formatting Preservation
Translator/Services/FileWriter.cs
New InsertMissingKeysAsync() method inserts missing keys by splicing into existing JSON while preserving line formatting, trailing commas, and newline styles; BuildRebuilt() performs the text reconstruction and validation.
TranslationOrchestrator Refresh Operation
Translator/Services/TranslationOrchestrator.cs
RefreshKeysAsync() scans language JSON files, loads source keys, calls InsertMissingKeysAsync() on each file, and returns RefreshResult with per-file and global key insertion counts.
CLI refresh-keys Command Registration and Handler
Translator/Program.cs
Registers refresh-keys command with --source-file, --languages, and --btcpay-url options; handler applies configuration, logs warnings when both source inputs provided, calls RefreshKeysAsync(), and exits with status 1 if no files processed.
Unit and Integration Tests
Translator.Tests/CLI/CliTests.cs, Translator.Tests/Services/FileWriterRefreshTests.cs, Translator.Tests/Services/TranslationOrchestratorTests.cs
CLI test exercises command end-to-end; FileWriter tests validate key positioning, placeholder values, formatting preservation, idempotency, and JSON escaping; Orchestrator tests verify missing-key insertion, language filtering, unknown file skipping, and idempotence.
Documentation, Manifest, and Bulk Translation Updates
README.md, manifest.json, translations/*.json (10 language files)
README documents refresh-keys usage and behavioral differences from update; manifest refreshed with updated Sha and timestamps; all translation files receive bulk additions/updates for passkeys, authenticator, multisig, LNURL-pay, permissions, and other new UI strings.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Poem

🐰 Fresh keys now bloom without the AI's call,
Placeholders inserted, formatting preserved for all,
No API keys required for this gentle refresh—
Just English defaults filling translation mesh!

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/newkeys-no-openrouter

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 5

🧹 Nitpick comments (4)
translations/italian.json (1)

1096-1096: 💤 Low value

Consider translating "Maintainer".

The term "Maintainer" appears untranslated. While it's commonly used in open-source contexts, for consistency with other role/user-related terms in Italian (e.g., "Amministratore" for Administrator), consider translating it to "Manutentore" or "Responsabile".

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@translations/italian.json` at line 1096, The "Maintainer" translation key in
translations/italian.json currently keeps the English value; update the value
for the "Maintainer" key to an Italian equivalent (e.g., "Manutentore" or
"Responsabile") to match other role translations and maintain consistency across
the locale file.
translations/korean.json (1)

1315-1319: ⚡ Quick win

Passkey terminology is mixed (English/Korean) across related strings.

Some entries transliterate/retain “Passkey” while surrounding Korean text is localized; this can feel inconsistent in the same flow. Recommend deciding one style (keep “Passkey” brand-like term everywhere, or use a Korean equivalent consistently).

Also applies to: 1557-1561, 2031-2031, 2450-2450

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@translations/korean.json` around lines 1315 - 1319, Translation strings for
passkey-related keys ("Passkey", "Passkey (Sign in with Passkey)", "Passkey name
(e.g., MacBook Touch ID)", "Passkeys", and the long description) mix English
"Passkey"/"Passkeys" with Korean text; pick a consistent style (either keep the
English brand "Passkey" everywhere or fully localize to a Korean equivalent) and
update all related keys mentioned (also at the other occurrences noted) to use
that chosen term consistently and adjust surrounding Korean phrasing accordingly
so the flow reads uniformly.
translations/portuguese (brazil).json (1)

19-19: ⚡ Quick win

Possible missing translation for "Labels".

The term "Labels" appears untranslated in this entry, but elsewhere in the file (line 1034, line 38, line 1214) "Labels"/"Label" is consistently translated as "Etiquetas"/"Etiqueta". Consider translating to maintain terminology consistency:

-  "{0} Labels": "{0} Labels",
+  "{0} Labels": "{0} Etiquetas",
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@translations/portuguese` (brazil).json at line 19, The translation entry for
the key "{0} Labels" is still in English; update its value to the Portuguese
equivalent used elsewhere ("{0} Etiquetas") to keep terminology consistent with
other keys like "Label"/"Etiqueta" and occurrences on lines referenced (e.g.,
the same "{0} Labels" key).
translations/serbian.json (1)

1-2540: ⚡ Quick win

Machine-generated translations require native-speaker review.

As noted in the PR description, these translations are machine-generated and need review by native Serbian speakers. While the technical structure (JSON format, placeholders like {0}, HTML tags like <strong>) is correctly preserved, the quality and accuracy of the Serbian translations should be validated by someone fluent in Serbian to ensure:

  • Correct grammar and natural phrasing
  • Appropriate terminology for technical concepts (passkeys, multisig, LNURL, etc.)
  • Cultural and linguistic appropriateness
  • Consistency with existing translations

The technical implementation is sound, but human linguistic validation is recommended before relying on these translations in production.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@translations/serbian.json` around lines 1 - 2540, Summary: The JSON contains
machine-generated Serbian translations that require native-speaker linguistic
review. Fix: Have a native Serbian reviewer proofread all values in
translations/serbian.json (including keys like "_maintainer" and entries such as
"Passkeys", "LNURL", "Lightning", "BIP39 Seed", "PSBT", "xpub", and others),
ensuring grammar, natural phrasing, consistent technical terminology, and
cultural appropriateness; do not alter placeholders or HTML tags (e.g. {0}, {1},
<strong>, <code>), keep JSON structure intact, and update any mistranslated
strings for consistency with existing translations and UI context before merging
and testing in the running UI.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@translations/italian.json`:
- Line 78: The "Abort" key in the translations JSON is still in English; update
the value for the "Abort" key to the appropriate Italian translation (e.g.,
replace "Abort" : "Abort" with "Abort" : "Annulla" to match other action labels)
so the Italian localization uses the translated string.

In `@translations/korean.json`:
- Line 1057: The translation for the key "Lightning" is inconsistent with nearby
entries; change its value from "Lightning" to the Korean equivalent "라이트닝" in
the translations JSON (update the "Lightning" key's value) so the UI matches
surrounding translations.
- Line 1096: The translation key "Maintainer" currently mapped to "관리자" is
ambiguous with "Administrator"; update the Korean value for the "Maintainer"
JSON key to a distinct, accurate term such as "유지보수 담당자" (or "유지 관리자") to
clearly differentiate it from the Administrator translation, ensuring the change
is applied to the "Maintainer" entry in translations/korean.json.

In `@translations/romanian.json`:
- Line 1808: Replace the untranslated value for the JSON key "Signer" with the
Romanian translation "Semnatar" to match the existing translations for
signer/semnatar used elsewhere (e.g., "Signer key submitted successfully.",
"Submit signer key"); update the value for the key "Signer" from "Signer" to
"Semnatar" ensuring the capitalization matches other top-level labels.

In `@Translator/Services/TranslationOrchestrator.cs`:
- Around line 584-611: The code treats an empty languageCodes as an active
filter, causing all files to be skipped; change the creation of filterCodes so
an empty languageCodes is treated as "no filter" (null) — e.g., set filterCodes
to null when languageCodes is null or has no elements and only call
ToHashSet(StringComparer.OrdinalIgnoreCase) when languageCodes.Any() is true;
this will make the later check (filterCodes != null &&
!filterCodes.Contains(code)) behave correctly and allow the translationFiles
foreach to process all files when no languages were specified.

---

Nitpick comments:
In `@translations/italian.json`:
- Line 1096: The "Maintainer" translation key in translations/italian.json
currently keeps the English value; update the value for the "Maintainer" key to
an Italian equivalent (e.g., "Manutentore" or "Responsabile") to match other
role translations and maintain consistency across the locale file.

In `@translations/korean.json`:
- Around line 1315-1319: Translation strings for passkey-related keys
("Passkey", "Passkey (Sign in with Passkey)", "Passkey name (e.g., MacBook Touch
ID)", "Passkeys", and the long description) mix English "Passkey"/"Passkeys"
with Korean text; pick a consistent style (either keep the English brand
"Passkey" everywhere or fully localize to a Korean equivalent) and update all
related keys mentioned (also at the other occurrences noted) to use that chosen
term consistently and adjust surrounding Korean phrasing accordingly so the flow
reads uniformly.

In `@translations/portuguese` (brazil).json:
- Line 19: The translation entry for the key "{0} Labels" is still in English;
update its value to the Portuguese equivalent used elsewhere ("{0} Etiquetas")
to keep terminology consistent with other keys like "Label"/"Etiqueta" and
occurrences on lines referenced (e.g., the same "{0} Labels" key).

In `@translations/serbian.json`:
- Around line 1-2540: Summary: The JSON contains machine-generated Serbian
translations that require native-speaker linguistic review. Fix: Have a native
Serbian reviewer proofread all values in translations/serbian.json (including
keys like "_maintainer" and entries such as "Passkeys", "LNURL", "Lightning",
"BIP39 Seed", "PSBT", "xpub", and others), ensuring grammar, natural phrasing,
consistent technical terminology, and cultural appropriateness; do not alter
placeholders or HTML tags (e.g. {0}, {1}, <strong>, <code>), keep JSON structure
intact, and update any mistranslated strings for consistency with existing
translations and UI context before merging and testing in the running UI.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 035ffa81-1bd8-421c-8199-31b470dca5aa

📥 Commits

Reviewing files that changed from the base of the PR and between d1d6bc8 and 0030e6c.

📒 Files selected for processing (25)
  • README.md
  • Translator.Tests/CLI/CliTests.cs
  • Translator.Tests/Services/FileWriterRefreshTests.cs
  • Translator.Tests/Services/TranslationOrchestratorTests.cs
  • Translator/Program.cs
  • Translator/Services/BaseTranslationService.cs
  • Translator/Services/FileWriter.cs
  • Translator/Services/TranslationOrchestrator.cs
  • manifest.json
  • translations/dutch.json
  • translations/french.json
  • translations/german.json
  • translations/hindi.json
  • translations/indonesian.json
  • translations/italian.json
  • translations/japanese.json
  • translations/korean.json
  • translations/norwegian.json
  • translations/portuguese (brazil).json
  • translations/romanian.json
  • translations/russian.json
  • translations/serbian.json
  • translations/spanish.json
  • translations/thai.json
  • translations/turkish.json

Comment thread translations/italian.json Outdated
Comment thread translations/korean.json Outdated
Comment thread translations/korean.json Outdated
Comment thread translations/romanian.json Outdated
Comment thread Translator/Services/TranslationOrchestrator.cs Outdated
rockstardev and others added 4 commits June 9, 2026 17:20
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
@rockstardev
rockstardev merged commit aa611dc into main Jun 9, 2026
1 check passed
Comment thread translations/spanish.json
"All Directions": "Todas las direcciones",
"All Labels": "Todas las Etiquetas",
"All Plugins": "Todos los plugins",
"All signer keys submitted": "Todas las claves de firmantes enviadas",

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Todas las claves de los firmantes enviadas

Comment thread translations/spanish.json
"Combine filters:": "Combinar filtros:",
"Comma-separated list of currencies (eg. USD,EUR,JPY)": "Lista separada por comas de monedas (ej. USD,EUR,JPY)",
"Compatible wallets": "Wallets compatibles",
"Complete signer collection before creating the multisig wallet.": "Completa la recopilación de firmantes antes de crear la billetera multisig.",

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Completa la recopilación de los firmantes antes de crear la billetera multisig.

Comment thread translations/spanish.json
"Contact Us": "Contáctanos",
"Container Name": "Nombre del contenedor",
"Continue": "Continuar",
"Continue multisig setup in progress": "Continuar la configuración multisig en curso",

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Continuar la configuración de multisig en curso

Comment thread translations/spanish.json
"Logout": "Cerrar sesión",
"Logs": "Registros",
"Mails": "Correos",
"Maintainer": "Maintainer",

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Mantenedor

Comment thread translations/spanish.json
"On-Chain Payout Processor": "Procesador de pagos On-Chain",
"On-chain wallets": "Billeteras on-chain",
"One or more selected users are invalid.": "Uno o más usuarios seleccionados no son válidos.",
"One or more signers no longer have wallet signing permission.": "Uno o más firmantes ya no tienen permiso de firma de billetera.",

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"Uno o más firmantes ya no tienen permiso de firma de en la billetera."

Comment thread translations/spanish.json
"Overpaid amount": "Cantidad pagada en exceso",
"Overpaid amount cannot be calculated": "No se puede calcular el monto pagado en exceso",
"Override the block explorers used": "Anular los exploradores de bloques utilizados",
"Override the server default maximum number of stores for this user. Leave empty to use the server default.": "Anular el número máximo de tiendas predeterminado del servidor para este usuario. Dejar vacío para usar el valor predeterminado del servidor.",

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"Anular el número máximo de tiendas predeterminadas del servidor para este usuario. Dejar vacío para usar el valor predeterminado del servidor."

Comment thread translations/spanish.json
"Reference Id": "ID de referencia",
"Refund": "Reembolso",
"Refund {0}": "Reembolsar {0}",
"Refund pull payment created.": "Reembolso de pago pull creado.",

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Se ha creado el pago de reembolso.

Comment thread translations/spanish.json
"Request {0} - {1}/{2} ({3}).": "Solicitud {0} - {1}/{2} ({3}).",
"Request Pairing": "Solicitar Emparejamiento",
"Request signer keys from store users": "Solicitar claves de firmantes a los usuarios de la tienda",
"Request signer keys, collect account keys, and create the multisig wallet": "Solicita las claves de firmantes, recopila las claves de cuenta y crea la billetera multisig",

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"Solicita las claves de los firmantes, recopila las claves de cuenta y crea la billetera multisig"

@NicolasDorier

NicolasDorier commented Jun 10, 2026

Copy link
Copy Markdown
Member

This should not be used

dotnet run -- refresh-keys --source-file ./Translations.Default.cs

This list is not up to date because it only include what is hardcoded injected into the DI. There are more strings than this that get registered to DI, so you should use --btcpay-url http://localhost:14142

Btw, if you install plugins and plugins register those strings in the DI, those can be added to the translation list if we wanted.

image

EDIT: The issue isn't only caused by --btcpay-url http://localhost:14142. It is also caused by the fact, I am not registering some strings. I need to do this first.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants