* refactor(cli): revert dynamic slash command LLM translation (#4137)
Removes the runtime LLM-translation path for dynamic slash command
descriptions added in #3871, along with its `general.dynamicCommandTranslation`
setting and the `/language translate` subcommand tree.
Keeps the built-in locale coverage from the same PR untouched. Localization
of dynamic command descriptions should be solved at the source (manifest
fields, not runtime model calls); see #4137 for the proposed alternative.
* refactor(cli): drop translate prompts from mustTranslateKeys
Follow-up to the dynamic command translation revert: the 7 prompt keys
were stripped from every locale file in the previous commit, but the
allow-list in mustTranslateKeys still demanded them.
* refactor(cli): drop dead CommandService.fromCommands and vacuous tests
Follow-up cleanup after the dynamic command translation revert.
CommandService.fromCommands was introduced by #3871 solely to wrap the
LLM-translated command list. With the LLM-translation path gone, it has
no remaining non-test callers — remove it and the matching test mock.
Also drop two assertions in languageCommand.test.ts that checked for the
absence of a top-level /language cache command. They tested a migration
state that never existed in this branch and now pass vacuously.
* docs: drop /language translate references after revert
Two user-facing docs documented the /language translate subcommands
(status/on/off/cache refresh/clear) that were removed in the dynamic
command translation revert. Strip them so users following the docs
don't hit "Invalid command" errors.
* refactor(cli): drop unused localizeDescription field
The DynamicCommandLocalizationService that read this flag was removed in
the revert, leaving the field with five setters and zero readers. Drop the
field, its JSDoc, and the five `localizeDescription: true` assignments.
Also tidy the now-misleading `modelDescription` JSDoc and the stale
`reloadCommands` comment that referenced the removed feature.
* refactor(cli): drop unused getLanguageNameForTranslationTarget
The only caller was the removed DynamicCommandLocalizationService.
Remove the function from `i18n/languages.ts` and the matching
import + re-export from `i18n/index.ts`.
* fix(i18n): Correct zh-TW translations to match Traditional Chinese conventions
Fix ~131 lines of Traditional Chinese (zh-TW) translations that used
Simplified Chinese character forms instead of standard Traditional
Chinese usage.
Changes:
- 文件 → 檔案 (47 occurrences)
- 爲 → 為 (45 occurrences)
- 啓 → 啟 (44 occurrences)
- 曆史 → 歷史 (6 occurrences)
- 鏈接 → 連結 (4 occurrences)
- 菜單 → 選單 (3 occurrences)
* fix(i18n): Replace 服務器 with 伺服器 (15 occurrences)
Align with Traditional Chinese convention where 伺服器 is the standard
term for 'server' in computing contexts.
* fix(i18n): Update zh-TW.js header comment to prevent accidental overwrite
Clarify that the file is the authoritative source and should not be
overwritten with auto-generated output, to prevent future maintainers
from regenerating with raw OpenCC and losing manual corrections.
* fix(i18n): Add zh-TW regression check and maintenance docs
Addresses reviewer feedback on PR #4129 (points 2 and 3):
- scripts/check-i18n.ts: Iterate over parsed zh-TW translation values
(not raw file content) and report the offending key. Replace the
earlier substring list with ZH_TW_FORBIDDEN_PATTERNS, which targets
the three real regression categories: variant Traditional characters
produced by OpenCC s2t (爲, 啓), Mainland-Chinese vocabulary (服務器,
菜單, 鏈接), and pure Simplified characters. Excludes 禁用 / 配置 /
文件 / 打開 to avoid false positives on Taiwan-valid usage.
- scripts/tests/check-i18n.test.ts: Cover the new check, including
negative cases for Taiwan-valid vocabulary.
- docs/users/features/language.md: Document zh-TW maintenance — the
vocabulary table, why raw OpenCC s2t output is not acceptable, and
where the CI-enforced list lives.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
* fix(i18n): Address review feedback on zh-TW check (#4129)
- check-i18n.ts: Sort ZH_TW_FORBIDDEN_PATTERNS longest-first and break
on first match so e.g. `历史` reports the specific bigram instead of
also firing the bare `历` rule (no duplicate CI errors).
- check-i18n.ts: Add ZH_TW_ALLOWED_EXCEPTIONS escape hatch so a future
legitimate translation (e.g. 區塊鏈 in a UI string) can opt out by key
without weakening the global pattern list.
- docs/users/features/language.md: Add a "CI enforced?" column so
contributors can tell which rows block CI vs. which are review-only
style guidance. Replace bare `曆` in the table with the `曆史` bigram
and note that `曆` is correct in calendar terms (日曆, 農曆, 西曆) —
prevents a future maintainer from globally replacing 曆→歷.
- Tests: Cover the dedup behavior on overlapping patterns.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
* docs(i18n): Note word-boundary limitation of zh-TW substring check
Document the known limitation that `includes()`-based pattern matching
does not respect Chinese word boundaries — a bigram like `鏈接` will
false-positive on `區塊鏈接口` (區塊鏈 + 接口). Direct contributors to
`ZH_TW_ALLOWED_EXCEPTIONS` when this happens instead of weakening the
pattern list.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com>