This commit is contained in:
Михаил Капелько
2026-04-03 10:19:38 +03:00
parent 493863ae5a
commit d4028d2a0d
17 changed files with 1616 additions and 61 deletions

View File

@@ -1,93 +0,0 @@
Title: Что нам стоит на КМП построить?
URL: https://habr.com/ru/articles/989286/
Может ли Kotlin Multiplatform сократить трудозатраты при разработке одного продукта под несколько платформ? Мои вычисления говорят, что да, на 21%. Покажу это на примере своего хобби-проекта GitBudget для Android + iOS.
# Текущее положение дел
Одним из популярных способов разработки под несколько платформ является схема «одна платформа - одна команда разработки». Например, взглянем на известный мессенджер, заточенный под парковки. Некоторое время назад я словил следующую багу исчезновения сообщений:
<cut/>
<iframe src="https://kornerr.ru/vid/max-msg-disappear_2026-01-28.mp4"></iframe>
Как следует из видео, в ходе переписки с GigaChat у меня пропадали сообщения: на Android бага проявилась лишь раз (4-я секунда видеозаписи), на Web бага повторялась стабильно. Разное поведение на разных платформах свидетельствует о том, что продукт под разные платформы делают разные команды разработки. У каждой команды свой язык программирования, своя архитектура, свой процесс code review, свой уникальный набор порождаемых багов, своя команда тестирования, свой ФОТ и т.д..
Таким образом, чем больше мы дублируем в коде, тем больше мы вынуждены дублировать организационно. КМП может помочь сократить дублирование части кода, но, конечно, не полностью, а лишь на определённый процент. Каков этот процент? Посчитаем на примере моего хобби-проекта GitBudget.
# Обзор GitBudget
GitBudget - это крошечный хобби-проект для упрощения ведения собственных трат. На текущий момент нет истории трат, поддержки Git и прочего запланированного. Тем не менее, я пользуюсь этим приложением не первый месяц для упрощения ежедневного подсчёта двух важных для меня цифр:
1. Перерасход: Насколько на текущий день траты превышают план (бюджет)
2. Осталось ₽/д: Сколько можно потратить сегодня и в последующие дни текущей недели средств, чтобы не превысить недельный план (бюджет)
Углубляться в формулу и в архитектуру сейчас не буду, т.к. они не предмет данной статьи. Пытливый читатель всё это найдёт сам [на GitHub](https://github.com/kornerr/git-budget).
Ознакомимся с внешним видом приложения на Android и iOS:
![Android, iOS](https://habrastorage.org/webt/e2/bz/f5/e2bzf5lblg0xsydakc88zb5a_hu.jpeg)
Никакой фантастики в UI/UX нет, все элементы интерфейса стандартные (и даже не везде выровненные). Использование приложения на текущий момент сводится к трём действиям пользователя:
1. Вставить из буфера обмена траты за вчера (Spent)
2. Вставить из буфера обмена остаток баланса на вчерашний день (Morning balance)
3. Скопировать итоговый расчёт в буфер обмена (Result)
# Трудозатраты на разработку
Для удобства подсчёта условимся о разделении всего кода приложения на три группы:
| № | Группа | Пример | Файлы Android | Файлы iOS |
| --- | --- | --- | --- | --- |
| 1 | UI | Jetpack Compose, SwiftUI | MainActivity.kt, VM.kt | AppView.swift, VM.swift |
| 2 | Платформа | ClipboardManager, UIPasteboard | budget.kt, main.kt, other-android.kt, registerOneliners.kt | budget.swift, cld-ios.swift, other-ios.swift |
| 3 | Логика | budgetShouldResetMorningBalance | budgetFun.kt, entities.yml | budgetFun.kt, entities.yml |
КМП в GitBudget я использую лишь для логики, а UI и платформенный код нативные. Почему так? Потому что логика полностью под моим контролем, она обновляется по моему усмотрению. С UI и платформенным кодом ситуация иная - это собственность корпораций Apple и Google, они задают правила игры и обновляют UI с платформой по своему усмотрению (например, придумывают [Liquid Glass](https://habr.com/ru/articles/956116/), от которого не увернуться).
Считать будем два объективных показателя - количество строк кода и время, затраченное на реализацию какой-либо функциональности. На каждый из этих показателей посмотрим в разрезе вышеобозначенных трёх групп - UI, платформа, логика - и двух платформ - Android, iOS.
## Первый показатель: Количество строк кода
| № | Платформа | Всего | UI | Платформа | Логика |
| --- | --- | --- | --- | --- | --- |
| 1 | Android | 692 | 160 (23%) | 221 (32%) | 311 (45%) |
| 2 | iOS | 540 | 90 (16%) | 139 (26%) | 311 (58%) |
**Вывод-1**: 311 строк логики для iOS я **не писал повторно** благодаря КМП, это **58%** всего кода iOS.
**Вывод-2**: 311 ненаписанных повторно строк кода для iOS с точки зрения обеих платформ (692 + 540 = 1232) означают, что **25%** кода всего проекта я не писал повторно.
## Второй показатель: Время реализации функциональности
Под запись я добавил кнопку `Paste` для поля ввода `Morning balance` как для Android:
<iframe src="https://kornerr.ru/vid/git-budget-balance-android_800_2026-01-28.mp4"></iframe>
Так и для iOS:
<iframe src="https://kornerr.ru/vid/git-budget-balance-ios_800_2026-01-28.mp4"></iframe>
В итоге получились такие цифры:
| № | Платформа | Тип реализация | Особенности реализации | Время |
| --- | --- | --- | --- | --- |
| 1 | Android | Первичная | Создаём новую функциональность, которой не было, собираем почти все грабли | 17:34 |
| 2 | iOS | Вторичная | Подключаем готовую логику, дописываем лишь UI, граблей практически нет | 07:33 (43%) |
**Вывод-3**: Повторение функциональности на iOS с готовой логикой заняло на **57% меньше времени**, т.е. произошло **в 2 раза быстрее**
**Вывод-4**: Если принять, что без КМП функциональность на каждой из двух платформ делали бы в сумме 17:34 * 2 = 35:08 минут, то сэкономленные 10 минут при повторении функциональности для iOS означают, что для всего проекта я **сэкономил 21% времени**.
# Выводы
Итак, экономия с КМП в цифрах выглядит так:
1. Количество строк для iOS снизилось на **58%**
2. Суммарно количество строк кода по всему проекту снизилось на **25%**
3. Время, необходимое на повторение функциональности для iOS, снизилось на **57%**
4. Суммарно затраченное время по всему проекту на реализацию функциональности снизилось на **21%** (эту цифру я использовал в самом начале статьи)
# Вопросы читателю
1. Суммарная экономия в 21% по времени проекта - это много или мало?
2. Окупает ли экономия в 21% явно не однодневный переход команд на новый процесс разработки?
3. Насколько важен синхронный выпуск функциональности на обе платформы, причём работающей одинаково на каждой платформе?

View File

@@ -1,22 +0,0 @@
Title: КМП как альтернатива сокращению
Кому: Зуев Игорь, Корнюшин Пётр, Сухов Сергей, Терентьев Евгений, Петров Виктор
Привет, коллеги,
завтра состоится серия созвонов по поводу сокращения троих человек из
команды iOS Connect.
У меня есть встречное предложение по повышению эффективности
команд разработки с помощью Kotlin Multiplatform. Предлагаю перевести
сокращаемых троих человек в новую команду КМП, которую я готов возглавить
без отрыва от руководства командой iOS Connect.
КМП может сэкономить около 21% времени разработки, подробно я это расписал
в статье на Хабре: https://habr.com/ru/articles/989286/
Если предложение заинтересовало, буду рад обсудить детали данной спецоперации.
С уважением,
Михаил.

View File

@@ -1,3 +1,446 @@
02.04: 35
* прочитать предыдующую статью
* написать короткую статью за раз
* перевести на английский
01.04: 60
* проверить замену hwSet с template на std::any
быстро не удалось
итог: оставить шаблоны
* генерить hwSet для .h
31.03: 45
* fobjContexts -> other.contextIds
* генерить F
30.03: 40
* генерить расширения
registerCallbackC
* ввести rawCPPSDK
* оставить в tmp.kt лишь временное ручное (setupComponentDebugging)
29.03: 25
* генериь конвертацию
28.03: 35
* скинуть Всеволоду ЗС
https://github.com/OGStudio/kotlin-dialect/pull/6
* определиться с форматом конвертации
нужно ли ввести тип kotlincpp?
или лучше отдельный файл генерить?
чем больше файлов, тем как-будто хуже в среднем
тогда, выходит, тип нужен новый
sdkc++?
итого:
ввести sdkc++ или c++sdk
* написать kd.yml желаемый
27.03: 55
* дополнить пример kd example кнопкой
* создать видеодемонстрацию примера
26.03: 30
* перенести тело hwSet в KT внутри класса API
25.03: 40
* сделать заготовку oneliners
* сделать обёртку над KDController
* сделать обёртку над KDContext
* продумать решение вопроса с processOneliners
статичные функции в статичном компоненте!
24.03: 35
* линковать sdk-mac в ver-mac
* сделать заготовку компонента main
23.03: 50
* подготовить заготовку Qt HW для ver-mac-x64
* сделать заготовку sdk-mac-x64
22.03: 60
* установить AS на W10
* добавить в README инструкции для запуска примера
* переиначить ссылку на KD
сделать через клон
иначе это неподъёмно будет для пользоателей примера
никто не догадается сделать клон
когда в примере была ссылка на родителя
* оформить ЗС
https://github.com/OGStudio/kotlin-dialect/pull/4
* влить ЗС
21.03: 60
* убрать пустые файлы из ver-android
* переименовать в example/helloworld
* убрать лишние импорты из MainActivity
* подготовить компоненту main
* сгенерить kd.kt
* заигнорить/удалить ignore.kd.kt
* сделать отображение окна через шуд
* сделать отображение "hello world" через шуд
20.03: 70
* подготовить проект ver-android
19.03: 35
* создать kotlin-dialect-hello-world на Android, десктоп, iOS, web для винды
создать в репе kotlin-dialect?
добавить тег kotlin-dialect
нет, лучше отдельно, т.к. тогда можно будет форкать!
хотя форкать - это как-будто не самое критичное
это ведь скорее examples/helloworld
сильно ли важно форкать? как-будто это сильно второстепенно
ведь можно скопировать, и всё
итог: не надо делать отдельную репу, хватит текущей
* KD: README
убрать --out
уточнить: Klin, a translator to convert YML to Kotlin
-> to Kotlin and Swift
* игнорировать kd.kt, emb64.kt
* установить зависимости новые
brew install gradle
* поднять gradle до 9.3.1
чтобы собиралось с openjdk 25
* README: добавить building prerequisites
* собрать
18.03: 60
* установить Android Studio Panda 2
17.03: 30
* переместить файлы из bootcamp на второй комп
* удалить Windows
* установить Linux Mint
16.03: 40
* скачать Linux Mint
15.03: 30
* заполнить CHANGELOG.md за ЗС-2
забыл про 2.1
* поднять версию до 3.0
я же отменяю --out, это breaking change
* заполнить CHANGELOG.md про 3.0
* оформить ЗС
https://github.com/OGStudio/kotlin-dialect/pull/3
* влить ЗС
* tag 3.0
14.03: 40
* встроить src/*.swift
embSwift64?
embKotlin64?
* добавить embSwift64 в outputSwift
* генерить F в Swift (проверить генерацию F)
struct F {
static let didClickReload = F.shared.didClickReload??
}
* проверить использование F в KOM
всё работает, не надо придумывать FF
* применить обновлённую версию klin для генерации
kom
удалить cld-ios.swift
* проверить работоспособность в KOM
лишь затем вливать
всё работает
13.03: 55
* сделать цикличное сохранение по всем output paths
типы
jsexport
kotlin
swift
реагировать на смену currentOutputPathId для задания c.outputFile и c.outputFileContents
т.е. два шуда надо обновить
а затем в эффектах завязаться на более поздний
* сохранять файлы
* применить обновлённую версию klin для генерации
самого klin
тесты kd
* удалить шаг stripTestKDJS
* определиться насчёт 'import iv'
где его указывать?
swift: ?
да, это самое простое
* подготовить исходники KDController ext и registerOneliners
* проверить сборку kom ios сейчас
работает
с тестовым ручным struct FF и экспортированным F.shared из KT
* YML: поддержать 'swift:'
чтобы 'import iv' указать
* добавить rawSwift в outputSwift
12.03: 40
* ввести appShouldResetInputFileDir
* сделать запись одного первого output path
11.03: 45
* ввести outputKotlin
просто убрать import js and @JsExport
делать на результат outputJSExport
* генерить kotlin
без @JsExport
* генерить F obj с @JsExport для type: jsexport
хотя можно jsexport по умолчанию везде делать как-будто
* генерить js
оставлять @JsExport
* удалить appShouldParseOutputFilePath
* удалить --out
в т.ч. сообщение-помощь при запуске без аргументов
* переиначить outputPaths
* ввести заготовочную генерацию outputSwift
чтобы просто было что-то в файле по итогу сохранения
10.03: 25
* ограничить debug output
* ввести outputJSExport
09.03: 50
* подготовить yml
√ для klin
√ для klin test
√ для kom
* разбирать output
* ввести util/debug-klin
запуск не dist/app.js, а из BUILD_DIR
08.03: 40
* оформить fexp
пусть пока только и для JVM
но оно же есть
* влить
* ОБНОВИТЬ сертификат kornerr.ru
чтобы починить статью КМП
а затем скинуть офер Александру Ноксону
сделать README в vps/cert
всё-таки надо
а то за квартал забываю
07.03: 50
* разделить klin/kd.yml на два
js: в klin
jvm: в test
* разделить скрипт util/run-klin-dbg на build и dist
чтобы dist не перезатирал ничего автоматом
ибо dist редко нужно делать
а build - постоянно
run - убрал совсем, ибо это на самом деле build лишь
* сократить вывод максимальный отладочный до 50
* вынести расчёты FObj в fobj.kt
* убрать генерацию полей F структур, надо ведь только для контекстов генерить
06.03: 45
* (неудачно) попытаться генерить
* продумать уместность fexp как есть
возможно, стоит просто влить как есть
даже несмотря на то, что нужно ещё доработать для iOS
ибо тут сильное усложнение идёт
может, это усложнение стоит провести отдельными компонентами?
поэтому разумно закомитить текущие результаты по F
хотя и неполные
итог: надо влить
05.03: 40
* KD: продумать формат YML для генерации нужных обёрток в языке назначения
swift или ios?
outputs:
ver-android:
ver-ios:
sdk-ios:
ver-browser?nodejs?js?
* разбирать outputPaths
04.03: 40
* опубликовать статьи
03.03: 45
* прочитать предыдующую статью
* обновить в январской статье EN ссылку на Reddit
* написать заготовку статьи на Русском и Английском
02.03: 50
* добавить F Obj в output kd.kt
* добавить F.none
* объединить все файлы node.js в один файл js?
просто засунуть не помогло
* изучить, можно ли npx без загрузки из сети запускать
ибо npx удобнее всего
но без сети по умолчанию не работает
не нашёл такого
* убрать дублирование полей
* описать в README использование
01.03: 35
* собрать все поля всех контекстов
* сделать геренацию полей F по аналогии со спецструктурой YML
28.02: 40
* переместить kd.yml от klin внутрь klin
ведь у тестов будет свой kd.yml
чтобы не было путаницы
* подготовить kd.yml для тестов
* исправить запуск тестов
он как раз про то, что генерить надо разные варианты тех же файлов
в частности для тестов надо без @JsExport сделать
или мне нужны два разных вид файлов в src
одни c JsExport
другие - без
пока решил @JsExport решать на уровне скриптов util
ибо разруливать сейчас это через YML и Klin выглядит сильно лишним
27.02: 45
* поддержать isDbg
критически важно для переключения флага на стороне iOS БЕЗ пересборки KMP
* ввести outputEntityContents
* ввести outputKDContents
удалять package org.opengamestudio и import kotlin.js.JsExport
хотя если я их удаляю, то зачем мне их там размещать?
для кого-то, кто будет по одному файлу таскать?
никому это не надо
тогда легче сразу убрать ненужное, в т.ч. copyright
прям сейчас не удалить, ибо я пока ещё прямо ссылаюсь
так что надо удалять всё-таки
* генерить файлы KDController/Context/registerOneliners сразу в kd.kt
убрать симлинки на оригиналы
26.02: 30
* генерить b64 без package и import для каждого файла KD
хотя именно b64 можно генерить без предварительных правок
а вот после распаковки b64 правки как раз уместнее, ибо ближе к телу
* создать файл c package для хранения переменной с b64
* размещать b64 в коде
25.02: 35
* обдумать путаницу в названиях klin.kt/klin.yml
ведь проект называется Kotlin Dialect
а всё оказывается в непонятном файлы klin.kt
как-будто kd.yml и kd.kt гораздо яснее и естественнее
итог: переименовать всё в kd
хотя сам бинарь может остаться как раз klin
вот файлы уже kd
* переименовать файлы в kd
транслятор остаётся с названием klin
* сохранять содержимое KDController/Context/registerOneliners как Base64
* ввести шаги в run-klin-dbg
22.02: 20
* добавить кодирование в/из Base64
21.02: 55
* создать новую репу kotlin-dialect
* обновить README
* обновить CHANGELOG.md
* отполировать перед влитием
F.field - потом будет
убрать object F
* оформить ЗС
* влить ЗС
20.02: 50
* восстановить чтение файла
* передать didLaunch
* восстановить запись файла
* восстановить прежнюю генерацию
с учётом @JsExport
* восстановить isDbg?
как-будто нет смысла
убрал
* перевести на Node.js
* выяснить формат F
проверить доступность как в Kt, так и в JS
object F { val field = ... } работает
доступ везде есть как F.field
19.02: 35
* передавать аргументы
* задать аргументы временно внутри run-klin-dbg
передал klin.yml и klin.kt
18.02: 45
* переименовать инструмент в kd?
klin как-то не вяжется
с другой стороны, kd уже присуствует в npx
тогда фиг туда добавить этот очень важный инструмент
итог: оставляем klin
* временно ввести cld/entities для генерации Context?
или просто файл entities.kt взять как есть?
тогда и запускать не надо будет ничего
и даже можно будет довести до состояния CLD
после чего уже самого себя использовать для генерации!
итог: пока просто скопировать файлы
* скопировать большинство файлов
17.02: 35
* выбрать имя генератора
klin
и город в МО
и сокращение от kotlin
* переименовать generator в klin
16.02: 40
* починить сборку
проблема была в настройке settings
* выводить hw в консоль
проблема была в том, что не в src лежали исходники
* создать helloworld/
тут уже будут ver-nodejs, ver-android, ver-ios, ver-macos-x64/arm64, ver-linux-x64, ver-windows-x64
15.02: 45
* обдумать форму generator
тут будет лишь ver-nodejs
тогда, возможно, даже и смысла в ver-nodejs нет
да, смысла нет, это слишком важный инструмент, чтобы иметь несколько вариаций
хотя в будущем может появиться веб-интерфейс
да и другие версии
просто потому что могут
плюс это будет этаким стандартным подходом иметь ver-платформа везде
* создать заготовку проекта generator
14.02: 35
* продумать структуру проекта KD

View File

@@ -1,8 +1,21 @@
Title: ИИ является инструментом копирования, который не даёт ускорения
AltTitle: Практический опыт вайб-кодинга от синьора
ознакомитья с другой статьёй про AI
https://kean.blog/post/experiencing-claude-code
возможно, толковая
статья-треш про крутой Cursor
https://habr.com/ru/amp/publications/908750/
чел 15 лет не прогал, вот она аудитория
плюсы:
можно не знать проект
и вот тут Cursor помогает сократить время
но возникает и вопрос, кто именно пишет хвалебные отзывы
тот, кто не хочет разбираться с кодом из принципа?
хорошо описывает стуртуру кода и шаблоны используемые
хоть сам Cursor и не умеет им следовать
можно узнать о новых спецификаторах для Compose
@@ -16,6 +29,11 @@
но плохо представляешь себе код
минусы:
видос, когда не смог добавить таб
на вопрос
Вопрос к тебе на засыпку. По твоим представлениям, должен ли джун уметь делать такую задачу: Добавить новую вкладку в таббар с какой-нибудь иконкой и названием, а при её выборе отображать заглушку "Hello, world"?
коллега ответил
Это должно уметь делать задолго до того, как стать джуном
часто ошибается и пишет код не туда, т.е. нарушает архитектуру
приходится постоянно уточнять мысль вместо того, чтобы написать сразу туда
приходится и постоянно делать review/проверку
@@ -96,7 +114,22 @@
за 5 минут напишет ИИ? Или за 5 минут не напишет? А за 50 минут разве
тоже не напишет? А за 50 дней тоже не напишет? Вопросы, вопросы...
Если бы ИИ действительно экономил время, то почему многие инфоцыгане,
втюхивающие ИИ, просто бы не купили условно 10 мощных компов
или 10 лицензий, подписали бы контракт с условным Сбером или ВТБ
и тупо, если ИИ экономит условно 50% времени, то почему бы они
просто не предолжили фирмам-гигантам те же услуги со скидкой 50%?
Почему если ИИ такой крутой и заменяет или дополняет или ускоряет
программиста, то меньше программисты не получают? А они получают
всё больше и больше?
Не сходится что-то
ИИ как элетромобиль! Тоже предрекали десятилетия назад, что будет огого
и где в итоге огого? Да, они ездят, но типа огого нет. Появился
ещё один вид автомобильно. Принцип совершенно не изменился. Революции
тоже что-то не видно. То же и с ИИ - это просто другой инструмент,
который, если посчитать, как я посчитал, ничего не экономит. А если
посчитать углеродный след или стоимость лицензии, то с ИИ даже
и невыгодно работать выходит. Синьору.
лиды:
из статьи про KMP сделать ссыку на AI

View File

@@ -1,23 +1,125 @@
НАДО:
* создать generator
тут будет лишь ver-nodejs
тогда, возможно, даже и смысла в ver-nodejs нет
да, смысла нет, это слишком важный инструмент, чтобы иметь несколько вариаций
* создать helloworld/
тут уже будут ver-nodejs, ver-android, ver-ios, ver-macos-x64/arm64, ver-linux-x64, ver-windows-x64
* отполировать
* влить ЗС
создать сразу новый на май
* опубликовать
сайт
VK
* сообщить Ване Kai SD
далее сначала нужно перевести на nodejs
затем уже наварганить генерацию обёрток для C++
* генерить hwSet для .cpp
* генерить EffectRegistry
* генерить Context
* генерить API
KD = Redux in Kotlin for Android, iOS, Desktop, and Browser
* доработать генератор
чтобы KOM заработал без KT.h/cpp
дублировать руками KT.h/cpp в KD example не нужно
ибо бессмысленно
генерить по частям/файлам
чтобы отщипывать по частям из KOM
сделать в KOM ветку новую
* генерить для C++
и функций в KT для получения готовых экземпляров всего
сделать геренацию полей F по аналогии со спецструктурой YML
т.е. генерить спецструктуру со статическими полями?
это после C++ генерации станет ясно, как лучше оформить
* обновить version
src files say 2.0.0
wrong
must be 3.1.0
when C++ gen is ready
* обновить README
* оформить ЗС
https://github.com/OGStudio/kotlin-dialect/pull/7
* влить ЗС
* сделать Main статичной компонентой
* сделать текст на основе логики руками
* выставить VM.cpp:_mainIsVisible = false
* подготовить заготовку ver-windows-x64
* helloworld readme
показать и рассказать про выполнение команд
./util/gen-kd
и прочие
* собрать на W10
* удалить gradlew.bat
если в MSYS2 достаточно gradlew
* оформить ЗС
https://github.com/OGStudio/kotlin-dialect/pull/5
* влить
* проверить пересоздание лишнее при перевороте устройства Android
* доработать пример ver-android
поле ввода
кнопка
загрузки
вставки URL фиксированного
текст
картинка
загружать картинку по URL из поля ввода
* mainViewIsVisible: задать false по умолчанию
* поправить запуск android HW на W10?
спрошу у Всеволода
* переключить версию Android на KD
* переключить версию iOS на KD
* ввести budgetSet() вместо budgetCtrl().set()
* ввести setupDebugging с short str
* использовать F
* ввести budgetProto для регистрации шудов и неповторения кода компонента
* сделать веб-версию
* описать в README все три версии GB
* описать зависимости mac (brew install node) и linux
* поднять версию
если KD не менялось, то 3.0.1
ибо после смены gradle на 9.3.1 поменялось содержимое dist/stdlib
хоть оно и несущественно, но это уже изменение третьей цифры
хотя если будем генерить для C++
то это уже 3.1, ибо новое без breaking change
* tag next version
* KD: переименовать app.js в klin.js
иначе в dist вообще не ясно, что запускать
либо dist в klin переименовать?
dist/klin/app.js?
* починить --help
* KD: линтер сделать проверки упорядоченности по имени названий сущностей
* Klin: сообщать о несущестующем пути для output
* отдельно сделать версию CLDController для cinterop
ибо по умолчанию не компилится не для C++
либо это отдельный файл должен быть в CLD
формат надо обдумать
* префикс JS делать перед сущностями инструментом?
сущности - можно
а вот функции-то не выйдет
так что надо самому всё равно прописывать JS
либо исходные файлы
хотя это такое себе
* принимать импорты-замены
чтобы org.opengamestudio заменять на другое
* оформить ЗС
https://github.com/OGStudio/kotlin-dialect/pull/13
* влить ЗС