Cobalt — открытая платформа приложений для электронных книг Kobo: лаунчер, подписанный магазин приложений (App Store), Rust SDK и рантайм, который держит каждое приложение в собственном непривилегированном процессе.

Установка выполняется один раз через USB. После этого каждое приложение устанавливается, обновляется и удаляется прямо на устройстве по Wi-Fi. Перезагрузка возвращает штатный интерфейс Kobo.

Лаунчер Cobalt на Kobo Clara BW, показывающий Settings, App Store, Terminal, AI Chat, Audiobooks, Components, Daily Brief, Feeds и Gutenbird
Лаунчер на Kobo Clara BW.

Проект не аффилирован с Rakuten Kobo.

Kobo Clara BW запускает Audiobook Studio, Gutenbird, Terminal, Hacker News, Sidekick и App Store, затем устанавливает, запускает, удаляет и переустанавливает Sudoku по Wi-Fi
Запись с устройства на утроенной скорости.

Работа на реальном Kobo

Каждое приложение — это статический бинарник под ARM, работающий как отдельный непривилегированный процесс на штатном железе. App Store устанавливает, обновляет и удаляет приложения по Wi-Fi, проверяя подписи перед каждым запуском.

Статьи arXiv и агенты для написания кода — прямо на экране

Приведённые скриншоты сделаны с реального устройства, а не в эмуляторе. Приложение arXiv читает HTML-версию, которую arXiv публикует для каждой статьи начиная с декабря 2023 года: аннотации, разделы, формулы и таблицы результатов, разбитые на страницы под размер экрана.

Раздел препринта arXiv 'A hard optimization problem and its relaxation' на экране Kobo Clara BW
Препринт, страница 8 из 54, на экране.
Таблица результатов из статьи arXiv со сравнением языковых моделей на ридере Kobo
Таблица результатов из той же статьи.
Математические формулы и пронумерованный алгоритм из статьи arXiv на ридере Kobo
Математическая нотация и пронумерованный алгоритм.
Sidekick на Kobo показывает вопрос от Claude Code с тремя вариантами ответа и кнопкой «Оставить для терминала»
Sidekick показывает вопрос от Claude Code с вариантами ответа, доступными по нажатию.
Экран ожидания Sidekick на Kobo, подключённого к машине в локальной сети, с последним отправленным ответом
Sidekick, подключённый по локальной сети, ожидает следующий вопрос.

Приложения

Каждый скриншот ниже сделан на Kobo Clara BW. Приложения из магазина версионируются независимо от платформы; остальные поставляются вместе с установкой платформы.

Сетка приложений лаунчера Cobalt на e-ink экране

Launcher

Открывает установленные приложения и всегда сохраняет путь обратно к штатному ридеру Kobo.

Каталог App Store Cobalt со списком установленных и доступных приложений

App Store

Устанавливает, обновляет, удаляет и переустанавливает подписанные приложения по Wi-Fi.

Список новейших препринтов по машинному обучению в приложении arXiv на Kobo

arXiv

Просматривает новейшие препринты по теме и читает полный текст прямо на экране.

Завершённая партия судоку из 81 клетки на Kobo Clara BW

Sudoku

Доступно только через магазин по замыслу: установка доказывает доставку приложения, которого нет в исходном USB-пакете.

Буква S, заполняющая экран Kobo, пока подсветка передаёт её азбукой Морзе

Morse

Передаёт набранное сообщение азбукой Морзе через подсветку экрана, буква за буквой на весь экран.

Плеер аудиокниг с обложкой, позицией воспроизведения и элементами управления на e-ink экране

Audiobook Studio

Исследует тему, пишет текст, озвучивает и воспроизводит оригинальную аудиокнигу.

Полка обложек книг из каталога OPDS на Kobo

Gutenbird

Читает любую OPDS-библиотеку: Project Gutenberg, Standard Ebooks, Open Library или собственную.

Ранжированный список историй Hacker News на ридере Kobo

Hacker News

Разделы Top, New, Ask и Show с полными ветками комментариев.

Список подписанных RSS-лент и статей в приложении Feeds

Feeds

Находит RSS-ленту сайта и показывает статьи без исходной вёрстки страницы.

Пронумерованная ежедневная новостная сводка на e-ink экране

Daily Brief

Собирает новости дня в фоне, пока используется другое приложение.

Ответ ИИ, отображённый как удобный для чтения текст на экране Kobo

AI Command Center

Задаёт вопрос и превращает ответ в текст, удобный для чтения с сенсорным управлением.

Запрос от агента для написания кода с вариантами ответа по нажатию в Sidekick

Sidekick

Одобряет или отклоняет запросы от агентов, пишущих код, не отрываясь от клавиатуры компьютера.

Командная строка и сенсорная клавиатура на экране Kobo

Terminal

Нативная для экрана оболочка, где клавиши мгновенно отправляют ввод.

Типографика и UI-компоненты Cobalt на e-ink экране

Components

Элементы управления, макеты, типографика и состояния UI-набора инструментов на экране.

Состояние батареи и информация об оборудовании в разделе Settings

Settings

Подключение, оборудование и обновления платформы — отдельно от магазина.

