Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
70 changes: 69 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,73 @@
# Changelog

## [4.0.34] - 2026-09-26

### Added

- 📤 **Инструмент `attach_telegram` — отправка файлов в Telegram** — AI может прикрепить любой локальный файл и отправить его прямо в чат с ботом:
- JS-API `attachTelegram(filePath, caption?, comment?)`: `caption` — подпись к файлу, `comment` — то, что AI хочет добавить от себя (зачем файл, что внутри, на что обратить внимание);
- если задан только `comment`, он уходит подписью; если заданы оба — `comment` дописывается к `caption` отдельной строкой;
- лимит 45 МБ (запас под лимит Telegram в 50 МБ), подпись и комментарий обрезаются до 1024 символов;
- отправка через уже настроенного бота (`telegramBot.sendDocument`) — новых зависимостей нет;
- файлы больше лимита, отсутствующий файл или ненастроенный бот возвращают понятную ошибку;
- объявление в `cuckoo-tools.d.ts`, обёртка `attachTelegram` в песочнице `JsRunner`.
- 📁 **Telegram-бот: выбор проекта кнопками** — новая команда `/projects` (алиасы `/project`, `/proj`) открывает список проектов inline-клавиатурой:
- список собирается из сохранённых связок «сессия → проект» активного профиля, плюс текущий проект;
- постраничный вывод по 8 проектов с кнопками «◀️ Назад / Вперёд ▶️» и счётчиком страниц;
- выбор проекта переключает окно на **существующую сессию** этого проекта (та же навигация, что и `/switch`) — новый чат не создаётся;
- кнопка «⌨️ Ввести путь вручную» принимает абсолютный путь к папке следующим сообщением;
- если проект не выбран, команды `/diff`, `/log`, `/sessions` показывают сообщение вместе с клавиатурой выбора.

### Changed

- 📜 **`/log` и `/sessions` редактируют сообщение, а не плодят новые** — при повторном вызове и при листании страниц бот обновляет уже отправленное сообщение (`editMessageText`); если сообщение было удалено вручную — отправляется новое.
- 🆕 **`/new` сообщает результат** — вместо тишины или `⚠️ undefined` бот отвечает явно: «🆕 Новый чат открыт», «⚠️ Нет активного окна…» или «❌ Не удалось открыть новый чат: \<причина\>».
- 🌐 **Язык бота больше не навязывается** — `readSettings()` отдаёт ровно то, что записано в файле настроек, без подстановки языка системы; при `/start` бот больше не требует принудительно выбрать язык, а сразу показывает справку.

### Fixed

- 🐛 **`/new` не отвечал** — `newChat()` делает `loadURL` на домашнюю страницу и выгружает JS-контекст окна, поэтому `executeJavaScript` с ожиданием результата зависал навсегда. Теперь вызов «выстрелил-и-забыл», а ответ приходит сразу.
- 🐛 **Пагинация выбора проекта падала** — `ReferenceError: msgId is not defined` в обработчике callback-кнопок; id сообщения теперь берётся из `cbq.message`, а при неудачном редактировании есть фолбэк на отправку нового сообщения.
- 🐛 **Выбор проекта не применялся в приложении** — установка проекта по известному пути не переключала окно на его сессию. Добавлен IPC `set-project-dir` (+ `setProjectDir` в preload и `setProjectByDir` в main): поиск сессии по папке проекта и навигация на неё.
- 🐛 **Ошибка `setProjectDir недоступен в окне`** — метода не существовало; добавлен полный путь IPC → preload → main.

### Removed

- 🧹 **Принудительная фиксация языка DeepSeek** — удалён модуль `src/preload/dom/deepseek-language.js`, который переключал Language на «Система» и блокировал селект (`pointer-events:none`, `aria-disabled`, гашение `onMouseDown`/`onKeyDown`). Язык интерфейса DeepSeek снова выбирается пользователем свободно.

### Added (EN)

