mcpField
S
svintl

svintl

github.com/temich開発6269 回インストール2 週間前に更新
リポジトリ

svintl について

svintlは、Svelteの国際化辞書を管理するCLIで、多言語アプリを開発する人向けです。翻訳ファイルを生成し、OpenAIによる言語追加、動的な値、複数形、マウント単位の管理に対応します。

主な機能

  1. 01CLIによる辞書管理
  2. 02OpenAIを使った翻訳生成
  3. 03プレースホルダーと複数形の処理
  4. 04マウント単位で翻訳を整理

活用シーン

  1. 01翻訳キーの一括追加や更新
  2. 02コンテキストに基づく辞書の生成
  3. 03動的な文言や複数形の利用
  4. 04アプリ領域ごとの翻訳分割

インストール

コマンドをコピーしてターミナルで実行します。

$npx skills add https://github.com/temich/svintl --skill svintl

インストール後、Claude Code で/svintlを入力して読み込まれたか確認します。

詳細

svintl — Svelte 向け i18n

OpenAI による自動翻訳を利用して、国際化辞書を管理する CLI ツールです。

基本ルール

intl ディレクトリ内の *.yaml、built.js、types.ts ファイルは生成されるファイルです。手動で編集せず、npx intl CLI で編集してください。

CLI コマンド

npx intl hola                               # init dictionaries (default: src/lib/intl/)
npx intl hola -p ./custom/path              # init at custom path
npx intl add key.path "Value" "context"     # add a new key — fails if it already exists; context optional
npx intl set key.path "Updated value"       # update a key that already exists — fails if missing
npx intl set "mount/key.path" "Value"       # target a mount with the mount/ prefix
npx intl add --from strings.yaml            # many new keys in one run — `key: value` or `key: { value, context }`, flat (`a.b: …`) or nested (`a: { b: … }`)
npx intl set --from strings.yaml            # many existing keys in one run; `--from -` reads stdin
npx intl add key.path "Value" --debug       # --debug (add or set): print the OpenAI request first
npx intl create de --tokens 60000           # --tokens (any command): output-token limit per OpenAI request, default 30000
npx intl const key.path "Same everywhere"   # same value across all locales (no translation)
npx intl unit items.count "item"            # pluralized entry (auto-generates plural forms)
npx intl move old.key new.key               # rename key/branch
npx intl del key.path                       # delete key/branch
npx intl create es                          # add a locale (BCP 47 tag) — auto-translates the whole dictionary into it
npx intl destroy es -y                      # delete locale (without -y it fails)
npx intl mount foo ./any/path               # create empty mount
npx intl import foo ./any/path              # adopt existing dict dir as mount, reconcile locales
npx intl unmount foo                        # remove mount (keeps files)
npx intl context "Project description"      # set project-wide translation guidance
npx intl context --clear                    # clear project context
npx intl genders he she none                # enable gender-aware translations (list the gender values)
npx intl genders                            # print current gender values
npx intl sync en key.path                   # reconcile: re-translate one key into all locales from source en
npx intl sync en                            # reconcile: re-translate the whole dictionary from source en
npx intl build                              # rebuild JS/TS from YAML

辞書の形式

任意の階層構造を持つ YAML で、末端の値には文字列を指定します。

native: English
example:
  hello: "Hello world"

使用方法:{$dict.example.hello}

動的な値 — プレースホルダー

単純なケースでは、CLI がプレースホルダー構文から !js 関数を自動生成するため、手動で記述する必要はありません。

npx intl set greeting "Hello, {name}!"            # {name} → function param
npx intl set joined "[names] joined {groupName}"  # [names] → Intl.ListFormat

複雑なロジックの場合は、intl set で !js 関数を渡します。

npx intl set greeting '!js (count) => `${count || "No"} item${count === 1 ? "" : "s"}`'

コンポーネントでの使用方法:{$dict.greeting(user.name)}

フレーズ全体を辞書に記述してください。 テンプレート内で動的な値を挟んで文を分割しないでください。


