Это мотивационная статья для тех, кто хочет сделать что-то своё, но не знает с чего начать. В потоке информации про нейросети сложно понять реальные возможности — я покажу на конкретном примере как Claude Code помог мне сделать macOS-приложение без опыта в Swift.
Предыстория: техника Pomodoro и мои проблемы
Техника Pomodoro — метод управления временем: 25 минут работы, 5 минут отдыха.
У меня были классические проблемы:
Сложность начать рутину — классическая прокрастинация, "нужно хотя бы начать"
Гиперфокус — когда не делаешь паузы и слишком погружаешься, в итоге становишься выжатым как лимон
Как следствие необходимость переключения контекста — нужно принудительно отдохнуть от компьютера (режим блокировки)
Я искал простой таймер для macOS — чтобы он решал одну задачу и не был перегружен лишним функционалом и интерфейсом.
Первый таймер: Pomodoro.me
Плюсы:
Таймер в menu bar — быстрый контроль времени
При завершении таймера появляется окно поверх всех окон
Предлагает действия: остановить, начать отдых/работу
Самое полезное — добавить время к текущему интервалу ("ну ещё 5 минуточек!!!")

Минусы:
После добавления времени таймер показывает 00:00
Повторного уведомления нет
Проект по факту заброшен
Попользовавшись им какое-то время, я начал искать альтернативы.
Находка: TomatoBar
Нашёл open source таймер TomatoBar.
Проблемы: слишком простой, проект заброшен (последний коммит в 2023), неотвеченные Pull Request'ы.
Поковырявшись в репозитории, увидел популярный форк от AuroraWright, который собрал все PR в себя (последний коммит 6 месяцев назад).
Он был гораздо интереснее, но оставалась главная проблема: таймер не ставился на паузу в конце события, оставаясь жёстко привязанным к заданному времени.
Проблема техники Pomodoro: негибкость
По факту достаточно сложно пользоваться жестким временным интервалом, ведь обычно нужно какое-то время, чтобы завершить текущее действие. Или если поймал поток — нельзя просто взять и прекратить задачу.
Нельзя просто взять и прекратить задачу

Но раз это open source — можно же взять и добавить функционал добавления времени как в Pomodoro.me!
Взять и перенести

Попытка №1: Дизассемблер
От разработки на macOS и Swift я очень далёк. Решил вспомнить школьное время — закинул Pomodoro.me в дизассемблер чтобы посмотреть как именно создаются окна.
Что нашёл: окно уведомления вызвается в режиме screensaver и поэтому отображается поверх всех окон, что мне и нужно было, нашёл это в документации по swift по ключевым словам, запутался в объектах и функциях создания окна. Дальше ковыряться уже желания не было. Забил. Но потом я использовал Claude Code в помощи с дизассемблированием в другом проекте.
Попытка №2: Вайбкодинг
К этому моменту я уже пользовался для разработки на PHP сначала Claude Desktop, а потом Claude Code. И ко мне пришёл инсайт:
"Ведь я же могу дать задачу клауду чтобы он добавил мне этот функционал!"
Сделал форк, и начал писать промты в таком стиле:
Вот тебе репозиторий TomatoBar
Вот скриншоты уведомлений из Pomodoro.me (удобно что можно скришоты прямо в CLI вставлять)
Сделай мне также
Добавь режим паузы
Что получилось: что нужно использовать screensaver для окна он сам определил, добавил опции в настройки, что-то даже заработало. Но таймер работал не совсем так как я хотел, а после очередных "улучшалок" приложение стало крашиться при запуске таймера.
Понял что подход нужно менять. Нужно реализовывать фичи step-by-step.
Сохранил все изменения в отдельный бранч и начал заново. Claude в режиме "сделай всё сразу" может добавить своих "улучшений" которые ты не просил и которые всё ломают. И нужно контролировать, понимает ли он контекст того что он изменяет.
Отступление про pet-проекты
Помимо того что я решал задачу с личным инструментом для рабочего окружения, выполнялась общая рекомендация для pet-проектов — прокачивать с помощью них навыки.
Здесь я прокачал работу с git, что лучше фиксировать изменения отдельными коммитами вместо того чтобы пытаться сделать сразу всё. Это отражало и в итоге помогло решить мою личную проблему с многозадачностью, когда в голове много мыслей\задач\проектов, постоянное переключение между ними и попытка делать всё сразу (привет СДВГ).
Попытка №3: Он вам не вайбкодинг!
Режимы работы с Claude Code
Изначально я использовал просто Claude — прислать код, попросить изменить, скопировать обратно. Потом перешёл на Claude Code + GitHub Desktop, чтобы видеть какой именно код меняется.
Сначала я использую режим plan mode и обсуждаю что именно нужно сделать, архитектуру и корректирую план действий.
Потом я использую режим bypassPermissions и Claude применяет все изменения сразу, сам ищет и запрашивает всю информацию. В целом в последних обновлениях он выходит в режим планирования в том числе и через bypassPermissions и не приходится подтвеждать каждые попытки считать файл или найти что-то в интернете.
Далее я смотрю результат в GitHub Desktop и смотрю что изменилось в коде (по мне это удобнее чем постоянно принимать изменения через пул реквесты, тут можно сразу принять решения принять код, отказаться, сделать коммиты более чистыми).
Процесс разработки
Выписал список фич, стал делать поэтапно.
Когда смотрел что Claude меняет, понимал что нужно менять архитектуру. Делал рефакторинг.
Переделал State Machine: добавил длинный отдых для полного соответствия типам событий, добавил нужные события для режимов выбора пользователем.
State Machine Transition Table
/*
* State Machine Transition Table
*
* Events:
* - startStop: start/stop timer
* - confirmedNext: user confirmed transition to next interval
* - skipEvent: skip current interval
* - intervalCompleted: timer reached 0 (fact)
* → auto-transition if shouldAutoTransition() == true
* → stay in state if shouldAutoTransition() == false (pause for user choice)
* - sessionCompleted: session finished (based on stopAfter setting)
*
* From: idle
* → work (startStop, if startWith = work)
* → shortRest (startStop, if startWith = rest)
*
* From: work
* → shortRest (intervalCompleted/confirmedNext, if currentWorkInterval < workIntervalsInSet)
* → longRest (intervalCompleted/confirmedNext, if currentWorkInterval >= workIntervalsInSet)
* → idle (sessionCompleted if sessionStopAfter = work, OR startStop)
*
* From: shortRest
* → work (intervalCompleted/confirmedNext)
* → idle (sessionCompleted if sessionStopAfter = shortRest, OR startStop)
*
* From: longRest
* → work (intervalCompleted/confirmedNext resets currentWorkInterval)
* → idle (sessionCompleted if sessionStopAfter = longRest, OR startStop)
*/
И так на каждом этапе приходилось продумывать архитектуру и рефакторить — для простого и удобного внедрения своих хотелок без костылей.
Было \ Стало

