Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
65 commits
Select commit Hold shift + click to select a range
b0cd4f1
refactor(i18n): split settings json into smaller files
YangQing-Lin Jan 10, 2026
c55b084
refactor(i18n): load settings from split module
YangQing-Lin Jan 10, 2026
22bada9
refactor(i18n): remove legacy settings.json
YangQing-Lin Jan 10, 2026
7948a44
chore(i18n): update sync-settings-keys for split layout
YangQing-Lin Jan 10, 2026
4175d65
test(i18n): add split settings guards
YangQing-Lin Jan 10, 2026
618d1f7
chore: align biome schema version
YangQing-Lin Jan 10, 2026
6f78fef
chore(i18n): document messages loading contract
YangQing-Lin Jan 10, 2026
3f48fec
chore(i18n): add settings split verification notes
YangQing-Lin Jan 10, 2026
eb5b0c9
chore: format code (refactor-i18n-split-settings-3f48fec)
github-actions[bot] Jan 10, 2026
4c580f6
chore: fix i18n request formatting
YangQing-Lin Jan 10, 2026
a1eff62
Merge branch 'refactor/i18n-split-settings' of github.com:YangQing-Li…
YangQing-Lin Jan 10, 2026
d3c2838
chore: format code (refactor-i18n-split-settings-a1eff62)
github-actions[bot] Jan 10, 2026
ec0e3a0
fix: replace settings placeholder translations
YangQing-Lin Jan 10, 2026
54a500a
chore: verify settings sync script is idempotent
YangQing-Lin Jan 10, 2026
a6276fb
test: run i18n settings split guards
YangQing-Lin Jan 10, 2026
0418d47
test: add audit for zh-CN placeholder settings strings
YangQing-Lin Jan 10, 2026
9dffc85
chore: apply biome formatting
YangQing-Lin Jan 10, 2026
1b430a2
chore: document manual i18n settings verification
YangQing-Lin Jan 10, 2026
6248bb3
fix: translate all providers filter in ja
YangQing-Lin Jan 10, 2026
879f4fa
fix: translate all providers filter in zh-TW
YangQing-Lin Jan 10, 2026
9aab36a
fix: translate providers section copy in zh-TW
YangQing-Lin Jan 10, 2026
176a15b
fix: translate providers section copy in ja
YangQing-Lin Jan 10, 2026
acfaed8
feat: extend placeholder audit output
YangQing-Lin Jan 10, 2026
3d8d02d
feat: add allowlist for placeholder audit
YangQing-Lin Jan 10, 2026
466a95e
docs: define i18n translation quality rules
YangQing-Lin Jan 10, 2026
86ca518
chore: add i18n audit fail commands
YangQing-Lin Jan 10, 2026
45eb990
docs: add i18n PR checklist
YangQing-Lin Jan 10, 2026
d587911
chore: format i18n audit tests
YangQing-Lin Jan 10, 2026
53b74c4
fix: translate dashboard placeholders
YangQing-Lin Jan 10, 2026
c18faea
fix: translate myUsage placeholders
YangQing-Lin Jan 10, 2026
1a58b7b
fix: enforce locale-specific parentheses
YangQing-Lin Jan 10, 2026
f8f3593
fix: start translating provider form strings
YangQing-Lin Jan 10, 2026
9805f1d
fix: translate provider form strings
YangQing-Lin Jan 10, 2026
fde1c77
fix: translate provider guide content
YangQing-Lin Jan 10, 2026
4394513
Merge branch 'refactor/i18n-split-settings' of github.com:YangQing-Li…
YangQing-Lin Jan 10, 2026
346aaa2
test: add ja dashboard parentheses guard
YangQing-Lin Jan 10, 2026
06eb086
test: add zh-TW dashboard parentheses guard
YangQing-Lin Jan 10, 2026
7c739aa
test: add zh-TW myUsage parentheses guard
YangQing-Lin Jan 10, 2026
3fd0515
chore: translate ja provider form strings
YangQing-Lin Jan 10, 2026
b602598
chore: translate zh-TW provider form strings
YangQing-Lin Jan 10, 2026
8c5a279
chore: translate ja providers guide
YangQing-Lin Jan 10, 2026
7a88230
chore: translate zh-TW providers guide
YangQing-Lin Jan 10, 2026
c566674
chore: refine zh-TW dashboard strings
YangQing-Lin Jan 10, 2026
e109c0f
chore: translate ja providers strings
YangQing-Lin Jan 10, 2026
3739f31
chore: translate zh-TW providers strings
YangQing-Lin Jan 10, 2026
51e15a0
chore: refine zh-TW api test strings
YangQing-Lin Jan 10, 2026
7a46faa
chore: translate zh-TW settings small modules
YangQing-Lin Jan 10, 2026
e3c3aff
chore: translate ja settings small modules
YangQing-Lin Jan 10, 2026
2437d19
chore: clear i18n placeholders in settings
YangQing-Lin Jan 10, 2026
99572eb
chore: format code (refactor-i18n-split-settings-2437d19)
github-actions[bot] Jan 11, 2026
fa64111
test: fix biome formatting in i18n test
YangQing-Lin Jan 11, 2026
ae244a2
Merge branch 'refactor/i18n-split-settings' of github.com:YangQing-Li…
YangQing-Lin Jan 11, 2026
e45cc2e
chore: verify Biome lint gate (I18NE-030)
YangQing-Lin Jan 11, 2026
564ab84
chore: add messages emoji audit script (I18NE-010)
YangQing-Lin Jan 11, 2026
aaa9fc7
fix: remove emoji from messages warnings (I18NE-040)
YangQing-Lin Jan 11, 2026
80d2068
test: add messages no-emoji audit gate (I18NE-050)
YangQing-Lin Jan 11, 2026
2ee38f5
docs: add zh-CN i18n docs (I18NE-020)
YangQing-Lin Jan 11, 2026
44eeb5e
docs: add messages no-emoji rule (I18NE-060)
YangQing-Lin Jan 11, 2026
92ebaf0
chore: run full regression checks (I18NE-070)
YangQing-Lin Jan 11, 2026
1d295fc
docs: add i18n PR evidence template (I18NE-080)
YangQing-Lin Jan 11, 2026
6670c4e
fix: make messages no-emoji audit path-sep safe
YangQing-Lin Jan 11, 2026
2ce7c90
docs: add bun alias for messages no-emoji audit
YangQing-Lin Jan 11, 2026
819672f
Merge branch 'dev' into refactor/i18n-split-settings
YangQing-Lin Jan 11, 2026
cf829f3
Merge branch 'dev' into refactor/i18n-split-settings
YangQing-Lin Jan 11, 2026
bfd982d
fix: detect keycap and flag emoji sequences in i18n message audits
YangQing-Lin Jan 11, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,12 @@ bun run typecheck
# 如果更改影响运行逻辑,执行端到端验证或 bun run test
```

### i18n 变更(翻译质量/抽查)

如果 PR 涉及 i18n 文案(尤其是 `settings` / `dashboard` / `myUsage`),请遵循:
- 规则说明:`docs/i18n-translation-quality.md`
- PR Checklist:`docs/i18n-pr-checklist.md`

CI 会在 PR 上运行 `Docker Build Test`(见 `.github/CI_CD_SETUP.md`)。如需验证容器构建,可本地执行:

```bash
Expand Down
2 changes: 1 addition & 1 deletion biome.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{
"$schema": "https://biomejs.dev/schemas/2.3.10/schema.json",
"$schema": "https://biomejs.dev/schemas/2.3.11/schema.json",
"vcs": {
"enabled": true,
"clientKind": "git",
Expand Down
36 changes: 36 additions & 0 deletions docs/i18n-pr-checklist.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
# i18n PR checklist

> 中文对照版: [i18n-pr-checklist.zh-CN.md](i18n-pr-checklist.zh-CN.md)

This checklist is for changes that affect i18n messages, especially `settings`, `dashboard`, and `myUsage`.

## Required (automation)

- [ ] Run placeholder audit (scoped):
- `bun run i18n:audit-placeholders`
- [ ] If the PR is meant to eliminate placeholders, ensure fail mode is clean:
- `bun run i18n:audit-placeholders:fail`
- [ ] Run messages no-emoji audit (fail mode):
- `bun run i18n:audit-messages-no-emoji:fail`
- [ ] Run unit tests relevant to i18n/settings split:
- `bunx vitest run tests/unit/i18n/settings-split-guards.test.ts`
- `bunx vitest run tests/unit/i18n/settings-index-modules-load.test.ts`

## Required (review evidence)

- [ ] Include in PR description:
- the audit output diff (before/after) or a short summary (counts by locale + key modules)
- any allowlist changes with reasons (keep allowlist minimal and auditable)

## Required (manual spotcheck)

For at least `ja` and `zh-TW`:
- [ ] Settings pages (key areas): provider list, provider form, request filters, notifications
- [ ] Dashboard key widgets
- [ ] My Usage page

Attach screenshots (or provide a local path) for the key pages above.

## Rules to follow

See `docs/i18n-translation-quality.md` for R1/R2/R3 rules and allowlist conventions.
36 changes: 36 additions & 0 deletions docs/i18n-pr-checklist.zh-CN.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
# i18n PR 检查清单

> English: [i18n-pr-checklist.md](i18n-pr-checklist.md)

此清单适用于会影响 i18n messages 的变更,尤其是 `settings`、`dashboard`、`myUsage`。

## 必做(自动化)

- [ ] 运行 placeholder 审计(scoped):
- `bun run i18n:audit-placeholders`
- [ ] 若该 PR 目标是清零 placeholders,确保 fail 模式无命中:
- `bun run i18n:audit-placeholders:fail`
- [ ] 运行 messages no-emoji 审计(fail 模式):
- `bun run i18n:audit-messages-no-emoji:fail`
- [ ] 运行与 i18n/settings split 相关的单元测试:
- `bunx vitest run tests/unit/i18n/settings-split-guards.test.ts`
- `bunx vitest run tests/unit/i18n/settings-index-modules-load.test.ts`

## 必做(Review 证据)

- [ ] 在 PR 描述中包含:
- 审计输出 diff(before/after)或简短摘要(按 locale 统计 + 关键模块)
- 如有 allowlist 变更,说明原因(保持 allowlist 最小且可审计)

## 必做(人工抽查)

至少覆盖 `ja` 与 `zh-TW`:
- [ ] Settings 页面(关键区域):provider list、provider form、request filters、notifications
- [ ] Dashboard 关键组件
- [ ] My Usage 页面

为上述关键页面附上截图(或提供本地路径)。

## 需要遵守的规则

参见 `docs/i18n-translation-quality.md` 获取 R1/R2/R3 规则与 allowlist 约定。
68 changes: 68 additions & 0 deletions docs/i18n-pr-evidence-2026-01-11.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
# i18n no-emoji / docs zh evidence (2026-01-11)

This document is intended to be copy-pasted into a PR description.

## Summary

- Emoji cleanup (messages JSON):
- Before: 20 strings contained emoji (top files: `provider-chain.json`, `settings/data.json` across locales)
- After: 0 hits from `rg -n --pcre2 "\\p{Extended_Pictographic}" messages`
- Placeholder audit (zh-CN equality placeholders): OK
- Quality gates: `lint` / `typecheck` / `test` / `build` all pass

## Emoji cleanup details (messages JSON)

Key locations that were cleaned (keys unchanged, only values updated):
- `messages/<locale>/provider-chain.json`
- `provider-chain.timeline.circuitTriggered`
- `provider-chain.timeline.systemErrorNote`
- `messages/<locale>/settings/data.json`
- `settings.data.import.warningMerge`
- `settings.data.import.warningOverwrite`

Commands:
- Before/after scan:
- `rg -n --pcre2 "\\p{Extended_Pictographic}" messages`
- Optional structured listing (prints masked preview, no emoji characters):
- `node scripts/audit-messages-emoji.js --format=tsv`

## Placeholder audit (R1)

- `bun run i18n:audit-placeholders:fail`
- Expected output:
- `OK: no zh-CN placeholder candidates found in split settings.`

## No-emoji gate (R4)

- Script (codepoints only, no emoji printing):
- `bun run i18n:audit-messages-no-emoji:fail`
- Regression test (part of `bun run test`):
- `tests/unit/i18n/audit-messages-no-emoji-script.test.ts`

## Full regression commands

- `bun run lint`
- `bun run typecheck`
- `bun run test`
- `bun run build`

## Related commits (local)

- `564ab845` chore: add messages emoji audit script (I18NE-010)
- `aaa9fc7d` fix: remove emoji from messages warnings (I18NE-040)
- `80d20686` test: add messages no-emoji audit gate (I18NE-050)
- `2ee38f59` docs: add zh-CN i18n docs (I18NE-020)
- `44eeb5e9` docs: add messages no-emoji rule (I18NE-060)
- `92ebaf0e` chore: run full regression checks (I18NE-070)

## Manual spotcheck (ja / zh-TW)

Due to environment limitations (no GUI/browser automation in this run), screenshots are not attached here.

Recommended steps:
1. Start dev server: `bun run dev` (port 13500)
2. Open pages for both `ja` and `zh-TW` locales:
- Settings: `/settings` (providers list/form, request filters, notifications)
- Dashboard: `/dashboard` (key widgets)
- My Usage: `/my-usage`
3. Attach screenshots to the PR (or provide local file paths) and label each with locale + route.
37 changes: 37 additions & 0 deletions docs/i18n-settings-split.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
# i18n settings split

> 中文对照版: [i18n-settings-split.zh-CN.md](i18n-settings-split.zh-CN.md)

This repository splits `messages/<locale>/settings.json` into smaller JSON chunks under `messages/<locale>/settings/`.

## Layout
- `messages/<locale>/settings/*.json`: settings top-level object parts
- `messages/<locale>/settings/strings.json`: top-level string keys that belong directly under `settings`
- `messages/<locale>/settings/providers/*.json`: `settings.providers` object parts
- `messages/<locale>/settings/providers/strings.json`: provider-level string keys
- `messages/<locale>/settings/providers/form/*.json`: `settings.providers.form` object parts
- `messages/<locale>/settings/providers/form/strings.json`: provider form string keys

Runtime composition happens in `messages/<locale>/settings/index.ts` and is imported by `messages/<locale>/index.ts`.

## Verification
- Translation quality rules and audit commands:
- `docs/i18n-translation-quality.md`

- Sync keys across locales (canonical: zh-CN):
- `node scripts/sync-settings-keys.js`

- Unit tests:
- `bun run test`

- Scoped coverage for split-related modules:
- `bunx vitest run --coverage --coverage.include=scripts/sync-settings-keys.js --coverage.include=messages/**/settings/index.ts`

- Typecheck:
- `bun run typecheck`

- Lint:
- `bun run lint`

- Production build:
- `bun run build`
39 changes: 39 additions & 0 deletions docs/i18n-settings-split.zh-CN.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
# i18n settings split(拆分说明)

> English: [i18n-settings-split.md](i18n-settings-split.md)

本仓库将 `messages/<locale>/settings.json` 拆分为更小的 JSON 文件,存放在 `messages/<locale>/settings/` 目录下。

## 目录结构(Layout)

- `messages/<locale>/settings/*.json`: settings 顶层对象的各个子模块
- `messages/<locale>/settings/strings.json`: 直接属于 `settings` 顶层的字符串 key
- `messages/<locale>/settings/providers/*.json`: `settings.providers` 对象拆分后的子模块
- `messages/<locale>/settings/providers/strings.json`: provider 级别的字符串 key
- `messages/<locale>/settings/providers/form/*.json`: `settings.providers.form` 对象拆分后的子模块
- `messages/<locale>/settings/providers/form/strings.json`: provider form 的字符串 key

运行时拼装发生在 `messages/<locale>/settings/index.ts`,并由 `messages/<locale>/index.ts` 引入。

## 验证(Verification)

- 翻译质量规则与审计命令:
- `docs/i18n-translation-quality.md`

- 跨 locale 同步 key(canonical: zh-CN):
- `node scripts/sync-settings-keys.js`

- 单元测试:
- `bun run test`

- 针对 split 相关模块的 scoped coverage:
- `bunx vitest run --coverage --coverage.include=scripts/sync-settings-keys.js --coverage.include=messages/**/settings/index.ts`

- Typecheck:
- `bun run typecheck`

- Lint:
- `bun run lint`

- Production build:
- `bun run build`
64 changes: 64 additions & 0 deletions docs/i18n-translation-quality.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
# i18n translation quality rules (R1/R2/R3)

> 中文对照版: [i18n-translation-quality.zh-CN.md](i18n-translation-quality.zh-CN.md)

This document defines the **scope** and **executable rules** for i18n translation quality in this repo.
Downstream scripts and review checklists should follow this document as the source of truth.

## Scope

Must-translate scope (at least):
- `settings` (split settings messages under `messages/<locale>/settings/`)
- `dashboard` (`messages/<locale>/dashboard.json`)
- `myUsage` (`messages/<locale>/myUsage.json`)

Locales: `zh-CN` is canonical. Other supported locales: `en`, `ja`, `ru`, `zh-TW`.

## Rule R1: No zh-CN placeholders in non-canonical locales

For any non-canonical locale:
- If a leaf string **equals** the `zh-CN` leaf string at the same key path, and the `zh-CN` value contains Han characters, it is treated as a **placeholder candidate**.
- Placeholder candidates should be **fixed** (translated), or **explicitly allowlisted** with a documented reason.

Executable check:
- `bun run i18n:audit-placeholders`
- To fail the command on any findings: add `--fail`.
- `bun run i18n:audit-placeholders:fail`

Allowlist (auditable, minimal):
- `scripts/audit-settings-placeholders.allowlist.json`
- Supported filters: `key`, `keyPrefix`, `keyRegex`, `valueRegex`, plus `glossary` terms.

## Rule R2: Placeholders/tokens must be preserved

When updating translations, **do not change**:
- keys / JSON structure
- placeholder tokens (e.g. `{name}`, `{count}`, `{resetTime}`)
- URL / command snippets unless intentionally translated and verified safe

Recommended verification:
- unit tests under `tests/unit/i18n/`
- spot-check affected UI pages for the locale (see the PR checklist)

## Rule R3: Glossary and consistent terminology

Maintain a short glossary for terms that should be consistent across locales (brand, model names, product terms).

Initial glossary (expand as needed, but keep it minimal and reviewed):
- Provider / Model / API / HTTP/2
- Claude / OpenAI / Codex (names should not be translated)

## Rule R4: No emoji in messages JSON

`messages/**/*.json` must not contain emoji characters.

Executable check:
- `bun run i18n:audit-messages-no-emoji:fail`

Notes:
- The audit output prints file path + key path + Unicode codepoints (without printing emoji characters).

## Notes

- Prefer fixing translations over expanding allowlists.
- Every allowlist entry must have a clear reason in the allowlist file (and ideally referenced in the PR description).
64 changes: 64 additions & 0 deletions docs/i18n-translation-quality.zh-CN.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
# i18n 翻译质量规则(R1/R2/R3)

> English: [i18n-translation-quality.md](i18n-translation-quality.md)

本文档定义本仓库 i18n 翻译质量的 **scope** 与 **可执行规则**。
下游脚本与 review checklist 应以本文档为真相源。

## Scope

必须翻译的范围(至少包含):
- `settings`(拆分后的 settings messages,位于 `messages/<locale>/settings/`)
- `dashboard`(`messages/<locale>/dashboard.json`)
- `myUsage`(`messages/<locale>/myUsage.json`)

Locales:`zh-CN` 为 canonical。其他支持的 locales:`en`、`ja`、`ru`、`zh-TW`。

## Rule R1:非 canonical locale 禁止出现 zh-CN placeholder

对于任意非 canonical locale:
- 若某个 leaf string 在相同 key path 下 **等于** `zh-CN` 的 leaf string,且 `zh-CN` 的值包含汉字,则视为 **placeholder candidate**。
- placeholder candidates 应被 **修复**(翻译),或以明确理由 **加入 allowlist**。

可执行检查:
- `bun run i18n:audit-placeholders`
- 如需在任意命中时让命令失败:添加 `--fail`。
- `bun run i18n:audit-placeholders:fail`

Allowlist(可审计、保持最小):
- `scripts/audit-settings-placeholders.allowlist.json`
- 支持的过滤器:`key`、`keyPrefix`、`keyRegex`、`valueRegex`,以及 `glossary` terms。

## Rule R2:必须保留 placeholders/tokens

更新翻译时,**不要改动**:
- keys / JSON structure
- placeholder tokens(例如 `{name}`、`{count}`、`{resetTime}`)
- URL / command snippets(除非明确要翻译且已验证安全)

建议的验证方式:
- `tests/unit/i18n/` 下的单元测试
- 对受影响 locale 的 UI 页面做 spot-check(见 PR checklist)

## Rule R3:Glossary 与术语一致性

维护一份简短 glossary,用于跨 locale 保持一致的术语(品牌、模型名、产品术语等)。

初始 glossary(按需扩展,但保持最小并经过 review):
- Provider / Model / API / HTTP/2
- Claude / OpenAI / Codex(名称不翻译)

## Rule R4:messages JSON 禁止 Emoji

`messages/**/*.json` 中不允许出现 Emoji 字符。

可执行检查:
- `bun run i18n:audit-messages-no-emoji:fail`

说明:
- 审计输出包含文件路径 + key path + Unicode codepoints(不会直接打印 Emoji 字符本身)。

## Notes

- 优先修复翻译,而不是扩展 allowlists。
- 每条 allowlist 记录都必须在 allowlist 文件中写清原因(最好在 PR 描述中也有引用)。
2 changes: 1 addition & 1 deletion messages/en/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import notifications from "./notifications.json";
import providerChain from "./provider-chain.json";
import providers from "./providers.json";
import quota from "./quota.json";
import settings from "./settings.json";
import settings from "./settings";
import ui from "./ui.json";
import usage from "./usage.json";
import users from "./users.json";
Expand Down
4 changes: 2 additions & 2 deletions messages/en/provider-chain.json
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@
"remaining": "{count} attempts remaining",
"status": "Status",
"alreadyBroken": "Circuit already broken",
"circuitTriggered": "⚠️ Circuit breaker triggered",
"circuitTriggered": "Warning: Circuit breaker triggered",
"errorDetails": "Error Details",
"systemError": "Network/System Error",
"systemErrorFailed": "Network/System Error (Attempt {attempt})",
Expand All @@ -97,7 +97,7 @@
"errorMeaning": "Meaning: {meaning}",
"meaning": "Meaning",
"notCountedInCircuit": "This error is not counted in provider circuit breaker",
"systemErrorNote": "ℹ️ This error is not counted in provider circuit breaker",
"systemErrorNote": "Note: This error is not counted in provider circuit breaker",
"reselection": "Reselecting Provider",
"reselect": "Reselecting Provider",
"excluded": "Excluded: {providers}",
Expand Down
Loading
Loading