Ветка 0.8
251 релиз, из них 59 — бэкенд, архив сборок: 7, страниц: 9
19 августа 2026 — 24 октября 2026
Читать журналy83 code / журнал
Раздел собран из журнала репозитория при сборке сайта: это те же записи, что читают разработчик и агент. Здесь история коммитов по месяцам, счёт релизов и ссылки на полный журнал каждой ветки — от 0.1 до 0.8.
y83 code / журнал
Историю считает git: 598 коммитов за 63 дня — с 2026-08-25 по 2026-10-27.
журнал
Журнал разбит по минорным версиям: 9 веток, 269 релизов приложения и бэкенда плюс 151 записей архива сборок. Ветка идёт постранично — по 30 записей, чтобы раздел читался, а не листался бесконечно.
251 релиз, из них 59 — бэкенд, архив сборок: 7, страниц: 9
19 августа 2026 — 24 октября 2026
Читать журнал1 релиз
23 октября 2026
Читать журнал102 релиза, архив сборок: 84, страниц: 4
18 августа 2026 — 29 августа 2026
Читать журнал2 релиза, архив сборок: 1
18 августа 2026
Читать журнал40 релизов, архив сборок: 39, страниц: 2
14 августа 2026 — 17 августа 2026
Читать журнал11 релизов, архив сборок: 10
13 августа 2026 — 14 августа 2026
Читать журнал9 релизов, архив сборок: 8
13 августа 2026
Читать журнал2 релиза, архив сборок: 1
13 августа 2026
Читать журнал2 релиза, архив сборок: 1
13 августа 2026
Читать журналпоследнее
Пять последних записей журнала целиком — без пересказа: так выглядит обычный релиз проекта.
mcpServerStatus у ещё не загруженного треда: app-server возвращал пустой список, а UI оставлял статусы предыдущего треда — подпись core, а tools те же 65+3. Теперь экран сначала поднимает тред (thread/resume) и только потом читает его инструменты. Хаб (без треда) показывает глобальный профиль, а не последний открытый тред./mcp/context7 освобождён от локального токена (ключ Context7 подставляет бэкенд), иначе Codex получал 401 и терял три инструмента.requires_action: статус ждал следующего запроса модели, то есть всю генерацию картинки. Теперь ожидание считается только по открытой карточке, ответ (и старт инструмента, который CLI разрешил сам) переводит ход в running, а имя MCP-инструмента в баре читается как y83 · image_generate.image_generate/image_edit/image_status/image_cancel больше не входят в свёрнутую группу инструментов: у них отдельная карточка с галереей и просмотрщиком.user-запись с turnCompanion/sourceToolUseID; история отбрасывает такие companion-записи (и не считает их ходом), при этом isMeta-записи с настоящим промптом рядом с <system-reminder> остаются.tool_progress, а MCP-вызовы (в том числе image_generate) heartbeat не шлют — карточка молчала всю генерацию. Теперь незавершённый вызов тикает от метки старта, итог фиксируется по завершении, а heartbeat по-прежнему авторитетнее локального счётчика.Info и сырым значением CLI (Mode: acceptEdits). Теперь компактная плашка с иконкой настройки, переходом «было → стало» и временем; bypass подсвечен предупреждением. Чип режима в композере получил тот же вид: бордер, иконка, короткая подпись, у режима не по умолчанию — акцентный бордер.approvalId из результата remote_exec и привязывает заявку к конкретному Codex-треду: в уведомлении и карточке видно имя треда, тап ведёт ровно в него (включая фоновый тред через восстановление туннеля), а в диалоге сначала идут заявки открытого треда. Уведомления группируются по треду, два треда на одном сервере больше не сливаются в одно. Если привязки ещё нет (opencode-сессия, холодный старт) — «тред не определён» и тап в Approvals. Звук только на первое появление очереди, дальше тихие обновления и summary.;, &&, пайпы, 2>/dev/null и read-only циклы выполняются сразу. Для изменяющих команд появился явный grant «разрешить сервер на 10 минут» с отзывом; секреты, SSH-ключи, firewall и критические операции всё равно требуют отдельного подтверждения.native: Codex и Claude Code от собственной подписки. Экран «Аккаунты агентов» (хаб → AI & Agents) даёт по одному переключателю y83 | native на тип агента. В native CLI ходит напрямую по подписке (ChatGPT для Codex, Claude Pro/Max для Claude Code): роутер не подставляет ни адрес, ни токен, а из config.toml снимаются model_provider, model_catalog_json и секции y83_router. Политики, MCP y83 и context7 остаются. Вход выполняет сам CLI (codex login --device-auth, claude auth login): токены подписки наш код не читает и не проксирует. Пока режим native, а входа нет, ход не отправляется — чат показывает «вход не выполнен» вместо невнятного отказа, и тихого отката на роутер нет. Пикер моделей следует режиму: Codex берёт model/list у app-server, Claude — нативный список CLI. Стоимость хода в native не считается: подписка не даёт цены за токен.opencode.ai смешивает пути: gpt-6-luna, gpt-5.6-luna, grok-4.6/4.7 и muse-spark-*contributor принимают только /responses, claude-haiku-5-5 и minimax-m2.7 — только Anthropic /messages. Раньше у провайдера был один protocol, и такие модели падали с ModelProtocolUnsupported; теперь у каждой модели есть своё поле protocol (пусто — наследовать провайдерский). Роутер пробует протоколы по очереди, но повторяет запрос только когда апстрим отверг именно формат (ModelProtocolUnsupported, 404/405) и пока клиенту не отдан ни байт: на 429/5xx и таймауты повтора нет, иначе квота и гейт жгли бы лишние запросы. 403 повторяется только с телом ModelProtocolUnsupported — шлюз помечает так неподдерживаемый формат; RegionError и FreeTierError с тем же кодом остаются окончательным отказом. Принятый протокол запоминается в модели, ручной выбор не перетирается. Для messages добавлен полный транспорт в обратную сторону (chat↔Messages API, включая SSE) и заголовки x-api-key + anthropic-version. Ответ конвертируется по фактически принятому протоколу, поэтому клиент всегда получает свой формат (choices или SSE Responses), даже когда автоподбор ушёл на другой путь.[]any (после JSON) и как []map[string]any (собранный responsesToChat); конвертер в Anthropic понимал только первый и отправлял в /messages запрос без сообщений («at least one message is required»).POST /api/v1/providers/{id}/models/probe, конкурентность 4, кэш час) и пишет в стор probe: работает ли, каким протоколом, а при отказе — причину (region, privacy, no upstream, protocol, auth). Бейдж виден в карточке модели и в диалоге discover; «all» больше не включает заведомо мёртвые модели. Так видно, что gemini-4-argon шлюз не проксирует ни одним протоколом, mimo-v2.5-pro отсутствует в апстриме, а iceman-contributor-free отвечает 503.+a −r; раскрывается в список, тап по файлу показывает его diff. Отдельного события «итоговый diff хода» CLI не присылает, поэтому карточка собирается из уже пришедших карточек Write/Edit/MultiEdit: файл считается один раз, повторы складываются по строкам, упавший инструмент не считается. Граница — последнее сообщение человека, а не вся история./…. Набранное во время хода больше не уходит вторым ходом поверх первого: сообщение встаёт в локальную очередь над композером (правка тапом по тексту, «Отменить», «следующее») и отправляется само, когда CLI закрыл ход (turn_finished, а не status=idle — между ходами CLI ещё дописывает транскрипт). Предел — 20 сообщений, отказ виден в поле ошибки. «Отправить» появляется только когда ход уже не идёт: прерывать работающий ради очереди нельзя. В композере — палитра команд: список приходит из init.slash_commands самого CLI (встроенные команды, скиллы, плагины), раньше мост отдавал только счётчик. Команды, работающие лишь в терминале, помечены — в headless-режиме они отвечают «unavailable».~/.claude.json → mcpServers.y83 с локальным токеном (профиль core, в этом репозитории — dev через --mcp-config), провижн идемпотентен и переживает ротацию токена. В меню чата — секция tools с пунктом «MCP servers» («подключено/всего»), окно claude@mcp показывает живые статусы из самого CLI (mcp_status): транспорт, версия, инструменты и текст ошибки, с Reconnect для упавших и тумблером вкл/выкл (действует до перезапуска процесса — CLI не пишет его в конфиг). init теперь не теряет mcp_servers: сводка видна ещё до открытия окна. Заголовки серверов (config с X-Y83-Token) мост вырезает и в приложение не отдаёт.session окна «Chat settings» доделана до паритета с меню треда Codex: New session, Rename session, Session info, Keep screen on, Stop turn и Delete session. Переименование меняет имя в шапке сразу (POST …/title), Info показывает id, модель, режим и статистику транскрипта, удаление стирает сессию вместе с транскриптом и возвращает на список. Rename/Info/Delete гаснут, пока сессии нет в транскрипте, Delete — ещё и во время хода; мета секции показывает working/waiting.⋮ — она открывает окно «Chat settings» в стиле меню треда Codex: модель, уровень рассуждений, режим разрешений, токены, затраты и список сессий. Уровни переехали в отдельное окно claude@reasoning (чип уровня в шапке ведёт туда же), режимы — в claude@mode, токены — в claude@tokens с разбивкой хода и сумм сессии. Stop и история ушли из шапки (Stop остался в композере), поэтому во время хода шапка не меняется, а длинное имя модели больше не ломает чип уровня по буквам.context %, цена хода по реестру тарифов и доля кэша; тап открывает окно затрат треда со ходами по дням. Ходы пишутся в turn_costs (scope claude) и видны в общем экране «Затраты»; старые сессии бэкфиллятся из транскрипта. Роутер теперь прокидывает cache_read_input_tokens и cache_creation_input_tokens в Messages API (без этого CLI видел только input/output и кэш терялся).+N/−M, unified diff из structuredPatch), TodoWrite (чек-лист), Grep/Glob/WebFetch/WebSearch/Task и MCP — компактной строкой. Мост отдаёт компактную meta результата (stdout, stderr, structuredPatch, content, без originalFile), длительность инструмента по ts событий и thinkingDurationMs. Лента переведена на reverseLayout с общим авторитетом прокрутки Codex: автоследование за хвостом, пилюля «к последнему» со счётчиком новых ответов/ошибок, вставка в середине не рвёт позицию чтения.seq, и SSE подписывается с Last-Event-ID, поэтому история не дублируется реплеем кольца.--effort (low…max) и меняет уровень на ходу; мост передаёт его в POST …/effort, роутер — в reasoning_effort/reasoning.effort с нормализацией по модели. В шапке чата — чип auto/low…max с метром, в окне модели — секция // reasoning. output_config.effort из CLI раньше выбрасывался роутером, поэтому уровень не доезжал до провайдера.patchelf на $PREFIX/glibc/lib/ld-linux-aarch64.so.1, без Node и без bun-прослоек) и ходит в роутер через новый Anthropic-совместимый POST /codex-router/v1/messages. В приложении — свой чат: лента, размышления, карточки инструментов, разрешения Allow/Deny, выбор модели из каталога провайдеров, режим (manual/acceptEdits/plan/bypass), список сессий с продолжением и счётчики токенов. Мост — Go внутри ws-backend (backend/internal/claude), CLI запускается дочерним процессом.~/.claude/sessions), тестовые папки из $TMPDIR скрыты, сводки транскриптов кэшируются. Список сессий проекта получил поиск, группы по датам и удаление транскрипта (идущую сессию удалить нельзя — сначала Stop).custom-title), поэтому имя видно и в claude --resume; окно Info показывает модель, папку, время, ходы и токены. Идущую сессию и сессию, занятую терминалом, удалить нельзя — бэкенд отвечает 409.WorkingBar из Codex): этап (running: Bash · …, thinking…, waiting for your answer), таймер хода и полоса прогресса. Композер — карточка 20dp/тень 8dp с вложениями-чипами, счётчиком символов, expand/collapse, меню (Attach, Prompts…, Keep screen on, язык диктовки), меню режимов, голосом и Stop/Send по 40dp. Вложения идут путём в ~/y83-ws/uploads/ — агент читает файл сам, без правок моста.bash и read в нижнем регистре, а Claude Code присылает Bash/Read: гейт находил их без учёта регистра, но не переименовывал (EqualFold считал имена совпавшими), и апстрим отвечал 429 FreeUsageLimitError. Теперь имя приводится к каноническому всегда, а вызовы возвращаются клиенту под его именами. Codex и opencode не страдали — у них имена уже нижним регистром./api/v1/models), где встроенный zen называется opencode; роутер такого id не знал и молча подставлял первую модель списка — в шапке одно, исполнялось другое. Новый GET /api/v1/claude/models отдаёт каноничес- кие слаги роутера (zen/…, opencode-go/…, deepseek/…), а aliasModel подменяет только служебные claude-*; неизвестная модель — 404.system/api_error и синтетический assistant идут в ленту карточкой ошибки, ход завершается, а у CLI остаётся две попытки (CLAUDE_CODE_MAX_RETRIES). Messages-путь роутера лечит засвеченный лейн так же, как Codex: при FreeTierError/FreeUsageLimit лейн меняется и запрос повторяется.connected поднимается успешным ответом бэкенда, а потерянный поток переподключается на следующем ходе.minimax-m3.1-flash-free убрана из zen. Апстрим отвечает 410 ModelDeprecated; миграция zen.json v4 вычищает её из сохранённого каталога, сид и страховочная цепочка research её больше не берут.LazyColumn падал с Key "mode-N" was already used. Теперь id уникальны, счётчик растёт.dontAsk и auto; bypassPermissions теперь работает: процесс стартует с --allow-dangerously-skip-permissions, а включение требует отдельного диалога подтверждения. Отказы CLI (control_response) больше не проглатываются: POST …/mode и /model отдают 502 с текстом, чип откатывается к прежнему значению.Widgets (как в Codex), а чип режима получил свою иконку для каждого значения и меню с заголовком // permission mode — его больше не путают с «выбором агента» (модель живёт в шапке).session.tokens — уже накопленная сумма по сессии, но приложение прибавляло к ней сумму по сообщениям: окно токенов показывало двойной расход. Теперь источник истины — серверная сумма, а сумма по сообщениям осталась фолбэком для старого кэша.content и полем error (лимит, отказ авторизации) выбрасывался как служебная запись: вопрос человека оставался без ответа и без причины. Теперь такой ответ рисуется блоком с текстом ошибки, а ход считается упавшим.GET /diff?from= принимает только id запроса пользователя, а UI передавал id ответа — сервер отвечал «not a user message». Теперь id переводится на запрос, открывший ход.session.status.retry несёт attempt, message и next, но они терялись в парсере.session.tool.input.delta отбрасывались, и карточка до called оставалась с одним именем.read, write, edit, диффы, вывод инструментов, окна терминалов, навыков, MCP, модели и меню сессии рисовались жёстко (bodySmall + Monospace + 11 sp), поэтому выбор шрифта и размера в настройках на них не действовал. Теперь все они идут через chatStyle(...): код — ChatTextType.Code, подписи — Meta, — а номера строк диффа масштабируются вместе с кодом.res/values*.liveParts под другим messageID, и лента дорисовывала её вторым баблом (без подвала с временем и меню). Теперь live-сообщение не добавляется, если такая же часть уже есть в истории — сверка по ключу части, id вызова инструмента и полному тексту.session.reasoning.ended приходил без статуса и с проигнорированным текстом, а живые части навсегда оставались стриминговыми: каждая мысль шага показывала спиннер и растущий таймер до конца хода. Теперь конец события фиксирует длительность и сворачивает карточку, а граница шага (step.ended/новый step.started) закрывает рассуждение и текст, если событие потерялось при реконнекте. Полоса хода перестала показывать «Thinking»/«Writing» после того, как этап закончился.session) не обновлялся после успешной смены роли, поэтому повторный выбор отсекался проверкой «сервер уже на этой роли»: чип показывал Build, а сессия оставалась в plan. Теперь после POST /agent серверная роль перечитывается и ложится в кэш, а события session.agent.selected синхронизируют его с другими клиентами.?location[directory]=…, но GET /api/session понимает только плоский ?directory=… и на deepObject фильтр молча игнорирует. Запрос исправлен, плюс клиент дополнительно отбирает сессии по каталогу (защита от старого кэша и версий сервера, которые фильтр не применяют); это же чинит «удалить сессии проекта», которое раньше могло унести чужие.location.directory). v2 отдаёт его вложенным, а приложение смотрело плоское session.directory и получало null — из-за этого подписка SSE, каталоги навыков/MCP и счётчики сессий у проектов работали без каталога.time.archived (PATCH /api/session/{id} {"archived":…}), а не в префах приложения: архив из TUI виден в приложении и наоборот. «Show archived» запрашивает ?archived=true, а старые локальные отметки один раз переносятся на сервер при первом запуске.GET /api/session/active + открытые permission/form; опрос раз в 3 с и только при видимом экране), бегущую полосу хода и превью — последнее сообщение пользователя самой свежей сессии. Живые проекты поднимаются наверх, дальше по свежести; в шапке — N sessions · M projects · K live. «~» теперь означает настоящую домашнюю папку Termux, а не workdir агента./mcp/codex получил remote_servers, remote_exec, remote_exec_status и remote_job. Серверы берутся из реестра приложения (без паролей), read-only команды выполняются сразу, изменяющие ждут подтверждения в приложении (точная сохранённая команда, TTL 10 минут), длинные уходят в фоновые job с логами и pid на сервере. В /mcp/remote и opencode инструментов нет.available=false показывается как insufficient, а не как ошибка запроса.QuotaClient распознаёт DeepSeek по slug или хосту api.deepseek.com, читает официальный GET /user/balance ключом провайдера и отдаёт available + balances[] со строками currency, total, granted, toppedUp. Ошибки идут с префиксом balance:, кэш 45 с, singleflight и stale — общие с usage; история окон для баланса не пишется.vision, а основной слот и страховщик назначаются отдельно. Ручную модель нельзя убрать, пока она стоит в цепочке; встроенный Zen в пикере скрыт.credential), а синхронизация писала только legacy auth.json — после ротации ключа в API providers чат продолжал ходить старым (исчерпанным) ключом и падал с «Go usage limit exceeded». Теперь SyncOpenCode применяет ключ через API v2 (connect/key + удаление устаревших credential), повторяет попытку после автостарта opencode и вычищает ключ при выключении провайдера.Источник: CHANGELOG.md репозитория (7 546 строк) и CHANGELOG_ARCHIVE.md. Файлы лежат рядом с сайтом (tools/sync-docs.sh) и разбираются при сборке, поэтому страницы журнала не расходятся с репозиторием.