- 📤 **Tool `attach_telegram` — send files to Telegram** — the AI can attach any local file and send it straight to the chat with the bot:
- JS API `attachTelegram(filePath, caption?, comment?)`: `caption` is the file caption, `comment` is an extra note the AI adds itself (why the file, what's inside, what to look at);
- if only `comment` is given, it becomes the caption; if both are given, `comment` is appended to `caption` on a separate line;
- 45 MB limit (headroom under Telegram's 50 MB cap), caption and comment are truncated to 1024 chars;
- sent through the already-configured bot (`telegramBot.sendDocument`) — no new dependencies;
- oversized files, a missing file, or an unconfigured bot return a clear error;
- declared in `cuckoo-tools.d.ts`, wrapped as `attachTelegram` in the `JsRunner` sandbox.
- 📁 **Telegram bot: pick a project with buttons** — the new `/projects` command (aliases `/project`, `/proj`) opens a project list as an inline keyboard:
- the list is built from saved "session → project" mappings of the active profile plus the current project;
- paged output, 8 projects per page, with "◀️ Back / Next ▶️" buttons and a page counter;
- picking a project switches the window to the **existing session** of that project (same navigation as `/switch`) — no new chat is created;
- the "⌨️ Enter path manually" button accepts an absolute folder path as the next message;
- if no project is selected, `/diff`, `/log`, and `/sessions` show the message together with the project picker.

### Changed (EN)

- 📜 **`/log` and `/sessions` edit the message instead of posting new ones** — on repeat calls and when paging, the bot updates the message it already sent (`editMessageText`); if the message was deleted manually, a new one is sent.
- 🆕 **`/new` reports the result** — instead of silence or `⚠️ undefined`, the bot answers explicitly: "🆕 New chat opened", "⚠️ No active window…", or "❌ Failed to open a new chat: \\<reason\\>".
- 🌐 **The bot language is no longer forced** — `readSettings()` returns exactly what is stored in the settings file, with no system-language substitution; on `/start` the bot no longer demands a language choice and just shows help.

### Fixed (EN)

- 🐛 **`/new` did not respond** — `newChat()` calls `loadURL` to the home page, which unloads the window's JS context, so `executeJavaScript` awaiting a result hung forever. The call is now fire-and-forget and the reply comes back immediately.
- 🐛 **Project picker pagination crashed** — `ReferenceError: msgId is not defined` in the callback-button handler; the message id is now taken from `cbq.message`, and a failed edit falls back to sending a new message.
- 🐛 **Project selection did not apply in the app** — setting a project by a known path did not switch the window to its session. Added the IPC `set-project-dir` (plus `setProjectDir` in preload and `setProjectByDir` in main): it finds the session by project folder and navigates to it.
- 🐛 **"setProjectDir is unavailable in the window" error** — the method did not exist; the full IPC → preload → main path was added.

### Removed (EN)

- 🧹 **Forced DeepSeek language lock** — deleted the `src/preload/dom/deepseek-language.js` module, which switched Language to "System" and locked the select (`pointer-events:none`, `aria-disabled`, neutered `onMouseDown`/`onKeyDown`). The DeepSeek UI language can be chosen freely by the user again.

## [4.0.33] - 2026-09-23

### Added
Expand Down Expand Up @@ -171,4 +239,4 @@
- конвертация мс ↔ сек на границе UI, подпись `сек` / `sec`;
- валидация и тосты переписаны под новые единицы.
- **i18n для настроек задержки** — сообщения об ошибках и сохранении переведены на ru/en (ранее были захардкожены на китайском): ключи `overlay.delay.*`.
- Исправлена вёрстка строки задержки в overlay — подписи «до» и «сек» больше не переносятся по буквам (отдельный класс `.cuckoo-delay-label` вместо `.cuckoo-blur-label` с `space-between`).
- Исправлена вёрстка строки задержки в overlay — подписи «до» и «сек» больше не переносятся по буквам (отдельный класс `.cuckoo-delay-label` вместо `.cuckoo-blur-label` с `space-between`).
26 changes: 26 additions & 0 deletions botsrc/i18n.js
Original file line number Diff line number Diff line change
Expand Up @@ -152,6 +152,8 @@ const STRINGS = {

// ===== /new =====
"new.done": "🆕 Новый чат открыт.",
"new.noWindow": "⚠️ Нет активного окна — не удалось открыть новый чат.",
"new.failed": "❌ Не удалось открыть новый чат: {err}",

// ===== /diff =====
"diff.noProject": "⚠️ Проект не выбран.",
Expand All @@ -168,6 +170,17 @@ const STRINGS = {
"todos.empty": "☑ Список задач пуст.",
"todos.header": "☑ Задачи ({done}/{total}):",

// ===== Выбор проекта кнопками =====
"project.pickHint": "<i>Выбери проект кнопкой ниже.</i>",
"project.title": "📁 <b>Выбор проекта</b>",
"project.set": "✅ Проект выбран: <code>{dir}</code>",
"project.setFailed": "⚠️ Не удалось выбрать проект: {err}",
"project.current": "📁 Текущий проект: <code>{dir}</code>",
"project.none": "📁 Проект пока не выбран.",
"project.manual": "⌨️ Ввести путь вручную",
"project.manualHint": "⌨️ Отправь абсолютный путь к папке проекта следующим сообщением.",
"project.cancelled": "Отменено.",

// ===== /sessions и /switch =====
"sessions.empty": "📭 Сессий не найдено.",
"sessions.title": "🗂 <b>Сессии</b> (стр. {page}/{pages})",
Expand Down Expand Up @@ -398,6 +411,8 @@ const STRINGS = {

// ===== /new =====
"new.done": "🆕 New chat opened.",
"new.noWindow": "⚠️ No active window — cannot open a new chat.",
"new.failed": "❌ Failed to open a new chat: {err}",

// ===== /diff =====
"diff.noProject": "⚠️ Project not selected.",
Expand All @@ -414,6 +429,17 @@ const STRINGS = {
"todos.empty": "☑ Task list is empty.",
"todos.header": "☑ Tasks ({done}/{total}):",

// ===== Project picker =====
"project.pickHint": "<i>Pick a project with the button below.</i>",
"project.title": "📁 <b>Project selection</b>",
"project.set": "✅ Project selected: <code>{dir}</code>",
"project.setFailed": "⚠️ Failed to select project: {err}",
"project.current": "📁 Current project: <code>{dir}</code>",
"project.none": "📁 No project selected yet.",
"project.manual": "⌨️ Enter path manually",
"project.manualHint": "⌨️ Send the absolute path to the project folder as your next message.",
"project.cancelled": "Cancelled.",

// ===== /sessions and /switch =====
"sessions.empty": "📭 No sessions found.",
"sessions.title": "🗂 <b>Sessions</b> (page {page}/{pages})",
Expand Down
Loading
Loading