От HTML-таймера к TypeScript. Как менялась Kapsula
- вторник, 20 октября 2026 г. в 00:00:16
У меня Kapsula началась с таймера рабочего дня. Один HTML-файл, который написал ИИ. Открываешь, нажимаешь кнопку, он отсчитывает время. Потом гаснет экран телефона — и выясняется, что с напоминанием всё сложнее, чем казалось в браузере.
Про будильники и устройство оболочки я уже рассказывал. С тех пор приложение дошло до версии 0.5, и задача немного сдвинулась. Теперь в нём можно запускать отдельные JavaScript- и TypeScript-файлы, редактировать сохранённый код и возвращаться к своим данным после изменений.
Хочу показать, что получилось, на простом трекере тренировок. Добавить подход, закрыть приложение, открыть завтра, попросить ИИ что-нибудь поменять. Довольно обычные действия. Вот на них и становится видно, насколько полезна вся эта история с «приложением из чата».

Какой путь я сейчас стараюсь сделать удобным. Генерация кода остаётся в привычном AI-чате; Kapsula отвечает за его запуск и доступ к своему SDK.
Если коротко: Kapsula — приложение для Android и iPhone. Внутрь добавляешь свой небольшой инструмент: файлом, вставкой кода или, для HTML, ссылкой. Он запускается в песочнице. Для хранения данных, локальных уведомлений, звука и вибрации есть небольшой мост window.kapsula.
Отдельный APK для каждого такого инструмента собирать не надо. Но и самостоятельное приложение, которое можно вынести из Kapsula и отправить в стор, при этом не получается. Проект живёт внутри оболочки.
Изначально мне хватало одного HTML с CSS и JavaScript внутри. Для таймера это вполне нормальный формат: можно открыть файл в браузере, посмотреть интерфейс, поправить пару строк.
Но как только начинаешь менять такой инструмент, хочется видеть сохранённый исходник, понимать ошибку и не импортировать всё каждый раз как новый проект. Иначе после очередного «сделай кнопку покрупнее» легко получить ещё одну копию приложения с пустой историей.
Поэтому я занялся самим циклом доработки.
На раннем главном экране много внимания получало встроенное демо. Оно объясняло возможности приложения, но после добавления своей тулзы первым хочется видеть именно её.
В 0.5 свои проекты находятся выше, кнопка добавления стала заметнее, а демо вынесено отдельно. При новом запуске Kapsula открывает список проектов.
На скриншоте особо нечем хвастаться. Зато при следующем запуске свою тулзу уже не надо искать под демо.

Интерфейс 0.5 в браузерной проверке на ширине 320 px. На экране тестовый проект workout. Это снимок веб-части приложения, не фотография телефона.
Теперь необязательно просить ассистента упаковывать всё в HTML. Можно получить один .js или .ts и добавить его как проект. В случае вставки кода формат выбирается в форме; у выбранного файла он определяется по расширению.
Для интерфейса скрипту предоставляется #app. Дальше обычный DOM: создать форму, повесить обработчики, добавить стили. Вывод console.log, info, warn, error виден под интерфейсом. Полный отладчик я сюда пока не встроил, но хотя бы не приходится гадать, почему получился пустой экран.
С TypeScript есть важная граница. Это один самостоятельный скрипт с типами, интерфейсами и функциями. Imports, exports, npm-пакетов и JSX здесь пока нет. Взять целиком проект на Next.js и закинуть в Kapsula не выйдет.
Преобразование TypeScript выполняется на устройстве. Babel упакован в приложение и запускается по необходимости в отдельном Worker. Исходник никуда на компиляцию не отправляется; CDN тоже не нужен. После преобразования JavaScript попадает в ту же песочницу, что и раньше.

Исходный TS остаётся для редактора. Данные хранятся отдельно от кода и привязаны к проекту.
Это не полная проверка типов. Например, такой код может успешно преобразоваться:
const weight: number = 'двадцать';
Тип уберётся, а строка останется. Поэтому данные, которые прочитаны из хранилища, всё равно нужно проверять во время выполнения. Написать get<WorkoutState>() и считать, что старые записи автоматически стали правильными, не получится.
Из совсем приземлённых граблей: на iPhone выбор .ts-файла мог оказаться недоступен из-за фильтра типов файлов. До компилятора дело даже не доходило. Пришлось исправлять выбор файла. Такие вещи в красивую схему с Worker не помещаются, а пользователь упирается именно в них.
Для примера я взял дневник тренировок. В нём есть упражнение, вес, повторения и история подходов. Ещё кнопка отдыха на 90 секунд с запросом локального уведомления.
Важнее всего здесь история. Нажал «сохранить», вернулся к списку, открыл проект снова — запись должна быть на месте.

