zames_pro 2.5.1 → 2.6.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 +32 -0
- package/dist/agent-loop.js +145 -6
- package/dist/browser.js +1 -1
- package/dist/config-menu.js +231 -0
- package/dist/config.js +143 -0
- package/dist/i18n.js +276 -0
- package/dist/index.js +415 -189
- package/dist/input.js +72 -7
- package/dist/spinner.js +11 -37
- package/dist/system-prompt.js +8 -2
- package/package.json +1 -1
package/dist/i18n.js
ADDED
|
@@ -0,0 +1,276 @@
|
|
|
1
|
+
// Localization (i18n).
|
|
2
|
+
//
|
|
3
|
+
// Задачи:
|
|
4
|
+
// * менять язык интерфейса (справка, служебные сообщения);
|
|
5
|
+
// * язык ответов агента — через system-prompt;
|
|
6
|
+
// * язык ответов агента на обычный язык.
|
|
7
|
+
//
|
|
8
|
+
// Стратегия: единая карта переводов по ключам. Новые ключи легко добавить.
|
|
9
|
+
// Тексты на русском (ru) — дефолт, английский (en) — альтернатива.
|
|
10
|
+
export const DEFAULT_LOCALE = 'ru';
|
|
11
|
+
export const LOCALES = [
|
|
12
|
+
{ code: 'ru', name: 'Русский', englishName: 'Russian' },
|
|
13
|
+
{ code: 'en', name: 'English', englishName: 'English' },
|
|
14
|
+
];
|
|
15
|
+
export function isLocale(v) {
|
|
16
|
+
return v === 'ru' || v === 'en';
|
|
17
|
+
}
|
|
18
|
+
export function normalizeLocale(v) {
|
|
19
|
+
if (!v)
|
|
20
|
+
return DEFAULT_LOCALE;
|
|
21
|
+
const s = String(v).trim().toLowerCase();
|
|
22
|
+
if (s === 'ru' || s === 'russian' || s === 'русский')
|
|
23
|
+
return 'ru';
|
|
24
|
+
if (s === 'en' || s === 'english' || s === 'английский')
|
|
25
|
+
return 'en';
|
|
26
|
+
return DEFAULT_LOCALE;
|
|
27
|
+
}
|
|
28
|
+
// Каталог строк. Ключ -> { ru, en }. Если ключа нет — вернём сам ключ.
|
|
29
|
+
const CATALOG = {
|
|
30
|
+
'app.tagline': {
|
|
31
|
+
ru: 'агент поверх chat.deepseek.com через Playwright',
|
|
32
|
+
en: 'coding agent over chat.deepseek.com via Playwright',
|
|
33
|
+
},
|
|
34
|
+
'common.yes': { ru: 'да', en: 'yes' },
|
|
35
|
+
'common.no': { ru: 'нет', en: 'no' },
|
|
36
|
+
'common.on': { ru: 'вкл', en: 'on' },
|
|
37
|
+
'common.off': { ru: 'выкл', en: 'off' },
|
|
38
|
+
'common.none': { ru: '(нет)', en: '(none)' },
|
|
39
|
+
'common.unknown': { ru: 'неизвестно', en: 'unknown' },
|
|
40
|
+
// ---------- help ----------
|
|
41
|
+
'help.options': { ru: 'Опции CLI:', en: 'CLI options:' },
|
|
42
|
+
'help.opt.dir': { ru: 'рабочая директория агента', en: 'agent working directory' },
|
|
43
|
+
'help.opt.task': { ru: 'задача одной строкой', en: 'single-line task' },
|
|
44
|
+
'help.opt.chat': { ru: 'продолжить существующий чат по id', en: 'resume an existing chat by id' },
|
|
45
|
+
'help.opt.resume_last': { ru: 'вернуться в последний сохранённый чат', en: 'resume the last saved chat' },
|
|
46
|
+
'help.opt.new_chat': { ru: 'начать новый чат (по умолчанию)', en: 'start a new chat (default)' },
|
|
47
|
+
'help.opt.resend_prompt': { ru: 'дослать system-prompt в существующий чат', en: 'resend system-prompt into an existing chat' },
|
|
48
|
+
'help.opt.max_iter': { ru: 'лимит итераций (по умолчанию {n})', en: 'iteration limit (default {n})' },
|
|
49
|
+
'help.opt.headless': { ru: 'браузер без UI', en: 'headless browser' },
|
|
50
|
+
'help.opt.debug': { ru: 'подробный лог', en: 'verbose log' },
|
|
51
|
+
'help.opt.calibrate': { ru: 'режим калибровки селекторов', en: 'selector calibration mode' },
|
|
52
|
+
'help.opt.dev': { ru: 'режим разработки: авто-перечитывание модулей', en: 'dev mode: auto-reload modules' },
|
|
53
|
+
'help.opt.version': { ru: 'показать версию', en: 'show version' },
|
|
54
|
+
'help.opt.help': { ru: 'эта справка', en: 'this help' },
|
|
55
|
+
'help.while_working': { ru: 'Пока агент работает:', en: 'While the agent is working:' },
|
|
56
|
+
'help.key.queue': { ru: 'печать + Enter поставить сообщение в очередь (уйдёт после текущей задачи)', en: 'type + Enter queue a message (sent after the current task)' },
|
|
57
|
+
'help.key.history': { ru: '↑ / ↓ история введённых сообщений', en: '↑ / ↓ input history' },
|
|
58
|
+
'help.key.words': { ru: 'Ctrl+← / Ctrl+→ перемещение по словам', en: 'Ctrl+← / Ctrl+→ move by words' },
|
|
59
|
+
'help.key.slash': { ru: '/ + Tab подсказка и автодополнение slash-команд', en: '/ + Tab slash-command hints and completion' },
|
|
60
|
+
'help.key.newline': { ru: 'Ctrl+J / Ctrl+Enter новая строка (Shift+Enter в терминалах с поддержкой)', en: 'Ctrl+J / Ctrl+Enter new line (Shift+Enter in capable terminals)' },
|
|
61
|
+
'help.key.backslash': { ru: '\\ + Enter тоже новая строка', en: '\\ + Enter also a new line' },
|
|
62
|
+
'help.key.esc': { ru: 'Esc, Ctrl+C прервать текущую генерацию', en: 'Esc, Ctrl+C abort current generation' },
|
|
63
|
+
'help.commands': { ru: 'Обычные команды:', en: 'Commands:' },
|
|
64
|
+
'help.cmd.new': { ru: '/new, /clear новый чат (сброс контекста)', en: '/new, /clear new chat (reset context)' },
|
|
65
|
+
'help.cmd.sessions': { ru: '/sessions список сохранённых сессий', en: '/sessions list saved sessions' },
|
|
66
|
+
'help.cmd.resume_id': { ru: '/resume-id <id> восстановить сессию по полному id', en: '/resume-id <id> resume a session by full id' },
|
|
67
|
+
'help.cmd.chats': { ru: '/chats список последних чатов DeepSeek', en: '/chats recent DeepSeek chats' },
|
|
68
|
+
'help.cmd.resume': { ru: '/resume <n> открыть чат №n из /chats', en: '/resume <n> open chat #n from /chats' },
|
|
69
|
+
'help.cmd.chat': { ru: '/chat показать текущий chat id', en: '/chat show current chat id' },
|
|
70
|
+
'help.cmd.cd': { ru: '/cd <path> сменить рабочую директорию', en: '/cd <path> change working directory' },
|
|
71
|
+
'help.cmd.pwd': { ru: '/pwd текущая директория', en: '/pwd current directory' },
|
|
72
|
+
'help.cmd.status': { ru: '/status состояние сессии', en: '/status session state' },
|
|
73
|
+
'help.cmd.reload': { ru: '/reload перечитать модули логики без перезапуска', en: '/reload hot-reload logic modules' },
|
|
74
|
+
'help.cmd.undo': { ru: '/undo откатить последнюю запись/правку', en: '/undo revert the last write/edit' },
|
|
75
|
+
'help.cmd.undo_list': { ru: '/undo-list список того, что можно откатить', en: '/undo-list list revertable changes' },
|
|
76
|
+
'help.cmd.transcript': { ru: '/transcript путь к файлу транскрипта', en: '/transcript transcript file path' },
|
|
77
|
+
'help.cmd.config': { ru: '/config настройки: показать и изменить', en: '/config settings: view and edit' },
|
|
78
|
+
'help.cmd.lang': { ru: '/config lang <ru|en> сменить язык интерфейса и агента', en: '/config lang <ru|en> switch UI and agent language' },
|
|
79
|
+
'help.cmd.debug_dom': { ru: '/debug-dom сохранить HTML страницы (для отладки)', en: '/debug-dom dump page HTML (debug)' },
|
|
80
|
+
'help.cmd.help': { ru: '/help, help справка', en: '/help, help this help' },
|
|
81
|
+
'help.cmd.exit': { ru: '/exit, /quit, exit выход', en: '/exit, /quit, exit exit' },
|
|
82
|
+
'help.self_review': { ru: 'Самообзор (отладка агента):', en: 'Self-review (agent debugging):' },
|
|
83
|
+
'help.self.review': { ru: '/self-review [фокус] снять снапшот src/ и запустить ревью', en: '/self-review [focus] snapshot src/ and run review' },
|
|
84
|
+
'help.self.fix': { ru: '/self-fix <name> [фокус] вернуться в существующий снапшот и продолжить', en: '/self-fix <name> [focus] enter an existing snapshot and continue' },
|
|
85
|
+
'help.self.done': { ru: '/self-done выйти из режима ревью (вернуться в свою папку)', en: '/self-done leave review mode (back to your dir)' },
|
|
86
|
+
'help.self.list': { ru: '/self-list список снапшотов', en: '/self-list list snapshots' },
|
|
87
|
+
'help.self.diff': { ru: '/self-diff <name> различия между текущим src/ и снапшотом', en: '/self-diff <name> diff between current src/ and snapshot' },
|
|
88
|
+
'help.self.apply': { ru: '/self-apply <name> применить снапшот к src/ (с бэкапом)', en: '/self-apply <name> apply snapshot to src/ (with backup)' },
|
|
89
|
+
'help.files': { ru: 'Файлы:', en: 'Files:' },
|
|
90
|
+
'help.files.logs': { ru: 'Логи:', en: 'Logs:' },
|
|
91
|
+
'help.files.undo': { ru: 'Undo:', en: 'Undo:' },
|
|
92
|
+
'help.files.sessions': { ru: 'Сессии:', en: 'Sessions:' },
|
|
93
|
+
'help.files.profile': { ru: 'Профиль:', en: 'Profile:' },
|
|
94
|
+
'help.files.snapshots': { ru: 'Снапшоты:', en: 'Snapshots:' },
|
|
95
|
+
'help.files.tmp': { ru: 'Временные:', en: 'Temp:' },
|
|
96
|
+
'help.files.config': { ru: 'Конфиг:', en: 'Config:' },
|
|
97
|
+
// ---------- spinner ----------
|
|
98
|
+
'spinner.phrases': {
|
|
99
|
+
ru: 'Замешиваю кал…|Взбиваю кал до однородной массы…|Мешаю кал с логикой…|Взбалтываю кал в коктейль…|Кручу венчиком по калу…|Смешиваю кал с кофеином…|Замешиваю тесто из кала…|Взбиваю пену из кала…|Перемешиваю кал лопатой…|Замешиваю глину из кала…|Гомогенизирую кал до состояния бетона…|Взбалтываю кал до просветления…|Блендерю кал в смузи…|Замешиваю цемент из кала…|Взбиваю кашу из кала…|Мешаю кал с надеждой…|Взбалтываю осадок из кала…|Кручу блендером по калу…|Смешиваю кал до неразличимости…|Замешиваю раствор из кала…|Взбиваю коктейль «кал»…|Перемешиваю кал лопатой дедлайна…|Взбиваю пенку из кала…|Гомогенизирую кал до однородности…|Взбалтываю кал в бетономешалке…|Сбиваю кал в однородную массу…|Размешиваю кал до просветления…|Замешиваю кал из всего подряд…',
|
|
100
|
+
en: 'Mixing the slurry…|Whipping it to a smooth paste…|Stirring logic into it…|Shaking it into a cocktail…|Whisking it around…|Blending it with caffeine…|Kneading dough out of it…|Whipping it into foam…|Tossing it with a spatula…|Kneading clay out of it…|Homogenizing it into concrete…|Shaking it until clear…|Blending it into a smoothie…|Mixing cement out of it…|Whipping porridge out of it…|Stirring it with hope…|Swirling the sediment…|Running the blender over it…|Mixing it beyond recognition…|Mixing mortar out of it…|Whipping a cocktail of it…|Stirring it with the deadline spatula…|Whipping foam out of it…|Homogenizing it evenly…|Tumbling it in a cement mixer…|Beating it into a uniform mass…|Stirring it until clear…|Mixing it from whatever is around…',
|
|
101
|
+
},
|
|
102
|
+
'spinner.hint': { ru: 'Esc — стоп', en: 'Esc — stop' },
|
|
103
|
+
// ---------- status ----------
|
|
104
|
+
'status.workdir': { ru: 'Рабочая директория: {v}', en: 'Working directory: {v}' },
|
|
105
|
+
'status.review_mode': { ru: 'Режим ревью: {v}', en: 'Review mode: {v}' },
|
|
106
|
+
'status.review_none': { ru: 'нет', en: 'no' },
|
|
107
|
+
'status.orig_dir': { ru: 'Исходная директория: {v}', en: 'Original directory: {v}' },
|
|
108
|
+
'status.chat': { ru: 'Текущий чат: {v}', en: 'Current chat: {v}' },
|
|
109
|
+
'status.fresh_next': { ru: 'Fresh chat на след. задаче: {v}', en: 'Fresh chat next task: {v}' },
|
|
110
|
+
'status.prompt_next': { ru: 'System prompt на след. задаче: {v}', en: 'System prompt next task: {v}' },
|
|
111
|
+
'status.resend': { ru: 'Resend prompt (--resend-prompt): {v}', en: 'Resend prompt (--resend-prompt): {v}' },
|
|
112
|
+
'status.last_chat': { ru: 'Last chat: {v}', en: 'Last chat: {v}' },
|
|
113
|
+
'status.sessions': { ru: 'Сессии: {v}', en: 'Sessions: {v}' },
|
|
114
|
+
'status.dev': { ru: 'Dev mode (auto-reload): {v}', en: 'Dev mode (auto-reload): {v}' },
|
|
115
|
+
'status.max_iter': { ru: 'Лимит итераций: {v}', en: 'Iteration limit: {v}' },
|
|
116
|
+
'status.headless': { ru: 'Headless: {v}', en: 'Headless: {v}' },
|
|
117
|
+
'status.debug': { ru: 'Debug: {v}', en: 'Debug: {v}' },
|
|
118
|
+
'status.undo': { ru: 'Undo: {v}', en: 'Undo: {v}' },
|
|
119
|
+
'status.transcript': { ru: 'Транскрипт: {v}', en: 'Transcript: {v}' },
|
|
120
|
+
'status.locale': { ru: 'Язык: {v}', en: 'Language: {v}' },
|
|
121
|
+
// ---------- messages ----------
|
|
122
|
+
'msg.working_dir': { ru: 'Рабочая директория: {v}', en: 'Working directory: {v}' },
|
|
123
|
+
'msg.transcript': { ru: 'Транскрипт: {v}', en: 'Transcript: {v}' },
|
|
124
|
+
'msg.new_chat': { ru: 'Создаю новый чат...', en: 'Creating a new chat...' },
|
|
125
|
+
'msg.new_chat_ok': { ru: 'Новый чат.', en: 'New chat.' },
|
|
126
|
+
'msg.resuming': { ru: 'Восстанавливаю сессию {id}...', en: 'Restoring session {id}...' },
|
|
127
|
+
'msg.opening_chat': { ru: 'Открываю чат {id}...', en: 'Opening chat {id}...' },
|
|
128
|
+
'msg.chat_opened': { ru: 'Чат открыт.', en: 'Chat opened.' },
|
|
129
|
+
'msg.interactive': { ru: 'Интерактивный режим. Введите задачу. Команды — /help. Выход — /exit.', en: 'Interactive mode. Enter a task. Commands — /help. Exit — /exit.' },
|
|
130
|
+
'msg.queue_hint': { ru: 'Пока агент работает, можно печатать следующее сообщение — оно уйдёт в очередь (Enter — отправить, Esc — прервать).', en: 'While the agent works you can type the next message — it goes to the queue (Enter — send, Esc — abort).' },
|
|
131
|
+
'msg.unknown_cmd': { ru: 'Неизвестная команда: {v}. Набери /help.', en: 'Unknown command: {v}. Type /help.' },
|
|
132
|
+
'msg.bye': { ru: 'Выход.', en: 'Bye.' },
|
|
133
|
+
'msg.abort_gen': { ru: '⏹ Esc — прерываю генерацию...', en: '⏹ Esc — aborting generation...' },
|
|
134
|
+
'msg.abort_ctrlc': { ru: '⏹ Ctrl+C — прерываю генерацию...', en: '⏹ Ctrl+C — aborting generation...' },
|
|
135
|
+
'msg.queued': { ru: '📨 В очередь ({n}): ', en: '📨 Queued ({n}): ' },
|
|
136
|
+
'msg.from_queue': { ru: '▶ Из очереди: ', en: '▶ From queue: ' },
|
|
137
|
+
'msg.agent_error': { ru: '✖ Ошибка агента:', en: '✖ Agent error:' },
|
|
138
|
+
'msg.critical': { ru: 'Критическая ошибка:', en: 'Critical error:' },
|
|
139
|
+
'msg.not_dir': { ru: 'Не директория: {v}', en: 'Not a directory: {v}' },
|
|
140
|
+
'prompt.review': { ru: 'REVIEW', en: 'REVIEW' },
|
|
141
|
+
'msg.workdir_error': { ru: 'Не удалось определить рабочую директорию:', en: 'Failed to determine the working directory:' },
|
|
142
|
+
'msg.browser_error': { ru: 'Не удалось запустить браузер:', en: 'Failed to launch the browser:' },
|
|
143
|
+
'msg.open_chat_error': { ru: 'Не удалось открыть чат: {v}', en: 'Failed to open chat: {v}' },
|
|
144
|
+
'msg.new_chat_error': { ru: 'Не удалось создать новый чат: {v}', en: 'Failed to create a new chat: {v}' },
|
|
145
|
+
'msg.reload_start': { ru: 'Перечитываю модули логики...', en: 'Reloading logic modules...' },
|
|
146
|
+
'msg.reload_partial': { ru: 'Часть модулей не перезагрузилась:', en: 'Some modules failed to reload:' },
|
|
147
|
+
'msg.reload_done': { ru: 'Перезагружено модулей: {n}. Браузер и чат не тронуты.', en: 'Reloaded modules: {n}. Browser and chat untouched.' },
|
|
148
|
+
'msg.reload_error': { ru: 'Ошибка reload:', en: 'Reload error:' },
|
|
149
|
+
'msg.abort_gen_short': { ru: '⏹ Esc — прерываю генерацию...', en: '⏹ Esc — aborting generation...' },
|
|
150
|
+
'msg.abort_ctrlc_short': { ru: '⏹ Ctrl+C — прерываю генерацию...', en: '⏹ Ctrl+C — aborting generation...' },
|
|
151
|
+
// ---------- self-review ----------
|
|
152
|
+
'self.review_failed': { ru: 'Самообзор провалился:', en: 'Self-review failed:' },
|
|
153
|
+
'self.fix_usage': { ru: 'Использование: /self-fix <name> [фокус]', en: 'Usage: /self-fix <name> [focus]' },
|
|
154
|
+
'self.snapshot_not_found': { ru: 'Снапшот не найден: {v}', en: 'Snapshot not found: {v}' },
|
|
155
|
+
'self.init_review_chat': { ru: 'Инициализирую review-чат для снапшота...', en: 'Initializing review chat for the snapshot...' },
|
|
156
|
+
'self.enter_failed': { ru: 'Не удалось войти в снапшот:', en: 'Failed to enter the snapshot:' },
|
|
157
|
+
'self.not_in_review': { ru: 'Ты и так не в режиме ревью.', en: 'You are not in review mode.' },
|
|
158
|
+
'self.diff_usage': { ru: 'Использование: /self-diff <name>', en: 'Usage: /self-diff <name>' },
|
|
159
|
+
'self.apply_usage': { ru: 'Использование: /self-apply <name>', en: 'Usage: /self-apply <name>' },
|
|
160
|
+
'self.fix_hint': { ru: '\n💡 Режим ревью по снапшоту {name}. Пиши агенту задачу или /self-done.\n', en: '\n💡 Review mode on snapshot {name}. Send the agent a task or /self-done.\n' },
|
|
161
|
+
'self.done_hint': { ru: 'Вернулся в {v}. Следующая задача начнёт новый чат.\n', en: 'Back to {v}. The next task will start a new chat.\n' },
|
|
162
|
+
'self.review_hint': {
|
|
163
|
+
ru: '\n💡 Теперь ты в режиме ревью. Просто пиши агенту, например:\n «исправь ошибки»\n «доработай обработку ошибок в ask()»\n «покажи, что не так с undo»\nВыйти: /self-done. Применить: /self-apply {name}\n',
|
|
164
|
+
en: '\n💡 You are now in review mode. Just ask the agent, e.g.:\n "fix the errors"\n "improve error handling in ask()"\n "show what is wrong with undo"\nExit: /self-done. Apply: /self-apply {name}\n',
|
|
165
|
+
},
|
|
166
|
+
// ---------- chats / sessions ----------
|
|
167
|
+
'chats.recent': { ru: 'Последние чаты DeepSeek:', en: 'Recent DeepSeek chats:' },
|
|
168
|
+
'chats.use_resume': { ru: '\nИспользуй /resume <n> для продолжения.\n', en: '\nUse /resume <n> to continue.\n' },
|
|
169
|
+
'chats.none': { ru: 'Чатов не найдено.', en: 'No chats found.' },
|
|
170
|
+
'chats.fetch_error': { ru: 'Не удалось получить список:', en: 'Failed to fetch the list:' },
|
|
171
|
+
'chats.resume_usage': { ru: 'Использование: /resume <n> (или /chats для списка)', en: 'Usage: /resume <n> (or /chats for the list)' },
|
|
172
|
+
'chats.need_number': { ru: 'Нужен номер из /chats.', en: 'A number from /chats is required.' },
|
|
173
|
+
'chats.run_chats_first': { ru: 'Сначала выполни /chats.', en: 'Run /chats first.' },
|
|
174
|
+
'chats.no_n': { ru: 'Нет чата №{n}. Всего: {total}.', en: 'No chat #{n}. Total: {total}.' },
|
|
175
|
+
'chats.opening': { ru: 'Открываю: {v}', en: 'Opening: {v}' },
|
|
176
|
+
'chats.context_kept': { ru: ' Контекст чата сохранён. Системный промпт не пересылается (--resend-prompt чтобы дослать).\n', en: ' Chat context kept. System prompt is not resent (--resend-prompt to force).\n' },
|
|
177
|
+
'chats.prompt_will_resend': { ru: ' Системный промпт будет переслан на следующей задаче.\n', en: ' System prompt will be resent on the next task.\n' },
|
|
178
|
+
'chats.current_id': { ru: 'Текущий chat id: {v}', en: 'Current chat id: {v}' },
|
|
179
|
+
'chats.not_created': { ru: 'Чат ещё не создан.', en: 'No chat created yet.' },
|
|
180
|
+
'sessions.dir': { ru: 'Папка сессий: {v}', en: 'Sessions dir: {v}' },
|
|
181
|
+
'sessions.none': { ru: 'Сохранённых сессий нет. Они появятся после первой задачи/чата.', en: 'No saved sessions. They appear after the first task/chat.' },
|
|
182
|
+
'sessions.restore_hint': { ru: 'Восстановить: /resume-id <id> (полный id) или /resume <n> после /chats.', en: 'Restore: /resume-id <id> (full id) or /resume <n> after /chats.' },
|
|
183
|
+
'sessions.resume_id_usage': { ru: 'Использование: /resume-id <chat id>', en: 'Usage: /resume-id <chat id>' },
|
|
184
|
+
// ---------- undo / dom ----------
|
|
185
|
+
'undo.empty': { ru: 'История пуста.', en: 'History is empty.' },
|
|
186
|
+
'undo.reverted': { ru: '↶ Откатили: {v}', en: '↶ Reverted: {v}' },
|
|
187
|
+
'undo.restored': { ru: ' (восстановлено)', en: ' (restored)' },
|
|
188
|
+
'undo.deleted': { ru: ' (удалено)', en: ' (deleted)' },
|
|
189
|
+
'undo.failed': { ru: 'Не удалось откатить: {v}', en: 'Failed to revert: {v}' },
|
|
190
|
+
'undo.changed': { ru: 'изменён', en: 'changed' },
|
|
191
|
+
'undo.created': { ru: 'создан', en: 'created' },
|
|
192
|
+
'dom.saved': { ru: 'HTML сохранён: {v}', en: 'HTML saved: {v}' },
|
|
193
|
+
'dom.selectors': { ru: 'Селекторы:', en: 'Selectors:' },
|
|
194
|
+
'dom.save_error': { ru: 'Не удалось сохранить DOM:', en: 'Failed to save DOM:' },
|
|
195
|
+
// ---------- cd ----------
|
|
196
|
+
'cd.outside': { ru: 'Нельзя выйти за пределы: {v}', en: 'Cannot leave the sandbox: {v}' },
|
|
197
|
+
'cd.not_dir': { ru: 'Не директория: {v}', en: 'Not a directory: {v}' },
|
|
198
|
+
'cd.already': { ru: 'Уже здесь.', en: 'Already here.' },
|
|
199
|
+
'cd.left_review': { ru: 'Вышел из режима ревью (/cd).', en: 'Left review mode (/cd).' },
|
|
200
|
+
'cd.changed': { ru: 'Рабочая директория: {v}', en: 'Working directory: {v}' },
|
|
201
|
+
'cd.failed': { ru: 'Не удалось перейти: {v}', en: 'Failed to change directory: {v}' },
|
|
202
|
+
'calibrate': { ru: '\n🔧 Режим калибровки селекторов\n', en: '\n🔧 Selector calibration mode\n' },
|
|
203
|
+
'reload.auto_partial': { ru: '⚠ авто-reload: часть модулей не загрузилась, работаю на прежней версии:', en: '⚠ auto-reload: some modules failed, using previous version:' },
|
|
204
|
+
// ---------- config menu ----------
|
|
205
|
+
'cfg.group.ui': { ru: 'Интерфейс', en: 'Interface' },
|
|
206
|
+
'cfg.group.agent': { ru: 'Агент', en: 'Agent' },
|
|
207
|
+
'cfg.group.confirmation': { ru: 'Подтверждения', en: 'Confirmations' },
|
|
208
|
+
'cfg.group.undo': { ru: 'Откат (undo)', en: 'Undo' },
|
|
209
|
+
'cfg.group.transcript': { ru: 'Транскрипт', en: 'Transcript' },
|
|
210
|
+
'cfg.group.browser': { ru: 'Браузер / DeepSeek', en: 'Browser / DeepSeek' },
|
|
211
|
+
'cfg.f.ui_locale': { ru: 'Язык интерфейса и ответов агента', en: 'Interface and agent reply language' },
|
|
212
|
+
'cfg.f.maxIterations': { ru: 'Лимит итераций на задачу', en: 'Max agent loop iterations per task' },
|
|
213
|
+
'cfg.f.headless': { ru: 'Браузер без UI (нужен перезапуск)', en: 'Headless browser (needs restart)' },
|
|
214
|
+
'cfg.f.debug': { ru: 'Подробный лог', en: 'Verbose debug logging' },
|
|
215
|
+
'cfg.f.hotReload': { ru: 'Авто-перечитывание модулей перед задачей', en: 'Auto-reload logic modules before each task' },
|
|
216
|
+
'cfg.f.confirmation_write': { ru: 'Спрашивать перед Write', en: 'Ask before Write' },
|
|
217
|
+
'cfg.f.confirmation_edit': { ru: 'Спрашивать перед Edit', en: 'Ask before Edit' },
|
|
218
|
+
'cfg.f.confirmation_bash': { ru: 'Спрашивать перед Bash', en: 'Ask before Bash' },
|
|
219
|
+
'cfg.f.undo_enabled': { ru: 'Включить бэкапы для отката', en: 'Enable undo backups' },
|
|
220
|
+
'cfg.f.undo_maxBackups': { ru: 'Сколько бэкапов хранить', en: 'Max undo backups kept' },
|
|
221
|
+
'cfg.f.transcript_enabled': { ru: 'Вести транскрипт', en: 'Write transcript log' },
|
|
222
|
+
'cfg.f.browser_answerTimeoutMs': { ru: 'Ждать ответ, мс', en: 'Wait for an answer, ms' },
|
|
223
|
+
'cfg.f.browser_askRetries': { ru: 'Число повторов ask()', en: 'ask() retry count' },
|
|
224
|
+
'cfg.f.browser_stabilityChecks': { ru: 'Проверки стабильности ответа', en: 'Answer stability checks' },
|
|
225
|
+
'cfg.f.browser_stabilityDelayMs': { ru: 'Пауза между проверками, мс', en: 'Delay between stability checks, ms' },
|
|
226
|
+
'cfg.f.browser_minSendIntervalMs': { ru: 'Мин. пауза между отправками, мс', en: 'Min pause between sends, ms' },
|
|
227
|
+
'cfg.f.browser_rateLimitWaitMs': { ru: 'Пауза при лимите частоты, мс', en: 'Wait on rate limit, ms' },
|
|
228
|
+
'cfg.f.browser_maxRateLimitRetries': { ru: 'Число повторов при лимите', en: 'Rate-limit retry count' },
|
|
229
|
+
'cfg.menu.title': { ru: '⚙ Настройки — выбери параметр', en: '⚙ Settings — choose a parameter' },
|
|
230
|
+
'cfg.menu.hint': { ru: '↑/↓ — выбор, Enter — изменить, q/Esc — выйти', en: '↑/↓ select, Enter edit, q/Esc quit' },
|
|
231
|
+
'cfg.menu.edit_hint': { ru: 'Введи значение и Enter (пусто — отмена)', en: 'Enter a value and press Enter (empty — cancel)' },
|
|
232
|
+
'cfg.menu.saved': { ru: '✔ Сохранено: {v} = {value}', en: '✔ Saved: {v} = {value}' },
|
|
233
|
+
'cfg.menu.default': { ru: 'по умолчанию', en: 'default' },
|
|
234
|
+
'cfg.menu.notty': { ru: 'Меню доступно только в интерактивном терминале. Используй /config list|get|set.', en: 'The menu needs an interactive terminal. Use /config list|get|set.' },
|
|
235
|
+
// ---------- config ----------
|
|
236
|
+
'cfg.title': { ru: 'Настройки zames', en: 'zames settings' },
|
|
237
|
+
'cfg.current': { ru: 'Текущий конфиг:', en: 'Current config:' },
|
|
238
|
+
'cfg.usage': {
|
|
239
|
+
ru: 'Использование: /config [menu | list | get <путь> | set <путь> <значение> | reset <путь> | path | lang <ru|en>]',
|
|
240
|
+
en: 'Usage: /config [menu | list | get <path> | set <path> <value> | reset <path> | path | lang <ru|en>]',
|
|
241
|
+
},
|
|
242
|
+
'cfg.saved': { ru: 'Сохранено: {v} = {value}', en: 'Saved: {v} = {value}' },
|
|
243
|
+
'cfg.reset': { ru: 'Сброшено к дефолту: {v}', en: 'Reset to default: {v}' },
|
|
244
|
+
'cfg.value': { ru: '{v} = {value}', en: '{v} = {value}' },
|
|
245
|
+
'cfg.unknown_key': { ru: 'Неизвестный параметр: {v}', en: 'Unknown setting: {v}' },
|
|
246
|
+
'cfg.bad_value': { ru: 'Неверное значение для {v}: ожидалось {type}', en: 'Invalid value for {v}: expected {type}' },
|
|
247
|
+
'cfg.write_error': { ru: 'Не удалось записать конфиг: {v}', en: 'Failed to write config: {v}' },
|
|
248
|
+
'cfg.paths': { ru: 'Конфиг (глобальный): {global}\nКонфиг (проект): {project}', en: 'Config (global): {global}\nConfig (project): {project}' },
|
|
249
|
+
'cfg.keys': { ru: 'Доступные параметры:', en: 'Available settings:' },
|
|
250
|
+
'cfg.lang_set': { ru: 'Язык переключён на {v}.', en: 'Language switched to {v}.' },
|
|
251
|
+
'cfg.lang_usage': { ru: 'Использование: /config lang <ru|en>', en: 'Usage: /config lang <ru|en>' },
|
|
252
|
+
// ---------- system prompt ----------
|
|
253
|
+
'prompt.answer_language': {
|
|
254
|
+
ru: 'ВАЖНО: отвечай оператору на русском языке. Весь текст в поле message инструмента respond, а также любые пояснения — на русском.',
|
|
255
|
+
en: 'IMPORTANT: reply to the operator in English. All text in the respond tool message field, and any explanations, must be in English.',
|
|
256
|
+
},
|
|
257
|
+
'prompt.tools_header': { ru: 'You have access to the following tools:', en: 'You have access to the following tools:' },
|
|
258
|
+
};
|
|
259
|
+
export function translate(locale) {
|
|
260
|
+
const loc = isLocale(locale) ? locale : DEFAULT_LOCALE;
|
|
261
|
+
return (key, params) => {
|
|
262
|
+
const entry = CATALOG[key];
|
|
263
|
+
let template = entry ? entry[loc] || entry[DEFAULT_LOCALE] : key;
|
|
264
|
+
if (!params)
|
|
265
|
+
return template;
|
|
266
|
+
return template.replace(/\{(\w+)\}/g, (m, name) => {
|
|
267
|
+
return Object.prototype.hasOwnProperty.call(params, name)
|
|
268
|
+
? String(params[name])
|
|
269
|
+
: m;
|
|
270
|
+
});
|
|
271
|
+
};
|
|
272
|
+
}
|
|
273
|
+
export function localeDisplayName(locale) {
|
|
274
|
+
const found = LOCALES.find((l) => l.code === locale);
|
|
275
|
+
return found ? found.name : locale;
|
|
276
|
+
}
|