y83 code / журнал

Журнал релизов 0.8: часть 4 из 9

Полная ветка 0.8 из журнала проекта. Записи идут от свежих к старым, текст взят из CHANGELOG.md без правок — это тот же журнал, что читают разработчик и агент.

записей в ветке
251
приложение
185
бэкенд
59
архив сборок
7
период
19 августа 2026 — 24 октября 2026
страниц
4 из 9

журнал

Релизы ветки 0.8

Здесь записи 91–120 из 251: релизы приложения и бэкенда плюс записи архива сборок — каждая запись со своим набором правок.

0.8.128

10 октября 2026

Changed

  • Внутренний рефакторинг без изменений в поведении: BackendApi больше не создаётся в UI-экранах. Добавлены репозитории-интерфейсы в data/repo/ (PolicyRepository, ToolsRepository, HealthRepository, FsRepository, ApiProvidersRepository) с реализациями над общим BackendApi.default(); зависимости отдаёт локатор App (policyRepository(), toolsRepository(), healthRepository(), fsRepository(), apiProvidersRepository()). Затронуты PoliciesScreen, ToolsScreen, SetupScreen, AddDatabaseDialog, ProviderFormScreen, ProvidersViewModel и ImageViewerWindow; ProvidersViewModel принимает репозиторий параметром конструктора, поэтому API подменяется фейком без сети.
  • Отбор записей мини-браузера баз (*.db, папки первыми) вынесен в чистую dbPickEntries и покрыт юнит-тестом.

0.8.127

10 октября 2026

Changed

  • Внутренний рефакторинг без изменений в поведении: ui/projects/WebAiScreen.kt 1004 → 382 строки. Приватные composable'ы вынесены дословным переносом: WebAiScreenHeader.kt (125 строк — SummaryBar, EmptyAccountsCard, EmptyFilterCard) и WebAiAccountCards.kt (440 — AccountCard, StatusBadge, QuotaBar, SessionInfoLine, providerAccentColor, providerInitial и приватный StatusBadgeStyle); в WebAiScreen.kt остался экран (загрузка, фильтр по провайдеру, диалог удаления, pull-refresh). Все 9 composable-функций сверены с исходником построчно — расхождений нет, private → internal, импорты пересобраны.

0.8.126

10 октября 2026

Changed

  • Внутренний рефакторинг без изменений в поведении: CodexEventHandlers.kt 1477 → 403 строки. Файл разрезан по доменам дословным переносом: CodexEventItemHandlers.kt (689 строк — onItemStarted, onItemCompleted, recoverCompletedCard, settleItem, appendReasoningChunk, eventItemKind, isItemFinished, replaceById), CodexEventThreadHandlers.kt (232 — onTurnCompleted, addOrUpdateThread, updateThreadArchived/Status/Name, handleRequestFailed, recordEventToLog, commitItems, refreshThreadGoal, liveFallbackThread, withThreadId) и CodexEventRequestHandlers.kt (151 — onIncomingRequest, onUserInputRequest). В исходном файле остался только диспетчер handleWsEvent. Все 21 функция сверены с исходником построчно — расхождений нет; два private-хелпера (liveFallbackThread, withThreadId) открыты до internal, потому что их зовёт диспетчер в другом файле.

0.8.125

10 октября 2026

Changed

  • Внутренний рефакторинг без изменений в поведении: CodexEventStore.kt 1294 → 780 строк. Дословным переносом вынесены CodexEventCodec.kt (323 строки: кодирование элементов и snapshot-payload, encodeItem(sJson), encodeChanges, encodeMcp, encodeQuestion(Full), encodeOptions, snapshotType, cap), CodexEventDumps.kt (105: dumpCache, dumpLast, dumpPage, dumpItem, lastEvents) и CodexEventMaintenance.kt (84: setCacheEnabledFlag, setFeedDumpFlag, feedDump, clearAll, clearThread, cacheMaintenance). Горячий путь (дельты, append, loadTail, чекпоинты, ретеншен) остался в CodexEventStore. Все 21 функция сверены с исходником построчно — расхождений нет; открыты только счётчики брейкера (cacheFailCount, cacheRepairTried, setter cacheBroken) и вызовы из bridge//MainActivity получили импорты новых extension-функций.