Браузерный предпросмотр реального workout.ts, тестовая запись Squat / 20 kg / 10 повторений. Нативные уведомления в этом предпросмотре не работают.
Принцип хранения довольно скучный, зато понятный. Данные читаются через kapsula.storage и по ним восстанавливается экран. Ключ и формат записей остаются совместимыми между правками кода.
Вот сокращённый фрагмент с проверкой одной записи:
type TrainingSet = { exercise: string; weight: number; reps: number; }; function isTrainingSet(value: unknown): value is TrainingSet { if (!value || typeof value !== 'object') return false; const item = value as Partial<TrainingSet>; return typeof item.exercise === 'string' && typeof item.weight === 'number' && Number.isFinite(item.weight) && item.weight >= 0 && typeof item.reps === 'number' && Number.isInteger(item.reps) && item.reps > 0; }
В полном примере проверяются и остальные поля, и версия сохранённой структуры. Если данные несовместимы, код сообщает об этом, а не затирает историю пустым массивом.
Именно это стоит объяснять ассистенту при доработке: «Вот мой прежний исходник. Сохрани ключи хранилища и учти старый формат данных». Само наличие TypeScript от потери записей не спасает.
В настройках проекта есть «Обновить код». Там уже лежит сохранённый исходник. Можно исправить его прямо в редакторе или заменить целиком тем, что вернул ассистент.
Обновляется существующий проект, поэтому его хранилище остаётся. Если создать новый проект, у него будут свои отдельные данные.
На трекере это можно проверить совсем без героизма:
Добавить тестовый подход и дождаться сообщения о сохранении.
Закрыть проект и открыть снова.
В «Обновить код» поменять только заголовок My training log.
Сохранить, открыть проект и убедиться, что подход остался.
Такой цикл проверялся и на Android, и на iPhone. Отдельно на iPhone проверяли ошибочный TypeScript при обновлении: рабочая версия проекта и запись сохранились.
Синтаксическую ошибку Kapsula показывает до замены кода. Но если новый исходник синтаксически корректен и при этом сам удаляет данные, это уже другая проблема. Истории версий и автоматического отката пока нет. Перед большой переделкой рабочую копию лучше сохранить отдельно.
Если ошибка возникает при запуске, её можно скопировать для ИИ и вместе с исходником передать в свой чат. Автоматической отправки кода ассистенту нет — человек сам решает, что туда вставить.
У трекера есть отдых между подходами. В хранилище записывается время его окончания, а через kapsula.notify.schedule запрашивается системное уведомление. После возвращения остаток считается по часам, а не по числу срабатываний setInterval.
JavaScript при этом не становится фоновой службой. Доставкой занимается ОС, и на неё влияют разрешения, настройки уведомлений и режимы вроде «Не беспокоить». На Android принудительная остановка приложения тоже может помешать доставке.
Для начала стоит проверить эти 90 секунд на своём телефоне и убедиться, что уведомление приходит. А уже потом пользовался таймером. Подробно про эту часть писал в прошлой статье, здесь не буду пересказывать её целиком.
Следующим хочу попробовать небольшой React-компонент на JSX/TSX со встроенными зависимостями. Например, список покупок. Хочется проверить, удобно ли дорабатывать такой интерфейс вместе с ИИ, сколько занимает запуск и не слишком ли много приходится объяснять про ограничения.
Произвольный npm install в этот план не входит. У поддержки «любого React-проекта» совсем другой объём работы.
Следом хочу заняться файлами: выбором CSV, экспортом результата, системным «Поделиться». И отдельно — резервной копией кода вместе с данными проекта. Сейчас мы обсуждаем сохранность при обновлении, а пользователю ещё нужно как-то переносить свой инструмент на другой телефон.
Импорт проекта из нескольких файлов — следующая отдельная задача. Даже маленький инструмент довольно быстро обрастает CSS, картинками и вторым скриптом. Тут надо разбираться с путями, лимитами и изоляцией ресурсов.
Из функций телефона дальше рассматриваю камеру с вложениями и геолокацию по кнопке. Но каждую такую возможность хочется доводить на конкретном примере. Для камеры это мог бы быть домашний инвентарь с фотографиями, для геолокации — заметки о местах.
Python тоже есть в дальнейшей очереди, пока как исследование. Интересен сценарий с CSV и небольшими расчётами. Сначала нужно проверить размер среды, память, запуск и связь с SDK. Обещать срок выпуска здесь рано.
А рядом с новыми форматами остаётся менее эффектная работа: понятные ошибки, история изменений, возврат к рабочему коду. Меня как раз интересует, что из этого первым начинает мешать человеку, который сделал себе полезную тулзу и пользуется ею неделю.
Это направление следующих небольших обновлений. Перечисленные возможности ещё не входят в 0.5.
Хочется проверить эту идею на чужих задачах. Я со своими таймерами уже примерно понимаю, где неудобно. У человека, который делает дневник поездок или домашнюю бухгалтерию, список претензий будет совсем другой.
Если у вас уже есть маленькая программа, написанная с помощью ИИ, расскажите, что она делает и где живёт сейчас: в браузере, таблице, файле на ноутбуке или вообще осталась в истории чата. Что мешает пользоваться ею на телефоне?
И ещё вопрос про порядок развития. Что для вашей задачи полезнее первым: React, файлы с экспортом и backup или новая функция телефона? Например: «веду учёт домашних вещей, нужен импорт CSV и фото к записи». По такому описанию уже можно обсуждать решение и его цену. Просто список названий API помогает меньше.
Если пробовали похожий инструмент и в итоге забросили, тоже интересно почему. Может, для вашей задачи таблица оказалась удобнее. Это вполне полезный ответ.
Кто хочет проверить уже работающий вариант: здесь инструкция, исходник workout.ts и промпт. Встроенное демо бесплатное; для своих проектов нужен Pro — месячная подписка с семидневным пробным периодом для подходящих пользователей или разовая покупка навсегда. Условия показывает магазин.
Сейчас хочу пройти этот путь с 3–5 людьми: первый импорт, первая запись, изменение кода и повторное использование через несколько дней. Можно начать с описания задачи в комментариях. Личные данные и ключи из своих примеров, пожалуйста, уберите.