fix(i18n): restore the Japanese renderings the brand revert left in Latin (#12934)

* fix(i18n): restore the Japanese renderings the brand revert left in Latin

Before #12113 landed the canonical-rendering guard, the brand-mistranslation
revert treated ターミナル/エージェント/コミット/リポジトリ as machine-translation errors
and rewrote them back to English on every repair run. The guard stops new
damage, but ~700 values still carry it, so the Japanese UI reads
"この terminal を閉じると、agent の現在の作業が停止します。"

This heals what the catalog already holds and closes the defects the same
pipeline introduced elsewhere:

- Relocalize the four generic terms inside Japanese sentences. Both sides are
  anchored on an adjacent Japanese character and reject a `-`, word character
  or `.` neighbour, so `--agent`, agents.md and "Agent SDK" keep their spelling,
  and the 和欧間スペース survives in front of an interpolation.
- Preserve style blocks and command/identifier values in English. MT had
  rewritten a CSS selector to [データスラッシュメニュー], `background:` to `背景:` and a
  keyframe name to ブラウザフラッシュ, and had turned `pnpm install` into
  `pnpmインストール` and a toast dedup id into 陳腐なエージェント行. The same values are
  restored in ko, zh and es.
- Drop the phrase fixes that stripped ~してください from validation messages,
  which left 30 prompts ending in a bare noun.
- Settle terminology and typography: 紛争→競合, 資格情報→認証情報, 未知→不明,
  プロフィール→プロファイル, the full-width ellipsis, no separator space inside
  compound katakana, and one long-vowel form per word.
- Fix literal-translation errors (ナメクジ for slug, ミスター for MR, ランニング for
  Running, 高い/中くらい for priority labels) and complete the truncated Kimi
  status-bar description.
- Translate 570 values that were still English, 485 of them fragments the
  catalog had left untouched and 85 newly added strings.

The catalog is regenerated with `repair-locale-catalog.mjs` and the run is
idempotent: a second pass reports 0 leaf updates.

* fix(i18n): keep the leading space in concatenated Japanese fragments

* fix(i18n): close the self-review findings in the Japanese repair rules

Seven defects the relocalization pass introduced or left behind:

- `git commit` and `orca terminal` are two-word commands, and the position
  guards only looked at the character before the term, so the second word was
  katakana-ized ("git コミットが失敗したとき"). A command-head lookbehind covers
  git/gh/glab/orca/npm/pnpm/npx/yarn/docker/kubectl. A following Latin word now
  also blocks the rule, so "Agent SDK" keeps its spelling as the comment claims.
- `on: 'オン'` matched every "on" in the catalog, including the preposition in
  the external-automation delete confirmation, which rendered as
  "外部ソース オン myhost". Moved to a new ja key-override module so the toggle
  states and the preposition can differ; the module keeps
  locale-key-overrides.mjs under max-lines.
- The phrase fixes write Cookie and fast-forward back in Latin, but neither was
  in CJK_LATIN_SPACED_TERMS, so the 和欧間スペース was missing in five values.
- Three overrides spelled a half-width `...` that the ellipsis phrase fix
  rewrites anyway, so the comment described the opposite of the behavior.
- Two descriptions render as [text] <code> [text]. The Japanese closed the
  sentence with 。 and dropped the "such as" / "like" hand-off, leaving the code
  span outside the sentence in the Git and quick-command panes.
- `' vs {{value0}}'` and `' · {{value0}} external'` were missed by the previous
  leading-space fix, so "3 変更されたファイルvs main" rendered without a gap.

Adds three regression cases: two-word commands, the Latin-only label, and the
spacing for terms the phrase fixes reintroduce.

* fix(i18n): correct the Japanese an external review flagged

73 findings from a ChatGPT review of the full changed-value list, each
reproduced against the shipped catalog before being fixed:

- Two commands were translated into text that does not run: `pnpm playwright
  test` became `pnpm プレイライトテスト` and `gh auth login` became `GH 認証ログイン`.
  Both are pinned to English. A third value corrupted an identifier,
  rendering `packages/web` as `package/web`.
- Two descriptions carried a stale translation with no relation to their
  English source, and one had another row's text entirely.
- Syntax was misread in six values: `Command line Orca runs when…` read as
  "the command line runs", `Let programs … copy` as "copy the programs",
  `Dim files matched by .gitignore` kept `Dim` as a noun, and
  `powers live quota reads` became 強化.
- Wording that changed the warning: `diffs may miss recent commits` read as
  the commits being lost, `before merging is unblocked` as un-merging, and
  `the newer disk content` as new content.
- `host` was rendered as サーバー in eight values even though it covers SSH
  hosts, `worktrees` as ワークスペース, and `on this host` as リモート.
- Git vocabulary translated to its everyday sense: `upstream`→上流,
  `staged changes`→段階的な変更; and identifiers `lan`/`deploy` were localized.
- Instructions to the user had lost their imperative (…をインストールします),
  three validation messages still ended in a bare noun, and two completion
  notices read as future tense.
- Assorted breakage: 窓 for a desktop window, 分割分割線, ターミナルパネル for
  Terminal Panes, オプション for the macOS Option key, Herme for Hermes,
  and a reversed noun phrase in the repo-icon import error.

The `Open` action needed a key override: bare "Open" is the PR/issue state in
16 of 18 places, and only the browser download row and the checks panel use it
as the verb, matching what ko/zh/es already do.

Three fixes had to be reworded rather than written literally: the existing
新しい→新規 and 実験的→実験的機能 phrase fixes run after value overrides and
turned 新しい名前 into 新規名前 and 実験的な into 実験的機能な.

Not fixed: `{{value0}} site{{value1}} connected` still shows the plural-suffix
placeholder, which needs the code change already listed in the PR notes.

* fix(i18n): sweep the whole catalog for the defect classes the reviews found

The external review covered a sample. This runs each of its finding classes as
a detector over all 11,857 values and fixes what they turn up, as durable
pipeline rules rather than one-off value edits where the class recurs:

- host は サーバー ではない. Orca's "host" covers SSH hosts and this computer,
  so a phrase fix rewrites サーバー to ホスト whenever the English says host and
  does not also say server, where the two are deliberately distinct (15 values).
- worktree joins the guarded generic-term list, so the seven values still
  reading "worktree を削除" match the 205 that already say ワークツリー.
- Git vocabulary and brands restored from their everyday sense: 上流→upstream,
  起源→origin, 段階的な変更→ステージ済みの変更, エルメス/ヘルメス→Hermes,
  パワーシェル→PowerShell, アヒルアヒル→DuckDuckGo. All five terms are added to
  CJK_LATIN_SPACED_TERMS so the restored Latin keeps its 和欧間スペース.
- 14 more code values pinned to English: Tailwind class strings
  (size-4 text-muted-foreground → サイズ 4 テキストミュート前景), git refs
  (origin/main → 原点/メイン), sample hosts (example.com → 例.com) and spec
  fixtures (dashboard.spec.ts → ダッシュボードの仕様).
- 12 instructions regained their predicate (…を選択。 → …を選択してください。),
  and 窓のぼかし, macOSのオプションキー, 中くらいのセクション見出し are corrected.

Checked and deliberately not changed: toast notifications that end in 〜しました
(237) read correctly for a completion notice, and setting descriptions ending in
〜します (200) describe what the setting does rather than instructing the user.
Sound preset names stay katakana, matching the rest of that list.

Adds three regression cases covering the host rule and its server exception,
the Git/brand restorations, and the newly pinned class strings and refs.

* fix(i18n): keep Agent in Latin in the Japanese catalog

Japanese developer UIs conventionally leave Agent unlocalized — it names Orca's
own concept rather than the everyday word — so the ja catalog now writes it in
Latin and only normalizes the case, so no sentence mixes "agent" and "Agent".
The 和欧間スペース comes from the existing spaced-term list.

This is the one term where ja diverges from locale-generic-ui-terms.mjs, which
lists エージェント as the expected rendering; ターミナル, コミット and リポジトリ
follow it exactly. Three test expectations are updated to match, and the PR
description flags the divergence so a maintainer can ask for it to be reverted
— it is a single rule in locale-ja-phrase-fixes.mjs.

The guards are unchanged, so `--agent`, agents.md, `orca agent` and "Agent SDK"
keep their spelling.

* fix(i18n): preserve selectors with no declaration block, and sharpen progress labels

CodeRabbit was right that `STYLE_BLOCK` only matched a selector when it carried
a declaration block or an attribute selector. `div.pricing-grid >
div.card.starter:nth-of-type(1) > a.cta` was unprotected and only survived
because MT happened to leave it alone.

A value now also counts as style when every whitespace token is selector-shaped
and at least two carry a class, id, pseudo or attribute. The first attempt at
that threshold counted a sentence-final period as a selector join and froze 259
ordinary two-sentence strings in English; the marker must now be followed by a
letter, so `Show live workspace ports. Click it for …` stays translated. Both
directions are pinned by tests.

The predicate moved to locale-style-values.mjs to keep locale-translation-policy
under max-lines.

A DeepL cross-check of the whole changed-value list surfaced six more:

- Progress labels had lost their 〜中: `Creating...` read 作成…, `Reopening...`
  read 再開…, `Thinking…` read 考え…
- `Hide from sidebar` / `Show in sidebar` carried a stale 左サイドバーから Orca
  Mobileを削除 in one of six places, with the 和欧間スペース missing too
- `Recent or tab strip.` was 最近のまたはタブストリップ。, which is not Japanese

Everything else DeepL flagged was this PR's settled terminology (Agent, Issue,
ホスト, 競合, fast-forward) or a fragment where DeepL had no surrounding context.

* fix(i18n): treat proper nouns as brands, and cut the comment noise

Review feedback, all verified against the catalog:

- Hermes, PowerShell, Mermaid, Claude Code and VS Code are proper nouns, so
  they belong in BRAND_MISTRANSLATIONS with the other product names, not in the
  ja phrase fixes. Claude コードセッション, マーメイドダイアグラム and VS コードで開く
  were unfixed until now because nothing covered them.
- Sweeping every proper noun against the catalog found more the same way:
  Orca IDE rendered as OrcaIDE, and Git had no 和欧間スペース in eight values,
  because neither term was in CJK_LATIN_SPACED_TERMS.
- Settings-search keywords are lowercase, so the brand revert (case-sensitive)
  cannot reach them. windows read 窓, gitignore read ギティ無視, component read
  成分 (the chemistry sense), compose read 作曲する, and neovim/hermes/powershell
  were transliterated. Pinned by value.
- The override sources still spelled エージェント in 34 places even though the
  shipped value is Agent, so the file no longer said what it produced. The
  代理人 rule also ran after the Agent rule, so a future MT 代理人 would have
  stayed katakana; it now maps straight to Agent.
- Two of my own overrides had no matching English source left and were dead.

Comment volume is cut from 80 added lines to 25. The locale modules carry 2-8
comment lines each, and this PR was running an order of magnitude over that;
what is left is one line per genuinely non-obvious constraint.

BRAND_MISTRANSLATIONS moves to its own module to keep locale-translation-policy
under max-lines.

* fix(i18n): give every English string one Japanese rendering

215 English sources had two or more Japanese forms in the catalog, so the same
button read 削除 in one place and 削除する in another. Several of the variants
were also wrong outright: Hide read 隠れる, Sort read 選別, Run read 走る, and
"Don't ask again" read 二度と聞かないでください.

Picks follow the catalog majority — action labels drop する, completion notices
use 〜しました, status labels are 体言, and デフォルト / フィルター / スコープ /
ディストリビューション / 並べ替え win their pairs. A value override is keyed on the
English string, so one entry makes every occurrence agree.

Three key overrides contradicted the value they now share and were realigned;
seven pairs remain and are deliberate, where the same English is a different
thing per call site (Cursor the product vs the caret, Open the PR state vs the
action, Forward the port vs the browser button).

Grab mode picks a page element and hands it to the AI, but read 掴む as a button
and グラブモード in the web-client notice while the rest of the feature said 取得.