0.8.124

10 октября 2026

Changed

  • Внутренний рефакторинг без изменений в поведении: CodexThreads.kt 1054 → 689 строк. Кластер проектов и рабочего каталога (setCwd, createProject, refreshProjects, renameProject, removeProject, cancelProjectThreadDeletion, deleteProjectThreads, clearProjectsNotice) вынесен дословным переносом в новый CodexProjectActions.kt (397 строк); открытие тредов (openThread, reopenThread, newThread, scheduleOpenRetry, shouldSkipFreshThreadOpen, openErrorMessage) осталось в CodexThreads.kt. Все 18 top-level функций сверены с исходником построчно — расхождений нет, сигнатуры и логика не менялись.

0.8.123

10 октября 2026

Changed

  • Экран Updates приведён к единой сетке приложения: contentPadding списка (верх FirstSectionTopPadding, низ 24dp) и все заголовки секций через sectionHeaderSlot — одна высота строки (48dp), зазор над секцией 16dp, под заголовком 8dp. Убран разнобой «заголовок-полоска 48dp у developer против 18dp у соседних секций».
  • Секция developer (только dev-устройство) переоформлена: заголовок в общем стиле секций, разворот — chevron справа, рядом с ним моно-бейдж версии codex («codex 0.162.1 → 0.164.0» при наличии апдейта, «codex 0.162.1» иначе) — версии видно, не раскрывая панель. Панель при входе свёрнута, как и раньше. Содержимое разложено по четырём карточкам в стиле экрана — APK build (debug/release + Build), Release to server, Backend (build / swap / cleanup) и Codex (installed/upstream, Update codex, Check for updates); логи и блокировки кнопок перенесены дословно, поведение операций не менялось.

0.8.122

10 октября 2026

Changed

  • Внутренний рефакторинг слоя API без изменений в поведении: BackendApi.kt 1490 → 126 строк. Доменные методы вынесены в extension-файлы по доменам (BackendApiEnv, BackendApiFs, BackendApiWebAi, BackendApiWebAiChat, BackendApiSqlite, BackendApiSettings, BackendApiProviders, BackendApiUpdates, BackendApiScheduler), медиа- и image-jobs — в уже существующие MediaApi/ImageJobsApi. В ядре остались baseUrl, общий json, шесть профилей HttpClients, url() и request() (открыты до internal); вызовы у 36 файлов не менялись — добавлены только импорты extension-функций (164 импорта, 128 методов). Набор методов сверен с baseline: 136 членов → 138 расширений, потерь нет.

0.8.121

10 октября 2026

Changed

  • Внутренний рефакторинг экрана чата Codex без изменений в поведении: CodexChatScreen.kt 1519 → 250 строк. Состояние экрана (открытые окна, анкер скролла, «первый рендер») переехало в CodexChatState, побочные эффекты — в CodexChatEffects, секции Scaffold — в CodexChatTopBar, CodexChatBottomBar и CodexChatFeed, оверлеи — в CodexChatDialogs, CodexChatToolScreens и CodexChatOverlaysTail (порядок отрисовки сохранён). Ключи эффектов и разметка перенесены дословно.

0.8.120

10 октября 2026

Added

  • Обновление codex на dev-машине прямо из приложения. В Updates → developer появился блок Codex: локальная версия и последняя в GitHub, кнопки Check for updates и Update. Апгрейд качает релиз из GitHub, сверяет sha256 с digest ассета, arm64 и --version, делает backup и атомарно подменяет bin/codex, перезапускает app-server через svreg, проходит WS-смоук и schema-diff app-server с сохранённым baseline; при провале возвращает предыдущий бинарь. Лог — ~/.y83/codex-upgrade.log, итог — ~/.y83/codex-upgrade.json. Публикация осталась прежней: Release to server сам зовёт publish-codex.sh.

backend 0.8.218

10 октября 2026бэкенд

Added

  • REST /api/v1/env/codex и апгрейд. Проверка локальной версии codex против GitHub (кэш 1 час, ?refresh=1), запуск апгрейда и статус с шагом, логом и итогом — только на dev-машине (иначе 403). Скрипты scripts/codex-check.sh и scripts/codex-upgrade.sh — одна точка правды для проверки и безопасной подмены бинаря.

