design: макеты 15 экранов + принципы Android + откуда взят код

- design/mockups/ — 15 макетов (одно состояние = один файл), из /tmp перенесены в репо
- design/screenshots/ — те же экраны PNG
- design/PRINCIPLES.md — принципы: что берём у десктопа, что на телефоне иначе
- design/BORROW.md — что откуда: ядро (Nexus), тема (десктопный макет), отрисовка Markdown (ai/assistent)
- design/gen_mockups.py — генератор макетов, путь вывода теперь рядом с ним
- README: разделы «Принципы» и «Откуда код» со ссылками
This commit is contained in:
2026-09-20 13:59:22 +03:00
parent ef4804a477
commit d5aa844fa0
36 changed files with 6013 additions and 0 deletions
+147
View File
@@ -0,0 +1,147 @@
# Что откуда взято
**Правило простое:** чужое не переписываем заново, а берём и говорим, откуда
взяли. Ниже по каждому куску: откуда, что именно, и что с ним делать на телефоне.
| Куски кода | Откуда | Состояние |
|---|---|---|
| Ядро агента | `subochev/agentik` → Nexus `caffeine` | **подключено** |
| Скелет приложения, тема | свой, в этом репозитории | **есть** |
| Отрисовка Markdown | `ai/assistent` | **ещё не перенесена** |
| Макеты экранов | свои, из десктопного дизайна | **лежат в `design/`** |
---
## 1. Ядро агента — берём из Nexus
**Откуда:** репозиторий `https://git.binom.pw/subochev/agentik`, модуль `client`.
Библиотека публикуется в Nexus (репозиторий `caffeine`) — **руками не публикуем**,
публикует CI/CD по релизу.
**Что берём:** `pw.binom.agentik:client`, версия задана в
`gradle/libs.versions.toml` (`agentik = "5"`).
**Что важно знать про неё:** движок библиотека **не задаёт** — он передаётся
снаружи. На Android это OkHttp:
```kotlin
agentikHttpClient(OkHttp, token) { ... } // ktor-client-okhttp уже подключён
```
Это не наша выдумка, а условие задачи: библиотека не должна тянуть на телефон
чужой движок. Своя авторизация у agentik — **отдельная**, не копия A2A.
## 2. Скелет приложения и тема — своё
`app/src/main/kotlin/pw/binom/agentik/android/` — написано в этом репозитории,
коммит `ef4804a` («Скелет Android-клиента agentik»).
**Тема** (`ui/theme/Color.kt`, `Theme.kt`) — цвета **согласованы с десктопным
клиентом**: они пришли из одобренного десктопного макета
`agentik-desktop/approved/001-sidebar-utility.html`. Значения: фон `#121218`,
панель `#17212B`, акцент `#6AB2F2`, текст `#EBEBEB`, приглушённый `#768C9E`,
ошибка `#EC3942`.
Экраны обязаны читать `MaterialTheme.colorScheme.*`, а **не** палитру напрямую —
чтобы позже появились другие темы без правки экранов (требование `R1.1`
десктопных требований).
## 3. Отрисовка Markdown — берём из `ai/assistent`
**Откуда:** https://git.binom.pw/ai/assistent (ветка `main`,
проверено на коммите `2c5b3f9`). Репозиторий приватный — скачивать по RAW-адресу
с логином: `https://git.binom.pw/ai/assistent/raw/branch/main/<путь>`.
**Писать своё не надо — надо взять это.** Четыре файла:
| Файл | Строк | Что внутри |
|---|---|---|
| `client-shared/src/main/kotlin/pw/binom/client/shared/markdown/MarkdownSegment.kt` | 59 | куски разметки: текст, блок кода, таблица, картинка, разделитель + стилевые участки |
| `client-shared/src/main/kotlin/pw/binom/client/shared/markdown/MarkdownParserImpl.kt` | 353 | `parseMarkdown(markdown): List<MarkdownSegment>` |
| `client-shared/src/main/kotlin/pw/binom/client/shared/ui/MarkdownRendering.kt` | 377 | сама отрисовка: inline-стили, ссылки, код с копированием, таблицы, картинки |
| `client/src/main/kotlin/pw/binom/client/ui/MarkdownRenderer.kt` | 25 | обёртка: открытие ссылки в браузере, `parseMultiline` — **образец использования** |
### Как переносить на Android
Модуль `client-shared` собран под **Compose Desktop** (JVM) — целиком как
зависимость его взять нельзя, на телефоне не соберётся. Поэтому **файлы
копируются в наш модуль**, а не подключаются.
Проверено по коду — переносятся почти дословно:
- `MarkdownSegment.kt`, `MarkdownParserImpl.kt` — **ни одной строки** под JVM,
Swing, AWT или Skiko. Чистая логика;
- `MarkdownRendering.kt` — только `androidx.compose.*` и **ни одного диалога**
и ни одного оконного примитива. Единственная платформенная мелочь —
`LocalClipboardManager` (для копирования кода), на Android он есть.
**Переделать придётся только одно:** открытие ссылок. В четвёртом файле это
`java.awt.Desktop.getDesktop().browse(...)` — **на телефоне AWT нет**. Вместо
этого системный переход:
```kotlin
context.startActivity(Intent(Intent.ACTION_VIEW, url.toUri()))
```
### Зависимость
Одна, и она уже есть в нашем Nexus:
```kotlin
implementation("ru.otpbank.ai:markdown:0.51.0")
```
Плюс репозиторий в `build.gradle.kts` — без него не соберётся:
```kotlin
maven {
url = uri("http://192.168.76.117/repository/developerspace-prod-mvn-hosted/")
isAllowInsecureProtocol = true
}
```
### Что из assistent НЕ берём
`MessageBubble.kt` (789 строк, пузырь сообщения целиком) — тянет за собой модуль
`chat-common`. Нам он не нужен: пузырь у нас свой, из макетов. Архитектуру,
слои, готовые экраны (`ChatScreen`, `SettingsDialog`) и модули `chat-*` —
**тоже не берём**, у нас своё (границы заимствования разобраны в десктопном
репозитории: `BORROW-FROM-ASSISTENT.md`).
### Приёмы отрисовки — самое ценное
В десктопном репозитории разобраны чужие грабли с указанием мест в коде:
`BORROW-FROM-ASSISTENT.md`, раздел «Приёмы отрисовки». Читать **до** переноса.
Главная из них: `Box(horizontalScroll)` внутри контейнера с бесконечной
максимальной шириной (`wrapContentWidth`) роняет Compose с ошибкой
`measured with an infinity maximum width` — таблицы размечаются парой разных
режимов. На телефоне экран узкий, и это особенно чувствительно.
**Состояние:** файлы ещё не перенесены — это отдельная задача. Переносить из
`ai/assistent` коммита `2c5b3f9` (свежее проверять там же).
## 4. Макеты экранов — свои, но выросли из десктопных
`design/mockups/` — пятнадцать экранов, по одному состоянию на файл. Рисовались
как продолжение одобренного десктопного дизайна
(`agentik-desktop/approved/001-sidebar-utility.html` — «привычный мессенджер»),
поэтому палитра, значки и порядок экранов совпадают с десктопом.
Чем отличаются — `PRINCIPLES.md`. Кратко: телефон всегда узкий, вместо
«Назад внутри узкого окна» — системная кнопка и жест, вместо модальных окон —
шторки снизу.
## 5. Принципы — не копируем, ссылаемся
Принципы (что видно на экране, группы, агенты, непрочитанные, «нет данных —
нет цифры», сообщения как источник правды) описаны в десктопном репозитории:
`REQUIREMENTS.md`, `approved/README.md`, `THEMES.md`, `STORAGE.md`, `CACHE.md`.
**Копий не делаем** — один источник правды лучше двух, которые разъедутся.
Отличия Android — в `PRINCIPLES.md`.
---
## Про доступы
Адрес и токен агента — **настройки приложения**, вводятся человеком, в коде
репозитория их нет и быть не должно. В историю коммитов секреты не попадают.