Also from CodeRabbit: a single dotted, colon or bracketed token — button.primary,
a:hover, wsl.exe, localhost:3000 — is code whether it names a selector, a file
or a host, so it is preserved too. That caught localhost:3000 reading
ローカルホスト:3000. And an override still spelled `Agent 、` with a space before
the Japanese comma.

The unified map lives in locale-ja-unified-values.mjs to keep the override file
under max-lines.

* fix(i18n): scope the catalog change to ja, and drop the zh-only Terminal form

The ja brand list carried 端子 as a Terminal mistranslation, but 端子 is the
zh rendering and never appears in ja — the Japanese one is 端末, which the
phrase fixes already rewrite to ターミナル. Listing 端末 here instead would be
wrong in the other direction, because this list reverts to Latin. The round-5
expectation moves to 端末 → ターミナル, which is behaviour that can actually occur.

The ko/zh/es identifier restorations are pulled back out; they are real bugs
(pr-view read PR视图, pnpm install read pnpm 설치) but they belong in their own
PR rather than a Japanese one. One zh line has to stay: without it,
verify-localization-catalog refuses the new stale-agent-row-{{value0}} entry
because repair would rewrite the Chinese text to English. That value is a toast
dedup id, not copy.

* chore(i18n): regenerate the Japanese catalog on the current base

The branch point moved forward 68 commits, which added 45 keys to en.json. The
catalog is rebuilt from that base so the repair run stays idempotent, and the
one string the new keys left in English is translated.

* fix(i18n): preserve the code strings rendered inside <code> and font-mono

@smwbev scanned by call-site context rather than value shape — a translate()
that renders inside <code> or a font-mono element is code — and found values
the shape-based list missed. Reproduced against the catalog and fixed here:

- {prompt} read {プロンプト}. It is the substitution token for the commit-message
  prompt template, so a translated one never substitutes.
- /goal read /ゴール, which is not a slash command.
- npm run dev read npm 実行開発, in the same font-mono placeholder role as
  pnpm install.
- nbformat read nbフォーマット.

upstream and upstream/main were already covered. The remaining values in the
scan break in zh rather than ja, but the entries are locale-agnostic, so
orca.yaml, LIN-329, GH #1799 and orca · zsh are pinned here too and #13124
restores the Chinese catalog.

* fix(i18n): repair Japanese translations of code, CLI, and URLs

Code samples, CLI arguments, URLs, and template variables must remain
executable. Adds to NEVER_TRANSLATE_VALUES to prevent future mistakes,
fixes ja.json mistranslations, and adds regression tests.

---------

Co-authored-by: m4air <m4air@m4airs-Air.localdomain>
This commit is contained in:
makoto-developer 2026-08-10 07:40:48 +09:00 committed by GitHub
parent 01bcc8dca2
commit bf406720a0
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
15 changed files with 3842 additions and 2948 deletions

View File

@ -0,0 +1,167 @@
// Per-locale renderings that are machine-translation errors for a brand or product name, and get
// reverted to the Latin original. Ordinary vocabulary that merely looks like a brand lives in
// locale-generic-ui-terms.mjs and stays translated.
export const BRAND_MISTRANSLATIONS = {
ko: {
Codex: ['사본', '코덱스'],
Gemini: ['쌍둥이자리'],
Claude: ['클로드'],
Grok: ['그록'],
Orca: ['오르카', '범고래'],
Cursor: ['커서'],
OpenCode: ['오픈코드'],
OpenClaw: ['오픈클로'],
OpenClaude: ['오픈클로드'],
Antigravity: ['반중력'],
Continue: ['계속하다'],
Charm: ['매력'],
Goose: ['거위'],
Pi: ['파이'],
'GitHub Copilot': ['GitHub 코파일럿', '코파일럿'],
Git: ['힘내'],
Discord: ['디스코드'],
Linear: ['선형'],
Agent: ['에이전트'],
Agents: ['에이전트'],
agent: ['에이전트'],
agents: ['에이전트'],
Commit: ['커밋'],
Commits: ['커밋'],
commit: ['커밋'],
commits: ['커밋'],
Markdown: ['마크다운', '가격 인하'],
markdown: ['마크다운', '가격 인하'],
Repo: ['저장소', '레포'],
Repos: ['저장소', '레포'],
repo: ['저장소', '레포'],
repos: ['저장소', '레포'],
Terminal: ['터미널'],
Terminals: ['터미널'],
terminal: ['터미널'],
terminals: ['터미널']
},
zh: {
Codex: ['法典'],
Gemini: ['双子座'],
Claude: ['克洛德', '克劳德'],
Grok: ['格罗克'],
Orca: ['虎鲸', '逆戟鲸'],
Cursor: ['光标'],
OpenCode: ['开放代码'],
OpenClaw: ['开爪'],
OpenClaude: ['开放克劳德'],
Antigravity: ['反重力'],
Continue: ['继续'],
Charm: ['魅力'],
Goose: ['鹅'],
Pi: ['圆周率'],
Droid: ['机器人'],
Kimi: ['基米'],
// Why: zh-only — 登月计划 is the literal "moon landing programme", not Kimi's vendor. ja and
// ko render this keyword their own way, so it must not go in the cross-locale preserve set.
moonshot: ['登月计划'],
'GitHub Copilot': ['GitHub 副驾驶', '副驾驶'],
Bitbucket: ['位桶'],
Linear: ['线性', '线形'],
Jira: ['吉拉'],
Tailscale: ['尾鳞', '尾鱗'],
Agent: ['代理', '智能体'],
Agents: ['代理', '智能体'],
agent: ['代理', '智能体'],
agents: ['代理', '智能体'],
Commit: ['提交'],
Commits: ['提交'],
commit: ['提交'],
commits: ['提交'],
Markdown: ['降价'],
markdown: ['降价'],
Repo: ['存储库', '仓库', '回购协议', '回购'],
Repos: ['存储库', '仓库', '回购协议', '回购'],
repo: ['存储库', '仓库', '回购协议', '回购'],
repos: ['存储库', '仓库', '回购协议', '回购'],
Terminal: ['终端', '端子'],
Terminals: ['终端', '端子'],
terminal: ['终端', '端子'],
terminals: ['终端', '端子'],
Bash: ['重击'],
PowerShell: ['电源外壳'],
REST: ['休息'],
HEAD: ['头'],
Swift: ['迅速'],
Rust: ['锈'],
'Claude Code': ['Claude·科德'],
'Git AI Author': ['Git AI 作者']
},
ja: {
Codex: ['法典', 'コーデックス'],
Gemini: ['双子座'],
Claude: ['クロード'],
Grok: ['グロック'],
Orca: ['シャチ', '逆戟鲸', 'オルカ'],
Cursor: ['カーソル'],
OpenCode: ['オープンコード', 'オープン・コード'],
OpenClaw: ['オープンクロー'],
OpenClaude: ['オープンクロード'],
Antigravity: ['反重力'],
Continue: ['続ける', '続行'],
Charm: ['魅力'],
Goose: ['ガチョウ', '雁'],
Pi: ['円周率'],
Droid: ['ロボット', 'ドロイド'],
'GitHub Copilot': ['GitHub コパイロット', 'コパイロット'],
Discord: ['不和'],
Linear: ['線形'],
Agent: ['エージェント'],
Agents: ['エージェント'],
agent: ['エージェント'],
agents: ['エージェント'],
Commit: ['コミット'],
Commits: ['コミット'],
commit: ['コミット'],
commits: ['コミット'],
Markdown: ['マークダウン'],
markdown: ['マークダウン'],
Hermes: ['エルメス', 'ヘルメス'],
PowerShell: ['パワーシェル'],
Mermaid: ['マーメイド'],
'Claude Code': ['Claude コード'],
'VS Code': ['VS コード'],
Repo: ['リポジトリ', 'リポ'],
Repos: ['リポジトリ', 'リポ'],
repo: ['リポジトリ', 'リポ'],
repos: ['リポジトリ', 'リポ'],
// 端子 is the zh mistranslation and never appears in ja; the ja one is 端末, which the phrase
// fixes rewrite to ターミナル rather than back to Latin.
Terminal: ['ターミナル'],
Terminals: ['ターミナル'],
terminal: ['ターミナル'],
terminals: ['ターミナル']
},
es: {
Codex: ['códice', 'Códice'],
Gemini: ['Géminis'],
Claude: ['claudia', 'Claudia'],
Orca: ['orca', 'Orcas', 'orcas'],
OpenCode: ['código abierto', 'Código abierto'],
OpenClaude: ['Openclaude'],
Antigravity: ['antigravedad', 'Antigravedad'],
'GitHub Copilot': ['Copiloto de GitHub'],
Discord: ['discordia'],
Linear: ['lineal', 'Lineal'],
Jira: ['jira'],
Agent: ['Agente', 'agente'],
Agents: ['Agentes', 'agentes'],
agent: ['agente'],
agents: ['agentes'],
Commit: ['Confirmación', 'confirmación', 'Confirmar', 'Comprometerse'],
Commits: ['Confirmaciones', 'confirmaciones', 'Compromisos', 'compromisos', 'Se compromete'],
commit: ['confirmación', 'confirmar', 'comprometerse', 'compromiso'],
commits: ['confirmaciones', 'compromisos'],
Markdown: ['Reducción', 'reducción', 'Rebaja', 'rebaja', 'rebajas'],
markdown: ['reducción', 'rebaja', 'rebajas'],
Repo: ['Repositorio', 'repositorio'],
Repos: ['Repositorios', 'repositorios'],
repo: ['repositorio'],
repos: ['repositorios']
}
}

View File

@ -46,5 +46,16 @@ export const CJK_LATIN_SPACED_TERMS = [
'PowerShell',
'Git AI Author',
'Token',
'token'
'token',
'fast-forward',
'Cookie',
'Cookies',
'upstream',
'origin',
'Hermes',
'DuckDuckGo',
'Mermaid',
'VS Code',
'IDE',
'Git'
]

View File

@ -0,0 +1,10 @@
// Japanese overrides for English values whose translation depends on the call site.
export const JA_KEY_OVERRIDES = {
// "on" is the toggle state here, but the preposition in the delete confirmation below.
'auto.components.github.PRFilterSections.1e9b5244f2': { ja: 'オン' },
'auto.components.settings.TerminalPane.29154326bb': { ja: 'オン' },
'auto.components.automations.AutomationsPage.1b586f0e2b': { ja: 'の' },
// Bare "Open" is the PR state elsewhere; these two are the action, as ko/zh/es render it.
'auto.components.browser.pane.BrowserPane.756bfc25c9': { ja: '開く' },
'auto.components.right.sidebar.checks.panel.content.7c1f0a2b11': { ja: '開く' }
}

View File

