Repository navigation
Releases
v0.3.17 — уведомления в фоне, иконки по категориям, ответы на вопросы в ленте
English
Notifications finally work on a phone in a pocket, and the answered-question card stays where the question was. Two regressions from this cycle were reverted, not patched.
- Background notifications. React Native pauses its own JS timers when the app leaves the foreground (
JavaTimerManagerdrops the frame callback whileisPausedand no headless task is active), so nothing generated notifications and only the SSE replay on resume made them appear.KeepAliveServiceis now aHeadlessJsTaskServicethat keeps a headless task alive for the whole run, and the watch polls the server (/api/session/active) instead of local state. Completion, questions and permission requests reach a locked phone. - Notification icons. Android draws a small icon as a monochrome mask; expo-notifications falls back to the full-colour app icon (a white square) and can only use one icon per app. Notifications are now posted by a small native module with a vector mask per category: question, error, completed, permission.
- "Session running" card is gone. The foreground service cancels its own notification right after promotion; the service keeps its foreground state, so the background watch keeps running. The channel is untouched — deleting it crashed the app in 0.3.16, which is fully reverted.
- Answered questions stay under the message that asked them. The card used to render above the composer, i.e. under the newest answer. V2 form metadata names the message, so the card renders there.
- Model picker above the keyboard. Opening the picker now dismisses the IME first, like the reasoning-effort picker; the sheet no longer mounts under a keyboard that is already up.
- Notifications only while the app is in the background, one per finished run, deduplicated between the stream and the poll, dropped if they arrive while the chat is on screen.
- Settings cleanup. The Notifications section is the OS permission state plus the five switches.
Installs over 0.3.15 — no uninstall needed. CI: 720 tests, typecheck, coverage gate, release-APK checks (permissions, service, signature) and the CUA smoke.
APK SHA256 (opencode-mobile-v2.apk):
11f171061c27f0f3332c5e2ede99b75582a68f5327b93ec76fb413805f8999b7
Русский
Уведомления наконец работают на телефоне в кармане, а карточка отвеченного вопроса остаётся там, где вопрос был задан. Два регресса этого цикла откачены, а не залатаны.
- Уведомления в фоне. React Native сам останавливает JS-таймеры, когда приложение уходит в фон (
JavaTimerManagerснимает колбэк кадров, покаisPausedи нет активной headless-задачи), поэтому уведомления не рождались вовсе — их приносил только реплей SSE при открытии.KeepAliveServiceтеперьHeadlessJsTaskServiceи держит headless-задачу весь прогон, а сторож опрашивает сервер (/api/session/active) вместо локального состояния. Завершение, вопросы и запросы разрешений доходят до заблокированного телефона. - Иконки уведомлений. Android рисует small icon как монохромную маску; expo-notifications подставляет полноцветную иконку приложения (белый квадрат) и умеет одну иконку на всё приложение. Теперь уведомления публикует небольшой нативный модуль с векторной маской на категорию: вопрос, ошибка, завершение, разрешение.
- Карточка «Сессия выполняется» убрана. Foreground-сервис отменяет своё уведомление сразу после промоушена; сервис сохраняет foreground-состояние, поэтому фоновый сторож продолжает работать. Канал не трогается — его удаление роняло приложение в 0.3.16, и та версия откачена целиком.
- Отвеченный вопрос остаётся под сообщением, которое его задало. Карточка рисовалась над композером, то есть под самым новым ответом. V2-форма называет сообщение, поэтому карточка рендерится там.
- Выбор модели над клавиатурой. Перед открытием шита клавиатура закрывается — как у выбора усилия; шит больше не монтируется под уже поднятым IME.
- Уведомления только когда приложение свёрнуто, одно на завершённый прогон, с дедупликацией между потоком и опросом, и выбрасываются, если пришли при открытом чате.
- Чистка настроек. Раздел «Уведомления» — это статус системного разрешения и пять переключателей.
Ставится поверх 0.3.15 без удаления приложения. CI: 720 тестов, typecheck, порог покрытия, проверки релизного APK (разрешения, сервис, подпись) и CUA smoke.
SHA256 APK (opencode-mobile-v2.apk):
11f171061c27f0f3332c5e2ede99b75582a68f5327b93ec76fb413805f8999b7
v0.3.7 — голосовой ввод, выбор модели и усилия, Expo SDK 58
⚠️ Устарел — используйте v0.3.17.
⚠️ Outdated — use v0.3.17 instead.
English
Voice input works for the first time, and both pickers open again. This release also moves the app to Expo SDK 58.
- Voice input.
expo-image-pickerwas configured withmicrophonePermission: false, and that plugin treats the value as blocking the permission: expo wrote<uses-permission android:name="android.permission.RECORD_AUDIO" tools:node="remove"/>, soRECORD_AUDIOnever reached the assembled manifest and the permission request could only answer "denied". The option shipped in the same commit as voice input, so the feature never worked. CI now fails the build if the release APK lacks the permission. - Model and reasoning-effort pickers.
@gorhom/bottom-sheet5.2.8 measured the window incorrectly under React Native 0.88 / edge-to-edge, so the sheet mounted off-screen: the chip tap landed and nothing appeared. Bumped to 5.2.14. - "Unregistered ActivityResultLauncher" no longer needs a restart. From
expo-modules-core58 the activity-result registry re-registers a launcher on its next use instead of throwing after Android destroys the Activity while the process lives. - Expo SDK 58, React Native 0.88.1, React 19.3.0. SDK 58 regenerates
android/on every prebuild, so release signing,dependenciesInfo,usesCleartextTrafficand the IME reporter moved into a config plugin instead of hand-edited native files. - The CUA smoke now exercises both pickers — picking a model and a reasoning effort, checking the chip label follows, and dumping logcat on failure.
Installs over 0.3.6 — no uninstall needed. Verified on a real device (photo attachment, model and effort selection, voice input) and in CI: 667 tests, typecheck, coverage gate, release APK smoke.
APK SHA256 (opencode-mobile-v2.apk):
dddffedb9203cfbdce9c45f350edba580a3d81aab7bb9e49d02e684918ed1c6f
Русский
Голосовой ввод впервые работает, шиты выбора модели и усилия снова открываются. Плюс приложение переехало на Expo SDK 58.
- Голосовой ввод. В
expo-image-pickerстоялmicrophonePermission: false, а этот плагин трактуетfalseкак блокировку разрешения: expo писал<uses-permission android:name="android.permission.RECORD_AUDIO" tools:node="remove"/>. В итоговый манифестRECORD_AUDIOне попадал, поэтому запрос разрешения мог ответить только «denied». Опция появилась тем же коммитом, что и голосовой ввод, — фича не работала никогда. Теперь CI валит сборку, если в релизном APK нет этого разрешения. - Шиты выбора модели и усилия.
@gorhom/bottom-sheet5.2.8 неверно считал высоту окна под React Native 0.88 / edge-to-edge, и шит монтировался вне экрана: тап по чипу срабатывал, а на экране ничего не появлялось. Обновлено до 5.2.14. - «Unregistered ActivityResultLauncher» больше не требует перезапуска. Начиная с
expo-modules-core58 реестр activity-result перерегистрирует лончер при следующем использовании, вместо того чтобы бросать исключение после уничтожения Activity при живом процессе. - Expo SDK 58, React Native 0.88.1, React 19.3.0. SDK 58 пересоздаёт
android/на каждом prebuild, поэтому подпись релиза,dependenciesInfo,usesCleartextTrafficи IME-репортер переехали в config-плагин вместо правки нативных файлов руками. - CUA smoke теперь реально проверяет оба шита — выбирает модель и усилие, проверяет, что подпись на чипе меняется, и дампит logcat при падении.
Ставится поверх 0.3.6 без удаления приложения. Проверено на живом устройстве (прикрепление фото, выбор модели и усилия, голосовой ввод) и в CI: 667 тестов, typecheck, порог покрытия, smoke релизного APK.
SHA256 APK (opencode-mobile-v2.apk):
dddffedb9203cfbdce9c45f350edba580a3d81aab7bb9e49d02e684918ed1c6f
v0.3.6 — исправлено прикрепление фото / photo attachment fixed
English
Fixes attaching a photo from the chat composer.
- Tapping
+no longer dies before the picker opens. On the reporting device the system photo-picker activity rejected the launch immediately, so the only feedback was "image not attached" with no picker on screen. The app now retries once with the legacyACTION_GET_CONTENTintent, which the device's file manager answers. - A failure now names its reason. A rejected picker and a failed JPEG conversion used to show the same generic alert, so a report could not tell them apart. The technical reason is written to the log buffer (included in diagnostics reports) and shown in the alert.
Installs over 0.3.5 — no uninstall needed. Verified in CI: 664 tests, typecheck, coverage gate, and the release APK smoke on an Android 15 emulator.
APK SHA256 (opencode-mobile-v2.apk):
59217a73eda080ebbc11863ed325cd7951b762c33dc6cf3841cccdf50b18c2a4
Русский
Исправляет прикрепление фото из поля ввода чата.
- Тап по «+» больше не падает до открытия пикера. На устройстве, где это воспроизвелось, системная activity выбора фото отклоняла запуск сразу, и единственной реакцией было «изображение не прикреплено» без единого экрана пикера. Теперь приложение повторяет попытку со старым интентом
ACTION_GET_CONTENT, который обслуживает файловый менеджер устройства. - Ошибка называет причину. Отказ пикера и сбой конвертации в JPEG показывали один и тот же общий алерт, поэтому по отчёту нельзя было понять, что именно произошло. Теперь техническая причина пишется в буфер логов (уходит вместе с отчётом диагностики) и показывается в алерте.
Ставится поверх 0.3.5 без удаления приложения. Проверено в CI: 664 теста, typecheck, порог покрытия и smoke релизного APK на эмуляторе Android 15.
SHA256 APK (opencode-mobile-v2.apk):
59217a73eda080ebbc11863ed325cd7951b762c33dc6cf3841cccdf50b18c2a4
0.3.5 — tool duration fix / время работы инструмента
English
0.3.5 (70) — a long-running tool no longer looks like a frozen app. Installs over 0.3.4 without uninstalling.
- Elapsed time while a tool runs. The tool row printed a duration only when both the start and the end timestamp were present, and a running tool has no end — so a ten-minute command sat there with no sign of life and the session looked hung. It now ticks the elapsed time every second, and reads
5m 05spast the first minute. - V2 servers send no tool timing at all. Checked against the live server: every tool part arrives as
{status, input, content, metadata}with notimefield, so there was nothing to measure even for finished tools. The V2 compatibility layer now builds that window from the event timestamps: the first event of a call opens it, the terminal one closes it.
No other behaviour changed.
APK: opencode-mobile-v2.apk + SHA256SUMS.txt.
Русский
0.3.5 (70) — долго работающий инструмент больше не выглядит как зависшее приложение. Ставится поверх 0.3.4 без удаления приложения.
- Прошедшее время, пока инструмент работает. Длительность в строке показывалась только когда есть и начало, и конец, а у выполняющегося инструмента конца нет — поэтому десятиминутная команда висела без признаков жизни, и сессия выглядела зависшей. Теперь время тикает каждую секунду, а после первой минуты показывается как
5m 05s. - V2-сервер вообще не присылает время инструментов. Проверено на живом сервере: каждая часть приходит как
{status, input, content, metadata}без поляtime, так что измерять было нечего даже у завершённых вызовов. Слой совместимости с V2 теперь строит это окно из отметок событий: первое событие вызова открывает его, завершающее — закрывает.
Другое поведение не менялось.
APK: opencode-mobile-v2.apk + SHA256SUMS.txt.
0.3.4 — inline code and model picker fixes / inline-код и списки моделей
⚠️ Устарел — используйте v0.3.5: он содержит эти же исправления плюс время работы инструмента.
English
0.3.4 (69) — two fixes: inline code in chat was drawn with misplaced highlight bars that cut letters, and the model / reasoning-effort pickers could come up empty after the phone came back. Installs over 0.3.3 without uninstalling.
- Chat text renders cleanly. Inline code was highlighted with a background bar. On Android that bar is positioned from the code span's own box, and for a span that wraps it is taller than its line: the bar starts above the previous line and covers the letters there, and a smaller code font shifts it about half a line down. Reproduced on an Android emulator in several style variants — the bars themselves are what corrupted the text, not the glyphs. Inline code is now marked by colour and monospace only, so there is no rectangle that can land in the wrong place.
- The model and effort sheets no longer come up empty. The provider catalog was fetched once per connection. If that single request landed while the phone was locked or the server was asleep, the list stayed empty for the rest of the session and only Settings → Models revived it (that screen loads the catalog itself). Now a failed request keeps the list already loaded, returning to the app refreshes it, and opening the picker with an empty catalog fetches again before showing the sheet.
APK: opencode-mobile-v2.apk + SHA256SUMS.txt.
Русский
0.3.4 (69) — два исправления: inline-код в чате рисовался съехавшими плашками, которые резали буквы, а списки моделей и усилия могли остаться пустыми после возврата к телефону. Ставится поверх 0.3.3 без удаления приложения.
- Текст в чате отрисовывается чисто. Inline-код подсвечивался плашкой. На Android плашка позиционируется по собственному боксу фрагмента кода, и если фрагмент переносится, плашка выше своей строки: она начинается над предыдущей строкой и закрывает буквы там, а уменьшенный шрифт кода сдвигает её примерно на полстроки вниз. Воспроизведено на эмуляторе Android в нескольких вариантах стиля — портит текст именно прямоугольник, а не глифы. Теперь inline-код выделяется только цветом и моноширинным шрифтом, так что прямоугольнику негде съехать.
- Списки моделей и усилия больше не пустые. Каталог провайдеров запрашивался один раз на соединение. Если этот единственный запрос приходился на заблокированный телефон или спящий сервер, список оставался пустым до конца сессии, и оживляли его только Настройки → Модели (этот экран загружает каталог сам). Теперь неудачный запрос сохраняет уже загруженный список, возврат в приложение обновляет каталог, а открытие списка с пустым каталогом сначала запрашивает его заново.
APK: opencode-mobile-v2.apk + SHA256SUMS.txt.
0.3.3 — update notice, background answer, long-background hang
English
0.3.3 (68) — three device fixes: the in-app update notice, the re-typing of an answer received in the background, and a session that hung after a long background. Installs over 0.3.2 without uninstalling.
- The update notice works again. Opening the release page now marks that version as seen and hides the strip.
Linking.openURLresolves tovoid, so the previous truthiness check never dismissed it. The banner also re-checks whenever the app returns to the foreground, and the About row refreshes every time Settings is opened instead of only on the first mount. - An answer received in the background no longer re-types itself. Returning after a long pause replaces the SSE stream before refreshing the transcript, so the buffered backlog cannot replay older, shorter snapshots over the complete answer. Text and reasoning parts additionally only grow while a run streams.
- A long background no longer hangs the session. Android can kill the event socket without an error while JS is suspended, and the stall watchdog only watched active runs. Returning after 15+ seconds now opens a fresh stream and re-syncs the open session, the busy state and pending permission/question forms, instead of staying silent until the next prompt waits out the 30-second window. A quick app switch keeps the existing stream.
APK: opencode-mobile-v2.apk + SHA256SUMS.txt.
Verification: 651 tests, tsc --noEmit, coverage 98.36 % lines / 86.22 % branches / 97.24 % functions; gitleaks secret scan and Android CUA smoke in CI.
Русский
0.3.3 (68) — три исправления с устройства: оповещение об обновлении, повторная «печать» ответа, полученного в фоне, и зависание сессии после долгого сворачивания. Ставится поверх 0.3.2 без удаления приложения.
- Оповещение об обновлении снова работает. Открытие страницы релиза теперь помечает версию просмотренной и убирает плашку:
Linking.openURLрезолвится вvoid, поэтому прежняя проверка результата не срабатывала никогда. Плашка также перепроверяет обновления при возврате приложения на передний план, а строка «О приложении» обновляется при каждом открытии настроек, а не только при первом монтировании. - Ответ, полученный в фоне, больше не печатается заново. При возврате после долгой паузы приложение заменяет поток SSE до обновления транскрипта, поэтому накопившийся бэклог не перерисовывает готовый ответ более старыми и короткими снимками. Кроме того, текстовые части и рассуждения только растут во время прогона.
- Долгое сворачивание больше не вешает сессию. Android может убить сокет событий без ошибки, пока JS приостановлен, а сторож зависаний следил только за активными прогонами. Возврат после 15+ секунд в фоне теперь открывает новый поток и пересинхронизирует открытую сессию, статус занятости и висящие формы подтверждений/вопросов, вместо того чтобы молчать до следующего промпта (до 30 секунд). Быстрое переключение приложений поток не трогает.
APK: opencode-mobile-v2.apk + SHA256SUMS.txt.
Проверки: 651 тест, tsc --noEmit, покрытие 98.36 % строк / 86.22 % ветвей / 97.24 % функций; скан секретов gitleaks и Android CUA smoke в CI.
0.3.2 — audit fixes and security hardening / исправления по аудиту и безопасность
English
0.3.2 (67) — audit fixes, security hardening and a leaner build. Installs over 0.3.1 without uninstalling.
- Connection editing keeps the right API version. A fresh "Test connection" now survives Save, and saving the same address without testing re-probes the server, so swapping a V1 server for V2 on the same URL no longer leaves a stale protocol recorded.
- Auth rejections no longer guess the protocol.
401/403on/api/infois returned by a password-protected V1 server too, so the generation stays unknown until authentication succeeds. - Voice input uses the phone's real locale.
ru-RUandzh-CNreach the recognizer unchanged instead ofru-US/zh-US. - Localized chat and notifications. Message role labels and notification titles/bodies follow en / ru / zh-Hans; server-supplied text still never reaches the lock screen.
- Tests are typechecked.
*.test.ts(x)are back intsconfig.json; the 49 test-type errors this exposed are fixed. - Leaner CI and APK checks.
versionCode/versionNameare read fromapp.json, the signing certificate is compared with a pinned SHA-256 (no 86 MB download), and the assembled APK is checked forSYSTEM_ALERT_WINDOWand for being debuggable. - Fewer round trips and writes. Model and agent switches run in parallel; switching the active connection writes SecureStore once.
- Removed unused code.
@tanstack/react-query, theagentlabs.ccwaitlist form and retry queue, the dead Chatwoot client,android/sentry.properties, and the dev network-inspector flag in release builds. Shared HTTP, stored-JSON parsing and model-picker parts replace duplicated copies. - Security. Diagnostics no longer log or share credentials embedded in a URL; session ids from deep links and notifications are validated before they reach an API path. Full report:
docs/security-review-0.3.2.md.
Verification: 638 tests, tsc --noEmit, coverage 98.35 % lines / 86.29 % branches / 97.23 % functions; gitleaks secret scan and Android CUA smoke in CI.
Русский
0.3.2 (67) — исправления по аудиту, усиление безопасности и более лёгкая сборка. Устанавливается поверх 0.3.1 без удаления приложения.
- Редактирование подключения сохраняет верный API. Свежий результат «Проверить подключение» теперь переживает «Сохранить», а сохранение того же адреса без теста заново опрашивает сервер — замена V1 на V2 по тому же URL больше не оставляет старую версию протокола.
- Отказ авторизации больше не угадывает протокол.
401/403на/api/infoотдаёт и V1-сервер за паролем, поэтому версия остаётся неизвестной до успешной авторизации. - Голосовой ввод использует локаль телефона.
ru-RUиzh-CNуходят в распознаватель как есть, без подмены наru-US/zh-US. - Локализация чата и уведомлений. Подписи ролей и заголовки/тексты системных уведомлений берутся из en / ru / zh-Hans; серверный текст в шторку по-прежнему не попадает.
- Тесты проверяются типами.
*.test.ts(x)возвращены вtsconfig.json; 49 ошибок типов в тестах исправлены. - Легче CI и проверка APK.
versionCode/versionNameчитаются изapp.json, сертификат подписи сверяется с закреплённым SHA-256 (без скачивания 86 МБ), а собранный APK проверяется наSYSTEM_ALERT_WINDOWиdebuggable. - Меньше запросов и записей. Смена модели и агента идёт параллельно; переключение активного подключения пишет SecureStore один раз.
- Удалён неиспользуемый код.
@tanstack/react-query, форма и очередь waitlistagentlabs.cc, мёртвый клиент Chatwoot,android/sentry.properties, dev-флаг сетевого инспектора в релизе. Общие HTTP-слой, разбор сохранённого JSON и части пикеров моделей заменили дубли. - Безопасность. Диагностика больше не логирует и не отдаёт креды, вшитые в URL; id сессии из deep link и уведомлений проверяется перед подстановкой в путь API. Полный отчёт —
docs/security-review-0.3.2.md.
Проверки: 638 тестов, tsc --noEmit, покрытие 98.35 % строк / 86.29 % ветвей / 97.23 % функций; скан секретов gitleaks и Android CUA smoke в CI.
0.3.1 — mid-stream header crash fix / исправление краша при выходе из сессии
English
0.3.1 — no crash when leaving a session mid-stream.
- Fixed the native crash (
react-native-screens, "child already has a parent") that could happen when you left a session while it was still streaming. The session header now applies its options throughnavigation.setOptionsin an effect, so it updates only when the visible data changes — title, folder badge, context ring, theme. Ported from upstream v0.4.17. - Added a regression test that pins the header wiring (666 tests total).
Installs over 0.3.0. Signed with the same key as 0.2.20–0.3.0.
Русский
0.3.1 — нет краша при выходе из сессии во время стрима.
- Исправлен нативный краш (
react-native-screens, «child already has a parent»), который мог случиться при выходе из сессии, пока она ещё печатала ответ. Заголовок сессии теперь применяет опции черезnavigation.setOptionsв эффекте и обновляется только при изменении видимых данных — названия, бейджа папки, кольца контекста, темы. Порт из апстрима v0.4.17. - Добавлен регрессионный тест на разводку заголовка (всего 666 тестов).
Ставится поверх 0.3.0. Подписан тем же ключом, что 0.2.20–0.3.0.
0.3.0 — работает с opencode 1.x и 2.x / works with opencode 1.x and 2.x
English
0.3.0 — one app for opencode 1.x and 2.x.
Both server generations
The app now speaks the V1 API (opencode 1.18.x, what npm install -g opencode-ai still installs) and the V2 API (opencode 2.x, the native binary). On connect it probes the address once, remembers the answer per connection, and uses the matching transport: /global/health + /global/event for V1, /api/info + /api/event for V2. The probe classifies by response body and content type, never by status code — an unknown route on either generation falls through to the web UI and answers 200 text/html, which is exactly how a V2-only client used to report "connected" on a V1 server and then fail on every request.
Settings → Server → Server API forces v1 or v2 and applies immediately, without a restart. Auto is the default.
Events that only 1.18.x sends (session.idle, permission.updated, and the permission.v2.* names) are normalized; without that, an approval prompt would never appear and the run would hang forever.
Session info
- The header button is a ring that fills with context usage — blue, amber past 50 %, red past 80 % — instead of a static icon.
- The panel shows the total spend for the whole session next to the token count and the context percentage. The cost used to be summed over loaded messages, which understates a long session; the server's cumulative total is preferred, and on providers that report no price (opencode-go) the tokens are priced from the model catalog.
- Prompts per session gains All: the whole transcript, no trimming.
Favorites
A star in each model row pins the model to a "Favorites" section on top of both pickers. Stored on the device (provider and model ids only), shared across connections. A starred model stays in its provider list; a hidden model stays hidden.
Fixes reported from the device
- Chat no longer loses messages mid-session. "Load older" marked the history complete, and every later refresh replaced the transcript with a page trimmed to the setting — messages vanished until the session was reopened.
- "Load older" really loads everything. It asked the API without a limit, the server answered its default 50 messages and the history was marked complete, so everything older became unreachable.
- The stop button is always there during a run, even for a run started elsewhere (app restarted, opened mid-run, another device). A refused interrupt now says so instead of failing silently.
- Attach and paste can't fail silently anymore, and the reasoning-effort sheet no longer opens behind the keyboard.
- Tool cards are never blank: the live progress title, the
shelltool name and empty outputs are all handled. - Sessions in the list are no longer cut off at the server's newest 50 (V2) or 100 (V1) — both transports walk their cursor now.
- Tunnels work: ngrok and localtunnel no longer answer with their own page instead of the API.
Security
- Approval and question notifications carry fixed text, never server-supplied tool names, paths or question bodies: the notification shade is readable on a locked phone.
- No telemetry (Sentry and PostHog are not in the build).
- Repository renamed to
opencode-v1-v2-mobile. The APK file is stillopencode-mobile-v2.apkso updates install in place and the release signature check keeps working.
Русский
0.3.0 — одно приложение для opencode 1.x и 2.x.
Оба поколения сервера
Приложение работает и с V1 API (opencode 1.18.x, его до сих пор ставит npm install -g opencode-ai), и с V2 API (opencode 2.x, нативный бинарник). При подключении адрес один раз опрашивается, ответ запоминается для этого подключения, и дальше используется подходящий транспорт: /global/health + /global/event для V1, /api/info + /api/event для V2. Определение идёт по телу и типу ответа, а не по коду: неизвестный маршрут на обоих поколениях проваливается в веб-интерфейс и отвечает 200 text/html — именно поэтому клиент, знавший только V2, показывал «подключено» на V1-сервере и падал на первом же настоящем запросе.
Настройки → Сервер → API сервера принудительно включает v1 или v2 и применяется сразу, без перезапуска. По умолчанию — «Авто».
События, которые присылает только 1.18.x (session.idle, permission.updated и имена permission.v2.*), нормализуются: без этого запрос подтверждения не появился бы, а прогон висел бы вечно.
Информация о сессии
- Кнопка в заголовке — кольцо, заполняемое по расходу контекста: синее, жёлтое после 50 %, красное после 80 %.
- В панели: общая стоимость за всю сессию рядом с токенами и процентом контекста. Раньше стоимость суммировалась по загруженным сообщениям и занижалась для длинной сессии; теперь берётся накопленный итог сервера, а на провайдерах без цены (opencode-go) токены ценятся по каталогу модели.
- В «Промптов на сессию» появился вариант Вся: весь транскрипт без обрезки.
Любимые модели
Звёздочка в строке модели закрепляет её в секции «Любимые» сверху обоих пикеров. Хранится на устройстве (только id провайдера и модели), общее для всех подключений. Любимая модель остаётся и в списке своего провайдера, скрытая — остаётся скрытой.
Исправления по отчётам с устройства
- Чат больше не теряет сообщения по ходу. «Загрузить старые» помечал историю загруженной, а каждое следующее обновление экрана заменяло переписку страницей, обрезанной до настройки, — сообщения исчезали до перезахода.
- «Загрузить старые» действительно грузит всё. Запрос шёл без
limit, сервер отдавал свои 50 сообщений по умолчанию, и история помечалась загруженной — всё старше становилось недоступным. - Кнопка «стоп» есть всегда во время прогона, даже если запуск начат не с этого экрана (приложение перезапускалось, открыли посреди работы, другое устройство). Отказ сервера теперь показывается, а не теряется.
- Вложение и вставка не могут молча не сработать, а шторка выбора уровня рассуждений больше не открывается за клавиатурой.
- Карточки инструментов не бывают пустыми: живой заголовок прогресса, имя
shellи пустой вывод обрабатываются. - Список сессий больше не обрезан 50 (V2) или 100 (V1) последними — оба транспорта идут по курсору.
- Туннели работают: ngrok и localtunnel больше не отвечают своей страницей вместо API.
Безопасность
- Уведомления о подтверждении и о вопросе содержат фиксированный текст, а не присланные сервером имена инструментов, пути и текст вопроса: шторка читается с заблокированного телефона.
- Телеметрии нет (Sentry и PostHog в сборку не входят).
- Репозиторий переименован в
opencode-v1-v2-mobile. Файл APK по-прежнему называетсяopencode-mobile-v2.apk, чтобы обновление ставилось поверх и проверка подписи продолжала работать.
Install / Установка: download opencode-mobile-v2.apk below and install over the previous version — no uninstall needed. Verify with SHA256SUMS.txt.
0.2.30 — a failed run now says why / неудачный прогон показывает причину
⚠️ Устарел — используйте v0.3.0.
Updates over 0.2.29 without uninstalling the app.
A failed run now says why
When a run fails — for example a free model answering 429 Free usage limit reached — the server stores the reason on the assistant message and sends no answer text. The chat drew that as an empty bubble, so a session that was actually erroring looked frozen: your messages went out and nothing came back, and the only way to see the cause was the desktop client or the server log. The reason now appears in the chat in red, exactly where the answer would have been, and it stays visible after reopening the session because it comes from the transcript.
APK: opencode-mobile-v2.apk (same signature as 0.2.20–0.2.29). Checksum in SHA256SUMS.txt next to it.
Обновляется поверх 0.2.29 без удаления приложения.
Неудачный прогон теперь объясняет причину
Когда прогон падает — например, бесплатная модель отвечает 429 Free usage limit reached — сервер записывает причину в assistant-сообщение и не присылает текст ответа. Чат рисовал такой ответ пустым пузырём, поэтому сессия, которая на самом деле падала с ошибкой, выглядела зависшей: сообщения уходили, в ответ не приходило ничего, а причину можно было увидеть только в десктопном клиенте или в логе сервера. Теперь причина показывается в чате красным, ровно там, где был бы ответ, и остаётся видимой после перезахода в сессию — она берётся из переписки.
APK: opencode-mobile-v2.apk (та же подпись, что у 0.2.20–0.2.29). Контрольная сумма — в SHA256SUMS.txt рядом.