Skip to content

feat: add Paraglide-based CLI i18n#24

Closed
nyatinte wants to merge 3 commits intomainfrom
codex/paraglide-i18n-cli
Closed

feat: add Paraglide-based CLI i18n#24
nyatinte wants to merge 3 commits intomainfrom
codex/paraglide-i18n-cli

Conversation

@nyatinte
Copy link
Copy Markdown
Owner

@nyatinte nyatinte commented Mar 14, 2026

What

  • add Paraglide-based i18n with English/Japanese message sources and locale initialization
  • localize CLI, UI, and workspace user-facing strings through generated messages

Why

  • close the current i18n gap for Japanese-speaking users without changing the CLI surface
  • make locale detection deterministic in the CLI by using os-locale with English fallback
  • keep the current unit-test scope focused while deferring prompt-level coverage to a more appropriate test layer

Ref

@gemini-code-assist
Copy link
Copy Markdown
Contributor

Summary of Changes

Hello, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request significantly enhances the CLI by integrating internationalization capabilities. It allows the application to present messages in different languages, initially supporting English and Japanese, thereby improving accessibility for a broader user base. The changes involve setting up a new i18n framework, localizing all user-facing text, and ensuring that the build and test processes correctly handle the new language assets.

Highlights

  • Internationalization (i18n) Implementation: Introduced Paraglide.js for internationalization, enabling the CLI to support multiple languages, starting with English and Japanese.
  • Localized User-Facing Strings: All user-facing messages in the CLI, UI prompts, and workspace-related errors have been localized using Paraglide's message system.
  • Automated Locale Detection: Implemented deterministic locale detection in the CLI using the os-locale package, with a fallback to the system's Intl.DateTimeFormat if os-locale fails.
  • Build and Test Workflow Integration: Updated build and test scripts to include a paraglide:compile step, ensuring that generated i18n messages are available before compilation and testing, and configured .gitignore to ignore these generated files.
  • Enhanced Test Coverage for Localization: Added dedicated tests for locale resolution and updated existing CLI tests to assert against localized error messages, improving the robustness of the i18n implementation.
Changelog
  • .gitignore
    • Added src/paraglide/ to ignore generated internationalization files.
  • messages/en.json
    • Added English message definitions for CLI and UI strings.
  • messages/ja.json
    • Added Japanese message definitions for CLI and UI strings.
  • package.json
    • Added paraglide:compile script to generate i18n messages.
    • Updated build and test scripts to run paraglide:compile before their main tasks.
    • Added @inlang/paraglide-js as a development dependency.
    • Added os-locale as a production dependency for locale detection.
  • pnpm-lock.yaml
    • Updated lockfile to include new dependencies: @inlang/paraglide-js, os-locale, and their transitive dependencies.
  • project.inlang/settings.json
    • Added Inlang project settings, configuring base locale, supported locales, and message format plugin.
  • src/cli.test.ts
    • Added mock for @clack/prompts to control isCancel and log.message behavior.
    • Imported m for localized messages and setLocale for test setup.
    • Introduced resetCliTestState function for consistent test environment setup.
    • Added helper functions expectPackageSelectionError and expectResolveScriptError for localized error assertions.
    • Updated existing tests to use localized messages (m.no_packages_match, m.multiple_packages_match, m.cancelled, m.no_scripts_in_package) for error and cancellation scenarios.
  • src/cli.ts
    • Imported m from ./i18n for localized messages.
    • Replaced hardcoded user-facing strings with calls to m.<message_key>() for internationalization.
  • src/i18n.test.ts
    • Added new test file for internationalization logic.
    • Included tests for resolveSupportedLocale and initializeLocale functions.
    • Mocked os-locale to control locale detection in tests.
  • src/i18n.ts
    • Added new file to handle internationalization logic.
    • Implemented resolveSupportedLocale to normalize and select supported locales.
    • Implemented initializeLocale to detect the system locale using os-locale (with Intl.DateTimeFormat fallback) and set it via Paraglide.js.
    • Exported m (messages) for use throughout the application.
  • src/index.ts
    • Imported initializeLocale from ./i18n.
    • Called initializeLocale() at the start of the main function to set the application's locale.
  • src/ui.ts
    • Removed SELECT_PACKAGE_MESSAGE constant.
    • Imported m from ./i18n for localized messages.
    • Replaced hardcoded UI prompt messages with calls to m.<message_key>().
  • src/workspace.test.ts
    • Imported m and setLocale for i18n support in tests.
    • Added setLocale('en', { reload: false }) to beforeEach for consistent locale in tests.
    • Updated WorkspaceNotFoundError message to use m.workspace_root_required().
  • src/workspace.ts
    • Imported m from ./i18n for localized messages.
    • Replaced hardcoded WorkspaceNotFoundError message with m.workspace_root_required().
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for GitHub and other Google products, sign up here.

You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

Copy link
Copy Markdown
Contributor

@gemini-code-assist gemini-code-assist Bot left a comment

Choose a reason for hiding this comment

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

Code Review

This pull request introduces internationalization support using Paraglide, which is a great enhancement for the CLI. The changes are well-structured, including the addition of message files for English and Japanese, updates to the build process, and the core logic for locale detection and initialization. The existing codebase has been correctly updated to use the new localized messages, and the new functionality is well-tested. I have one suggestion to improve the maintainability of the locale resolution logic for better scalability in the future.

Comment thread src/i18n.ts
Comment on lines +3 to +25
import { setLocale } from "./paraglide/runtime.js";

export type SupportedLocale = "en" | "ja";

const DEFAULT_LOCALE: SupportedLocale = "en";

export const m = messages;

export function resolveSupportedLocale(
input: string | undefined
): SupportedLocale {
if (!input) {
return DEFAULT_LOCALE;
}

const normalized = input
.trim()
.replace(/_/g, "-")
.replace(/[.:].*$/, "")
.toLowerCase();

return normalized.startsWith("ja") ? "ja" : DEFAULT_LOCALE;
}
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.

medium

This file can be simplified and made more maintainable by leveraging more of the exports from the Paraglide runtime.

  1. The SupportedLocale type and DEFAULT_LOCALE constant are redundant. Paraglide generates and exports them as Locale and sourceLocale.
  2. The implementation of resolveSupportedLocale is not very scalable as it hardcodes a check for the 'ja' locale. This can be made more maintainable by using availableLocales from the Paraglide runtime, which will automatically include any new languages you add to your project.
import {
  setLocale,
  sourceLocale,
  availableLocales,
  type Locale,
} from "./paraglide/runtime.js";

export type SupportedLocale = Locale;

const DEFAULT_LOCALE: SupportedLocale = sourceLocale;

export const m = messages;

export function resolveSupportedLocale(
  input: string | undefined,
): SupportedLocale {
  if (!input) {
    return DEFAULT_LOCALE;
  }

  const normalized = input
    .trim()
    .replace(/_/g, "-")
    .replace(/[.:].*$/, "")
    .toLowerCase();

  // Find the best match from available locales, preferring more specific matches.
  const bestMatch = [...availableLocales]
    .sort((a, b) => b.length - a.length)
    .find((l) => normalized.startsWith(l));

  return bestMatch ?? DEFAULT_LOCALE;
}

@nyatinte
Copy link
Copy Markdown
Owner Author

replaced by #64

@nyatinte nyatinte closed this Mar 15, 2026
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.

Internationalization (i18n): support English and Japanese

1 participant