cctrans 0.2.1 → 0.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,8 +1,20 @@
1
+ <div align="center">
2
+
1
3
  # cctrans
2
4
 
5
+ **Read Claude Code in your language — pay tokens in English.**
6
+
7
+ [![npm version](https://img.shields.io/npm/v/cctrans?color=cb3837&logo=npm)](https://www.npmjs.com/package/cctrans)
8
+ [![npm downloads](https://img.shields.io/npm/dm/cctrans?color=blue)](https://www.npmjs.com/package/cctrans)
9
+ [![GitHub stars](https://img.shields.io/github/stars/roy-jiang-opus/cctrans?style=flat&logo=github)](https://github.com/roy-jiang-opus/cctrans)
10
+ [![license](https://img.shields.io/badge/license-MIT-green)](LICENSE)
11
+ [![node](https://img.shields.io/node/v/cctrans)](package.json)
12
+
3
13
  **English** | [简体中文](README.zh-Hans.md) | [繁體中文](README.zh-Hant.md) | [日本語](README.ja.md) | [한국어](README.ko.md) | [Русский](README.ru.md) | [हिन्दी](README.hi.md)
4
14
 
5
- A **bilingual overlay** for Claude Code: every reply gets a translated line (Chinese / Japanese / Korean / Russian / Hindi) under each original English line, **right in the conversation**.
15
+ </div>
16
+
17
+ ---
6
18
 
7
19
  ```
8
20
  ● I will refactor the auth module to use async tokens.
@@ -11,11 +23,42 @@ A **bilingual overlay** for Claude Code: every reply gets a translated line (Chi
11
23
  ↳ 这涉及 3 个文件并添加重试层。
12
24
  ```
13
25
 
14
- - **Non-destructive**: the translation only appears on screen the transcript and the model's context **stay pure English**, so skills, docs, and code are unaffected.
15
- - **No history pollution, no main-loop tokens**: translation runs through a **separate cheap backend**, completely outside your Claude Code session.
16
- - **One-key toggle**: on by default; switch it off instantly when you want plain English.
26
+ A **bilingual overlay** for Claude Code: a translated line (Chinese / Japanese / Korean / Russian / Hindi) under each English line, **right in the conversation** — display-only, so the transcript, the model's context, and your token bill stay 100% English.
27
+
28
+ ## Features
29
+
30
+ - 🪞 **Inline bilingual display** — the translation appears under each English line, in the conversation itself, streaming along with the reply
31
+ - 🧩 **Two layouts** — per-line interleave, or `cctrans mode section`: whole English block first, then its grouped translation
32
+ - 🧾 **Non-destructive** — transcript and model context stay pure English; skills, docs, and code are untouched
33
+ - 🆓 **Zero main-loop tokens** — translation runs through a separate cheap backend (or a free one), completely outside your Claude Code session
34
+ - ⌨️ **Input translation (beta)** — type prompts in your language; the model works — and replies — in English (`cctrans input on`)
35
+ - 🌏 **6 target languages** — `zh-Hans` `zh-Hant` `ja` `ko` `ru` `hi`
36
+ - 🔌 **6 backends with auto-fallback** — OpenAI / Anthropic / DeepL / Azure / free Google / your own Claude subscription
37
+ - 🔒 **Key isolation** — API keys live only in a chmod-600 file; shell env vars are never read
38
+ - 🛟 **Fail-safe** — any error or timeout falls back to plain English; it never blocks your session
39
+
40
+ ## 🚀 Quick start
41
+
42
+ ```bash
43
+ npm install -g cctrans && cctrans install
44
+ ```
45
+
46
+ The install registers the hooks and walks you through setup (language → backend → API key → live verification). Then **restart Claude Code** — replies become bilingual. Toggle anytime by typing `!cctrans off` / `!cctrans on` inside Claude Code (`!` is CC's built-in bash mode — no model call, no tokens).
47
+
48
+ <details>
49
+ <summary>Install from source</summary>
17
50
 
18
- ## Why
51
+ ```bash
52
+ git clone https://github.com/roy-jiang-opus/cctrans.git
53
+ cd cctrans
54
+ node bin/cctrans.js install
55
+ ```
56
+
57
+ Requires `~/.local/bin` on your PATH, or use an alias: `alias cctrans='node /path/to/cctrans/bin/cctrans.js'`
58
+
59
+ </details>
60
+
61
+ ## 🤔 Why
19
62
 
20
63
  Two problems, one architecture:
21
64
 
@@ -33,7 +76,7 @@ Anthropic's tracking issue for language-adjusted limits ([#26401](https://github
33
76
 
34
77
  Full research notes with sources: [MOTIVATION.md](MOTIVATION.md).
35
78
 
36
- ## How it works
79
+ ## ⚙️ How it works
37
80
 
38
81
  Built on Claude Code's native **`MessageDisplay` hook** (v2.1.152+): it fires while each assistant message renders, handing the hook each completed text chunk (`delta`); the `displayContent` the hook returns **replaces the on-screen rendering only**, never the stored message.
39
82
 
@@ -50,41 +93,47 @@ Claude streams English
50
93
 
51
94
  > Verified on CC 2.1.169: deltas are **non-overlapping** completed chunks (not accumulated text), a plain `\n` renders the two languages on separate lines, and code blocks / paths / already-translated lines are skipped automatically.
52
95
 
53
- ## Install
54
-
55
- ```bash
56
- npm install -g cctrans && cctrans install
57
-
58
- # from source:
59
- git clone https://github.com/roy-jiang-opus/cctrans.git
60
- cd cctrans
61
- node bin/cctrans.js install # registers the hooks, links cctrans into ~/.local/bin, then runs the setup wizard
62
- ```
63
-
64
- Then **restart Claude Code** (new session) so the hook loads. Send any message — replies become bilingual.
65
-
66
- > Requires `~/.local/bin` on your PATH; otherwise use an alias:
67
- > `alias cctrans='node /path/to/cctrans/bin/cctrans.js'`
68
-
69
- ## Usage
96
+ ## 🎛 Commands
70
97
 
71
98
  | Command | What it does |
72
99
  |---------|--------------|
73
100
  | `cctrans on` / `cctrans off` / `cctrans toggle` | turn translation on / off / toggle |
74
101
  | `cctrans status` | show state (toggle, hook, backend, language) |
75
102
  | `cctrans lang [code]` | show/set target language: `zh-Hans` `zh-Hant` `ja` `ko` `ru` `hi` |
103
+ | `cctrans mode [line\|section]` | layout: translation under each line, or grouped per block |
76
104
  | `cctrans backend <id>` | switch translation engine |
77
105
  | `cctrans backends` | list engines and their availability |
78
- | `cctrans setup` | interactive wizard: language, backend, API keys |
106
+ | `cctrans setup` | interactive wizard: language, display mode, backend, API keys |
79
107
  | `cctrans key [id] [value]` | manage API keys in `~/.cc-translate/keys.json` |
80
- | `cctrans input on` / `cctrans input off` | translate non-English input to English (sent as context) |
108
+ | `cctrans input on` / `cctrans input off` | **(beta)** translate non-English input to English (sent as context) |
109
+ | `cctrans input threshold <n>` | non-Latin characters that trigger input translation (default 4) |
81
110
  | `cctrans last [N]` | translate the latest (or N-back) reply to the terminal |
82
111
  | `cctrans test <text>` | translate ad-hoc text to verify the engine |
83
- | `cctrans install` / `cctrans uninstall` | register / remove the hook |
112
+ | `cctrans install` / `cctrans uninstall` | register / remove the hooks |
113
+
114
+ ## 🧩 Display modes
84
115
 
85
- **Fastest toggle**: type `!cctrans off` or `!cctrans on` inside Claude Code's input box (`!` is CC's built-in bash modeno model call, no tokens).
116
+ `line` (default) interleaves: a translated line under each English line, streaming with the reply. `section` keeps English exactly as Claude streams it and splices in **one grouped translation when a block completes** much quieter for list-heavy replies:
86
117
 
87
- ## Translation backends
118
+ ```
119
+ Use these flags:
120
+ ↳ 使用以下参数:
121
+
122
+ - Enable the cache
123
+ - Set a small timeout
124
+ - Prefer the batch API
125
+ ↳ 启用缓存
126
+ ↳ 设置较短的超时
127
+ ↳ 优先使用批量 API
128
+ ```
129
+
130
+ ```bash
131
+ cctrans mode section # switch back anytime: cctrans mode line
132
+ ```
133
+
134
+ > In section mode a block's translation appears **when the block completes**, not while it streams — with a slow backend (e.g. `claude-code`, 3–6 s/call) that pause is noticeable, so API backends feel best here. If a block's translation fails, the English is unaffected and that block simply stays untranslated.
135
+
136
+ ## 🌐 Translation backends
88
137
 
89
138
  | Backend | Requires | Speed | Quality | Notes |
90
139
  |---------|----------|-------|---------|-------|
@@ -101,7 +150,7 @@ API keys live **only** in `~/.cc-translate/keys.json` (chmod 600) — set them w
101
150
 
102
151
  All other settings (backend, language, marker, models, Azure endpoint) live in `~/.cc-translate/state.json` — change them via `cctrans` commands or edit the file directly.
103
152
 
104
- ## Languages
153
+ ## 🗣 Languages
105
154
 
106
155
  Target languages cover **CJK + Russian + Hindi** (non-Latin scripts, so "this line is already in the target language" can be detected for free via Unicode ranges and skipped):
107
156
 
@@ -116,19 +165,28 @@ cctrans lang zh-Hans # Simplified Chinese (default)
116
165
 
117
166
  Chinese uses BCP-47 **script** codes (`zh-Hans`/`zh-Hant`) — Traditional Chinese is a script, not a region; `zh-CN` / `zh-TW` are accepted as aliases and normalized. Switching takes effect immediately (the hook re-reads state on every call); each language has its own cache.
118
167
 
119
- ## Input translation
168
+ ## ⌨️ Input translation (beta)
120
169
 
121
- `cctrans input on` enables a `UserPromptSubmit` hook: when your prompt is mostly non-English, an English translation is attached as context the model treats as the canonical instruction you keep typing in your language, the model works in English. (Verified on CC 2.1.169: hooks cannot rewrite the prompt itself, so the original stays in history with the English alongside.) English prompts pass through untouched; any error falls back to sending your prompt as-is.
170
+ `cctrans input on` enables a `UserPromptSubmit` hook: when your prompt contains enough non-Latin text (default 4+ characters — an absolute count, so file paths and identifiers never dilute the trigger; tune with `cctrans input threshold <n>`), an English translation is attached as context the model treats as the canonical instruction, and the model is asked to **reply in English** so the bilingual overlay keeps working and your conversation context stays English end-to-end. (Verified on CC 2.1.169: hooks cannot rewrite the prompt itself, so the original stays in history with the English alongside.) English prompts pass through untouched; any error falls back to sending your prompt as-is.
122
171
 
123
- ## Behavior & limits (verified)
172
+ > **Beta**: the translation call blocks prompt submission for ~0.5–1.5 s per non-English prompt. Off by default; the setup wizard asks once. Feedback → [issues](https://github.com/roy-jiang-opus/cctrans/issues).
173
+
174
+ ## 📏 Behavior & limits (verified)
124
175
 
125
176
  - The hook fires **per chunk during streaming**; each chunk is translated and replaced in place — translations appear progressively alongside the English.
126
177
  - The hook has a **10-second** timeout; this tool guards at 9s internally. Any error / timeout / oversized chunk (>9,000 chars) **falls back safely to the original English** — it never stalls the session.
127
- - Every translated line is **cached** by content hash (`~/.cc-translate/cache`); repaints and repeated text cost nothing.
178
+ - Every translated line is **cached** by content hash (`~/.cc-translate/cache`); repaints and repeated text cost nothing. Both modes share the cache.
179
+ - In section mode an in-flight block's text is buffered in `~/.cc-translate/msgstate` (same at-rest exposure as the cache); the file is removed when the message completes and stale ones are swept after 24h.
128
180
  - With `openai`, each chunk is roughly one API call (~$0.0001) and adds about 1s of latency vs. plain English; `google` is faster with slightly lower quality.
129
181
 
130
- ## Uninstall
182
+ ## 🔗 Stay in the loop
131
183
 
132
- ```bash
133
- node bin/cctrans.js uninstall # removes the hook; restart Claude Code to take effect
134
- ```
184
+ - ⭐ **Star / Watch** [github.com/roy-jiang-opus/cctrans](https://github.com/roy-jiang-opus/cctrans) to get release updates
185
+ - 📦 **npm** — [npmjs.com/package/cctrans](https://www.npmjs.com/package/cctrans) · upgrade with `npm update -g cctrans`
186
+ - 🗺 **Roadmap** — [ROADMAP.md](ROADMAP.md): what's shipped, what's next
187
+ - 📚 **Research** — [MOTIVATION.md](MOTIVATION.md): the non-English token-tax data behind this project
188
+ - 🐛 **Issues / language requests** — [github.com/roy-jiang-opus/cctrans/issues](https://github.com/roy-jiang-opus/cctrans/issues)
189
+
190
+ ## 📄 License
191
+
192
+ [MIT](LICENSE) © Roy Jiang
package/README.ru.md CHANGED
@@ -1,8 +1,20 @@
1
+ <div align="center">
2
+
1
3
  # cctrans
2
4
 
5
+ **Читайте Claude Code на родном языке — платите за токены по-английски.**
6
+
7
+ [![npm version](https://img.shields.io/npm/v/cctrans?color=cb3837&logo=npm)](https://www.npmjs.com/package/cctrans)
8
+ [![npm downloads](https://img.shields.io/npm/dm/cctrans?color=blue)](https://www.npmjs.com/package/cctrans)
9
+ [![GitHub stars](https://img.shields.io/github/stars/roy-jiang-opus/cctrans?style=flat&logo=github)](https://github.com/roy-jiang-opus/cctrans)
10
+ [![license](https://img.shields.io/badge/license-MIT-green)](LICENSE)
11
+ [![node](https://img.shields.io/node/v/cctrans)](package.json)
12
+
3
13
  [English](README.md) | [简体中文](README.zh-Hans.md) | [繁體中文](README.zh-Hant.md) | [日本語](README.ja.md) | [한국어](README.ko.md) | **Русский** | [हिन्दी](README.hi.md)
4
14
 
5
- **Двуязычный оверлей** для Claude Code: в каждом ответе под каждой строкой оригинального английского текста появляется строка перевода (китайский / японский / корейский / русский / хинди) — **прямо в диалоге**.
15
+ </div>
16
+
17
+ ---
6
18
 
7
19
  ```
8
20
  ● I will refactor the auth module to use async tokens.
@@ -11,11 +23,42 @@
11
23
  ↳ Это затрагивает 3 файла и добавляет слой повторных попыток.
12
24
  ```
13
25
 
14
- - **Неразрушающий**: перевод появляется только на экранетранскрипт и контекст модели **остаются чисто английскими**, так что skills, документация и код не затрагиваются.
15
- - **Не загрязняет историю, не тратит токены основного цикла**: перевод выполняется через **отдельный дешёвый бэкенд**, полностью вне вашей сессии Claude Code.
16
- - **Переключение одной командой**: включён по умолчанию; мгновенно выключается, когда нужен чистый английский.
26
+ **Двуязычный оверлей** для Claude Code: строка перевода (китайский / японский / корейский / русский / хинди) под каждой английской строкой, **прямо в диалоге** только для отображения, поэтому транскрипт, контекст модели и ваш счёт за токены остаются на 100% английскими.
27
+
28
+ ## Возможности
29
+
30
+ - 🪞 **Встроенное двуязычное отображение** — перевод появляется под каждой английской строкой по мере стриминга ответа
31
+ - 🧩 **Два варианта компоновки** — построчное чередование или `cctrans mode section`: сначала весь английский блок, затем его сгруппированный перевод
32
+ - 🧾 **Неразрушающий** — транскрипт и контекст модели остаются чисто английскими; skills, документация и код не затронуты
33
+ - 🆓 **Ноль токенов основного цикла** — перевод идёт через отдельный дешёвый (или бесплатный) бэкенд, полностью вне сессии Claude Code
34
+ - ⌨️ **Перевод ввода (beta)** — печатайте на родном языке, модель работает — и отвечает — на английском (`cctrans input on`)
35
+ - 🌏 **6 целевых языков** — `zh-Hans` `zh-Hant` `ja` `ko` `ru` `hi`
36
+ - 🔌 **6 бэкендов с автооткатом** — OpenAI / Anthropic / DeepL / Azure / бесплатный Google / ваша подписка Claude
37
+ - 🔒 **Изоляция ключей** — API-ключи только в файле chmod-600; переменные окружения никогда не читаются
38
+ - 🛟 **Отказоустойчивость** — любая ошибка или таймаут откатывается к чистому английскому; сессия никогда не блокируется
39
+
40
+ ## 🚀 Быстрый старт
41
+
42
+ ```bash
43
+ npm install -g cctrans && cctrans install
44
+ ```
45
+
46
+ Установка регистрирует хуки и проводит через настройку (язык → бэкенд → API-ключ → живая проверка). Затем **перезапустите Claude Code** — ответы станут двуязычными. Переключайте в любой момент, набрав `!cctrans off` / `!cctrans on` в поле ввода Claude Code (`!` — встроенный bash-режим CC: без вызова модели, без токенов).
47
+
48
+ <details>
49
+ <summary>Установка из исходников</summary>
17
50
 
18
- ## Зачем это нужно
51
+ ```bash
52
+ git clone https://github.com/roy-jiang-opus/cctrans.git
53
+ cd cctrans
54
+ node bin/cctrans.js install
55
+ ```
56
+
57
+ Требуется `~/.local/bin` в PATH, либо алиас: `alias cctrans='node /path/to/cctrans/bin/cctrans.js'`
58
+
59
+ </details>
60
+
61
+ ## 🤔 Зачем это нужно
19
62
 
20
63
  Две проблемы, одна архитектура:
21
64
 
@@ -33,7 +76,7 @@ Issue Anthropic о лимитах с поправкой на язык ([#26401](
33
76
 
34
77
  Полные заметки исследования с источниками: [MOTIVATION.md](MOTIVATION.md).
35
78
 
36
- ## Как это работает
79
+ ## ⚙️ Как это работает
37
80
 
38
81
  Использует нативный хук **`MessageDisplay`** Claude Code (v2.1.152+): он срабатывает при рендеринге каждого сообщения ассистента, передавая хуку завершённый фрагмент текста (`delta`); возвращаемый хуком `displayContent` **заменяет только отображение на экране**, не меняя сохранённое сообщение.
39
82
 
@@ -51,41 +94,47 @@ Claude стримит английский текст
51
94
 
52
95
  > Проверено на CC 2.1.169: фрагменты `delta` **не перекрываются** (это не накапливающийся текст), обычный `\n` выводит два языка на отдельных строках, а блоки кода / пути / строки уже на целевом языке пропускаются автоматически.
53
96
 
54
- ## Установка
55
-
56
- ```bash
57
- npm install -g cctrans && cctrans install
58
-
59
- # from source:
60
- git clone https://github.com/roy-jiang-opus/cctrans.git
61
- cd cctrans
62
- node bin/cctrans.js install # регистрирует хуки, линкует cctrans в ~/.local/bin, затем запускает мастер настройки
63
- ```
64
-
65
- Затем **перезапустите Claude Code** (новая сессия), чтобы хук загрузился. Отправьте любое сообщение — ответы станут двуязычными.
66
-
67
- > Требуется `~/.local/bin` в PATH; иначе используйте алиас:
68
- > `alias cctrans='node /path/to/cctrans/bin/cctrans.js'`
69
-
70
- ## Использование
97
+ ## 🎛 Команды
71
98
 
72
99
  | Команда | Действие |
73
100
  |---------|----------|
74
101
  | `cctrans on` / `cctrans off` / `cctrans toggle` | включить / выключить / переключить перевод |
75
102
  | `cctrans status` | показать состояние (переключатель, хук, бэкенд, язык) |
76
103
  | `cctrans lang [code]` | показать/задать целевой язык: `zh-Hans` `zh-Hant` `ja` `ko` `ru` `hi` |
104
+ | `cctrans mode [line\|section]` | компоновка: перевод под каждой строкой или сгруппированно по блокам |
77
105
  | `cctrans backend <id>` | сменить движок перевода |
78
106
  | `cctrans backends` | список движков и их доступность |
79
- | `cctrans setup` | интерактивный мастер: язык, бэкенд, API-ключи |
107
+ | `cctrans setup` | интерактивный мастер: язык, режим отображения, бэкенд, API-ключи |
80
108
  | `cctrans key [id] [value]` | управление ключами в `~/.cc-translate/keys.json` |
81
- | `cctrans input on` / `cctrans input off` | переводить неанглийский ввод на английский (отправляется как контекст) |
109
+ | `cctrans input on` / `cctrans input off` | **(beta)** переводить неанглийский ввод на английский (отправляется как контекст) |
110
+ | `cctrans input threshold <n>` | число нелатинских символов, запускающее перевод ввода (по умолчанию 4) |
82
111
  | `cctrans last [N]` | перевести последний (или N-й с конца) ответ в терминал |
83
112
  | `cctrans test <текст>` | перевести произвольный текст для проверки движка |
84
- | `cctrans install` / `cctrans uninstall` | зарегистрировать / удалить хук |
113
+ | `cctrans install` / `cctrans uninstall` | зарегистрировать / удалить хуки |
114
+
115
+ ## 🧩 Режимы отображения
85
116
 
86
- **Самый быстрый способ переключения**: набрать `!cctrans off` или `!cctrans on` прямо в поле ввода Claude Code (`!`встроенный bash-режим CC: без вызова модели, без токенов).
117
+ `line` (по умолчанию) чередует строки: перевод под каждой английской строкой, в потоке вместе с ответом. `section` оставляет английский ровно таким, каким его стримит Claude, и вставляет **один сгруппированный перевод, когда блок завершён** заметно спокойнее для ответов с большими списками:
87
118
 
88
- ## Бэкенды перевода
119
+ ```
120
+ Use these flags:
121
+ ↳ Используйте эти флаги:
122
+
123
+ - Enable the cache
124
+ - Set a small timeout
125
+ - Prefer the batch API
126
+ ↳ Включите кэш
127
+ ↳ Задайте небольшой таймаут
128
+ ↳ Предпочитайте batch API
129
+ ```
130
+
131
+ ```bash
132
+ cctrans mode section # вернуться можно в любой момент: cctrans mode line
133
+ ```
134
+
135
+ > В режиме section перевод блока появляется **когда блок завершён**, а не во время стриминга — с медленным бэкендом (например `claude-code`, 3–6 с/вызов) эта пауза заметна, поэтому здесь лучше всего подходят API-бэкенды. Если перевод блока не удался, английский не затрагивается — блок просто остаётся непереведённым.
136
+
137
+ ## 🌐 Бэкенды перевода
89
138
 
90
139
  | Бэкенд | Требует | Скорость | Качество | Примечание |
91
140
  |--------|---------|----------|----------|------------|
@@ -102,7 +151,7 @@ API-ключи хранятся **только** в `~/.cc-translate/keys.json`
102
151
 
103
152
  Остальные настройки (бэкенд, язык, маркер, модели, эндпоинт Azure) находятся в `~/.cc-translate/state.json` — меняйте их командами `cctrans` или правьте файл напрямую.
104
153
 
105
- ## Языки
154
+ ## 🗣 Языки
106
155
 
107
156
  Целевые языки — **CJK + русский + хинди** (нелатинские письменности, поэтому «строка уже на целевом языке» определяется бесплатно по диапазонам Unicode и пропускается):
108
157
 
@@ -117,19 +166,28 @@ cctrans lang zh-Hans # упрощённый китайский (по умолч
117
166
 
118
167
  Для китайского используются **коды письменности** BCP-47 (`zh-Hans`/`zh-Hant`) — традиционный китайский это письменность, а не регион; `zh-CN` / `zh-TW` принимаются как алиасы и нормализуются автоматически. Смена языка применяется мгновенно (хук перечитывает состояние при каждом вызове); кэши языков независимы.
119
168
 
120
- ## Перевод ввода
169
+ ## ⌨️ Перевод ввода (beta)
121
170
 
122
- `cctrans input on` включает хук `UserPromptSubmit`: когда ваш промпт в основном не на английском, английский перевод прикрепляется как контекст, который модель считает каноничной инструкцией вы продолжаете печатать на родном языке, модель работает на английском. (Проверено на CC 2.1.169: хуки не могут переписать сам промпт, поэтому оригинал остаётся в истории рядом с английским.) Английский ввод проходит без изменений; при любой ошибке промпт безопасно отправляется как есть.
171
+ `cctrans input on` включает хук `UserPromptSubmit`: когда промпт содержит достаточно нелатинского текста (по умолчанию от 4 символов — абсолютный счёт, поэтому пути и идентификаторы не размывают порог; настраивается через `cctrans input threshold <n>`), английский перевод прикрепляется как контекст, который модель считает каноничной инструкцией, и модель просят **отвечать на английском** так двуязычный оверлей продолжает работать, а контекст разговора остаётся английским от начала до конца. (Проверено на CC 2.1.169: хуки не могут переписать сам промпт, поэтому оригинал остаётся в истории рядом с английским.) Английский ввод проходит без изменений; при любой ошибке промпт безопасно отправляется как есть.
123
172
 
124
- ## Поведение и ограничения (проверено)
173
+ > **Beta**: вызов перевода блокирует отправку каждого неанглийского промпта на ~0.5–1.5 с. По умолчанию выключено; мастер настройки спросит один раз. Отзывы → [issues](https://github.com/roy-jiang-opus/cctrans/issues)
174
+
175
+ ## 📏 Поведение и ограничения (проверено)
125
176
 
126
177
  - Хук срабатывает **во время стриминга** на каждый фрагмент; каждый фрагмент переводится и заменяется на месте — перевод появляется постепенно вместе с английским.
127
178
  - Таймаут хука — **10 секунд**; внутренний гард инструмента — 9с. Любая ошибка / таймаут / превышение размера (>9000 символов) **безопасно откатывается к оригинальному английскому** — сессия никогда не зависает.
128
- - Каждая переведённая строка **кэшируется** по хэшу содержимого (`~/.cc-translate/cache`); перерисовки и повторяющийся текст бесплатны.
179
+ - Каждая переведённая строка **кэшируется** по хэшу содержимого (`~/.cc-translate/cache`); перерисовки и повторяющийся текст бесплатны. Оба режима используют общий кэш.
180
+ - В режиме section текст ещё не завершённого блока буферизуется в `~/.cc-translate/msgstate` (та же степень раскрытия данных на диске, что и у кэша); файл удаляется по завершении сообщения, а устаревшие файлы вычищаются через 24 ч.
129
181
  - С `openai` каждый фрагмент — примерно один вызов API (~$0.0001) и ~1с задержки по сравнению с чистым английским; `google` быстрее, но качество чуть ниже.
130
182
 
131
- ## Удаление
183
+ ## 🔗 Следите за проектом
132
184
 
133
- ```bash
134
- node bin/cctrans.js uninstall # удаляет хук; вступает в силу после перезапуска Claude Code
135
- ```
185
+ - ⭐ **Star / Watch** [github.com/roy-jiang-opus/cctrans](https://github.com/roy-jiang-opus/cctrans) — получайте обновления релизов
186
+ - 📦 **npm** — [npmjs.com/package/cctrans](https://www.npmjs.com/package/cctrans) · обновление: `npm update -g cctrans`
187
+ - 🗺 **Дорожная карта** — [ROADMAP.md](ROADMAP.md): что готово, что дальше
188
+ - 📚 **Исследование** — [MOTIVATION.md](MOTIVATION.md): данные о неанглийском «токенном налоге», лёгшие в основу проекта
189
+ - 🐛 **Issues / запросы языков** — [github.com/roy-jiang-opus/cctrans/issues](https://github.com/roy-jiang-opus/cctrans/issues)
190
+
191
+ ## 📄 Лицензия
192
+
193
+ [MIT](LICENSE) © Roy Jiang
package/README.zh-Hans.md CHANGED
@@ -1,8 +1,20 @@
1
+ <div align="center">
2
+
1
3
  # cctrans
2
4
 
5
+ **用母语读 Claude Code——token 按英文计费。**
6
+
7
+ [![npm version](https://img.shields.io/npm/v/cctrans?color=cb3837&logo=npm)](https://www.npmjs.com/package/cctrans)
8
+ [![npm downloads](https://img.shields.io/npm/dm/cctrans?color=blue)](https://www.npmjs.com/package/cctrans)
9
+ [![GitHub stars](https://img.shields.io/github/stars/roy-jiang-opus/cctrans?style=flat&logo=github)](https://github.com/roy-jiang-opus/cctrans)
10
+ [![license](https://img.shields.io/badge/license-MIT-green)](LICENSE)
11
+ [![node](https://img.shields.io/node/v/cctrans)](package.json)
12
+
3
13
  [English](README.md) | **简体中文** | [繁體中文](README.zh-Hant.md) | [日本語](README.ja.md) | [한국어](README.ko.md) | [Русский](README.ru.md) | [हिन्दी](README.hi.md)
4
14
 
5
- 给 Claude Code 加一层**双语对照**:每条回复在原始英文行下面自动补一行译文(中/日/韩/俄/印地),**就在对话里**,一行英文一行译文。
15
+ </div>
16
+
17
+ ---
6
18
 
7
19
  ```
8
20
  ● I will refactor the auth module to use async tokens.
@@ -11,11 +23,42 @@
11
23
  ↳ 这涉及 3 个文件并添加重试层。
12
24
  ```
13
25
 
14
- - **非破坏**:屏幕上多了译文,但转录文件和模型看到的上下文**仍是纯英文**——技术文档、skills、代码都不受影响。
15
- - **不污染历史、不耗主对话 token**:翻译由一个**独立的便宜后端**完成,跟你的 Claude Code 会话完全无关。
16
- - **一个键开关**:默认常开;读纯英文/代码时一键关掉。
26
+ Claude Code 加一层**双语对照**:每行英文下面一行译文(中/日/韩/俄/印地),**就在对话里**——仅作显示,转录、模型上下文和你的 token 账单 100% 保持英文。
27
+
28
+ ## ✨ 特性
29
+
30
+ - 🪞 **行内双语显示** —— 译文随回复流式出现在每行英文下方,就在对话里
31
+ - 🧩 **两种排版** —— 逐行对照,或 `cctrans mode section`:整块英文先出,再跟一段成组译文
32
+ - 🧾 **非破坏** —— 转录与模型上下文保持纯英文;skills、文档、代码不受影响
33
+ - 🆓 **主对话零 token** —— 翻译走独立便宜后端(也有免费选项),完全在 Claude Code 会话之外
34
+ - ⌨️ **输入翻译(beta)** —— 用母语打字,模型按英文工作、按英文回复(`cctrans input on`)
35
+ - 🌏 **6 种目标语言** —— `zh-Hans` `zh-Hant` `ja` `ko` `ru` `hi`
36
+ - 🔌 **6 个后端自动降级** —— OpenAI / Anthropic / DeepL / Azure / 免费 Google / 你自己的 Claude 订阅
37
+ - 🔒 **密钥隔离** —— API key 只存在 chmod-600 的文件里,从不读终端环境变量
38
+ - 🛟 **故障安全** —— 任何错误或超时都回退为纯英文,绝不卡住会话
39
+
40
+ ## 🚀 快速开始
41
+
42
+ ```bash
43
+ npm install -g cctrans && cctrans install
44
+ ```
45
+
46
+ 安装会注册钩子并引导你完成配置(语言 → 后端 → API key → 实时验证)。然后**重启 Claude Code**——回复变成双语。随时在 Claude Code 输入框里输入 `!cctrans off` / `!cctrans on` 开关(`!` 是 CC 内置 bash 模式,不调用模型、不花 token)。
47
+
48
+ <details>
49
+ <summary>从源码安装</summary>
17
50
 
18
- ## 为什么做这个
51
+ ```bash
52
+ git clone https://github.com/roy-jiang-opus/cctrans.git
53
+ cd cctrans
54
+ node bin/cctrans.js install
55
+ ```
56
+
57
+ 需要 `~/.local/bin` 在 PATH 里,或用别名:`alias cctrans='node /path/to/cctrans/bin/cctrans.js'`
58
+
59
+ </details>
60
+
61
+ ## 🤔 为什么做这个
19
62
 
20
63
  两个痛点,一个架构解决:
21
64
 
@@ -33,7 +76,7 @@ Anthropic 关于按语言调整额度的 issue([#26401](https://github.com/anthr
33
76
 
34
77
  完整调研数据与来源:[MOTIVATION.md](MOTIVATION.md)。
35
78
 
36
- ## 工作原理
79
+ ## ⚙️ 工作原理
37
80
 
38
81
  利用 Claude Code 原生的 **`MessageDisplay` 钩子**(v2.1.152+):它在每条助手消息渲染时触发,把完成的文本片段(`delta`)交给钩子;钩子返回的 `displayContent` **替换屏幕显示**,但不改变存储的消息。
39
82
 
@@ -50,41 +93,47 @@ Claude 流式输出英文
50
93
 
51
94
  > 已在 CC 2.1.169 实测:`delta` 是**互不重叠**的已完成片段(不是累积文本),普通 `\n` 即可让两种语言分行显示,代码块/路径/已是目标语言的行自动跳过。
52
95
 
53
- ## 安装
54
-
55
- ```bash
56
- npm install -g cctrans && cctrans install
57
-
58
- # from source:
59
- git clone https://github.com/roy-jiang-opus/cctrans.git
60
- cd cctrans
61
- node bin/cctrans.js install # 注册钩子、链接 cctrans 到 ~/.local/bin,然后运行 setup 向导
62
- ```
63
-
64
- 然后**重启 Claude Code**(开新会话)让钩子生效。发任意消息,回复就会双语对照。
65
-
66
- > 需要 `~/.local/bin` 在 PATH 里;否则用别名:
67
- > `alias cctrans='node /path/to/cctrans/bin/cctrans.js'`
68
-
69
- ## 使用
96
+ ## 🎛 命令
70
97
 
71
98
  | 命令 | 作用 |
72
99
  |------|------|
73
100
  | `cctrans on` / `cctrans off` / `cctrans toggle` | 开 / 关 / 切换翻译 |
74
101
  | `cctrans status` | 查看状态(开关、钩子、后端、语言) |
75
102
  | `cctrans lang [code]` | 查看/切换目标语言:`zh-Hans` `zh-Hant` `ja` `ko` `ru` `hi` |
103
+ | `cctrans mode [line\|section]` | 排版:译文跟在每行下方,或按块成组 |
76
104
  | `cctrans backend <id>` | 切换翻译引擎 |
77
105
  | `cctrans backends` | 列出所有引擎及其可用性 |
78
- | `cctrans setup` | 交互式向导:语言、后端、API key |
106
+ | `cctrans setup` | 交互式向导:语言、显示模式、后端、API key |
79
107
  | `cctrans key [id] [value]` | 管理 `~/.cc-translate/keys.json` 里的 API key |
80
- | `cctrans input on` / `cctrans input off` | 把非英文输入翻译成英文(作为上下文发给模型) |
108
+ | `cctrans input on` / `cctrans input off` | **(beta)** 把非英文输入翻译成英文(作为上下文发给模型) |
109
+ | `cctrans input threshold <n>` | 触发输入翻译的非拉丁字符数(默认 4) |
81
110
  | `cctrans last [N]` | 把最近(或往前第 N 条)回复翻译到终端 |
82
111
  | `cctrans test <文本>` | 翻译一段文本,验证引擎 |
83
112
  | `cctrans install` / `cctrans uninstall` | 注册 / 移除钩子 |
84
113
 
85
- **最快的开关方式**:在 Claude Code 输入框里直接输入 `!cctrans off` 或 `!cctrans on`(`!` 是 CC 的内置 bash 模式,不调用模型、不花 token)。
114
+ ## 🧩 显示模式
115
+
116
+ `line`(默认)逐行对照:每行英文下面一行译文,随回复流式出现。`section` 让英文完全按 Claude 的流式输出原样呈现,在**一个块完成时**插入一段成组译文——对列表很多的回复要安静得多:
86
117
 
87
- ## 翻译后端
118
+ ```
119
+ Use these flags:
120
+ ↳ 使用以下参数:
121
+
122
+ - Enable the cache
123
+ - Set a small timeout
124
+ - Prefer the batch API
125
+ ↳ 启用缓存
126
+ ↳ 设置较短的超时
127
+ ↳ 优先使用批量 API
128
+ ```
129
+
130
+ ```bash
131
+ cctrans mode section # 随时切回:cctrans mode line
132
+ ```
133
+
134
+ > section 模式下,一个块的译文在**该块完成时**才出现,而不是边流式边出——后端慢时(如 `claude-code`,3–6 秒/次)这个停顿会比较明显,所以这里 API 后端体验最好。某个块翻译失败时,英文不受影响,该块只是保持未翻译。
135
+
136
+ ## 🌐 翻译后端
88
137
 
89
138
  | 后端 | 前提 | 速度 | 质量 | 说明 |
90
139
  |------|------|------|------|------|
@@ -101,7 +150,7 @@ API key **只**存放在 `~/.cc-translate/keys.json`(chmod 600)——用 `cctran
101
150
 
102
151
  其余设置(后端、语言、标记、模型、Azure 端点)都在 `~/.cc-translate/state.json` 里——用 `cctrans` 命令修改或直接编辑文件。
103
152
 
104
- ## 多语言
153
+ ## 🗣 多语言
105
154
 
106
155
  目标语言支持 **CJK + 俄语 + 印地语**(非拉丁文字,可按 Unicode 区间零成本判断"该行已是目标语言"并跳过):
107
156
 
@@ -116,19 +165,28 @@ cctrans lang zh-Hans # 简体中文(默认)
116
165
 
117
166
  中文采用 BCP-47 **文字码**(`zh-Hans`/`zh-Hant`)——繁体是文字系统而非地区;`zh-CN` / `zh-TW` 仍可作为别名使用,会自动归一化。切换语言即刻生效(钩子每次调用都读状态),不同语言的缓存相互独立。
118
167
 
119
- ## 输入翻译
168
+ ## ⌨️ 输入翻译(beta)
120
169
 
121
- `cctrans input on` 启用 `UserPromptSubmit` 钩子:当你的输入大部分是非英文时,英文译文会作为上下文附给模型并被视为权威指令——你继续用母语打字,模型按英文工作。(已在 CC 2.1.169 核实:钩子无法改写 prompt 本身,所以原文仍在历史里,英文随附。)英文输入原样通过;任何错误都安全回退为原样发送。
170
+ `cctrans input on` 启用 `UserPromptSubmit` 钩子:当你的输入包含足够多的非拉丁字符时(默认 4 个以上——按绝对数量计,文件路径和标识符不会稀释触发条件;用 `cctrans input threshold <n>` 调整),英文译文会作为上下文附给模型并被视为权威指令,同时要求模型**用英文回复**——这样双语 overlay 持续生效,对话上下文全程保持英文。(已在 CC 2.1.169 核实:钩子无法改写 prompt 本身,所以原文仍在历史里,英文随附。)英文输入原样通过;任何错误都安全回退为原样发送。
122
171
 
123
- ## 行为与限制(已核实)
172
+ > **Beta**:翻译调用会在每条非英文输入提交前阻塞约 0.5–1.5 秒。默认关闭;setup 向导会询问一次。反馈 → [issues](https://github.com/roy-jiang-opus/cctrans/issues)
173
+
174
+ ## 📏 行为与限制(已核实)
124
175
 
125
176
  - 钩子在**流式输出中**按片段触发,每段单独翻译并就地替换——所以译文会随英文逐段出现。
126
177
  - 钩子有 **10 秒**超时;本工具内部 9 秒兜底。任何错误/超时/超长(>9000 字符)都会**安全回退成原始英文**,绝不卡住会话。
127
- - 每行译文按内容哈希**缓存**(`~/.cc-translate/cache`),重绘和重复文本零成本。
178
+ - 每行译文按内容哈希**缓存**(`~/.cc-translate/cache`),重绘和重复文本零成本。两种模式共享同一缓存。
179
+ - section 模式下,进行中块的文本会缓冲在 `~/.cc-translate/msgstate`(落盘暴露面与缓存相同);消息完成后该文件即删除,过期残留文件 24 小时后清理。
128
180
  - 用 `openai` 时每段约一次 API 调用(~$0.0001),流式输出会比纯英文多约 1 秒/段的延迟;`google` 更快但质量略低。
129
181
 
130
- ## 卸载
182
+ ## 🔗 关注项目
131
183
 
132
- ```bash
133
- node bin/cctrans.js uninstall # 移除钩子;重启 Claude Code 生效
134
- ```
184
+ - ⭐ **Star / Watch** [github.com/roy-jiang-opus/cctrans](https://github.com/roy-jiang-opus/cctrans),第一时间获取版本更新
185
+ - 📦 **npm** —— [npmjs.com/package/cctrans](https://www.npmjs.com/package/cctrans) · 升级:`npm update -g cctrans`
186
+ - 🗺 **路线图** —— [ROADMAP.md](ROADMAP.md):已完成与计划中的功能
187
+ - 📚 **调研** —— [MOTIVATION.md](MOTIVATION.md):本项目背后的非英语 token 税数据
188
+ - 🐛 **Issue / 新语言请求** —— [github.com/roy-jiang-opus/cctrans/issues](https://github.com/roy-jiang-opus/cctrans/issues)
189
+
190
+ ## 📄 许可证
191
+
192
+ [MIT](LICENSE) © Roy Jiang