<strong>{brand}</strong>{$dict.form.destroyDescription}


{@html $dict.form.destroyDescription(brand)}
npx intl set "apps/form.destroyDescription" \
  '!js (brand) => `<strong>${brand}</strong> and all accumulated data will be permanently deleted.`'

名前にマークアップが必要で、どの言語でも常にフレーズの先頭にある場合は、タグを !js 関数内に記述し、{@html} でレンダリングしてください。値を渡す前に、ユーザーが制御する値をエスケープしてください。

複数形

npx intl unit を使用すると、Intl.PluralRules ベースの関数が生成されます。

npx intl unit items.count "item"

次のように生成されます。

items:
  count:
    - one: item
      other: items

使用方法:{$dict.items.count(count)}

ロシア語やアラビア語など、複雑なロケールでは few、many なども自動的に生成されます。

性別

有効にすると(npx intl genders he she none)、性別に応じたフレーズは、最後の引数に性別('he' | 'she' | 'none')を取る関数になります。フレーズ自体の引数が先に来ます。たとえば (name, gender) => … のようになります。列挙した値は、生成される Grammar ユニオン型になります。

マウント

翻訳を複数のディレクトリに分けて整理できます。

npx intl mount admin ./src/features/admin/intl
npx intl set "admin/dashboard.title" "Admin Dashboard"

マウントキーには、CLI コマンドで {mount}/ プレフィックスを使用します。

mount は空のマウントを作成し、import は内容のあるディレクトリ(独自の context.yaml を含む)を取り込み、そのロケールをルートに合わせて調整します。ルートにない言語を削除し、ルートにない言語を生成して(取り込んだ inputs を翻訳します)、共通するロケールはそのままにします。

インポートのパターン

ルート辞書:

<script lang="ts">
  import { dict, locale } from '$lib/intl'
</script>
<h1>{$dict.example.hello}</h1>

マウント辞書:

<script lang="ts">
  import { dict } from './intl'
</script>
<h1>{$dict.dashboard.title}</h1>

マウントの intl/index.ts(package.json で #lib/* をマッピングしている場合(SvelteKit 3 など)は、$lib/intl の代わりに #lib/intl/index.js を使用します。mount と import はここにその形式を書き込み、build は built.js に書き込みます):

import { derived } from 'svelte/store'
import { locale } from '$lib/intl'
import { dictionaries } from './built.js'
import type { Locale, Dictionary } from './types'

const dict = derived(locale, ($locale) => dictionaries[$locale])
export { dict, dictionaries, locale }
export type { Locale, Dictionary }

翻訳精度を高めるためのコンテキスト

npx intl set app.welcome "Welcome" "greeting shown on homepage"
npx intl context "B2B SaaS for enterprise users"

コンテキストは context.yaml に保存され、新しいロケールを作成する際に OpenAI が使用します。

ワークフロー

  1. npx intl add/set/unit/const を使用して翻訳を追加・更新します。複数のキーは、add --from / set --from のファイルにまとめます。npx intl をループで呼び出してはいけません。
  2. npx intl build を実行して JS/TS を生成します(自動実行されることもよくあります)。
  3. コンポーネントで dict ストアをインポートします。
  4. テンプレートで $dict.key.path を使用します。

避けること

  • YAML を手動で編集すること — CLI を使用してください。
  • npx intl のループ実行 — 呼び出しのたびにプロセス、翻訳リクエスト、ビルドが発生します。キーをファイルに書き込み、add --from を一度だけ実行してください。
  • 一括追加に const + sync を使うこと — sync は辞書全体を再翻訳します。add --from を使用してください。
  • 通常の編集で npx intl sync を使うこと — 手動でソースを編集した後の調整にのみ使用します。代わりに add / set を使用してください。
  • BCP47 に準拠しないロケールコード — en-US、es、pt-BR など、有効なタグを使用してください。
  • テンプレート内でフレーズを分割すること — 動的な値を辞書の接尾辞/接頭辞と連結しないでください。文全体を表す単一の {placeholder} / !js エントリーを使用してください。

コメント