dsh-locale-ja
DeepSeek Harness (DSH) の Web GUI を日本語にする言語パックプラグインです。
en / zh を置き換えるのではなく、ja ロケールを追加します。in-box のクライアント UI が
持つ 42 名前空間 / 1257 キーを収録しています。訳が抜けたキーは en にフォールバックするので、
生のキーが画面に出ることはありません。
インストール
dsh plugin --profile web add file:/path/to/jpdsh
dsh plugin add はプロファイルディレクトリで pnpm を実行し、インストール結果から
dsh.profile.bundles を更新します。このパッケージは dsh.bundle を宣言しているため、
プロファイルの1レイヤーとして組み込まれます。
git から直接入れることもできます。
dsh plugin --profile web add github:rbstxt/dsh-locale-ja
インストール後、設定 → 一般 → 言語 で「日本語」を選ぶか、$DSH_HOME/settings.yaml に
次を書きます。
locale:
preference: ja
headless や sdk など、ブラウザ面を持たないプロファイルは対象外です。
仕組み
DSH のプラグインは bundle と client の二面でできています。このパッケージもその規約に乗っています。
| 面 | 宣言 | 役割 |
|---|
| bundle | dsh.bundle.patch | プロファイルへ Loader 行を1つ挿入する |
| client | dsh.client、platform: web | lib/client.js をブラウザ面として配信する |
起動の流れは次のとおりです。
dsh plugin add が dsh.profile.bundles にパッケージを追加する
cordis.patch.yml が id: locale-ja の Loader 行を挿入する
@deepseek-ai/dsh-client-modules が dsh.client を検出し、/plugins/dsh-locale-ja/client.js として配信する
- ブラウザ側の cordis が
lib/client.js の apply(ctx) を実行する
apply が使うのは @deepseek-ai/dsh-client-locale の言語パック API だけです。
ctx.effect(() => ctx.locale.addLanguage({ id: "ja", label: "日本語", fallback: "en" }), "…");
for (const [ns, dict] of Object.entries(DICTIONARIES)) {
ctx.effect(() => ctx.locale.register(ns, "ja", dict), `…`);
}
addLanguage が言語の定義を、register(ns, locale, dict) が名前空間ごとの辞書を登録します。
この単一ロケール形式は言語パック専用の入口で、既存機能が所有する名前空間にも別ロケールを
足せます。重複判定は namespace と locale の組単位です。登録はすべて ctx.effect の所有物なので、
プラグインを外せば ja ごと消えます。
ホスト面の lib/index.js は何もしません。dsh.client を宣言した解決可能な Loader 行で
あることだけが役割で、モデルから見えるサービスは増やしません。
ファイル構成
| パス | 役割 |
|---|
lib/client.js | ブラウザ面。生成物 |
lib/index.js | ホスト面 |
cordis.patch.yml | bundle パッチ |
locales/ja.json | マージ済み日本語辞書 |
translation/ | 原文の抽出結果、翻訳の入出力、訳語集 |
tools/ | 抽出、分割、整合、ビルド、検証のスクリプト |
メンテナンス
DSH 本体を更新して UI 文字列が増えたら、同じ手順を回します。
node tools/capture-dictionaries.mjs --out translation/source-en-zh.json --verbose
node tools/split-translation.mjs translation/source-en-zh.json
# translation/in/part-NN.json を訳して out/part-NN.json に書く
node tools/consistency-pass.mjs --write
node tools/build-plugin.mjs
node tools/verify-client.mjs
capture-dictionaries.mjs は各 lib/client.js を VM で読み込み、window.__ModuleLoader__.load
のファクトリを取り出します。そのうえでモックしたクライアントコンテキストで apply(ctx) を呼び、
locale.register を記録します。バンドルは Rolldown の __toESM ヘルパーでモジュールの
名前空間を自前で組み立てるため、ハーネスはバンドル中の識別子をすべて公開するプロキシを使い、
react.memo のような名前付きエクスポートが消えないようにしています。
build-plugin.mjs は名前空間、キー集合、プレースホルダーを検証し、欠落や余剰があれば
ビルドを中止します。訳の抜けは画面では英語へのフォールバックとしてしか見えないので、
ビルド時に落とすほうが安全です。
検証
node tools/verify-client.mjs
# ok: 日本語 (ja), 42 namespaces, 1257 keys, 43 owned effects
生成したバンドルを本番と同じ契約、つまり __ModuleLoader__.load → factory(require) →
apply(ctx) の順で実行し、登録内容が locales/ja.json と一致することを確認します。
隔離した DSH_HOME を使えば、手元の環境を汚さずに統合確認できます。
DSH_HOME=/tmp/dsh-ja-test dsh plugin --profile web add file:$PWD
printf 'locale:\n preference: ja\n' > /tmp/dsh-ja-test/settings.yaml
DSH_HOME=/tmp/dsh-ja-test dsh web --port 3081 --no-open
ヘッドレス Chrome で確認できた範囲は次のとおりです。
<html lang="ja"> が設定される
- サイドバー、設定の全タブ、プラグイン一覧、オンボーディングが日本語で表示される
- 日本語を含まない行に未訳の英字は残らない。プラグイン ID やモデル名などの識別子は除く
検証時のスクリーンショット
翻訳の方針
訳語集は translation/GLOSSARY.md、機械的な規則は tools/consistency-pass.mjs にあります。
- ボタンやラベルは体言止め
{placeholder} は変更しない。省略記号は …
- 英字と日本語の間は半角スペース1つ。数字と助数詞は続ける。例は
{n}件、1回
- 時間の単位は日本語に開く。例は
{seconds}秒、{n}日。トークンの単位は原綴りのまま。例は {value} tok、{value}K
- API、JSON、CLI、Diff、Schema、TTFT などの技術用語と製品名は原綴り
制約
@deepseek-ai/dsh-client-locale 側の制約で、登録時に取り込まれた文言は言語を切り替えても追従しません。スロット経由で描画される文言は即時に切り替わります。
- 翻訳するのはクライアント UI の文言だけです。プラグイン ID、モデル ID、コマンド名、ファイルパス、ホストが返すエラーコードは識別子なので翻訳しません。
- DSH 本体のバージョンが上がって名前空間やキーが増えた場合、上の手順の再実行が必要です。未訳のキーは英語で表示されます。
ライセンス
MIT