Changed

  • setup.sh не трогает codex на dev-машине (dev-guard): обновление окружения больше не откатывает версию, принятую из GitHub.
  • scripts/versions.sh показывает codex — локально / на раздаче / в апстриме.

0.8.119

10 октября 2026

Added

  • Хаб → Codex: раздел стал набором отдельных экранов. В разделе Codex пять строк — Cache watch, Skills, MCP, Features, Policies (Policies переехал из AI & Agents), каждая открывает свой экран со своей терминальной шапкой: codex@cache-watch, codex@skills, codex@mcp, codex@features, codex@policies. Конфиг-экраны Skills/MCP/Features работают из хаба без чата; вложение скилла, «Использовать» и тестовый вызов MCP-инструмента в этом режиме скрыты — они привязаны к треду.
  • Cache watch — настройки сторожа и история сбросов на одном экране. Отдельные Settings и Session resets слиты: тумблер, пороги и режим сброса сверху, ниже — учёт ротаций кэш-сессии. Видно, сколько раз сессию сбрасывали вручную (баннер/меню треда) и сколько раз сработал автомат (режим Auto), с разбивкой по моделям, по последним 14 дням и историей событий; историю можно очистить. Счётчики живут на бэкенде и переживают рестарт приложения. Старые id codex_settings/codex_resets остаются alias'ами для моста.

Changed

  • Cache watch и Policies — терминальные шапки и токены темы (сетка 4dp, SelectChip, hairline-карточки). Метрика Cache watch показывает режим сброса и пороги сторожа, а в суффиксе — счётчики manual/auto.

Fixed

  • Skills/MCP/Features из хаба не открываются пустыми на холодном старте. Раньше запрос уходил до готовности WS-сокета (возвращался null): Skills показывал предупреждение, MCP и Features — пустые списки, а догрузка после подключения была только у скиллов. Теперь hub-экраны ждут Connected, показывают спиннер и грузятся по факту подключения.
  • Skills из хаба читают рабочую папку агента. Раньше без открытого треда skills/list уходил в домашнюю папку Termux, и «проектные» скиллы были чужими.
  • MCP из хаба объясняет пустой runtime-статус. Без треда серверы стартуют лениво, поэтому вместо невнятного «не запущен» показана подсказка, что статус появится после открытия треда, а тумблеры и лимиты уже применяются.

backend 0.8.217

10 октября 2026бэкенд

Added

  • Учёт ротаций кэш-сессии. POST /api/v1/router/session/rotate принимает reason (manual/auto), model и pct и пишет запись в ~/.y83-ws/router-rotations.json: lifetime-счётчики по причинам и моделям, разбивка по дням за 90 дней, последние 500 событий. Добавлены GET /api/v1/router/session/rotations (счётчики + история, курсор before) и DELETE /api/v1/router/session/rotations (обнулить). Пустой reason считается ручным сбросом — старые клиенты совместимы.

0.8.118

9 октября 2026