Постоянный список задач с выполненными пунктами

Todo

Постоянный список с сенсорным вводом и отметкой выполненных пунктов.

Завершённая партия крестиков-ноликов на e-ink экране

Tic-tac-toe

Два игрока, частичное обновление отдельных ячеек поля.

Датчик Холла Kobo реагирует на магнит

Magnet

Находит датчик Холла за корпусом ридера и сообщает об изменении его состояния.

SDK: приложение — это один файл на Rust

Разработчику нужно реализовать трейт KoboApp, описать экраны декларативно — остальное берёт на себя рантайм: раскладку, планирование обновления e-ink дисплея, навигацию назад и жизненный цикл приложения.

Приложения не открывают ресурсы устройства напрямую — они запрашивают доступ. Сеть, хранилище, аудио, подсветка и Wi-Fi защищены системой разрешений, а отказ возвращается как значение, которое приложение может обработать.

E-ink интерфейс
Текст, плитки, диалоги, клавиатуры, пагинация, планирование частичного обновления экрана
Симуляторы
Симуляторы в браузере и в рантайме с диагностикой раскладки
Асинхронные операции
HTTPS, докачка по диапазонам, отменяемые задачи, запланированные пробуждения
Состояние
Атомарное хранилище данных для каждого приложения по ключам
Публикация
Подписанные статические бинарники под ARMv7, публикуемые при слиянии PR приложения
kobo new my-app
cd my-app
kobo dev
use kobo_sdk::{
    ActionId, Context, KoboApp, ScreenBuilder,
};

#[derive(Default)]
struct Hello { taps: u32 }

impl KoboApp for Hello {
    fn on_start(&mut self, ctx: &mut Context) {
        self.show(ctx);
    }

    fn on_action(
        &mut self, ctx: &mut Context, a: ActionId,
    ) {
        if a == kobo_sdk::action_id("tap") {
            self.taps += 1;
        }
        self.show(ctx);
    }
}

impl Hello {
    fn show(&self, ctx: &mut Context) {
        let screen = ScreenBuilder::new("hello")
            .top_bar("Hello")
            .heading(format!("{} taps", self.taps))
            .button("tap", "Tap me")
            .build();
        ctx.set_screen(screen);
    }
}

fn main() {
    let app = Hello::default();
    let _ = kobo_sdk::run("hello", app);
}

Магазин: подписанные пакеты, проверенные перед запуском

App Store читает подписанный каталог из фиксированного GitHub-релиза. Каждый пакет содержит один исполняемый файл под ARM и подписанный манифест. Рантайм проверяет каталог, пакет, установленный манифест и сам бинарник перед каждым запуском приложения.

Релизы приложений не зависят от релизов платформы: слияние PR с приложением собирает его под ARM, подписывает и обновляет каталог. Не требуется ни повышение версии Cobalt, ни переустановка — приложение просто появляется в магазине.

Сама платформа Cobalt также обновляется по Wi-Fi, через раздел Settings, по отдельному от каталога приложений каналу. USB-кабель нужен лишь однажды.

Транзакции установки и обновления каталога устойчивы к сбоям: прерванное обновление оставляет ридер с прежней версией.

Установка из исходников

  1. Зарядите Kobo Clara BW (N365) и подключите его по USB. Другие модели отклоняются платформой, а не определяются приблизительно.
  2. Запустите настройку:
git clone https://github.com/BandarLabs/Cobalt.git
cd Cobalt
rustup target add armv7-unknown-linux-musleabihf
cargo run -p kobo-cli -- setup
  1. Перезапустите ридер и откройте Cobalt в меню Kobo.
  2. Откройте Store. Дальше всё происходит по Wi-Fi.

Полная инструкция, включая шаги восстановления, доступна в документации проекта на GitHub.

Как добавить своё приложение

Вклад в виде нового приложения оформляется как обычный pull request. Если оно работает на реальном устройстве и PR это подтверждает — оно будет принято и опубликовано.

  1. Разработать приложение. Добавить его как пакет workspace в apps/<app-id>/ и зарегистрировать в apps/catalog.json.
  2. Протестировать. Добавить модульные тесты и тесты раскладки, запустить в симуляторах браузера и рантайма.
  3. Запустить на собственном устройстве. На реальном Clara BW, а не только в симуляторе.
  4. Открыть PR с гифкой или фотографиями работы приложения. После проверки и слияния процесс публикации подпишет пакет, и он появится в магазине — без отдельного релиза платформы.

Владельцам других моделей Kobo также рады: портирование приветствуется, но сначала стоит открыть issue, чтобы согласовать профиль устройства.

Поддержка устройств и безопасность

Cobalt не заменяет загрузочную цепочку Kobo. Запись на устройство разрешена только при точном совпадении модели оборудования и версии прошивки, а перезагрузка возвращает штатный ридер. Первая установка изменяет файлы в пользовательском разделе хранилища и предоставляется без каких-либо гарантий.

Аппаратно протестирован только профиль Clara BW. Установка на другие модели не рекомендуется до появления проверенного и протестированного на железе профиля. Cobalt — независимый проект, не связанный с Rakuten Kobo.