@ -1,9 +1,46 @@
// Japanese phrase fixes from high-visibility UI audit rounds 14.
// Why: keep locale-phrase-fixes.mjs under max-lines while preserving repair coverage.
const JA_SENTENCE_CHAR = '[぀-ヿ一-龯、。・「」()]'
// Two-word commands (`git commit`, `orca terminal`) must keep their second word in Latin.
const COMMAND_HEAD = '(?<!\\b(?:git|gh|glab|orca|npm|pnpm|npx|yarn|docker|kubectl) )'
// #12113 stopped new damage; ~700 values still read "terminal を閉じる" and are healed here.
// Anchored on adjacent Japanese, so `--agent`, agents.md and "Agent SDK" keep their spelling.
const RELOCALIZED_GENERIC_TERMS = [
['[Tt]erminals?', 'ターミナル', 'terminal'],
['[Cc]ommits?', 'コミット', 'commit'],
['[Rr]epos?', 'リポジトリ', 'repo'],
// Agent stays Latin in ja; this only normalizes the case.
['[Aa]gents?', 'Agent', 'agent'],
['[Ww]orktrees?', 'ワークツリー', 'worktree']
].flatMap(([latin, katakana, whenEnIncludes]) => [
{
// The trailing space only goes when Japanese follows, so 和欧間スペース survives before {{…}}.
pattern: new RegExp(
`(?<=${JA_SENTENCE_CHAR}) ?${COMMAND_HEAD}${latin}(?![-\\w.])(?! [A-Za-z])(?: (?=${JA_SENTENCE_CHAR}))?`,
'g'
),
replacement: katakana,
whenEnIncludes
},
{
pattern: new RegExp(
`(?<![-\\w])${COMMAND_HEAD}${latin}(?![-\\w.]) ?(?=${JA_SENTENCE_CHAR})`,
'g'
),
replacement: katakana,
whenEnIncludes
}
])
export const JA_PHRASE_FIXES = [
...RELOCALIZED_GENERIC_TERMS,
{ pattern: /エージェント/g, replacement: 'Agent', whenEnIncludes: 'agent' },
{ pattern: /解雇/g, replacement: '閉じる', whenEnIncludes: 'Dismiss' },
{ pattern: /却下/g, replacement: '閉じる', whenEnIncludes: 'Dismiss' },
{ pattern: /代理人/g, replacement: 'エージェント', whenEnIncludes: 'agent' },
{ pattern: /代理人/g, replacement: 'Agent', whenEnIncludes: 'agent' },
{ pattern: /支店/g, replacement: 'ブランチ', whenEnIncludes: 'ranch' },
{ pattern: /港(?!口)/g, replacement: 'ポート', whenEnIncludes: 'ort' },
{ pattern: /会議/g, replacement: 'セッション', whenEnIncludes: 'session' },
@ -198,7 +235,7 @@ export const JA_PHRASE_FIXES = [
{ pattern: /電話サイズ/g, replacement: 'スマートフォンサイズ', whenEnIncludes: 'phone' },
{
pattern: /コンピュータと電話/g,
replacement: 'コンピュータとスマートフォン',
replacement: 'コンピュータとスマートフォン',
whenEnIncludes: 'phone'
},
{ pattern: /前の問題/g, replacement: 'フロントマター', whenEnIncludes: 'Front Matter' },
@ -235,11 +272,40 @@ export const JA_PHRASE_FIXES = [
whenEnIncludes: 'More PR actions'
},
{ pattern: /アクション/g, replacement: '操作', whenEnIncludes: 'action' },
{ pattern: /を選択してください/g, replacement: 'を選択', whenEnIncludes: 'Select' },
{ pattern: /を選択してください/g, replacement: 'を選択', whenEnIncludes: 'Choose' },
{ pattern: /入力してください/g, replacement: '入力', whenEnIncludes: 'Enter' },
{ pattern: /追加してください/g, replacement: '追加', whenEnIncludes: 'Add' },
{ pattern: /試してください/g, replacement: '試す', whenEnIncludes: 'Try' },
// Orca's host covers SSH hosts and this computer; skipped where the English also says server.
{
pattern: /(ランタイム)?サーバー/g,
replacement: 'ホスト',
whenEnMatches: /^(?![\s\S]*\bservers?\b)[\s\S]*\bhosts?\b/i
},
{ pattern: /上流/g, replacement: 'upstream', whenEnIncludes: 'upstream' },
{ pattern: /起源/g, replacement: 'origin', whenEnIncludes: 'origin' },
{ pattern: /段階的な変更/g, replacement: 'ステージ済みの変更', whenEnIncludes: 'staged' },
{ pattern: /紛争/g, replacement: '競合', whenEnIncludes: 'conflict' },
{ pattern: /資格情報/g, replacement: '認証情報', whenEnIncludes: 'credential' },
{ pattern: /未知/g, replacement: '不明', whenEnIncludes: 'unknown' },
{ pattern: /クッキー/g, replacement: 'Cookie', whenEnIncludes: 'cookie' },
{ pattern: /プロフィール/g, replacement: 'プロファイル', whenEnIncludes: 'profile' },
{ pattern: /(?<![ンプリ])ロード中/g, replacement: '読み込み中', whenEnIncludes: 'load' },
{
pattern: /(?<![ンプリ])ロードしています/g,
replacement: '読み込んでいます',
whenEnIncludes: 'load'
},
{ pattern: /構成されて/g, replacement: '設定されて', whenEnIncludes: 'configur' },
{ pattern: /第一方/g, replacement: 'ファーストパーティ', whenEnIncludes: 'first-party' },
{ pattern: /早送り/g, replacement: 'fast-forward', whenEnIncludes: 'fast-forward' },
{ pattern: /ファストフォワード/g, replacement: 'fast-forward', whenEnIncludes: 'fast-forward' },
{ pattern: /([぀-ヿ一-龯])\.\.\./g, replacement: '$1…', whenEnMatches: /./ },
{ pattern: /([-ヿ]) (?=[-ヿ])/g, replacement: '$1', whenEnMatches: /./ },
{ pattern: /サーバ(?!ー)/g, replacement: 'サーバー', whenEnMatches: /./ },
{ pattern: /フォルダ(?!ー)/g, replacement: 'フォルダー', whenEnMatches: /./ },
{ pattern: /エディタ(?!ー)/g, replacement: 'エディター', whenEnMatches: /./ },
{ pattern: /レンダラ(?!ー)/g, replacement: 'レンダラー', whenEnMatches: /./ },
{ pattern: /ブラウザー/g, replacement: 'ブラウザ', whenEnMatches: /./ },
{ pattern: /エミュレーター/g, replacement: 'エミュレータ', whenEnMatches: /./ },
{ pattern: /コンピューター/g, replacement: 'コンピュータ', whenEnMatches: /./ },
{ pattern: /インターフェイス/g, replacement: 'インターフェース', whenEnMatches: /./ },
// Why: JP engineers use "Issue" in Latin, not katakana. Runs last so all *→イシュー fixes above normalize to Issue.
{ pattern: /イシュー/g, replacement: 'Issue', whenEnIncludes: 'issue' }
]

View File

@ -0,0 +1,246 @@
// One rendering per English string. 215 sources carried two or more Japanese forms; picks follow
// the catalog majority — action labels drop する, completion notices use 〜しました, status labels
// are 体言, and デフォルト / フィルター / スコープ / ディストリビューション / 並べ替え win their pairs.
export const JA_UNIFIED_VALUES = {
"Can't reach {{value0}}": '{{value0}} に接続できません',
'Copy Address': 'アドレスをコピー',
'Open Externally': '外部で開く',
'Show Orca Mobile Button': 'Orca Mobile ボタンを表示',
Paste: '貼り付け',
'WSL default': 'WSL のデフォルト',
'Unable to open the workspace attached to this issue.':
'この Issue にリンクされたワークスペースを開けませんでした。',
'Failed to connect to project.': 'プロジェクトへの接続に失敗しました。',
'Dev-only tools for exercising UI states.': 'UI の状態を確認するための開発者専用ツール。',
'Start new workspace': '新規ワークスペースを開始',
'Open workspace attached to issue': 'Issue にリンクされたワークスペースを開く',
'No one assigned': '担当者なし',
'Edit assignees': '担当者を編集',
'Edit labels on GitHub': 'GitHub でラベルを編集',
'check #': 'チェック #',
Started: '開始済み',
'Status:': 'ステータス:',
'Loading check details…': 'チェックの詳細を読み込んでいます…',
'No description provided.': '説明はありません。',
'Review comment added.': 'レビューコメントを追加しました。',
Copied: 'コピーしました',
'No activity yet.': 'まだアクティビティはありません。',
Merge: 'マージ',
'Create workspace': 'ワークスペースを作成',
'Loading labels': 'ラベルを読み込んでいます',
Hide: '非表示',
Resolve: '解決',
'Start workspace': 'ワークスペースを開始',
Unassigned: '未割り当て',
'Copy prompt': 'プロンプトをコピー',
'Failed to copy {{value0}}': '{{value0}} のコピーに失敗しました',
'{{value0}} copied': '{{value0}} をコピーしました',
'Add project': 'プロジェクトを追加',
'Cloning...': 'クローン作成中…',
'Add SSH host': 'SSH ホストを追加',
Later: '後で',
"Don't ask again": '今後表示しない',
'Atlassian account settings': 'Atlassian のアカウント設定',
'Create a token in': 'でトークンを作成します',
'Atlassian API token': 'Atlassian API トークン',
'Use a Jira Cloud site URL, Atlassian email, and API token to browse issues.':
'Jira Cloud のサイト URL、Atlassian のメールアドレス、API トークンを使って Issue を閲覧します。',
'Connect Jira site': 'Jira サイトに接続',
Updated: '更新済み',
Owner: 'オーナー',
'Connect Jira': 'Jira に接続',
'Change the query or clear it.': '検索条件を変更するか、クリアしてください。',
'No matching GitHub work': '一致する GitHub の作業はありません',
'No GitLab work matches this filter.': 'このフィルターに一致する GitLab の作業はありません。',
'No GitLab MRs match this filter.': 'このフィルターに一致する GitLab の MR はありません。',
'No GitLab issues match this filter.': 'このフィルターに一致する GitLab の Issue はありません。',
Resume: '再開',
github: 'GitHub',
'Could not build launch command for {{value0}}.':
'{{value0}} の起動コマンドを作成できませんでした。',
Update: '更新',
'Re-check': '再確認',
'Checks passed': 'チェックに合格しました',
'Copy command': 'コマンドをコピー',
Pinned: 'ピン留め済み',
'Remove {{value0}} filter': '{{value0}} フィルターを解除',
selected: '選択中',
'Remove {{value0}}': '{{value0}} を削除',
'Last active': '最終アクティブ',
'Unpushed commits': '未プッシュのコミット',
Ignored: '無視済み',
Sort: '並べ替え',
Context: 'コンテキスト',
'Delete {{value0}}': '{{value0}} を削除',
Commits: 'コミット',
'Expand details': '詳細を展開',
'Uncommitted changes': '未コミットの変更',
'No projects match your search.': '検索条件に一致するプロジェクトはありません。',
Scope: 'スコープ',
'Context copied': 'コンテキストをコピーしました',
'Worktree not ready — try again in a moment.':
'ワークツリーが準備できていません — しばらくしてから再試行してください。',
'Open a workspace before resuming a session.':
'セッションを再開する前に、ワークスペースを開いてください。',
Run: '実行',
'ios simulator': 'iOS シミュレータ',
'Kill session {{value0}}': 'セッション {{value0}} を強制終了',
Disconnected: '切断済み',
'OpenCode Go Usage': 'OpenCode Go の使用量',
'Switch to': '切り替え先',
'Update failed': '更新に失敗しました',
cancelling: 'キャンセル中',
Unavailable: '利用不可',
'Usage unavailable': '使用量を取得できません',
Usage: '使用量',
Bundled: '同梱',
'Update available': '更新があります',
Skipped: 'スキップ済み',
'1 update available': '1 件の更新があります',
'{{value0}} updates available': '{{value0}} 件の更新があります',
Stop: '停止',
'Up to date': '最新',
'Host path': 'ホストパス',
'Open project on SSH host': 'SSH ホスト上のプロジェクトを開く',
'Clone from URL': 'URL からクローン',
more: '件以上',
'Keep hidden': '非表示のままにする',
Manual: '手動',
Automation: 'オートメーション',
Notes: 'ノート',
'Board settings': 'ボード設定',
'Project on SSH host': 'SSH ホスト上のプロジェクト',
'Created by automation': 'オートメーションによって作成',
'Open in Orca': 'Orca で開く',
'Failed to copy link': 'リンクのコピーに失敗しました',
'Delete Worktree': 'ワークツリーを削除',
rename: '名前変更',
'Create workspace for {{value0}}': '{{value0}} のワークスペースを作成',
'Browse folder': 'フォルダーを参照',
'{{value0}} failed': '{{value0}} 件失敗',
Neutral: '中立',
'Set up': 'セットアップ',
'Add a persistent machine you can log into over SSH.':
'SSH でログインできる永続的なマシンを追加します。',
'on the server and paste the printed pairing URL.':
'をサーバーで実行し、出力されたペアリング URL を貼り付けます。',
'Keep Local Main Up to Date': 'ローカル main を最新の状態に保つ',
Saved: '保存済み',
Replace: '置換',
'Account scope': 'アカウントスコープ',
'Agent Permissions': 'Agent の権限',
'Show the Orca Mobile button at the top of the left sidebar.':
'左サイドバー上部に Orca Mobile ボタンを表示します。',
'Enable Orca CLI': 'Orca CLI を有効化',
'Registered the Orca CLI in PATH.': 'Orca CLI を PATH に登録しました。',
'Failed to load CLI status.': 'CLI ステータスの読み込みに失敗しました。',
'Fix PATH': 'PATH を修正',
installed: 'インストール済み',
cli: 'CLI',
'Opened macOS Privacy & Security': 'macOS のプライバシーとセキュリティを開きました',
'Could not request permission': '権限をリクエストできませんでした',
Shown: '表示中',
'Clear all': 'すべてクリア',
'Each connected Linear workspace has one key stored by the active runtime. Full-access keys can cover all teams the key owner can access; restricted keys can be replaced any time.':
'接続された各 Linear ワークスペースには、アクティブなランタイムが保存したキーが 1 つあります。フルアクセスキーはキー所有者がアクセスできるすべてのチームを対象にできます。制限付きキーはいつでも置き換えられます。',
'Add workspace access': 'ワークスペースへのアクセスを追加',
'Learn more': '詳しく見る',
'Gitea credentials are configured but could not authenticate. Check the token, API base URL, and repository permissions, then restart Orca if environment variables changed.':
'Gitea の認証情報は設定されていますが、認証できませんでした。トークン、API ベース URL、リポジトリの権限を確認し、環境変数を変更した場合は Orca を再起動してください。',
'Azure DevOps credentials are configured but could not authenticate. Check the token, API base URL, and repository permissions, then restart Orca if environment variables changed.':
'Azure DevOps の認証情報は設定されていますが、認証できませんでした。トークン、API ベース URL、リポジトリの権限を確認し、環境変数を変更した場合は Orca を再起動してください。',
'Bitbucket credentials are configured but could not authenticate. Check the token and repository permissions, then restart Orca if environment variables changed.':
'Bitbucket の認証情報は設定されていますが、認証できませんでした。トークンとリポジトリの権限を確認し、環境変数を変更した場合は Orca を再起動してください。',
'The GitLab CLI is installed but not authenticated. Run this command in a terminal:':
'GitLab CLI はインストールされていますが、認証されていません。ターミナルで次のコマンドを実行してください:',
'Install GitLab CLI': 'GitLab CLI をインストール',
'CLI.': 'CLI。',
'The GitHub CLI is installed but not authenticated. Run this command in a terminal:':
'GitHub CLI はインストールされていますが、認証されていません。ターミナルで次のコマンドを実行してください:',
'Install GitHub CLI': 'GitHub CLI をインストール',
'Disconnect {{value0}}': '{{value0}} の接続を解除',
'Add Linear access to browse and link issues.':
'Linear アクセスを追加して、Issue を閲覧およびリンクします。',
'Pull requests and build statuses via Azure DevOps REST API tokens.':
'Azure DevOps REST API トークン経由の PR とビルドステータス。',
'Pull requests and build statuses via Bitbucket Cloud API tokens.':
'Bitbucket Cloud API トークン経由の PR とビルドステータス。',
'Reload from Disk': 'ディスクから再読み込み',
'Refresh network interfaces': 'ネットワークインターフェースを更新',
'CLI arguments': 'CLI 引数',
Created: '作成日時',
Switch: '切り替え',
'Status unavailable': 'ステータスを取得できません',
'Checking…': '確認中…',
'Updating servers…': 'サーバーを更新しています…',
'{{value0}} shortcut': '{{value0}} のショートカット',
'Connect {{provider}}': '{{provider}} に接続',
'Try again': '再試行',
'Windows default': 'Windows のデフォルト',
'Loading distributions': 'ディストリビューションを読み込んでいます',
'WSL Distribution': 'WSL ディストリビューション',
'Default Shell': 'デフォルトのシェル',
'Right-click pastes the clipboard. Ctrl+right-click opens the context menu.':
'右クリックでクリップボードを貼り付けます。Ctrl+右クリックでコンテキストメニューを開きます。',
credentials: '認証情報',
display: 'ディスプレイ',
setup: 'セットアップ',
note: 'メモ',
update: '更新',
'default branch': 'デフォルトブランチ',
target: '対象',
'Client default': 'クライアントのデフォルト',
'Select distro': 'ディストリビューションを選択',
'Sign out': 'サインアウト',
'Available on': 'で利用可能',
'Update this server manually once to enable remote updates.':
'リモート更新を有効にするには、このサーバーを一度手動で更新してください。',
Official: '公式',
'Open on {{value0}}': '{{value0}} で開く',
'Create {{value0}}': '{{value0}} を作成',
'{{value0}} #{{value1}} is already open': '{{value0}} #{{value1}} はすでに開いています',
'Copy Details': '詳細をコピー',
'Clear Notes': 'ノートをクリア',
'Fix with AI': 'AI で修正',
'AI Fix': 'AI 修正',
'Committed on Branch': 'コミット先のブランチ',
Changes: '変更点',
'Filter files by name': 'ファイル名でフィルター',
'Choose the agent and edit the full command input before launch.':
'起動前に Agent を選択し、コマンド入力全体を編集してください。',
'Unable to resolve the workspace connection.': 'ワークスペースの接続を解決できません。',
'Branch has unpushed commits': 'ブランチに未プッシュのコミットがあります',
'No enabled AI agents. Configure agents in Settings.':
'有効な AI Agent がありません。[設定] で Agent を構成してください。',
'Saved AI agent is unavailable. Use Customize launch to choose another agent.':
'保存された AI Agent は使用できません。[起動のカスタマイズ] から別の Agent を選択してください。',
'Commit failure prompt is empty. Update Source Control AI settings.':
'コミット失敗プロンプトが空です。ソース管理の AI 設定を更新してください。',
'Create PR': 'PR を作成',
'{{value0}} msgs': '{{value0}} 件のメッセージ',
'No projects/folders match your search.': '検索に一致するプロジェクト/フォルダーはありません。',
Keep: '保持',
'Skill command copied and inserted below for review.':
'スキルコマンドをコピーし、確認用に以下へ挿入しました。',
'Try it out': '試してみる',
'1 pending': '保留中 1 件',
'Zoom in': 'ズームイン',
'Zoom out': 'ズームアウト',
Undo: '元に戻す',
'{{value0}} failing': '{{value0}} 件失敗',
'{{value0}} pending': '{{value0}} 件保留中',
'Draft review': '下書きレビュー',
'Switch profile': 'プロファイルを切り替え',
'Draw on the page, then copy the markup to paste into your agent.':
'ページに描き込み、マークアップをコピーして Agent に貼り付けます。',
// Grab mode picks a page element and hands it to the AI; 掴む / グラブモード were literal.
Grab: '取得',
'Grab mode is unavailable in the web client.':
'要素の取得モードは Web クライアントでは使用できません。',
agent: 'Agent',
'{{value0}} workspace{{value1}} connected':
'{{value0}} ワークスペース{{value1}} が接続されました',
Plugins: 'プラグイン',
'Orca will continue to work, but commands such as orca status, orca terminal, and orchestration are unavailable for this session.\n\n{{guidance}}\n\nCause: {{cause}}':
'Orca は引き続き使用できますが、このセッションでは orca status や orca terminal などのコマンドとオーケストレーションを利用できません。\n\n{{guidance}}\n\n原因: {{cause}}'
}

View File

@ -1,25 +1,27 @@
import { JA_UNIFIED_VALUES } from './locale-ja-unified-values.mjs'
// Japanese value overrides from high-visibility UI audit rounds 14.
// Why: keep locale-value-overrides.mjs under max-lines while preserving exact-match repairs.
export const JA_VALUE_OVERRIDES = {
const JA_AUDIT_OVERRIDES = {
'Retry loading presets': 'プリセットの読み込みを再試行',
'Retry Download': 'ダウンロードを再試行',
'Enter a reviewer': 'レビュアーを入力',
'Choose folder': 'フォルダーを選択',
'Choose pet': 'ペットを選択',
'Choose a sound': 'サウンドを選択',
'Pick your default agent': 'デフォルトのエージェントを選択',
'Pick your default agent': 'デフォルトの Agent を選択',
'Complete {{artifact_url}}': '{{artifact_url}} を完了',
'Control terminals and agents from your phone.':
'スマートフォンからターミナルとエージェントを操作',
'スマートフォンからターミナルと Agent を操作します。',
'Add reviewer': 'レビュアーを追加',
Reviewer: 'レビュアー',
Reviewers: 'レビュアー',
'Fix broken checks': '失敗したチェックを修正',
'No broken checks to fix.': '修正が必要な失敗したチェックはありません',
'No broken checks to fix.': '修正が必要なチェックはありません',
'Started an AI agent for the broken checks.':
'失敗したチェックに対して AI エージェントを開始しました。',
'失敗したチェックに対して AI Agent を開始しました。',
'Failed to start an AI agent for the broken checks: {{value0}}':
'失敗したチェックのため AI エージェントを開始できませんでした: {{value0}}',
'失敗したチェックのため AI Agent を開始できませんでした: {{value0}}',
'Checks unavailable': 'チェックは利用できません',
'Checks pending': '保留中のチェック',
checks: 'チェック',
@ -92,7 +94,7 @@ export const JA_VALUE_OVERRIDES = {
Launch: '起動',
'Launch:': '起動:',
'Launch plan': '起動プラン',
'Launch agent': 'エージェントを起動',
'Launch agent': 'Agent を起動',
'Launch {{value0}} in a new terminal': '新規ターミナルで {{value0}} を起動',
Play: '再生',
Action: '操作',
@ -148,8 +150,8 @@ export const JA_VALUE_OVERRIDES = {
'Select a workspace to browse files': 'ファイルを参照するワークスペースを選択',
'Select a workspace to search': '検索するワークスペースを選択',
'Select a workspace to view changes': '変更を表示するワークスペースを選択',
'Choose agent to fix commit failure': 'コミット失敗を修正するエージェントを選択',
'Choose an agent for this commit failure': 'このコミット失敗に対するエージェントを選択',
'Choose agent to fix commit failure': 'コミット失敗を修正する Agent を選択',
'Choose an agent for this commit failure': 'このコミット失敗に対する Agent を選択',
'Enter a commit message to commit': 'コミットメッセージを入力してコミット',
'Choose parent folder...': '親フォルダーを選択...',
'Check for stuck work, stale generated files, failing validation, and anything that needs human attention. Report only actionable issues.':
@ -234,5 +236,313 @@ export const JA_VALUE_OVERRIDES = {
'Cursor Opacity': 'カーソルの不透明度',
'Cursor Shape': 'カーソル形状',
'Blinking Cursor': 'カーソルの点滅',
'Terminal Cursor': 'Terminal カーソル'
'Terminal Cursor': 'ターミナルのカーソル',
'Local folders and Git repositories': 'ローカルフォルダーと Git リポジトリ',
'Started an AI agent for the conflicts.': '競合の解決のために AI Agent を開始しました。',
'Previous conflict': '前の競合',
'1 commit ahead of {{value0}}': '{{value0}} より 1 コミット進んでいます',
'1 commit behind {{value0}}': '{{value0}} より 1 コミット遅れています',
'3 commits ahead': '3 コミット進んでいます',
'Fast-forwarded {{branch}} by 1 commit.': '{{branch}} を 1 コミット分 fast-forward しました。',
'e.g. cloudflared access ssh --hostname %h': '例: cloudflared access ssh --hostname %h',
'Git is not installed': 'Git がインストールされていません',
'CLI not installed': 'CLI がインストールされていません',
'Locate SDK folder': 'SDK フォルダーを選択',
'Not found. Install Android Studio, then create a Virtual Device.':
'見つかりません。Android Studio をインストールしてから、仮想デバイスを作成してください。',
'ANSI blue color': 'ANSI青色',
'MR !{{value0}}': 'MR !{{value0}}',
mrs: 'MR',
'No human comments.': 'ユーザーによるコメントはありません。',
'Any state': 'すべての状態',
State: '状態',
Health: '健全性',
Ordering: '並べ替え',
Start: '開始',
'Local {{value0}} is behind {{value1}}': 'ローカル {{value0}} は {{value1}} より遅れています',
'behind main': 'main より遅れています',
'behind (base commit:': '遅れ (ベースコミット:',
'No pending todos. Youre all caught up!': '保留中の ToDo はありません。すべて完了しています!',
High: '高',
Medium: '中',
Low: '低',
'Split Terminal Down': 'ターミナルを下に分割',
'Split Terminal Right': 'ターミナルを右に分割',
'Split Up': '上に分割',
'Split Down': '下に分割',
"Install the Browser Use skill so agents can operate Orca's browser.":
'Browser Use スキルをインストールすると、 Agent が Orca のブラウザを操作できるようになります。',
'bold ·': '太字 ·',
'Duplicate of another issue in this repository': 'このリポジトリ内の別の Issue と重複',
'Choose a different issue.': '別の Issue を選択してください。',
'No matching issues loaded.': '一致する Issue がありません。',
'Duplicate of another issue': '別の Issue と重複',
'mentioned this': 'がこの Issue をメンションしました',
'closed this': 'がこの Issue をクローズしました',
'reopened this': 'がこの Issue を再オープンしました',
'moved this': 'がこの Issue を移動しました',
'Failed to save setup startup behavior.': 'セットアップ時の起動設定を保存できませんでした。',
'Failed to resolve MR base.': 'MR のベースブランチを特定できませんでした。',
'Failed to copy context.': 'コンテキストのコピーに失敗しました。',
// 3-way split: [this][query]["]. The closing side is already 」, so end the sentence here.
'No settings found for "': '検索条件に一致する設定が見つかりませんでした:「',
"Doesn't apply to agents where you've overridden launch arguments.":
'起動引数を上書きしている Agent には適用されません。',
'Check for Server Updates': 'サーバーの更新を確認',
'All servers are up to date.': 'すべてのサーバーが最新です。',
'Open worktree': 'ワークツリーを開く',
'Update this server': 'このサーバーを更新',
'Git repository': 'Git リポジトリ',
'{{host}} is no longer a saved SSH host, so this workspace is no longer connected to a live host. It can only be removed from Orca — files and branches on the remote are left untouched.':
'{{host}} は保存済みの SSH ホストではなくなったため、このワークスペースは稼働中のホストに接続されていません。Orca から削除することのみ可能です。リモート上のファイルとブランチはそのまま残ります。',
'The app shell could not finish rendering. Retry to remount it, or relaunch Orca if the error persists.':
'アプリシェルのレンダリングを完了できませんでした。再マウントを試すか、エラーが解決しない場合は Orca を再起動してください。',
'Workspaces are unavailable on a mobile-scope pairing. Reconnect using the browser access link from Settings → Runtime Environments → Share this Orca server.':
'モバイル向けペアリングではワークスペースを使用できません。[設定] → [リモート Orca サーバー] → [この Orca サーバーを共有する] から、ブラウザ用リンクで再接続してください。',
'Change this later in Settings → Browser.': '後で [設定] → [ブラウザ] から変更できます。',
'Orca Cloud sign-in is not configured': 'Orca Cloud へのサインインが設定されていません',
'{{provider}} could not authenticate the credentials available in this environment. Check the {{provider}} login or environment token, then retry.':
'{{provider}} はこの環境で利用できる認証情報で認証できませんでした。{{provider}} のログインまたは環境トークンを確認して、再試行してください。',
'e.g. ollama run llama3.1 {prompt}': '例: ollama run llama3.1 {prompt}',
'e.g. ollama run llama3.1 {{value0}}': '例: ollama run llama3.1 {{value0}}',
'Connecting terminal...': 'ターミナルに接続中…',
'Starring…': 'スターを付けています…',
'self-hosted': 'セルフホスト',
'not-authenticated': '未認証',
'side-by-side': '左右に並べて',
'Side-by-side': '左右に並べて',
'Pull requests and commit statuses via the Gitea REST API.':
'Gitea REST API 経由の PR とコミットステータス。',
Key: 'キー',
slug: 'スラッグ',
// Rendered as [fragment][var name][fragment] by two cards that share these fragments.
'Public repositories are detected from their git remote. Set':
'パブリックリポジトリは git リモートから検出されます。設定:',
'for private repositories, and set': '(プライベートリポジトリ用)。また、',
'only when Orca cannot derive the API base URL from the git remote.':
'は、Orca が git リモートから API のベース URL を取得できない場合のみ設定します。',
'only when Orca cannot derive the API URL from the remote.':
'は、Orca がリモートから API URL を取得できない場合のみ設定します。',
Set: '設定:',
'. Set': '。設定:',
', or set': '、または',
and: 'と',
// Concatenated: the leading space is part of the string, not padding.
' and ': ' と ',
' in {{value0}}': '{{value0}}',
' • Last scan error: {{value0}}': ' • 最終スキャンエラー: {{value0}}',
' vs {{value0}}': ' vs {{value0}}',
'When you create a workspace, Orca refreshes the remote base and safely fast-forwards your matching local branch, such as':
'ワークスペースを作成すると、Orca はリモートベースを更新し、一致するローカルブランチを安全に fast-forward します。対象は',
'. This keeps commands like': '。これにより、',
'from comparing against stale history. Orca skips the update if that branch has uncommitted changes or local-only commits.':
'などのコマンドが古い履歴と比較されるのを防ぎます。対象のブランチにコミットしていない変更やローカルのみのコミットがある場合、Orca は更新をスキップします。',
'Supports skills, file paths, and built-in commands like':
'スキル、ファイルパス、および次のような組み込みコマンドに対応しています:',
' · {{value0}} external': ' · 外部 {{value0}} 件',
'Use your current': '現在のアカウントを使用',
Running: '実行中',
'Back to runs': '実行一覧に戻る',
Failed: '失敗',
Unknown: '不明',
'Identity file': '秘密鍵ファイル',
'Identity File': '秘密鍵ファイル',
key: 'キー',
failing: '失敗',
'Selected host': '選択したホスト',
'Copied cleanup payload.': 'クリーンアップ用ペイロードをコピーしました。',
'Jump to...': '移動先…',
'Start work': '作業を開始',
'Remove {{value0}} contained {{value1}} from Orca':
'含まれている {{value1}} {{value0}} 件を Orca から削除',
'People in {{orgName}} who can collaborate on Orca.':
'{{orgName}} で Orca を共同利用できるメンバーです。',
'People in your organization who can collaborate on Orca.':
'組織内で Orca を共同利用できるメンバーです。',
'Adds action recipes for Source Control commit, pull request, branch-name, and fix actions.':
'ソース管理のコミット、PR、ブランチ名、修正操作に使うアクションレシピを追加します。',
'Repo fallback for text actions that select Custom command.':
'「カスタムコマンド」を選択したテキスト操作に使う、リポジトリ単位のフォールバック。',
'Recipe-created runtimes are workspace-owned. Clean up stale entries after crashes, failed creates, or manual recovery.':
'レシピで作成されたランタイムはワークスペースに紐づいています。クラッシュ、作成失敗、手動リカバリの後に残った古いエントリをクリーンアップします。',
'Failed to register the recipe-created project root on the runtime.':
'レシピによって作成されたプロジェクトルートをランタイムに登録できませんでした。',
'Update all {{value0}} servers': '{{value0}} 台のサーバーをすべて更新',
'This QR code grants limited (mobile) access. To use the full web app, open the browser access link from Settings → Runtime Environments → Share this Orca server → New Link.':
'この QR コードでは、モバイル向けの制限付きアクセスのみ利用できます。完全版の Web アプリを使用するには、[設定] → [リモート Orca サーバー] → [この Orca サーバーを共有する] → [新規リンク] から、ブラウザ用アクセスリンクを開いてください。',
'Loading skills...': 'スキルを読み込み中…',
'Start agents on your tasks without leaving Orca': 'Orca から離れずに、タスクから Agent を開始',
'Workspace created from {{value0}}, but Orca could not fast-forward local {{value1}} because {{value2}}':
'ワークスペースは {{value0}} から作成されましたが、{{value2}} のため Orca はローカル {{value1}} を fast-forward できませんでした',
'Terminal, browser, or editor rendering failed in this workspace. Retry to remount it.':
'このワークスペースでは、ターミナル、ブラウザ、またはエディターのレンダリングに失敗しました。再マウントを試してください。',
'The dashboard could not finish rendering. Retry to remount it, or reopen it.':
'ダッシュボードのレンダリングを完了できませんでした。再マウントを試すか、開き直してください。',
'Review the prompt before starting an agent.':
'Agent を開始する前に、プロンプトを確認してください。',
'Use Add Project to enter a path on the selected host.':
'[プロジェクトの追加] から、選択したホスト上のパスを入力します。',
'Use repo-relative paths like packages/web or apps/api.':
'packages/web や apps/api などのリポジトリ相対パスを使用します。',
'orca.yaml first, then your local commands.': 'まず orca.yaml、次にローカルのコマンドの順です。',
'Rename Orca-created branches from the initial agent task.':
'Orca が作成したブランチの名前を、最初の Agent タスクに基づいて変更します。',
'Dim files matched by .gitignore in the file explorer.':
'ファイルエクスプローラーで、.gitignore に一致するファイルを薄く表示します。',
'Command line Orca runs when a text recipe uses Custom command.':
'テキストレシピで「カスタムコマンド」を使用したときに Orca が実行するコマンドライン。',
'Let programs in the terminal copy to the system clipboard through OSC 52, including over SSH.':
'ターミナル内のプログラムが、OSC 52 を使ってシステムのクリップボードにコピーできるようにしますSSH 経由を含む)。',
'Choose which optional saved Codex account powers live quota reads.':
'ライブクォータの取得に使用する、保存済みの Codex アカウント(任意)を選択します。',
'This plugin has no worker process. Its instructional content can still cause actions when you or an agent use it. Review the instructions and commands below before enabling it.':
'このプラグインにはワーカープロセスがありません。それでも、ユーザーや Agent が使用したときに、記載された手順が操作を引き起こす可能性があります。有効にする前に、以下の手順とコマンドを確認してください。',
'This removes the saved SSH host and its credentials from this computer. Remote files are not deleted.':
'保存済みの SSH ホストとその認証情報を、このコンピュータから削除します。リモートのファイルは削除されません。',
'Your new worktree is current, but local {{value0}} is {{value1}} {{value2}} behind. AI diffs may miss recent commits.':
'新規ワークツリーは最新ですが、ローカル {{value0}} は {{value1}} {{value2}} 遅れています。AI の差分に最近のコミットが反映されない可能性があります。',
'This check needs a manual action on GitHub (for example, approving the workflow run) before merging is unblocked.':
'マージのブロックが解除されるまでに、このチェックには GitHub 上での手動操作(例: ワークフロー実行の承認)が必要です。',
'This file changed on disk while you have unsaved edits. Saving will overwrite the newer disk content.':
'未保存の編集がある状態で、このファイルがディスク上で変更されました。保存すると、ディスク上の最新の内容を上書きします。',
'Local terminal reveal is unavailable while a remote runtime is active':
'リモートランタイムがアクティブな間は、ローカルターミナルの表示は利用できません',
'No quick commands saved.': '保存されているクイックコマンドはありません。',
'Repository not in Orca': 'このリポジトリは Orca に登録されていません',
'host folder not selected': 'ホストフォルダーが選択されていません',
'Add a Git repository or folder that already exists on the selected host.':
'選択したホストに既に存在する Git リポジトリまたはフォルダーを追加します。',
'Add another project from the selected host.': '選択したホストから別のプロジェクトを追加します。',
'Enter a host path for the clone destination.': 'クローン先のホスト上のパスを入力します。',
'Use a host path to add projects from a remote host.':
'ホスト上のパスを指定して、リモートホストからプロジェクトを追加します。',
'Use Add Project to enter a host path.':
'[プロジェクトの追加] から、ホスト上のパスを入力します。',
'Opens as a project on this host · {{value0}}':
'このホスト上のプロジェクトとして開きます · {{value0}}',
'No project path is available on this host for attachments.':
'このホスト上に、添付に使用できるプロジェクトパスがありません。',
'Clears them from Orca only. Remote files, worktrees, and branches are left untouched.':
'Orca からのみ削除します。リモートのファイル、ワークツリー、ブランチはそのまま残ります。',
'Agent location': 'Agent の実行場所',
upstream: 'upstream',
Upstream: 'upstream',
'Commit staged changes': 'ステージ済みの変更をコミット',
'Generate the commit message from staged changes.':
'ステージ済みの変更からコミットメッセージを生成します。',
lan: 'LAN',
deploy: 'deploy',
'Connect this source to check for Hermes automations in the remote profile.':
'このソースに接続すると、リモートプロファイル内の Hermes オートメーションを確認できます。',
'Notes sent to active agent.': 'メモをアクティブな Agent に送信しました。',
'Review before attaching. Captured page context may include visible site content.':
'添付する前に確認してください。取得したページのコンテキストには、表示中のサイトの内容が含まれる場合があります。',
'Agent took too long to start. The workspace is ready — paste the {{value0}} when the agent is idle.':
'Agent の起動に時間がかかりすぎました。ワークスペースの準備はできています。 Agent がアイドル状態になったら {{value0}} を貼り付けてください。',
'Install the Orca CLI before running agent skill setup.':
'Agent スキルのセットアップを実行する前に、Orca CLI をインストールしてください。',
'Run grok in a terminal on the computer running Orca and wait for it to start. If prompted, complete sign-in, then retry usage. You do not need to send a chat message.':
'Orca を実行しているコンピュータのターミナルで grok を実行し、起動するまで待ってください。サインインを求められた場合は完了してから、使用状況を再取得してください。チャットメッセージを送る必要はありません。',
'Choose an enabled agent before saving.': '保存する前に、有効な Agent を選択してください。',
'Selected agent is disabled. Choose an enabled agent before creating.':
'選択した Agent は無効です。作成する前に、有効な Agent を選択してください。',
'Choose an agent before starting.': '開始する前に、 Agent を選択してください。',
'Change this later from the project menu.': '後でプロジェクトメニューから変更できます。',
"Orca works with every CLI agent. Choose the one you'll reach for most. Switch any time.":
'Orca はすべての CLI Agent で動作します。最もよく使うものを選択してください。いつでも切り替えられます。',
'Downloading paused': 'ダウンロード一時停止中',
Canceled: 'キャンセル済み',
'Thinking...': '思考中…',
'No attached worktrees yet': '紐づくワークツリーはまだありません',
'Started an AI agent for the commit failure.':
'コミット失敗を修正するために AI Agent を開始しました。',
'terminals until reset': 'リセットするまでターミナルを維持',
'Failed to import repo icon': 'リポジトリアイコンのインポートに失敗しました',
'Terminal Panes': 'ターミナルペイン',
'Option composes special characters for your keyboard layout.':
'Option キーで、キーボードレイアウトに応じた特殊文字を入力します。',
'There are local terminals with running processes. Close the window anyway?':
'プロセスが実行中のローカルターミナルがあります。このままウィンドウを閉じますか?',
'Auto-generates a new name when you leave this text box empty.':
'このテキストボックスを空のままにすると、名前が自動生成されます。',
'Auto-name workspace from first agent message':
'最初の Agent メッセージからワークスペース名を自動生成',
'Controls the split divider line between panes in light mode.':
'ライトモードでのペイン間の分割線を制御します。',
'Controls the split divider line between panes in dark mode.':
'ダークモードでのペイン間の分割線を制御します。',
'Countdown timer showing time until prompt cache expires (Claude agents).':
'プロンプトキャッシュが期限切れになるまでの時間を示すカウントダウンタイマーClaude Agent )。',
'Install and manage experimental Orca plugins.':
'実験的機能の Orca プラグインをインストール・管理します。',
"Resident memory held by Orca plus the processes under each worktree's terminals.":
'Orca が保持する常駐メモリと、各ワークツリーのターミナル配下で実行中のプロセス。',
'No local Claude, Codex, or OpenCode usage found yet. The overview will populate after the next agent session writes token logs.':
'ローカルの Claude、Codex、OpenCode の使用状況はまだ見つかりません。次の Agent セッションがトークンログを書き込むと、概要に反映されます。',
'Choose or add a project before creating a workspace.':
'ワークスペースを作成する前に、プロジェクトを選択または追加してください。',
'Choose a project to get started.': '開始するには、プロジェクトを選択してください。',
'Please enter feedback before submitting.': '送信する前に、フィードバックを入力してください。',
'Add a Git project under this folder to attach GitHub or GitLab tasks.':
'GitHub または GitLab のタスクを関連付けるには、このフォルダー内に Git プロジェクトを追加してください。',
'Enter a valid website URL.': '有効な Web サイトの URL を入力してください。',
'Choose a WSL distro before projects can inherit WSL.':
'プロジェクトが WSL を継承できるようにするには、先に WSL ディストリビューションを選択してください。',
'Choose a different base branch before creating a {{value0}}.':
'{{value0}} を作成する前に、別のベースブランチを選択してください。',
'Optional. Orca can use your normal Codex login; add accounts only if you want quick switching in Orca.':
'任意。Orca は通常の Codex ログインを使用できます。Orca 上ですばやく切り替えたい場合にのみ、アカウントを追加してください。',
'Optional. Orca can use your normal Claude login; add accounts only if you want quick switching without moving chat sessions.':
'任意。Orca は通常の Claude ログインを使用できます。チャットセッションを移さずにすばやく切り替えたい場合にのみ、アカウントを追加してください。',
'Optional. Orca works with your existing provider logins; add accounts only if you want Orca to help switch between them.':
'任意。Orca は既存のプロバイダーのログインと連携します。Orca に切り替えを任せたい場合にのみ、アカウントを追加してください。',
'Use this computer by default. Choose a saved server only when you want supported projects, files, terminals, provider checks, and browser/mobile handoff to run through that server.':
'既定ではこのコンピュータを使用します。対応するプロジェクト、ファイル、ターミナル、プロバイダーチェック、ブラウザ/モバイルの引き継ぎをそのサーバー経由で実行したい場合にのみ、保存済みサーバーを選択してください。',
'Window Blur': 'ウィンドウのぼかし',
'Medium section heading.': '中サイズのセクション見出し。',
'macOS Option key': 'macOS の Option キー',
'Failed to add folder on this host': 'このホスト上でのフォルダーの追加に失敗しました',
'This workspace is locked by Git. Run git worktree unlock <worktree-path> from its repository, then retry deletion.':
'このワークスペースは Git によってロックされています。リポジトリで git worktree unlock <worktree-path> を実行してから、削除を再試行してください。',
'This workspace is locked by Git. Git reported: {{value0}}. Run git worktree unlock <worktree-path> from its repository, then retry deletion.':
'このワークスペースは Git によってロックされています。Git の報告: {{value0}}。リポジトリで git worktree unlock <worktree-path> を実行してから、削除を再試行してください。',
'Permanently deletes the remote Git worktrees and their branches. Cannot be undone.':
'リモートの Git ワークツリーとそのブランチを完全に削除します。この操作は取り消せません。',
'Click a card to copy a prompt. Use these in a Linear-linked worktree after the skill is installed.':
'カードをクリックするとプロンプトをコピーできます。スキルのインストール後、Linear にリンクしたワークツリーで使用してください。',
'Ticket actions work best in a worktree created from Tasks so the issue stays linked as context.':
'チケット操作は、タスクから作成したワークツリーで最も効果的です。Issue がコンテキストとしてリンクされたままになります。',
'Choose a base branch.': 'ベースブランチを選択してください。',
'Enter a {{value0}} title.': '{{value0}} のタイトルを入力してください。',
'Enter a valid five-field cron before saving.':
'保存する前に、有効な 5 フィールドの cron を入力してください。',
'Choose an available workspace before saving.':
'保存する前に、使用可能なワークスペースを選択してください。',
'Enter a valid advanced schedule before saving.':
'保存する前に、有効な詳細スケジュールを入力してください。',
'Creating...': '作成中…',
'Creating…': '作成中…',
'Reopening...': '再オープン中…',
'Thinking…': '思考中…',
'Hide from sidebar': 'サイドバーから非表示',
'Show in sidebar': 'サイドバーに表示',
'Recent or tab strip.': '「最近」またはタブストリップ。',
// Settings-search keywords: proper nouns keep their canonical spelling, and the rest were
// translated in the wrong sense (windows→窓, gitignore→ギティ無視, component→成分).
windows: 'Windows',
'windows powershell': 'Windows PowerShell',
'powershell 7': 'PowerShell 7',
neovim: 'Neovim',
hermes: 'Hermes',
duckduckgo: 'DuckDuckGo',
gitignore: 'gitignore',
component: 'コンポーネント',
compose: '特殊文字の入力',
sidekick: 'Sidekick',
'api token': 'API トークン',
'compare base': '比較ベース',
ahead: '進んでいる'
}
export const JA_VALUE_OVERRIDES = { ...JA_AUDIT_OVERRIDES, ...JA_UNIFIED_VALUES }

View File

@ -1,4 +1,5 @@
import { CROSS_LOCALE_KEY_OVERRIDES } from './locale-cross-locale-key-overrides.mjs'
import { JA_KEY_OVERRIDES } from './locale-ja-key-overrides.mjs'
import { KO_KEY_OVERRIDES } from './locale-ko-key-overrides.mjs'
import { MACOS_TCC_KEY_OVERRIDES } from './locale-macos-tcc-key-overrides.mjs'
@ -11,6 +12,9 @@ export function mergeLocaleKeyOverrides(base) {
// KO split overrides can share keys with zh/ja repairs; merge per locale.
merged[key] = { ...merged[key], ...overrides }
}
for (const [key, overrides] of Object.entries(JA_KEY_OVERRIDES)) {
merged[key] = { ...merged[key], ...overrides }
}
for (const [key, overrides] of Object.entries(MACOS_TCC_KEY_OVERRIDES)) {
merged[key] = { ...merged[key], ...overrides }
}

View File

@ -16,7 +16,7 @@ const BASE_LOCALE_KEY_OVERRIDES = {
'menu.showMobileButton': {
ko: 'Orca 모바일 버튼 표시',
zh: '显示 Orca Mobile 按钮',
ja: 'Orca モバイル ボタンを表示'
ja: 'Orca Mobile ボタンを表示'
},
'menu.toggleLeftSidebar': {
ko: '왼쪽 사이드바 표시/숨기기',
@ -169,7 +169,7 @@ const BASE_LOCALE_KEY_OVERRIDES = {
'auto.components.tab.bar.TabBarCreateEntry.b27864279e': {
ko: '에이전트 실행',
zh: '启动代理',
ja: 'エージェントを起動'
ja: 'Agent を起動'
},
'auto.components.sidebar.SidebarNav.c39ab10000': {
ko: 'Linear 작업 열기',
@ -343,7 +343,7 @@ const BASE_LOCALE_KEY_OVERRIDES = {
'settings.appearance.statusBar.kimiToggleDescription': {
ko: '활성 워크스페이스의 Kimi 구독 사용량을 표시합니다.',
zh: '显示当前工作区的 Kimi 订阅使用情况。',
ja: 'Kimi サブスクリプション'
ja: 'アクティブなワークスペースの Kimi サブスクリプション使用状況を表示します。'
},
'auto.components.mobile.MobileHero.cd4e5e816f': {
ko: '주머니 속의 워크스페이스.',
@ -433,17 +433,17 @@ const BASE_LOCALE_KEY_OVERRIDES = {
'auto.components.settings.AgentsPane.9bccf48906': {
ko: '에이전트 위치',
zh: '代理位置',
ja: 'エージェントの場所'
ja: 'Agent の場所'
},
'auto.components.skills.SkillsPage.38e0951c3a': {
ko: '에이전트 스킬',
zh: '代理技能',
ja: 'エージェントのスキル'
ja: 'Agent のスキル'
},
'auto.components.sidebar.SidebarNav.e518f544b1': {
ko: '감지된 에이전트 없음',
zh: '未检测到代理',
ja: 'エージェントが検出されません'
ja: 'Agent が検出されません'
},
'auto.components.onboarding.OnboardingFlow.04ae28d8ca': {
ko: '몇 시간 내내 보고 싶은 테마를 선택하세요.',
@ -478,7 +478,7 @@ const BASE_LOCALE_KEY_OVERRIDES = {
'auto.components.settings.ExperimentalPane.0277901cf7': {
ko: '완료된 에이전트, 차단 질문, 읽지 않은 상태 및 작업 트리 생성 이벤트에 대한 스레드 작업 트리 피드가 있는 에이전트 항목을 왼쪽 사이드바에 추가합니다. 실험적 — 이벤트 모델과 UI가 변경될 수 있습니다.',
zh: '将代理条目添加到左侧边栏,其中包含已完成代理、阻塞待办、未读状态和工作树创建事件的线程工作树提要。实验性——事件模型和 UI 可能会改变。',
ja: '完了したエージェント、ブロック中の質問、未読状態、ワークツリー作成イベントのスレッドワークツリーフィード付きエージェント項目を左サイドバーに追加します。実験的 — イベントモデルと UI は変更される場合があります。'
ja: '完了した Agent、ブロック中の質問、未読状態、ワークツリー作成イベントのスレッドワークツリーフィード付き Agent 項目を左サイドバーに追加します。実験的 — イベントモデルと UI は変更される場合があります。'
},
'auto.lib.fix.checks.agent.launch.9f00d7df0c': {
ko: '검사 프롬프트가 비어 있습니다. 소스 제어 AI 설정을 업데이트하세요.',
@ -488,7 +488,7 @@ const BASE_LOCALE_KEY_OVERRIDES = {
'auto.components.TaskPage.d0e3c8f933': {
ko: '일치하는 GitHub 작업이 없습니다',
zh: '没有匹配的 GitHub 工作项',
ja: '一致する GitHub 作業がありません'
ja: '一致する GitHub の作業はありません'
},
'auto.components.TaskPage.2af3ab5c58': {
ko: 'Linear에서 열 팀을 하나 선택하세요',
@ -513,7 +513,7 @@ const BASE_LOCALE_KEY_OVERRIDES = {
'auto.components.settings.IntegrationsPane.33ae9730a8': {
ko: 'Linear 액세스를 추가해 이슈를 탐색하고 연결합니다.',
zh: '添加 Linear 访问以浏览和链接议题。',
ja: 'Linear アクセスを追加してイシューを参照し、リンクします。'
ja: 'Linear アクセスを追加してIssue を閲覧およびリンクします。'
},
'auto.components.GitHubItemDialog.3ab6ac0fc8': {
ko: '선택한 GitHub 이슈 또는 PR을 미리보기하고 편집합니다.',

View File

@ -0,0 +1,33 @@
// CSS that lives in the i18n catalog. MT rewrote a selector to [データスラッシュメニュー] and a keyframe
// name to ブラウザフラッシュ, breaking the view in that locale only. Removing these from en.json is
// the real fix; until then the policy pins them to English.
const STYLE_BLOCK =
/@(keyframes|media|supports|font-face)\b|[.#][a-zA-Z][\w-]*[^{}]*\{[^{}]*[a-z-]+\s*:|\[[a-z-]+=["'][^"']*["']\]|\{[^{}]*[a-z-]+\s*:\s*[^{}]*[;}]/
// A selector with no declaration block has no braces for STYLE_BLOCK to key off.
const SELECTOR_TOKEN = /^(?:[>+~]|[a-zA-Z.#[][\w.#:()[\]"'=^$|*-]*)$/
const LONE_SELECTOR = /^#[a-zA-Z][\w-]*$|^\.[a-zA-Z][\w-]*-[\w-]+$/
// One dotted, colon or bracketed token — button.primary, a:hover, wsl.exe, localhost:3000. It is
// code whether it names a selector, a file or a host, and a translation breaks all three.
const LONE_QUALIFIED = /^[a-zA-Z][\w-]*(?:[.#:][\w-]+|\[[^\]]+\])$/
function isStandaloneSelector(enValue) {
if (/[{}]/.test(enValue)) {
return false
}
const tokens = enValue.trim().split(/\s+/)
if (!tokens.every((token) => SELECTOR_TOKEN.test(token))) {
return false
}
// A selector join, not a sentence period: two sentences would otherwise clear the threshold.
const marked = tokens.filter((token) => /^[#.][a-zA-Z]|[\w-][.#:][a-zA-Z]|\[/.test(token))
if (marked.length >= 2) {
return true
}
return tokens.length === 1 && (LONE_SELECTOR.test(tokens[0]) || LONE_QUALIFIED.test(tokens[0]))
}
export function isStyleValue(enValue) {
return STYLE_BLOCK.test(enValue) || isStandaloneSelector(enValue)
}

View File

@ -0,0 +1,153 @@
import { describe, expect, it } from 'vitest'
import { repairTranslatedValue, shouldPreserveEnglishValue } from './locale-translation-policy.mjs'
const ja = (enValue, localeValue, key = 'auto.test.relocalization') =>
repairTranslatedValue({ key, enValue, localeValue, locale: 'ja' })
describe('locale-translation-policy ja relocalization', () => {
it('heals generic terms the brand revert left in Latin mid-sentence', () => {
expect(ja('Close terminal?', 'この terminal を閉じますか?')).toBe('このターミナルを閉じますか?')
expect(ja('New Terminal', '新規 Terminal')).toBe('新規ターミナル')
expect(ja('Stop the agent?', 'この agent を停止しますか?')).toBe('この Agent を停止しますか?')
expect(ja('Nothing to commit.', 'commit するものはありません。')).toBe(
'コミットするものはありません。'
)
expect(ja('Open the repo', 'repo を開く')).toBe('リポジトリを開く')
})
it('leaves the second word of a two-word command in Latin', () => {
expect(ja('a commit hook or git commit fails', 'コミットフックまたは git commit が失敗')).toBe(
'コミットフックまたは git commit が失敗'
)
expect(ja('Run orca terminal', 'orca terminal を実行')).toBe('orca terminal を実行')
expect(ja('Install with pnpm install', 'pnpm install でインストール')).toBe(
'pnpm install でインストール'
)
})
it('leaves identifiers, flags, filenames, and Latin-only labels alone', () => {
expect(ja('Pass --agent to select one.', '--agent を渡して選択します。')).toBe(
'--agent を渡して選択します。'
)
expect(ja('Edit agents.md', 'agents.md を編集')).toBe('agents.md を編集')
expect(ja('Agent SDK settings', 'Agent SDK の設定')).toBe('Agent SDK の設定')
expect(ja('Agent SDK settings', 'この Agent SDK の設定')).toBe('この Agent SDK の設定')
expect(ja('Run git commit -m', 'git commit -m を実行')).toBe('git commit -m を実行')
})
it('keeps commands and identifiers in English so they still run', () => {
expect(shouldPreserveEnglishValue('pnpm install')).toBe(true)
expect(shouldPreserveEnglishValue('glab auth login')).toBe(true)
expect(shouldPreserveEnglishValue("gh pr list --json number -q '.[0].number'")).toBe(true)
expect(shouldPreserveEnglishValue('--model sonnet')).toBe(true)
expect(shouldPreserveEnglishValue('localhost, 127.0.0.1, *.internal')).toBe(true)
expect(shouldPreserveEnglishValue('stale-agent-row-{{value0}}')).toBe(true)
expect(shouldPreserveEnglishValue('text-foreground')).toBe(true)
expect(shouldPreserveEnglishValue('{basePrompt}')).toBe(true)
expect(shouldPreserveEnglishValue('{firstPrompt}')).toBe(true)
expect(shouldPreserveEnglishValue('{assistantMessage}')).toBe(true)
expect(shouldPreserveEnglishValue('/pricing')).toBe(true)
expect(shouldPreserveEnglishValue('/signup')).toBe(true)
})
it('repairs translated code examples back to executable values', () => {
expect(ja('--model sonnet', '--モデルソネット')).toBe('--model sonnet')
expect(
ja("gh pr list --json number -q '.[0].number'", "gh pr list --json 番号 -q '.[0].number'")
).toBe("gh pr list --json number -q '.[0].number'")
expect(ja('{basePrompt}', '{ベースプロンプト}')).toBe('{basePrompt}')
expect(ja('/pricing', '/価格設定')).toBe('/pricing')
})
it('keeps style blocks in English because a translated selector breaks the view', () => {
expect(shouldPreserveEnglishValue('.pp-card[data-card="starter"] .pp-cta')).toBe(true)
expect(shouldPreserveEnglishValue('@keyframes browser-flash { to { opacity: 1; } }')).toBe(true)
expect(shouldPreserveEnglishValue('.card { background: var(--card); }')).toBe(true)
// Why: the declaration requirement is what keeps prose containing braces translatable.
expect(shouldPreserveEnglishValue('e.g. {{value0}}')).toBe(false)
})
it('normalizes Japanese typography and settled terminology', () => {
expect(ja('Loading…', '読み込み中...')).toBe('読み込み中…')
expect(ja('Merge conflict', 'マージ紛争')).toBe('マージ競合')
// Why: MT inserts a Microsoft-style separator space that Japanese compounds do not use.
expect(ja('Status bar', 'ステータス バー')).toBe('ステータスバー')
expect(ja('Missing credentials', '資格情報がありません')).toBe('認証情報がありません')
expect(ja('Unknown', '未知')).toBe('不明')
expect(ja('Restart the server', 'サーバを再起動')).toBe('サーバーを再起動')
expect(ja('Open the browser', 'ブラウザーを開く')).toBe('ブラウザを開く')
})
it('leaves ranges and token samples out of the ellipsis rule', () => {
expect(ja('Compare main...HEAD', 'main...HEAD を比較')).toBe('main...HEAD を比較')
})
it('spaces the Latin terms the phrase fixes write back in', () => {
expect(ja('Clear cookies', 'クッキーを消去')).toBe('Cookie を消去')
expect(ja('Safely fast-forward the branch', 'ブランチを安全に早送りします')).toBe(
'ブランチを安全に fast-forward します'
)
})
it('uses ホスト for host, and leaves サーバー alone when English says server', () => {
expect(ja('Host path', 'サーバーパス')).toBe('ホストパス')
expect(ja('Enter a path that exists on the selected host.', 'ランタイムサーバー上のパス')).toBe(
'ホスト上のパス'
)
// Why: host and server are deliberately distinct wherever the English uses both.
expect(ja('Save the server host', 'サーバーを保存')).toBe('サーバーを保存')
})
it('restores Git vocabulary and brand names the MT localized', () => {
expect(ja('Branch upstream', 'ブランチの上流')).toBe('ブランチの upstream')
expect(ja('origin has commits', '起源にコミットがあります')).toBe('origin にコミットがあります')
expect(ja('Discard all staged changes?', '段階的な変更を破棄しますか?')).toBe(
'ステージ済みの変更を破棄しますか?'
)
expect(ja('Create Hermes automation', 'エルメスオートメーションを作成')).toBe(
'Hermes オートメーションを作成'
)
expect(ja('Delete the worktree', 'worktree を削除')).toBe('ワークツリーを削除')
})
it('keeps class strings, refs, and fixture filenames in English', () => {
for (const value of [
'size-4 text-muted-foreground',
'text-amber-700 dark:text-amber-300',
'origin/main',
'upstream/main',
'login.spec.ts',
'bastion.example.com'
]) {
expect(shouldPreserveEnglishValue(value)).toBe(true)
}
})
it('preserves a selector that has no declaration block', () => {
for (const value of [
'div.pricing-grid > div.card.starter:nth-of-type(1) > a.cta',
'.pp-cta',
'#dialog',
'.pp-card[data-card="starter"] .pp-cta',
'button.primary',
'a:hover',
'input[type="text"]',
'localhost:3000'
]) {
expect(shouldPreserveEnglishValue(value)).toBe(true)
}
// Why: two ordinary sentences carry two periods, which must not read as selector joins.
for (const value of [
'Open Settings > Git and try again.',
'Show live workspace ports. Click it for workspace-scoped ports and external listeners.',
'orca.yaml + local',
'.gitignore',
'Status:',
'Done.',
'#{{value0}}'
]) {
expect(shouldPreserveEnglishValue(value)).toBe(false)
}
})
})

View File

@ -108,18 +108,18 @@ describe('locale-translation-policy ja round 5', () => {
repairTranslatedValue({
key: 'auto.components.status.bar.WorkspaceSpaceManagerPanel.e9528a89b3',
enValue: 'Terminals',
localeValue: '端',
localeValue: '端',
locale: 'ja'
})
).toBe('Terminals')
).toBe('ターミナル')
expect(
repairTranslatedValue({
key: 'auto.components.skills.SkillsPage.38e0951c3a',
enValue: 'Agent Skills',
localeValue: 'エージェントのスキル',
localeValue: 'Agent のスキル',
locale: 'ja'
})
).toBe('エージェントのスキル')
).toBe('Agent のスキル')
expect(
repairTranslatedValue({
key: 'auto.components.tab.bar.TabBar.3d5d6c960d',

View File

@ -4,11 +4,14 @@ import {
overlapsCanonicalRendering
} from './locale-generic-ui-terms.mjs'
import { isScreenCursorContext } from './locale-screen-cursor-exemptions.mjs'
import { BRAND_MISTRANSLATIONS } from './locale-brand-mistranslations.mjs'
import { isStyleValue } from './locale-style-values.mjs'
import { LOCALE_KEY_OVERRIDES } from './locale-key-overrides.mjs'
import { LOCALE_PHRASE_FIXES } from './locale-phrase-fixes.mjs'
import { SEARCH_KEYWORD_OVERRIDES } from './locale-search-keyword-overrides.mjs'
import { LOCALE_VALUE_OVERRIDES } from './locale-value-overrides.mjs'
export { BRAND_MISTRANSLATIONS } from './locale-brand-mistranslations.mjs'
export { LOCALE_KEY_OVERRIDES } from './locale-key-overrides.mjs'
export { LOCALE_PHRASE_FIXES } from './locale-phrase-fixes.mjs'
export { SEARCH_KEYWORD_OVERRIDES } from './locale-search-keyword-overrides.mjs'
@ -164,167 +167,55 @@ export const NEVER_TRANSLATE_VALUES = new Set([
'lint',
'MD',
'/home/user/projects',
'Claude Code'
'Claude Code',
// Commands, refs, class strings and code samples: a translated one no longer runs or matches.
'pnpm install',
'glab auth login',
"gh pr list --json number -q '.[0].number'",
'--model sonnet',
'localhost, 127.0.0.1, *.internal',
'packages/web shared/ui',
'stale-agent-row-{{value0}}',
'text-foreground',
'source-control',
'combined-branch',
'pr-view',
'fix-login-flow',
'my-project',
'serve-sim',
'pnpm playwright test',
'gh auth login',
'size-4 text-muted-foreground',
'text-amber-700 dark:text-amber-300',
'text-emerald-700 dark:text-emerald-300',
'src/renderer packages/ui',
'upstream/main',
'origin/main',
'example.com',
'bastion.example.com',
'dashboard.spec.ts',
'checkout.spec.ts',
'login.spec.ts',
'untitled.md',
'review src/auth',
'throw src/auth',
// Rendered inside <code> or a font-mono element, so they are code the user copies or types.
'{prompt}',
'{basePrompt}',
'{firstPrompt}',
'{assistantMessage}',
'/goal',
'/pricing',
'/signup',
'npm run dev',
'nbformat',
'orca.yaml',
'upstream',
'LIN-329',
'GH #1799',
'orca · zsh'
])
export const BRAND_MISTRANSLATIONS = {
ko: {
Codex: ['사본', '코덱스'],
Gemini: ['쌍둥이자리'],
Claude: ['클로드'],
Grok: ['그록'],
Orca: ['오르카', '범고래'],
Cursor: ['커서'],
OpenCode: ['오픈코드'],
OpenClaw: ['오픈클로'],
OpenClaude: ['오픈클로드'],
Antigravity: ['반중력'],
Continue: ['계속하다'],
Charm: ['매력'],
Goose: ['거위'],
Pi: ['파이'],
'GitHub Copilot': ['GitHub 코파일럿', '코파일럿'],
Git: ['힘내'],
Discord: ['디스코드'],
Linear: ['선형'],
Agent: ['에이전트'],
Agents: ['에이전트'],
agent: ['에이전트'],
agents: ['에이전트'],
Commit: ['커밋'],
Commits: ['커밋'],
commit: ['커밋'],
commits: ['커밋'],
Markdown: ['마크다운', '가격 인하'],
markdown: ['마크다운', '가격 인하'],
Repo: ['저장소', '레포'],
Repos: ['저장소', '레포'],
repo: ['저장소', '레포'],
repos: ['저장소', '레포'],
Terminal: ['터미널'],
Terminals: ['터미널'],
terminal: ['터미널'],
terminals: ['터미널']
},
zh: {
Codex: ['法典'],
Gemini: ['双子座'],
Claude: ['克洛德', '克劳德'],
Grok: ['格罗克'],
Orca: ['虎鲸', '逆戟鲸'],
Cursor: ['光标'],
OpenCode: ['开放代码'],
OpenClaw: ['开爪'],
OpenClaude: ['开放克劳德'],
Antigravity: ['反重力'],
Continue: ['继续'],
Charm: ['魅力'],
Goose: ['鹅'],
Pi: ['圆周率'],
Droid: ['机器人'],
Kimi: ['基米'],
// Why: zh-only — 登月计划 is the literal "moon landing programme", not Kimi's vendor. ja and
// ko render this keyword their own way, so it must not go in the cross-locale preserve set.
moonshot: ['登月计划'],
'GitHub Copilot': ['GitHub 副驾驶', '副驾驶'],
Bitbucket: ['位桶'],
Linear: ['线性', '线形'],
Jira: ['吉拉'],
Tailscale: ['尾鳞', '尾鱗'],
Agent: ['代理', '智能体'],
Agents: ['代理', '智能体'],
agent: ['代理', '智能体'],
agents: ['代理', '智能体'],
Commit: ['提交'],
Commits: ['提交'],
commit: ['提交'],
commits: ['提交'],
Markdown: ['降价'],
markdown: ['降价'],
Repo: ['存储库', '仓库', '回购协议', '回购'],
Repos: ['存储库', '仓库', '回购协议', '回购'],
repo: ['存储库', '仓库', '回购协议', '回购'],
repos: ['存储库', '仓库', '回购协议', '回购'],
Terminal: ['终端', '端子'],
Terminals: ['终端', '端子'],
terminal: ['终端', '端子'],
terminals: ['终端', '端子'],
Bash: ['重击'],
PowerShell: ['电源外壳'],
REST: ['休息'],
HEAD: ['头'],
Swift: ['迅速'],
Rust: ['锈'],
'Claude Code': ['Claude·科德'],
'Git AI Author': ['Git AI 作者']
},
ja: {
Codex: ['法典', 'コーデックス'],
Gemini: ['双子座'],
Claude: ['クロード'],
Grok: ['グロック'],
Orca: ['シャチ', '逆戟鲸', 'オルカ'],
Cursor: ['カーソル'],
OpenCode: ['オープンコード', 'オープン・コード'],
OpenClaw: ['オープンクロー'],
OpenClaude: ['オープンクロード'],
Antigravity: ['反重力'],
Continue: ['続ける', '続行'],
Charm: ['魅力'],
Goose: ['ガチョウ', '雁'],
Pi: ['円周率'],
Droid: ['ロボット', 'ドロイド'],
'GitHub Copilot': ['GitHub コパイロット', 'コパイロット'],
Discord: ['不和'],
Linear: ['線形'],
Agent: ['エージェント'],
Agents: ['エージェント'],
agent: ['エージェント'],
agents: ['エージェント'],
Commit: ['コミット'],
Commits: ['コミット'],
commit: ['コミット'],
commits: ['コミット'],
Markdown: ['マークダウン'],
markdown: ['マークダウン'],
Repo: ['リポジトリ', 'リポ'],
Repos: ['リポジトリ', 'リポ'],
repo: ['リポジトリ', 'リポ'],
repos: ['リポジトリ', 'リポ'],
Terminal: ['ターミナル', '端子'],
Terminals: ['ターミナル', '端子'],
terminal: ['ターミナル', '端子'],
terminals: ['ターミナル', '端子']
},
es: {
Codex: ['códice', 'Códice'],
Gemini: ['Géminis'],
Claude: ['claudia', 'Claudia'],
Orca: ['orca', 'Orcas', 'orcas'],
OpenCode: ['código abierto', 'Código abierto'],
OpenClaude: ['Openclaude'],
Antigravity: ['antigravedad', 'Antigravedad'],
'GitHub Copilot': ['Copiloto de GitHub'],
Discord: ['discordia'],
Linear: ['lineal', 'Lineal'],
Jira: ['jira'],
Agent: ['Agente', 'agente'],
Agents: ['Agentes', 'agentes'],
agent: ['agente'],
agents: ['agentes'],
Commit: ['Confirmación', 'confirmación', 'Confirmar', 'Comprometerse'],
Commits: ['Confirmaciones', 'confirmaciones', 'Compromisos', 'compromisos', 'Se compromete'],
commit: ['confirmación', 'confirmar', 'comprometerse', 'compromiso'],
commits: ['confirmaciones', 'compromisos'],
Markdown: ['Reducción', 'reducción', 'Rebaja', 'rebaja', 'rebajas'],
markdown: ['reducción', 'rebaja', 'rebajas'],
Repo: ['Repositorio', 'repositorio'],
Repos: ['Repositorios', 'repositorios'],
repo: ['repositorio'],
repos: ['repositorios']
}
}
export const NATIVE_PICKER_LABELS = {
zh: { chinese: '中文(简体)', korean: '한국어', japanese: '日本語', spanish: 'Español' },
ko: { chinese: '中文(简体)', korean: '한국어', japanese: '日本語', spanish: 'Español' },
@ -348,6 +239,9 @@ export function shouldPreserveEnglishValue(enValue, key = '') {
if (isEnglishOnlyKey(key)) {
return true
}
if (isStyleValue(enValue)) {
return true
}
return NEVER_TRANSLATE_VALUES.has(enValue)
}

View File

@ -80,7 +80,7 @@ describe('locale-translation-policy', () => {
localeValue: '壊れた小切手に対して AI エージェントを開始しました。',
locale: 'ja'
})
).toBe('失敗したチェックに対して AI エージェントを開始しました。')
).toBe('失敗したチェックに対して AI Agent を開始しました。')
expect(
repairTranslatedValue({
key: 'auto.hooks.useSettingsNavigationMetadata.95a1886d94',
@ -88,7 +88,7 @@ describe('locale-translation-policy', () => {
localeValue: '電話機からターミナルとエージェントを制御します。',
locale: 'ja'
})
).toBe('スマートフォンからターミナルとエージェントを操作')
).toBe('スマートフォンからターミナルと Agent を操作します。')
expect(
repairTranslatedValue({
key: 'auto.components.GitHubItemDialog.934add88b6',
@ -398,7 +398,7 @@ describe('locale-translation-policy', () => {
localeValue: 'コンピューターと携帯電話で。',
locale: 'ja'
})
).toBe('コンピュータとスマートフォンで。')
).toBe('コンピュータとスマートフォンで。')
expect(
repairTranslatedValue({
key: 'auto.components.GitHubItemDialog.3ab6ac0fc8',

File diff suppressed because it is too large Load Diff

View File

@ -2783,7 +2783,7 @@
"agent": {
"row": {
"ad991ece5c": "智能体的窗格不再可用。",
"090d607412": "陈旧智能体行-{{value0}}"
"090d607412": "stale-agent-row-{{value0}}"
}
}
},