Verstak · Команда 20 июня 2026 · дневник разработки

Работа в четыре руки: дизайн-форк Ильи

Verstak пишу не я один. Параллельно работает Илья — дизайнер, который ведёт свой форк (verstak_rayner, в коммитах метятся как rayner). Я держу логику и инфраструктуру, он — внешний вид, UX-полировку и установщик. Это не теория «как делить работу», а реальная история про то, как два контрибьютора не наступают друг другу на ноги.

Зоны: src/ vs electron/

Грубое, но рабочее разделение:

Граница не идеальна (апдейтер живёт в electron/, а UX-часть его — в src/), но она задаёт «чья эта проблема по умолчанию». Когда зоны пересекаются, побеждает тот, у кого больше контекста по конкретному модулю.

Как мерджим без боли

Слияние форка Ильи (filatov/main) дало релизы 1.5.8, 1.5.15, 1.5.17. Конфликты были предсказуемые, и почти все — в двух местах:

  1. Changelog. Обе стороны добавляют записи в начало массива → конфликт почти гарантирован. Решение механическое: комбинируем оба набора записей, шов ],},{, без дублей. Это случилось дважды (1.5.15 и merge Ильи) — и оба раза лечится одинаково.
  1. Общие типы. Илья добавил streamStartedAt в SessionSnapshot — мой тест project-store-lifecycle упал, потому что его фикстура не знала про новое поле. Илья завернул fetchJson в {data, rateLimit} — мои вызовы release-notes читали сырой результат. Оба раза фикс — выровнять на новый контракт, а не откатывать чужое.

Правило, которое держит мир

Из регламента проекта, и я ему следую жёстко: не удалять чужой неиспользуемый код без явной просьбы. Когда я делал точечную чистку мёртвого кода, ts-prune показал кучу «неиспользуемых» экспортов — но часть из них была кодом Ильи, который он ещё доведёт. Я проверял каждый grep'ом перед удалением и трогал только то, что мёртво и моё. Чужой незавершённый код — не мусор, а work-in-progress.

Был и забавный момент с ts-prune: он флагнул useT, ToolCall, OnboardingWizard, ReviewButton, SkillPicker как неиспользуемые. Все они используются — через ре-экспорты и JSX. Линтер не видит JSX-использования и реэкспортов. Урок: автоматический «мёртвый код» — это гипотеза, а не приговор. Каждую проверяй руками.

Разделение, которое работает

Связка получилась честная: я не лезу в его пиксели, он не лезет в мою стейт-машину. Там, где надо состыковаться (новое поле в общем типе, новый IPC), — стыкуемся через контракт, а не через переписывание. Для этого и существуют TypeScript strict и тесты: они превращают «ой, я не знал, что ты это поменял» в красный билд за секунду.

→ Дальше: Удалённые проекты: правки прямо на сервере по SSH


← Все статьи · Скачать Verstak