Added

  • Терминал — пинч меняет шрифт (как в Termux). Щипок двумя пальцами больше не масштабирует картинку: меняется размер шрифта 5…24 sp, вместе с ним — сетка и window-change в tmux (reflow). Работает и в обычном shell, и внутри TUI-программы; в панели доп. клавиш появились A-/A+ (тот же параметр, что у ползунка в настройках), пишется в prefs с дебаунсом 400 мс.
  • Терминал — тап в TUI работает кликом мыши. Мышь запрашивает сам процесс (#{mouse_any_flag} в пробе tmux; без tmux — DECSET 1000/1002/1003 из alt-screen-сканера), тап уходит SGR-кликом в клетку под пальцем: в mc/htop/yazi наконец нажимаются кнопки и строки. Если мышь не запрошена, тап по-прежнему поднимает клавиатуру.

Changed

  • termlib вендорен с патчем, а не подключён как AAR. Исходники 0.3.0 лежат в third_party/termlib (см. README.md): добавляют режим fontZoom с колбэком onFontZoom и убирают 40-миллисекундное окно детекта второго пальца (из-за него щипок почти никогда не срабатывал). Нативные libjni_cb_term.so в git не лежат: отдельная конфигурация распаковывает jni/** из того же AAR в jniLibs, версия артефакта пинит ядро libvterm. APK не растёт.
  • tmux отдаёт панели полноценный терминал и цвет — default-terminal 'screen-256color' (дефолт screen резал палитру до 8 цветов), truecolor насквозь (:Tc), OSC 52 (set-clipboard on — копирование из приложения приходит в буфер Android) и COLORTERM=truecolor в rc. Живому tmux-серверу настройки досыпаются без перезапуска; на уже запущенную панель TERM применится после «Перезапустить tmux-сессию».
  • TUI-детект знает больше программ (yazi, btm/bpytop/nvtop/glances, hx/kak, visidata, pspg, aerc, zellij, gdu и др.).

Fixed

  • Смена шрифта больше не пересоздаёт терминал. Remount композиции (key(fontSp)) убран: при изменении шрифта не теряются позиция скролла, выделение и фокус клавиатуры — размер в 0.3.0 и так производная величина от initialFontSize.

backend 0.8.216

9 октября 2026бэкенд

Fixed

  • Переданная сессия DeepSeek больше не «не принимается». После повторного логина (transfer session) аккаунт сохранялся корректно, но кэш HTTP-клиентов DeepSeek продолжал держать старый Authorization и PoW-заголовок, поэтому все запросы по аккаунту падали с 40003 Authorization Failed (invalid token), а приложение предлагало войти и передать сессию снова (каждый вход убивал предыдущий токен — цикл). Теперь кэш привязан к отпечатку сессии (provider + токен + куки): смена токена/кук пересобирает клиент, плюс запись кэша сбрасывается при импорте сессии, снятии broken и удалении аккаунта.
  • userToken DeepSeek хранится в JSON-обёртке ({"value":"…","__version":"0"}): обёртка разворачивается при записи сессии (в БД и экспорте лежит голый токен), а не только при построении клиента; нормализация снимает Bearer, кавычки и до двух уровней вложенности.

backend 0.8.215

9 октября 2026бэкенд

Changed

  • dev_check {op:"changed"} находит изменённое полностью и быстрее. Discovery перешёл на git status --porcelain=v1 -uall -z: .kt в новых untracked-каталогах теперь проверяются (раньше git отдавал ?? dir/ и файлы пропускались), удалённые файлы не валят проверку (было «not found»), ренамейт проверяется по новому пути. Охват — не только Kotlin: .go идёт через gofmt -l, .sh — через новый tools/check-shell.sh (bash -n); в ответе появились kotlin/go/shell/skipped. Проверки идут пачками: 18 изменённых .kt — 27 с → 0.3 с.
  • Импорты больше не шумят. tools/imports.py не считает пропущенными имена из своего файла и своего package, уже импортированные (включая .*), member-доступ (ChatTextType.Agent), упоминания в строках/комментариях и enum-записи; неоднозначные имена пропускает. Индекс пакетов строится один раз на процесс (батч check <f1> <f2> ...). На проекте (≈700 .kt) ложных находок было 12, стало 0. check — advisory (выход 0), --strict для блокирующего режима; в dev_check находки лежат в advisory и проверку не валят.
  • tools/check-syntax.sh проверяет пачку файлов одним запуском python и без sed/grep на каждую строку; fun-эвристика больше не ругается на expression-body (fun f(): String = …).

Added

  • tools/check-shell.sh — bash -n пачкой (используется в dev_check и в стадии shell-syntax ворот).
  • tools/imports_test.py и стадия py-selftest в scripts/gate.sh — регрессии эвристики импортов ловятся воротами.
  • dev_repo {op:"imports"} помечает ответ advisory и подсказывает, что это эвристика, а не компилятор.

0.8.117

9 октября 2026

Added

  • Image jobs переживают перезаход. В ленте у генерации появились Copy job id, Cancel, безопасный Status refresh и явный Repeat. Активная карточка сама продолжает status-проверку, показывает queue/progress_text/elapsed и честный reason; batch отмечает local_saved, remote_only или download_failed с fallback на public URL.
  • Раздел Codex в хабе и настройки кэш-сторожа. В хабе появился раздел Codex → Settings: отдельный экран настроек агента. Сторож prompt-кэша стал настраиваемым — тумблер включения, порог «кэш ниже N%» (30/40/50, по умолчанию 50), число промахов подряд для срабатывания (2/3/5), минимальный вход для суда (10k/20k/30k/50k) и режим сброса: вручную (баннер с Reset) или автоматически (сессия ротируется сама после лимита, пауза между авто-сбросами 10 минут, ход не прерывается). Настройки общие для всех тредов и применяются к следующим запросам сразу.
  • Context7 как MCP: живая документация библиотек. В хабе (Инструменты → Tools) появилась карточка Context7: инструкция, кнопка Get key (дашборд открывается во встроенном браузере) и ввод ключа ctx7sk… с проверкой Test. Ключ хранится в ~/.y83-ws/tools.json (в config.toml секрета нет); без ключа Context7 работает анонимно с rate-limit. Телефонный codex ходит в Context7 не напрямую, а через локальный прокси бэкенда (/mcp/context7) — статический бинарь codex на Android не резолвит внешние имена (/etc/resolv.conf нет). Инструменты — mcp__context7__resolve-library-id и query-docs (бюджеты 3000/12000 токенов, меняются в экране MCP), вкл/выкл — тумблер в экране MCP. Бэкенд перезапускает codex при сохранении ключа, а на удалённом агенте тот же блок уезжает в конфиг при перепушe (там — прямой внешний URL с ключом).

Changed

  • Список тредов стал компактнее. Бейджи провайдера и ctx N% убраны с карточек; число локально закэшированных ходов показано без фона на одной строке со статусом и временем. Провайдер и подробные метрики контекста остались в окне Info треда.

backend 0.8.214

9 октября 2026бэкенд

Added

  • Persistent image-job registry и recovery MCP. Принятые генерации сохраняются в ~/.y83-ws/image_jobs.db; новые image_jobs и image_cancel восстанавливают/отменяют jobs после timeout и перезапуска. Одинаковый активный запрос возвращает существующий id, force_new нужен только явному повтору. REST GET/DELETE /api/v1/image-jobs/{id} обслуживает карточки, фоновый reconciler обновляет активные jobs.
  • Context7 как MCP: локальный прокси и секция в config.toml. Новый пакет internal/context7 пишет секцию [mcp_servers.context7] при каждом синке провайдеров и на старте; бюджеты resolve-library-id 3000 и query-docs 12000, ключ — из ~/.y83-ws/tools.json (context7_token), без ключа анонимный режим с rate-limit. Пользовательские enabled, disabled_tools и правки бюджетов из экрана MCP сохраняются.
  • /mcp/context7 — прокси к Context7 для телефонного codex. Статически слинкованный codex на Android не резолвит внешние имена (нет /etc/resolv.conf: по IP-литералу соединение проходит, по имени — нет), поэтому телефонный конфиг ссылается на loopback-прокси, а внешний HTTPS делает бэкенд (Go) и сам подставляет ключ. На телефоне API-ключ в config.toml не попадает вовсе; удалённый агент ходит в Context7 напрямую (на Ubuntu DNS работает) — там секция идёт с ключом в http_headers.
  • REST: GET/PUT /api/v1/tools/settings принимает context7_token (null — не менять, "" — снять) и отдаёт context7_has_token + маску context7_token_masked; POST /api/v1/tools/test с {"tool":"context7"} делает реальный tools/list (token/anonymous mode), ключ с чужим префиксом отвергается 400, после сохранения codex перезапускается.
  • Удалённый агент: buildRemoteConfig добавляет тот же блок (тумблер enabled зеркалится из телефонного config.toml), поэтому смена ключа меняет хэш конфига и уезжает при следующем открытии туннеля.

0.8.116

9 октября 2026

Fixed

  • Watchdog remote-туннеля больше не шумит. ensureRemoteTunnel() запускал корутину даже при уже подключённом WS — она мгновенно выходила, и при каждом переключении треда в лог сыпались пары watchdog start/stop, а проверка туннеля дёргалась зря. Теперь watchdog запускается только когда WS не подключён, пользователь не отключал сервер и прежний job не активен (tunnelWatchdogNeeded).
  • Дубли skip-логов устранены. Несколько экранов Codex держат свой CodexViewModel и зовут watchdog одновременно; одно и то же сообщение watchdog skip: user disconnected повторялось 3 раза за тик. Лог теперь не чаще раза в минуту на VM (shouldLogTunnelSkip).

0.8.115

9 октября 2026

Added

  • Инфо-экран треда и бейджи в списке Codex. В меню треда (⋮) под Rename появился пункт Info: полноэкранная справка с номером треда (короткий id), полным id с копированием, статусом, провайдером, проектом, временем, токенами и числом кэшированных ходов. На карточке треда — компактные бейджи провайдера, занятого контекста (ctx N%, предупреждающий акцент от 80%) и числа ходов. Токены берутся из локального снимка (ContextUsage) — без resume и подписки; число ходов — один групповой запрос к Room-кэшу.

backend 0.8.211

8 октября 2026бэкенд

Changed

  • Remote-профиль MCP получил генерацию картинок (URL-only). /mcp/remote теперь отдаёт image_generate и image_status: агент на Ubuntu-сервере генерирует картинки Krea 2 Turbo через y83.media телефона. Локальные файлы на remote-профиле не скачиваются — paths[]/path повторяют публичные urls[]/url, потому что пути телефона серверу не видны. Токен и квота остаются владельца.

0.8.114

8 октября 2026

Fixed

  • Живой remote-туннель больше не выглядит отключённым. Пока бэкенд переподнимает канал (status=reconnecting, в том числе при плановом health-рестарте reverse-туннеля), главная и список SSH-серверов показывают RECONNECTING с жёлтой точкой и кнопкой Disconnect, а не OFFLINE с Connect. Правило — чистая функция tunnelUiStateFor(status, localPort): живым считается туннель с локальным портом и статусом, отличным от disconnected/failed. Мигание в OFFLINE провоцировало ложные тапы Connect (tunnel/open … reused).
  • Watchdog не пересоздаёт живой туннель. CodexWatchdog.ensureRemoteTunnel() при живом туннеле только подхватывает/переподключает WS к тому же порту и сбрасывает заждавшийся backoff, а полный remote/tunnel/reconnect (close+open) зовёт лишь когда туннеля реально нет — раньше живой канал рвался каждые ~20 с.
  • Бэкенд снимает залипший reverse-листенер после обрыва SSH. Ошибка ssh: tcpip-forward request denied by peer (удалённый sshd ещё держит 127.0.0.1:19000 от мёртвой сессии) обрабатывается как address already in use: проверяем, что через reverse-порт не отвечает наш бэкенд, а владелец порта — sshd, затем fuser -k и повторный listen. Окно флапа после сетевого обрыва сокращается с ~40 с.

Added

  • Диагностика VPN для разбора обрывов SSH. vpn_state отдаёт durationSec (реальная длина сессии — connectedAt был временем последнего broadcast), а VpnManager пишет в лог приложения переходы connected/reconnecting/ disconnected/error с причиной: обрыв SSH идёт через интерфейс VPN, теперь его можно связать с событием VPN.
  • Плашка чата различает «восстанавливается». В шапке remote-треда три состояния: Connected (тап — Disconnect), Reconnecting… (жёлтая, тап — попытка сейчас) и Disconnected (красная, тап — подключиться заново).

0.8.113

8 октября 2026

Fixed

  • Ручное отключение remote-туннеля стало липким. Disconnect (карточка на главной, экран Tunnels, список SSH-серверов, шапка remote-чата) ставит метку в RemoteTunnelIntent, и CodexWatchdog.ensureRemoteTunnel() больше не пересоздаёт туннель за пользователя. Раньше метки не было: watchdog считал «WS не поднялся» сбоем и возвращал туннель через 1–20 с, а из-за activity-scoped ViewModel держал его живым бесконечно — на главной всё снова выглядело подключённым. Метку снимают Connect/Reconnect, открытие remote-агента и тап по плашке Disconnected в шапке чата (она стала кликабельной и сразу поднимает туннель). Метка живёт до перезапуска приложения, дискового состояния не пишет.

0.8.112

8 октября 2026

Added

  • Сторож prompt-кэша и сброс кэш-сессии. Если кэш шлюза «залипает» (три хода подряд доля кэша ниже половины ожидаемой при почти неизменном контексте), над лентой появляется баннер с фактическим процентом и кнопкой «Reset»: ротация ключа сессии на роутере бэкенда (POST /api/v1/router/session/rotate) — следующий запрос собирает кэш заново. «Continue» прячет баннер на час. Тот же сброс доступен в меню треда (⋮ → Reset cache session). Компакция, пауза, мелкий контекст и смена треда/модели суд не запускают.

0.8.111

8 октября 2026

Changed

  • Экран Git разбит на файлы. Вкладки и стили (GitChangesTab.kt, GitCommitsTab.kt, GitScreenStyle.kt) вынесены из GitScreen.kt (1122 → 486 строк) — без изменения поведения.

0.8.110

8 октября 2026

Fixed

  • Отправка ждёт готовности WS-сокета. CodexWsClient.isConnected() учитывает не только наличие сокета, но и завершённый handshake initialize → initialized; запросы, interrupt и notifications не уходят в полусоединённое состояние, а получают честный «not connected» — очередь хода дожидается переподключения вместо таймаута.

0.8.109

8 октября 2026

Fixed

  • Утечки WS-клиента и моста закрыты. CodexWsClient.stop() отменяет свой scope, гасит executor и чистит connection pool; мост переиспользует один OkHttpClient вместо нового на каждый реконнект, watchdog перешёл на delay вместо Thread.sleep.
  • Блокировка треда стала точечной. «Потерянный ход» помечает только свой тред — очередь других тредов не встаёт; разблокировка и turn/completed снимают флаг по своему треду. Stop-watchdog перед локальной финализацией сверяет статус хода через thread/read и не завершает ход, если сервер всё ещё inProgress.
  • Лента: единый путь восстановления карточек. Ответ, план, файлы и команды, пришедшие сразу completed, восстанавливаются одним восстановителем — убраны дубли карточек и двойной счёт статистики.
  • Карты памяти больше не растут бесконечно. persistedSigs получил лимит и чистку при удалении треда, liveAlias сбрасывается при смене треда, таймеры вопросов не текут при исключениях.
  • WebAI: экран не остаётся включённым. Флаг keep-screen-on снимается при выходе с экрана во время стрима.

Changed

  • Сторож очереди Codex спит 30 с в простое (вместо опроса сети каждые 5 с), серверная очередь перечитывается раз в минуту.
  • sqlite_execute распознаёт SELECT/PRAGMA после ведущих SQL-комментариев, id серверов кодируются в URL, время в карточках форматируется общим потокобезопасным форматтером вместо SimpleDateFormat на каждый вызов.

0.8.108

8 октября 2026

Fixed

  • Мост больше не отдаёт секреты. app_prefs маскирует значения token/secret/password/cookie/api-key-подобных ключей (полный дамп — только параметром raw:true), токен vision-агентов скрыт в ответах vision_agent/vision_config. Имена сессий браузера и файлов загрузок санитайзятся (../ больше не пишет вне каталога), browser_save_session / browser_load_session отвечают честной ошибкой вместо ok при провале, alert-команды отвечают unsupported вместо фиктивного успеха.
  • Параллельные browser_fetch_overlay больше не крадут результаты друг друга. Запрос получил id, Activity возвращает результат только своему запросу, а сами fetch'и сериализуются очередью; карточка-индикатор сбрасывается только если её не перекрыл новый кадр. browser_wait_for_timeout ограничен 60 с, app_screenshot не может висеть вечно (страховочный таймаут).
  • Закрытая вкладка браузера снимается с моста. browser_* больше не работают с destroyed WebView после closeTab; регистрация WebView привязана к generation экрана.
  • Гонки транспорта Codex. pending/pendingOutcome/nextId в WS-клиенте переведены на конкурентные коллекции и атомики; CancellationException пробрасывается (отмена корутины не превращается в «timeout»).
  • Сообщение очереди не застревает в Sending. При смене треда во время ретрая необработанные сообщения возвращаются в Waiting и доступны к повтору.
  • Терминал: два UTF-8-декодера (PTY и поток панели) — общий CharsetDecoder не потокобезопасен и мог портить многобайтовые последовательности.
  • WebAI: «Стоп» — не ошибка. Отмена стрима пользователем больше не подменяет ответ на «Failed to get a response».

backend 0.8.209

7 октября 2026бэкенд

Fixed

  • Кэш промптов OpenCode Go: сессия теперь на каждый тред. Ключ диалога строился по первым двум сообщениям и упирался в лимит 8192 байт — общий AGENTS.md (23 КБ) переполнял его, и все треды проекта делили одну сессию x-opencode-session. Шлюз отдавал из кэша только статический префикс (≈22.5k токенов, 71–73%), а разговорная часть промахивалась даже на следующем ходе: замеры 07.10.2026 — приложение стабильно cached=22400 и 22528 при входе 30k+. Теперь conversationKey берёт prompt_cache_key запроса (id треда Codex, он же client_metadata.thread_id), а хэш по содержимому остался фолбэком (первые 2 сообщения пользователя, ≤2048 байт каждое). Живые ходы приложения после фикса: 31744/31991 и 31872/32123 (99.2%).
  • Upstream-запрос роутера больше не рвётся вместе с клиентом. app-server закрывает соединение после ответа, и отмена контекста обрывала upstream-соединение — каждый ход шёл в шлюз новым соединением. Теперь upstream живёт до конца (context.WithoutCancel + 15 мин), хвост ответа дочитывается при обрыве клиента (streamCopy drain), а в лог пишутся reused/remote/cf_ray и identity-заголовки x-opencode-client / x-opencode-request (как у CLI).

Changed

  • cache_control-брейкпоинты выключены по умолчанию. Замер 07.10.2026 показал, что метки на хвосте не помогают (73% с ними и без), а тело запроса делают нестабильным; для опытов включаются Y83_OPENCODE_CACHE_BREAKPOINTS=1. Подсказки prompt_cache_key + prompt_cache_retention остаются включёнными и выключаются Y83_OPENCODE_CACHE_HINTS=0 или файлом ~/.y83-ws/opencode-cache-hints.off.

backend 0.8.200

7 октября 2026бэкенд

Changed

  • Провайдеры стали общими для Codex и OpenCode. Каталог мигрируется в один shared-набор с бэкапом, Qwen остаётся изолированным, а служебный локальный Zen скрыт из управления. Встроенные opencode/* и opencode-go больше не перезаписываются в opencode.json; ключ OpenCode Go синхронизируется в штатный auth.json, поэтому CLI не получает Missing API key.
  • cache_control-брейкпоинты prompt-кэша включены по умолчанию для шлюза opencode.ai. Раньше хвост диалога вообще не помечался, и шлюз кэшировал только статический префикс: замер 07.10.2026 дал cached=22784 при входе 60716 (37%) и 8 промахов из 12 запросов, после включения — 0 промахов из 11 (router cache low пишется при hit <50% и входе ≥30k). Выключить без перезапуска можно Y83_OPENCODE_CACHE_BREAKPOINTS=0 или файлом ~/.y83-ws/opencode-cache-breakpoints.off.

Fixed

  • Брейкпоинты кэша ставятся и в локальном complete. chatPayload собирает messages как []any, а маркер читал только []map[string]any и молча ничего не делал — на этом пути кэш оставался холодным даже при включённом флаге.

backend 0.8.194

6 октября 2026бэкенд

Fixed

  • Скриншоты из MCP снова видны в ленте Codex. Карточки ai_vision, browser_look, browser_shot и screen_look извлекают локальный path из результата и показывают preview без раскрытия карточки; remote-копия по-прежнему используется только как исходный remotePath.
  • Скриншоты view_image из remote-треда загружаются с сервера. Карточка изображения получает SSH-цель активного remote-агента и читает серверный путь через remote/fs/download; просмотр, share и сохранение используют ту же remote-копию.
  • Remote-автокомпакт больше не ограничен значением 121600. Генератор remote-конфига больше не задаёт model_auto_compact_token_limit*, поэтому Codex использует default активной модели — как локально; E2E проверяет отсутствие override на живом сервере.