В конце концов переименовал многие переменные для консистентности и упорядочил языковые файлы.
Нейминг и брендинг
Сначала хотел сделать Pull Request в форк AuroraWright. Потом понял, что во-первых проще самому управлять изменениями, а во вторых этот форк очень непросто найти и нужно делать отдельный проект.
Название: TomoBar
Выбрал TomoBar (и домен tomo.bar) — отсылка к "Tomato" + "Bar" (menu bar), лаконичное, не привязано напрямую к слову или переводу "помидор\томат", ну и подходящий домен был свободен.
Иконка: не простой помидор!
Когда смотрел App Store, видел что у всех таймеров всё однотипно: помидор, часы, таймер, фокус, стрела. Хотелось что-то иное.
В поиске по картинкам наткнулся на tomato monster в стиле pixel art, купил со стока, попросил ChatGPT нарисовать современную версию используя его как референс и то, что получилось, попросил дорисовать в стиле монстров из Футурамы.

Также выяснилось что в macOS 26 пошли обязательные требования к наличию суперэллипса, поэтому я воспользовался Icon Composer и перешел на XCode 26 (совсем не хотелось заморачиваться с генерацией иконок) и вручную подкорректировал пропорции чтобы лого умещался в суперэллипс.
Я также пробовал другие нейросети для генерации, но то что получилось выше — результат случайности. Так как сгенерировать похожее у меня больше не получилось.
Midjourney tomato monster

Режим тестирования и GitHub Actions
Собрать релиз через GitHub Workflow из оригинального TomatoBar не получалось. А в GitHub Workflows я такой же ноль, как и в Swift.
Моя любимая ситуация, когда мы можем точно описать требуемый результат и загнать нейросеть искать решение.
Описал поэтапный алгоритм действий для тестирования сборки, дал доступы через gh, также включил режим bypassPermissions, сказал повторять и искать решение проблемы пока сборка не пройдёт. И на почту стали приходить письма о неуспешных билдах...
В итоге решение он нашёл, нужно было на более новой версии xcode использовать пустышку вместо вызова codesign.
Code Signing: боль macOS разработки
Потом я купил Apple Developer Account. Для распространения вне App Store достаточно подписать и нотаризовать приложение с одним Developer сертификатом.
Для публикации в App Store нужно завести ещё один сертификат. Подписать и отправить приложение через XCode GUI было достаточно просто.
Но чтобы всё это запустить через Github Actions понадобился ещё один сертификат, профиль и куча танцев с бубнами, потому что где-то нужно было удалить подпись у сторонних компонентов, где то подписать компонент, где-то не подписывать. В итоге на автоматическую сборку и отправку в App Store было потрачено много времени и тестов.
Нужно больше сертификатов

Баг в Claude Code: проблема с импортом
В локальных настройках Claude у меня указано общаться со мной и делать коммиты на русском.
Но так как проект open source, я добавил в .claude/CLAUDE.md инструкцию загружать локальный файл через @, где написал что нужно писать всё на английском.
Но в каждом новом чате (в том числе после compacting) Claude упорно делал комментарии на русском. Каждый раз писал ему "нужно на английском". Надоело, решил выяснить почему не следует инструкциям. Оказалось — он вообще не загружал этот файл.
После тестирования выяснил, что импорт через @ работает только из корневого CLAUDE.md, хотя в документации написано что можно использовать оба файла, включая .claude/CLAUDE.md.
Эмоции
Я не скажу что всё шло гладко. Таких ситуаций была не одна:
Почему???

Всё равно общение в чате воспринимаешь как общение с человеком, и по существу нейросеть копирует этот стиль общения в ответах. Поэтому когда что-то идёт не так — эмоции те же что и при работе с коллегами.
Результат: TomoBar
Получился таймер с нужным подходящим для меня функционалом, который позволяет отойти от жёсткой парадигмы техники помодоро в сторону большей гибкости. Также копаясь в других форках TomatoBar я нашел функционал полной блокировки экрана, при котором нужно полностью уйти от компьютера и добавил его тоже (от перезагрузки он конечно не спасет, но свою функцию выполняет).
Выводы
Для хорошего результата нужно максимально точно и детально прописать все требования к продукту, продумать архитектуру, продумать тестирование. Но это уже не вайб-кодинг, это просто разработка с помощью нейросетей. В которой нужно понимать что хочешь, как ты хочешь и делает ли нейросеть то что тебе нужно. Да, это гораздо быстрее, чем делать всё самостоятельно и можно не углубляться в изучение языка, но всё-равно нужно понимать общие аспекты разработки.